📄 mpg_gethdr.c
字号:
/* gethdr.c, header decoding */
#include <stdio.h>
#include "mpg_config.h"
#include "mpg_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 0
static double mpeg_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
};
int Get_Seq_Hdr()
{
unsigned int code, time_out = 0xff;
for (;;)
{
if (Fault_Flag)
return 0;
if (!(time_out--))
return 0;
/* look for next_start_code */
next_start_code(ld);
code = Get_Bits32(ld);
switch (code)
{
case SEQUENCE_HEADER_CODE:
sequence_header();
if (mpeg.frameRate == -1.0)
mpeg.frameRate = mpeg_frame_rate_Table[mpeg_frame_rate_code];
return 1;
break;
default:
break;
}
}
}
int Get_GOP_Hdr()
{
unsigned int code, time_out = 0x4ff;
for (;;)
{
if (Fault_Flag)
return 0;
if (!(time_out--))
return 0;
/* look for next_start_code */
next_start_code(ld);
code = Show_Bits(ld, 32); //Get_Bits32(ld);
switch (code)
{
case GROUP_START_CODE:
return 1;
break;
case PICTURE_START_CODE:
case SEQUENCE_END_CODE:
case SEQUENCE_HEADER_CODE:
default:
Flush_Buffer32(ld);
if (Fault_Flag)
return 0;
break;
}
}
}
/*
* decode headers from one input stream
* until an End of Sequence or picture start code
* is found
*/
int Get_Hdr()
{
unsigned int code, time_out = 0xff;
for (;;)
{
if (Fault_Flag)
return 0;
if (!(time_out--))
return 0;
/* look for next_start_code */
next_start_code(ld);
code = Get_Bits32(ld);
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 (Fault_Flag)
return 0;
break;
}
}
}
/* align to start of next next_start_code */
void next_start_code(layer_data *laydat)
{
/* byte align */
Flush_Buffer(laydat, laydat->Incnt&7);
while (Show_Bits(laydat, 24) != 0x01L)
{
Flush_Buffer(laydat, 8);
if (Fault_Flag)
return;
}
}
/* decode sequence header */
static void sequence_header()
{
int pos;
pos = ld->Bitcnt;
horizontal_size = Get_Bits(ld, 12);
vertical_size = Get_Bits(ld, 12);
aspect_ratio_information = Get_Bits(ld, 4);
mpeg_frame_rate_code = Get_Bits(ld, 4);
//frame_rate = frame_rate_Table[frame_rate_code];
bit_rate_value = Get_Bits(ld, 18);
marker_bit(ld, "sequence_header()");
vbv_buffer_size = Get_Bits(ld, 10);
constrained_parameters_flag = Get_Bits(ld, 1);
if ((/*ld->load_intra_quantizer_matrix = */Get_Bits(ld, 1)))
{
}
if ((/*ld->load_non_intra_quantizer_matrix = */Get_Bits(ld, 1)))
{
}
#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", mpeg_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(ld, 1);
hour = Get_Bits(ld, 5);
minute = Get_Bits(ld, 6);
marker_bit(ld, "group_of_pictures_header()");
sec = Get_Bits(ld, 6);
frameID = Get_Bits(ld, 6);
closed_gop = Get_Bits(ld, 1);
broken_link = Get_Bits(ld, 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;
int temporal_reference;
int picture_coding_type;
int vbv_delay;
int full_pel_forward_vector;
int forward_f_code;
int full_pel_backward_vector;
int backward_f_code;
/* unless later overwritten by picture_spatial_scalable_extension() */
ld->pict_scal = 0;
pos = ld->Bitcnt;
temporal_reference = Get_Bits(ld, 10);
picture_coding_type = Get_Bits(ld, 3);
vbv_delay = Get_Bits(ld, 16);
if (picture_coding_type == P_TYPE || picture_coding_type == B_TYPE)
{
full_pel_forward_vector = Get_Bits(ld, 1);
forward_f_code = Get_Bits(ld, 3);
}
if (picture_coding_type == B_TYPE)
{
full_pel_backward_vector = Get_Bits(ld, 1);
backward_f_code = Get_Bits(ld, 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 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(ld);
while ((code = Show_Bits(ld, 32)) == EXTENSION_START_CODE || code == USER_DATA_START_CODE)
{
if (code == EXTENSION_START_CODE)
{
Flush_Buffer32(ld);
ext_ID = Get_Bits(ld, 4);
switch (ext_ID)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -