📄 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 + -