📄 sei.c
字号:
/*!
************************************************************************
* \file sei.c
* \brief
* Functions to implement SEI messages in decoder
* \by liuhui 2005/03/20 liuhui@mail.ustc.edu.cn
************************************************************************
*/
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include "global.h"
#include "memalloc.h"
#include "sei.h"
#include "vlc.h"
#include "header.h"
#include "parset.h"
#include "HRD.h"
extern unsigned int seq_parameter_set_id;
extern unsigned int cpb_dpb_cnt_minus1;
extern unsigned int *cpb_underflow_allowable_flag;
extern unsigned int *bit_rate_value_minus1_lsb;
extern unsigned int *bit_rate_value_minus1_msb;
extern unsigned int *cpb_size_value_minus1_lsb;
extern unsigned int *cpb_size_value_minus1_msb;
extern unsigned int *dpb_size_value_minus1_lsb;
extern unsigned int *dpb_size_value_minus1_msb;
extern unsigned int *initial_cpb_removal_delay_lsb;
extern unsigned int *initial_cpb_removal_delay_msb;
extern unsigned int *initial_cpb_removal_delay;
extern unsigned int *initial_dpb_output_delay_lsb;
extern unsigned int *initial_dpb_output_delay_msb;
extern unsigned int *initial_dpb_output_delay;
extern unsigned int *Bit_Buffer;
extern unsigned int *ROT;
extern struct DecodedPictureBuffer dpb;
extern struct FrameBuffer outframe;
extern struct FrameBuffer decframe;
extern unsigned int outputtimer;
extern int pre_picture_distance;
/*!
************************************************************************
* \brief
* Interpret the SEI rbsp
* \param msg
* a pointer that point to the sei message.
* \param size
* the size of the sei message
* \param img
* the image pointer
*
************************************************************************
*/
void InterpretSEIMessage(byte* msg, int size, Image *img)
{
int payload_type = 0;
int payload_size = 0;
int offset = 1; //skip first NAL header byte
#if TRACE
fprintf(p_trace,"\n");
tracebits2("start_code_prefix",24,0x01);
fprintf(p_trace,"ANNEX B NALU, len %d, forbidden_bit %d, nal_reference_idc %d, nal_unit_type %d,\n",
nalu->len,nalu->forbidden_bit,nalu->nal_reference_idc,nalu->nal_unit_type);
#endif
#if TRACE
tracebits2("SEI: NALU Header",8,nalu->buf[0]);
#endif
do
{
// sei_message();
payload_type = 0;
while ( msg[offset++] == 0xFF)
payload_type += 255;
payload_type += msg[offset-1]; // this is the last byte
payload_size = 0;
while ( msg[offset++] == 0xFF)
payload_size += 255;
payload_size += msg[offset-1]; // this is the last byte
switch ( payload_type ) // sei_payload( type, size );
{
case SEI_USER_DATA:
#if TRACE //liuhui 0601
tracebits2("SEI: UserData:PayloadType",8,payload_type);
tracebits2("SEI: UserData:PayloadSize",8,payload_size);
#endif
interpret_user_data(msg+offset, payload_size, img );
break;
case SEI_FULL_FRAME_FREEZE:
#if TRACE //liuhui 0601
tracebits2("SEI: FullFrameFreeze:PayloadType",8,payload_type);
tracebits2("SEI: FullFrameFreeze:PayloadSize",8,payload_size);
#endif
interpret_full_frame_freeze( msg+offset, payload_size, img );
break;
case SEI_FULL_FRAME_FREEZE_RELEASE:
#if TRACE //liuhui 0601
tracebits2("SEI: FullFrameFreezeRelease:PayloadType",8,payload_type);
tracebits2("SEI: FullFrameFreezeRelease:PayloadSize",8,payload_size);
#endif
interpret_full_frame_freeze_release( msg+offset, payload_size, img );
break;
case SEI_SCALABLE_LAYER_PROFILE_LEVEL:
#if TRACE //liuhui 0601
tracebits2("SEI: ScalaLayerProfileLevel:PayloadType",8,payload_type);
tracebits2("SEI: ScalaLayerProfileLevel:PayloadSize",8,payload_size);
#endif
interpret_scalable_layer_profile_level(msg+offset, payload_size, img );
break;
#ifdef _HRD_
case SEI_HRD_BUFFERING_PARAMETERS:
#if TRACE //liuhui 0601
tracebits2("SEI: HRDBufferParam:PayloadType",8,payload_type);
tracebits2("SEI: HRDBufferParam:PayloadSize",8,payload_size);
#endif
interpret_hrd_buffering_parameters(msg+offset, payload_size, img );
break;
#endif
case SEI_GRADUAL_RANDOM_ACCESS:
#if TRACE //liuhui 0601
tracebits2("SEI: GradualRandomAccess:PayloadType",8,payload_type);
tracebits2("SEI: GradualRandomAccess:PayloadSize",8,payload_size);
#endif
interpret_gradual_random_access(msg+offset, payload_size, img );
break;
default:
#if TRACE //liuhui 0601
tracebits2("SEI: Reserved:PayloadType",8,payload_type);
tracebits2("SEI: Reserved:PayloadSize",8,payload_size);
#endif
interpret_reserved( msg+offset, payload_size, img );
break;
}
offset += payload_size;
}while( 0 );
}
/*!
************************************************************************
* \brief
* Interpret the User data SEI message
* \param payload
* a pointer that point to the sei payload
* \param size
* the size of the sei message
* \param img
* the image pointer
************************************************************************
*/
void interpret_user_data( byte* payload, int size, Image *img )
{
byte uiUserData;
int i;
Bitstream *bitstream = AllocBitstream();
for(i = 0; i < size; i++)
bitstream->streamBuffer[i] = payload[i];
bitstream->frame_bitoffset = 0;
bitstream->bitstream_length = size;
#ifdef PRINT_USER_DATA
printf("----- USER_DATA SEI -----\n");
#endif
for( i = 0; i < size*8/17; i++)
{
uiUserData = SEI_u_v(8, "UserData", bitstream);
putchar(uiUserData);
uiUserData = SEI_u_v(8, "UserData", bitstream);
putchar(uiUserData);
uiUserData = SEI_u_v(1, "market_bit", bitstream);
}
if(((size*8)%17) > 8) /*Zhan Ma*/
{
uiUserData = SEI_u_v(8, "UserData", bitstream);
putchar(uiUserData);
}
printf("\n");
#if TRACE //liuhui 0601
if( (size*8 - bitstream->frame_bitoffset) != 0 ) //read trailing_bits
{
i = size*8 - bitstream->frame_bitoffset;
SEI_u_v(i, "SEI: trailing_bits", bitstream);
}
#endif
}
/*!
************************************************************************
* \brief
* Interpret the Full-frame freeze SEI message
* \param payload
* a pointer that point to the sei payload
* \param size
* the size of the sei message
* \param img
* the image pointer
*
************************************************************************
*/
void interpret_full_frame_freeze( byte* payload, int size, Image *img )
{
//when this function executes, full frame freeze valids
assert(size == 1);
assert( *payload == 0x80 );
#if TRACE //liuhui 0601
tracebits2("SEI: trailing_bits",8,*payload);
#endif
#ifdef PRINT_FULL_FRAME_FREEZE
printf("----- FULL_FRAME_FREEZE SEI -----\n");
#endif
}
/*!
************************************************************************
* \brief
* Interpret the Full-frame freeze release SEI message
* \param payload
* a pointer that point to the sei payload
* \param size
* the size of the sei message
* \param img
* the image pointer
*
************************************************************************
*/
void interpret_full_frame_freeze_release( byte* payload, int size, Image *img )
{
assert(size == 1);
assert(*payload == 0x80);
#if TRACE //liuhui 0601
tracebits2("SEI: trailing_bits",8,*payload);
#endif
#ifdef PRINT_FULL_FRAME_FREEZE_RELEASE
printf("----- FULL_FRAME_FREEZE_RELEASE SEI -----\n");
#endif
}
/*!
************************************************************************
* \brief
* Interpret the Scalable layer profile level SEI message
* \param payload
* a pointer that point to the sei payload
* \param size
* the size of the sei message
* \param img
* the image pointer
************************************************************************
*/
void interpret_scalable_layer_profile_level(byte* payload, int size, Image *img )
{
unsigned int ref_pic_profile_idc, ref_pic_level_idc;
assert(size == 3);
ref_pic_profile_idc = payload[0];
ref_pic_level_idc = payload[1];
#if TRACE //liuhui 0601
tracebits2("SEI: Profile_Idc",8,ref_pic_profile_idc);
tracebits2("SEI: Level_Idc",8,ref_pic_level_idc);
tracebits2("SEI: trailing_bits",8,payload[2]);
#endif
#ifdef PRINT_SCALABLE_LAYER_PROFILE_LEVEL
printf("----- SCALABLE_LAYER_PROFILE_LEVEL SEI -----\n");
printf("Ref_pic_profile_idc: %d\n", ref_pic_profile_idc );
printf("Ref_pic_level_idc : %d\n", ref_pic_level_idc );
#endif
}
#ifdef _HRD_ //BUG_FIX liuhui 0512
/*!
************************************************************************
* \brief
* Interpret the HRD buffering parameters SEI message
* \param payload
* a pointer that point to the sei payload
* \param size
* the size of the sei message
* \param img
* the image pointer
************************************************************************
*/
void interpret_hrd_buffering_parameters(byte* payload, int size, Image *img )
{
// unsigned int bit_rate,cpb_size,dpb_size,initCpbDelay,initDpbDelay;//guoyi BUG_FIX 01/06
unsigned int HrdIdx;
int i;
Bitstream *bitstream = AllocBitstream();
for(i = 0; i < size; i++)
bitstream->streamBuffer[i] = payload[i];
bitstream->frame_bitoffset = 0;
bitstream->bitstream_length = size;
//#define _PRINT_
seq_parameter_set_id = SEI_ue_v("seq_parameter_set_id", bitstream);
cpb_dpb_cnt_minus1 = SEI_ue_v("cpb_dpb_cnt_minus1", bitstream);
init_hrd(cpb_dpb_cnt_minus1 + 1);
#ifdef _PRINT_
printf("\n\n----------HRD SEI informations----------\n");
printf("seq_parameter_set_id :%d\n",seq_parameter_set_id);
printf("cpb_dpb_cnt_minus1 :%d\n", cpb_dpb_cnt_minus1 );
#endif
for(HrdIdx = 0; HrdIdx < cpb_dpb_cnt_minus1 + 1; HrdIdx++)
{
cpb_underflow_allowable_flag[HrdIdx] = SEI_u_1("cpb_underflow_allowable_flag[HrdIdx]", bitstream);
bit_rate_value_minus1_lsb[HrdIdx] = SEI_ue_v("bit_rate_value_minus1_lsb[HrdIdx]", bitstream);
SEI_u_v(1, "marker_bit", bitstream );
bit_rate_value_minus1_msb[HrdIdx] = SEI_ue_v("bit_rate_value_minus1_msb[HrdIdx]", bitstream);
SEI_u_v(1, "marker_bit", bitstream );
cpb_size_value_minus1_lsb[HrdIdx] = SEI_ue_v("cpb_size_value_minus1_lsb[HrdIdx]", bitstream);
SEI_u_v(1, "marker_bit", bitstream );
cpb_size_value_minus1_msb[HrdIdx] = SEI_ue_v("cpb_size_value_minus1_msb[HrdIdx]", bitstream);
SEI_u_v(1, "marker_bit", bitstream );
dpb_size_value_minus1_lsb[HrdIdx] = SEI_ue_v("dpb_size_value_minus1_lsb[HrdIdx]", bitstream);
SEI_u_v(1, "marker_bit", bitstream );
dpb_size_value_minus1_msb[HrdIdx] = SEI_ue_v("dpb_size_value_minus1_msb[HrdIdx]", bitstream);
SEI_u_v(1, "marker_bit", bitstream );
if( sps->initial_cpb_removal_delay_length > 16 )
{
initial_cpb_removal_delay_lsb[HrdIdx] = SEI_u_v(16, "initial_cpb_removal_delay_lsb[HrdIdx]", bitstream);
SEI_u_v( 1, "marker_bit", bitstream );
initial_cpb_removal_delay_msb[HrdIdx] = SEI_u_v(sps->initial_cpb_removal_delay_length-16, "initial_cpb_removal_delay_msb[HrdIdx]", bitstream);
}
else
initial_cpb_removal_delay[HrdIdx] = SEI_u_v(sps->initial_cpb_removal_delay_length, "initial_cpb_removal_delay [HrdIdx]", bitstream);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -