📄 gethdr.c
字号:
/* gethdr.c, header decoding *//* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. *//* * Disclaimer of Warranty * * These software programs are available to the user without any license fee or * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims * any and all warranties, whether express, implied, or statuary, including any * implied warranties or merchantability or of fitness for a particular * purpose. In no event shall the copyright-holder be liable for any * incidental, punitive, or consequential damages of any kind whatsoever * arising from the use of these programs. * * This disclaimer of warranty extends to the user of these programs and user's * customers, employees, agents, transferees, successors, and assigns. * * The MPEG Software Simulation Group does not represent or warrant that the * programs furnished hereunder are free of infringement of any third-party * patents. * * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, * are subject to royalty fees to patent holders. Many of these patents are * general enough such that they are unavoidable regardless of implementation * design. * */#include <stdio.h>#include "config.h"#include "global.h"/* private prototypes */static void sequence_header _ANSI_ARGS_((void));static void group_of_pictures_header _ANSI_ARGS_((void));static void picture_header _ANSI_ARGS_((void));static void extension_and_user_data _ANSI_ARGS_((void));static void sequence_extension _ANSI_ARGS_((void));static void sequence_display_extension _ANSI_ARGS_((void));static void quant_matrix_extension _ANSI_ARGS_((void));static void sequence_scalable_extension _ANSI_ARGS_((void));static void picture_display_extension _ANSI_ARGS_((void));static void picture_coding_extension _ANSI_ARGS_((void));static void picture_spatial_scalable_extension _ANSI_ARGS_((void));static void picture_temporal_scalable_extension _ANSI_ARGS_((void));static int extra_bit_information _ANSI_ARGS_((void));static void copyright_extension _ANSI_ARGS_((void));static void user_data _ANSI_ARGS_((void));static void user_data _ANSI_ARGS_((void));/* introduced in September 1995 to assist spatial scalable decoding */static void Update_Temporal_Reference_Tacking_Data _ANSI_ARGS_((void));/* private variables */static int Temporal_Reference_Base = 0;static int True_Framenum_max = -1;static int Temporal_Reference_GOP_Reset = 0;#define RESERVED -1 static double frame_rate_Table[16] ={ 0.0, ((23.0*1000.0)/1001.0), 24.0, 25.0, ((30.0*1000.0)/1001.0), 30.0, 50.0, ((60.0*1000.0)/1001.0), 60.0, RESERVED, RESERVED, RESERVED, RESERVED, RESERVED, RESERVED, RESERVED};/* * decode headers from one input stream * until an End of Sequence or picture start code * is found */int Get_Hdr(){ unsigned int code; for (;;) { /* look for next_start_code */ next_start_code(); code = Get_Bits32(); switch (code) { case SEQUENCE_HEADER_CODE: sequence_header(); break; case GROUP_START_CODE: group_of_pictures_header(); break; case PICTURE_START_CODE: picture_header(); return 1; break; case SEQUENCE_END_CODE: return 0; break; default: if (!Quiet_Flag) fprintf(stderr,"Unexpected next_start_code %08x (ignored)\n",code); break; } }}/* align to start of next next_start_code */void next_start_code(){ /* byte align */ Flush_Buffer(ld->Incnt&7); while (Show_Bits(24)!=0x01L) Flush_Buffer(8);}/* decode sequence header */static void sequence_header(){ int i; int pos; pos = ld->Bitcnt; horizontal_size = Get_Bits(12); vertical_size = Get_Bits(12); aspect_ratio_information = Get_Bits(4); frame_rate_code = Get_Bits(4); bit_rate_value = Get_Bits(18); marker_bit("sequence_header()"); vbv_buffer_size = Get_Bits(10); constrained_parameters_flag = Get_Bits(1); if((ld->load_intra_quantizer_matrix = Get_Bits(1))) { for (i=0; i<64; i++) ld->intra_quantizer_matrix[scan[ZIG_ZAG][i]] = Get_Bits(8); } else { for (i=0; i<64; i++) ld->intra_quantizer_matrix[i] = default_intra_quantizer_matrix[i]; } if((ld->load_non_intra_quantizer_matrix = Get_Bits(1))) { for (i=0; i<64; i++) ld->non_intra_quantizer_matrix[scan[ZIG_ZAG][i]] = Get_Bits(8); } else { for (i=0; i<64; i++) ld->non_intra_quantizer_matrix[i] = 16; } /* copy luminance to chrominance matrices */ for (i=0; i<64; i++) { ld->chroma_intra_quantizer_matrix[i] = ld->intra_quantizer_matrix[i]; ld->chroma_non_intra_quantizer_matrix[i] = ld->non_intra_quantizer_matrix[i]; }#ifdef VERBOSE if (Verbose_Flag > NO_LAYER) { printf("sequence header (byte %d)\n",(pos>>3)-4); if (Verbose_Flag > SEQUENCE_LAYER) { printf(" horizontal_size=%d\n",horizontal_size); printf(" vertical_size=%d\n",vertical_size); printf(" aspect_ratio_information=%d\n",aspect_ratio_information); printf(" frame_rate_code=%d",frame_rate_code); printf(" bit_rate_value=%d\n",bit_rate_value); printf(" vbv_buffer_size=%d\n",vbv_buffer_size); printf(" constrained_parameters_flag=%d\n",constrained_parameters_flag); printf(" load_intra_quantizer_matrix=%d\n",ld->load_intra_quantizer_matrix); printf(" load_non_intra_quantizer_matrix=%d\n",ld->load_non_intra_quantizer_matrix); } }#endif /* VERBOSE */#ifdef VERIFY verify_sequence_header++;#endif /* VERIFY */ extension_and_user_data();}/* decode group of pictures header *//* ISO/IEC 13818-2 section 6.2.2.6 */static void group_of_pictures_header(){ int pos; if (ld == &base) { Temporal_Reference_Base = True_Framenum_max + 1; /* *CH* */ Temporal_Reference_GOP_Reset = 1; } pos = ld->Bitcnt; drop_flag = Get_Bits(1); hour = Get_Bits(5); minute = Get_Bits(6); marker_bit("group_of_pictures_header()"); sec = Get_Bits(6); frame = Get_Bits(6); closed_gop = Get_Bits(1); broken_link = Get_Bits(1);#ifdef VERBOSE if (Verbose_Flag > NO_LAYER) { printf("group of pictures (byte %d)\n",(pos>>3)-4); if (Verbose_Flag > SEQUENCE_LAYER) { printf(" drop_flag=%d\n",drop_flag); printf(" timecode %d:%02d:%02d:%02d\n",hour,minute,sec,frame); printf(" closed_gop=%d\n",closed_gop); printf(" broken_link=%d\n",broken_link); } }#endif /* VERBOSE */#ifdef VERIFY verify_group_of_pictures_header++;#endif /* VERIFY */ extension_and_user_data();}/* decode picture header *//* ISO/IEC 13818-2 section 6.2.3 */static void picture_header(){ int pos; int Extra_Information_Byte_Count; /* unless later overwritten by picture_spatial_scalable_extension() */ ld->pict_scal = 0; pos = ld->Bitcnt; temporal_reference = Get_Bits(10); picture_coding_type = Get_Bits(3); vbv_delay = Get_Bits(16); if (picture_coding_type==P_TYPE || picture_coding_type==B_TYPE) { full_pel_forward_vector = Get_Bits(1); forward_f_code = Get_Bits(3); } if (picture_coding_type==B_TYPE) { full_pel_backward_vector = Get_Bits(1); backward_f_code = Get_Bits(3); }#ifdef VERBOSE if (Verbose_Flag>NO_LAYER) { printf("picture header (byte %d)\n",(pos>>3)-4); if (Verbose_Flag>SEQUENCE_LAYER) { printf(" temporal_reference=%d\n",temporal_reference); printf(" picture_coding_type=%d\n",picture_coding_type); printf(" vbv_delay=%d\n",vbv_delay); if (picture_coding_type==P_TYPE || picture_coding_type==B_TYPE) { printf(" full_pel_forward_vector=%d\n",full_pel_forward_vector); printf(" forward_f_code =%d\n",forward_f_code); } if (picture_coding_type==B_TYPE) { printf(" full_pel_backward_vector=%d\n",full_pel_backward_vector); printf(" backward_f_code =%d\n",backward_f_code); } } }#endif /* VERBOSE */#ifdef VERIFY verify_picture_header++;#endif /* VERIFY */ Extra_Information_Byte_Count = extra_bit_information(); extension_and_user_data(); /* update tracking information used to assist spatial scalability */ Update_Temporal_Reference_Tacking_Data();}/* decode slice header *//* ISO/IEC 13818-2 section 6.2.4 */int slice_header(){ int slice_vertical_position_extension; int quantizer_scale_code; int pos; int slice_picture_id_enable = 0; int slice_picture_id = 0; int extra_information_slice = 0; pos = ld->Bitcnt; slice_vertical_position_extension = (ld->MPEG2_Flag && vertical_size>2800) ? Get_Bits(3) : 0; if (ld->scalable_mode==SC_DP) ld->priority_breakpoint = Get_Bits(7); quantizer_scale_code = Get_Bits(5); ld->quantizer_scale = ld->MPEG2_Flag ? (ld->q_scale_type ? Non_Linear_quantizer_scale[quantizer_scale_code] : quantizer_scale_code<<1) : quantizer_scale_code; /* slice_id introduced in March 1995 as part of the video corridendum (after the IS was drafted in November 1994) */ if (Get_Bits(1)) { ld->intra_slice = Get_Bits(1); slice_picture_id_enable = Get_Bits(1); slice_picture_id = Get_Bits(6); extra_information_slice = extra_bit_information(); } else ld->intra_slice = 0;#ifdef VERBOSE if (Verbose_Flag>PICTURE_LAYER) { printf("slice header (byte %d)\n",(pos>>3)-4); if (Verbose_Flag>SLICE_LAYER) { if (ld->MPEG2_Flag && vertical_size>2800) printf(" slice_vertical_position_extension=%d\n",slice_vertical_position_extension); if (ld->scalable_mode==SC_DP) printf(" priority_breakpoint=%d\n",ld->priority_breakpoint); printf(" quantizer_scale_code=%d\n",quantizer_scale_code); printf(" slice_picture_id_enable = %d\n", slice_picture_id_enable); if(slice_picture_id_enable) printf(" slice_picture_id = %d\n", slice_picture_id); } }#endif /* VERBOSE */#ifdef VERIFY verify_slice_header++;#endif /* VERIFY */ return slice_vertical_position_extension;}/* decode extension and user data *//* ISO/IEC 13818-2 section 6.2.2.2 */static void extension_and_user_data(){ int code,ext_ID; next_start_code(); while ((code = Show_Bits(32))==EXTENSION_START_CODE || code==USER_DATA_START_CODE) { if (code==EXTENSION_START_CODE) { Flush_Buffer32(); ext_ID = Get_Bits(4); switch (ext_ID) { case SEQUENCE_EXTENSION_ID: sequence_extension(); break; case SEQUENCE_DISPLAY_EXTENSION_ID: sequence_display_extension(); break; case QUANT_MATRIX_EXTENSION_ID: quant_matrix_extension(); break; case SEQUENCE_SCALABLE_EXTENSION_ID: sequence_scalable_extension(); break; case PICTURE_DISPLAY_EXTENSION_ID: picture_display_extension(); break; case PICTURE_CODING_EXTENSION_ID: picture_coding_extension(); break; case PICTURE_SPATIAL_SCALABLE_EXTENSION_ID: picture_spatial_scalable_extension(); break; case PICTURE_TEMPORAL_SCALABLE_EXTENSION_ID: picture_temporal_scalable_extension(); break; case COPYRIGHT_EXTENSION_ID: copyright_extension(); break; default: fprintf(stderr,"reserved extension start code ID %d\n",ext_ID); break; } next_start_code(); } else {#ifdef VERBOSE if (Verbose_Flag>NO_LAYER) printf("user data\n");#endif /* VERBOSE */ Flush_Buffer32(); user_data(); } }}/* decode sequence extension *//* ISO/IEC 13818-2 section 6.2.2.3 */static void sequence_extension(){ int horizontal_size_extension; int vertical_size_extension; int bit_rate_extension; int vbv_buffer_size_extension; int pos; /* derive bit position for trace */#ifdef VERBOSE pos = ld->Bitcnt;#endif ld->MPEG2_Flag = 1; ld->scalable_mode = SC_NONE; /* unless overwritten by sequence_scalable_extension() */ layer_id = 0; /* unless overwritten by sequence_scalable_extension() */ profile_and_level_indication = Get_Bits(8); progressive_sequence = Get_Bits(1); chroma_format = Get_Bits(2); horizontal_size_extension = Get_Bits(2); vertical_size_extension = Get_Bits(2); bit_rate_extension = Get_Bits(12); marker_bit("sequence_extension"); vbv_buffer_size_extension = Get_Bits(8); low_delay = Get_Bits(1); frame_rate_extension_n = Get_Bits(2); frame_rate_extension_d = Get_Bits(5); frame_rate = frame_rate_Table[frame_rate_code] * ((frame_rate_extension_n+1)/(frame_rate_extension_d+1)); /* special case for 422 profile & level must be made */ if((profile_and_level_indication>>7) & 1) { /* escape bit of profile_and_level_indication set */ /* 4:2:2 Profile @ Main Level */ if((profile_and_level_indication&15)==5) { profile = PROFILE_422; level = MAIN_LEVEL; } } else { profile = profile_and_level_indication >> 4; /* Profile is upper nibble */ level = profile_and_level_indication & 0xF; /* Level is lower nibble */ } horizontal_size = (horizontal_size_extension<<12) | (horizontal_size&0x0fff); vertical_size = (vertical_size_extension<<12) | (vertical_size&0x0fff); /* ISO/IEC 13818-2 does not define bit_rate_value to be composed of * both the original bit_rate_value parsed in sequence_header() and * the optional bit_rate_extension in sequence_extension_header(). * However, we use it for bitstream verification purposes. */ bit_rate_value += (bit_rate_extension << 18); bit_rate = ((double) bit_rate_value) * 400.0; vbv_buffer_size += (vbv_buffer_size_extension << 10);#ifdef VERBOSE if (Verbose_Flag>NO_LAYER) { printf("sequence extension (byte %d)\n",(pos>>3)-4); if (Verbose_Flag>SEQUENCE_LAYER) { printf(" profile_and_level_indication=%d\n",profile_and_level_indication); if (profile_and_level_indication<128) { printf(" profile=%d, level=%d\n",profile,level); } printf(" progressive_sequence=%d\n",progressive_sequence); printf(" chroma_format=%d\n",chroma_format); printf(" horizontal_size_extension=%d\n",horizontal_size_extension); printf(" vertical_size_extension=%d\n",vertical_size_extension); printf(" bit_rate_extension=%d\n",bit_rate_extension); printf(" vbv_buffer_size_extension=%d\n",vbv_buffer_size_extension);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -