JM ldecod分析
ldecod简单分析
解码是规范中定义的涉及参数比较少。
下面是对简单分析中的函数列表进行解释。
初始化
解码的配置文件decoder.cfg在/bin下。
输入参数管理结构 参见关键数据结构
struct video_par是解码过程中用到video参数管理上下文结构。参见关键数据结构
decode 参数管理结构,包含上面列出的两个结构。
typedef struct decoder_params
{
InputParameters *p_Inp; //!< Input Parameters
VideoParameters *p_Vid; //!< Image Parameters
int64 bufferSize; //!< buffersize for tiff reads (not currently supported)
int UsedBits; // for internal statistics, is adjusted by read_se_v, read_ue_v, read_u_1
FILE *p_trace; //!< Trace file
int bitcounter;
} DecoderParams;
OpenDecoder
int OpenDecoder(InputParameters *p_Inp)
完成的主要动作有:
创建 DecoderParams 结构, alloc_decoder(&p_Dec),并用已经解释好的输入参数结构进行初始化。
alloc_decoder
alloc_video_params(&((*p_Dec)->p_Vid));
alloc_params(&((*p_Dec)->p_Inp));
alloc_video_params
解码上下文管理参数 VideoParameters的初始化完成了以下若干动作:
- 初始化dpb buffer,MAX_NUM_DPB_LAYERS为2,解码缓冲区管理参见DPB管理
- 分配ppSliceList slice指针数组 最大slice为16
- 分配nalu空间,为最大空间8000000
- 分配pDecOuputPic 解码图片列表
- pNextPPS ,分配pps 空间
/*!
***********************************************************************
* \brief
* Allocate the Video Parameters structure
* \par Output:
* Video Parameters VideoParameters *p_Vid
***********************************************************************
*/
static void alloc_video_params( VideoParameters **p_Vid)
{
int i;
if ((*p_Vid = (VideoParameters *) calloc(1, sizeof(VideoParameters)))==NULL)
no_mem_exit("alloc_video_params: p_Vid");
if (((*p_Vid)->old_slice = (OldSliceParams *) calloc(1, sizeof(OldSliceParams)))==NULL)
no_mem_exit("alloc_video_params: p_Vid->old_slice");
if (((*p_Vid)->snr = (SNRParameters *)calloc(1, sizeof(SNRParameters)))==NULL)
no_mem_exit("alloc_video_params: p_Vid->snr");
// Allocate new dpb buffer
for (i = 0; i < MAX_NUM_DPB_LAYERS; i++)
{
if (((*p_Vid)->p_Dpb_layer[i] = (DecodedPictureBuffer*)calloc(1, sizeof(DecodedPictureBuffer)))==NULL)
no_mem_exit("alloc_video_params: p_Vid->p_Dpb_layer[i]");
(*p_Vid)->p_Dpb_layer[i]->layer_id = i;
reset_dpb(*p_Vid, (*p_Vid)->p_Dpb_layer[i]);
if(((*p_Vid)->p_EncodePar[i] = (CodingParameters *)calloc(1, sizeof(CodingParameters))) == NULL)
no_mem_exit("alloc_video_params:p_Vid->p_EncodePar[i]");
((*p_Vid)->p_EncodePar[i])->layer_id = i;
if(((*p_Vid)->p_LayerPar[i] = (LayerParameters *)calloc(1, sizeof(LayerParameters))) == NULL)
no_mem_exit("alloc_video_params:p_Vid->p_LayerPar[i]");
((*p_Vid)->p_LayerPar[i])->layer_id = i;
}
(*p_Vid)->global_init_done[0] = (*p_Vid)->global_init_done[1] = 0;
#if (ENABLE_OUTPUT_TONEMAPPING)
if (((*p_Vid)->seiToneMapping = (ToneMappingSEI*)calloc(1, sizeof(ToneMappingSEI)))==NULL)
no_mem_exit("alloc_video_params: (*p_Vid)->seiToneMapping");
#endif
if(((*p_Vid)->ppSliceList = (Slice **) calloc(MAX_NUM_DECSLICES, sizeof(Slice *))) == NULL)
{
no_mem_exit("alloc_video_params: p_Vid->ppSliceList");
}
(*p_Vid)->iNumOfSlicesAllocated = MAX_NUM_DECSLICES;
//(*p_Vid)->currentSlice = NULL;
(*p_Vid)->pNextSlice = NULL;
(*p_Vid)->nalu = AllocNALU(MAX_CODED_FRAME_SIZE);
(*p_Vid)->pDecOuputPic = (DecodedPicList *)calloc(1, sizeof(DecodedPicList));
(*p_Vid)->pNextPPS = AllocPPS();
(*p_Vid)->first_sps = TRUE;
}
分配OldSliceParams
typedef struct old_slice_par
{
unsigned field_pic_flag;
unsigned frame_num;
int nal_ref_idc;
unsigned pic_oder_cnt_lsb;
int delta_pic_oder_cnt_bottom;
int delta_pic_order_cnt[2];
byte bottom_field_flag;
byte idr_flag;
int idr_pic_id;
int pps_id;
#if (MVC_EXTENSION_ENABLE)
int view_id;
int inter_view_flag;
int anchor_pic_flag;
#endif
int layer_id;
} OldSliceParams;
分配SNRParameters
typedef struct snr_par
{
int frame_ctr;
float snr[3]; //!< current SNR (component)
float snr1[3]; //!< SNR (dB) first frame (component)
float snra[3]; //!< Average component SNR (dB) remaining frames
float sse[3]; //!< component SSE
float msse[3]; //!< Average component SSE
} SNRParameters;
Allocate new dpb buffer
在video参数结构中管理有两个解码缓冲区
struct decoded_picture_buffer *p_Dpb_layer[MAX_NUM_DPB_LAYERS];
CodingParameters *p_EncodePar[MAX_NUM_DPB_LAYERS];
LayerParameters *p_LayerPar[MAX_NUM_DPB_LAYERS];
typedef struct coding_par
{
int layer_id;
int profile_idc;
int width;
int height;
int width_cr; //!< width chroma
int height_cr; //!< height chroma
int pic_unit_bitsize_on_disk;
short bitdepth_luma;
short bitdepth_chroma;
int bitdepth_scale[2];
int bitdepth_luma_qp_scale;
int bitdepth_chroma_qp_scale;
unsigned int dc_pred_value_comp[MAX_PLANE]; //!< component value for DC prediction (depends on component pel bit depth)
int max_pel_value_comp[MAX_PLANE]; //!< max value that one picture element (pixel) can take (depends on pic_unit_bitdepth)
int yuv_format;
int lossless_qpprime_flag;
int num_blk8x8_uv;
int num_uv_blocks;
int num_cdc_coeff;
int mb_cr_size_x;
int mb_cr_size_y;
int mb_cr_size_x_blk;
int mb_cr_size_y_blk;
int mb_cr_size;
int mb_size[3][2]; //!< component macroblock dimensions
int mb_size_blk[3][2]; //!< component macroblock dimensions
int mb_size_shift[3][2];
int max_vmv_r; //!< maximum vertical motion vector range in luma quarter frame pixel units for the current level_idc
int separate_colour_plane_flag;
int ChromaArrayType;
int max_frame_num;
unsigned int PicWidthInMbs;
unsigned int PicHeightInMapUnits;
unsigned int FrameHeightInMbs;
unsigned int FrameSizeInMbs;
int iLumaPadX;
int iLumaPadY;
int iChromaPadX;
int iChromaPadY;
int subpel_x;
int subpel_y;
int shiftpel_x;
int shiftpel_y;
int total_scale;
unsigned int oldFrameSizeInMbs;
//padding info;
void (*img2buf) (imgpel** imgX, unsigned char* buf, int size_x, int size_y, int symbol_size_in_bytes, int crop_left, int crop_right, int crop_top, int crop_bottom, int iOutStride);
int rgb_output;
imgpel **imgY_ref; //!< reference frame find snr
imgpel ***imgUV_ref;
Macroblock *mb_data; //!< array containing all MBs of a whole frame
Macroblock *mb_data_JV[MAX_PLANE]; //!< mb_data to be used for 4:4:4 independent mode
char *intra_block;
char *intra_block_JV[MAX_PLANE];
BlockPos *PicPos;
byte **ipredmode; //!< prediction type [90][74]
byte **ipredmode_JV[MAX_PLANE];
byte ****nz_coeff;
int **siblock;
int **siblock_JV[MAX_PLANE];
int *qp_per_matrix;
int *qp_rem_matrix;
}CodingParameters;
typedef struct layer_par
{
int layer_id;
struct video_par *p_Vid;
CodingParameters *p_Cps;
seq_parameter_set_rbsp_t *p_SPS;
struct decoded_picture_buffer *p_Dpb;
}LayerParameters;
switch( pDecoder->p_Inp->FileFormat )
{
default:
case PAR_OF_ANNEXB:
malloc_annex_b(pDecoder->p_Vid, &pDecoder->p_Vid->annex_b);
open_annex_b(pDecoder->p_Inp->infile, pDecoder->p_Vid->annex_b);
break;
case PAR_OF_RTP:
OpenRTPFile(pDecoder->p_Inp->infile, &pDecoder->p_Vid->BitStreamFile);
break;
}
根据输入文件流的类型,使用相应的模块打开文件输入流。这里有两种,标准中的H264裸流和RTP封装的网络流。
init_out_buffer(pDecoder->p_Vid);
分配一个frameStore结构。见输出图像管理
DecodeOneFrame
DecodeOneFrame(&pDecPicList);
调用 decode_one_frame(pDecoder)
decode_one_frame
decode_one_frame 工作流程
new_frame 为0,分配slice 结构给读取slice做准备。malloc_slice() 所做工作如后节所述。
初始化slice的dpb_layer 为第一个layer。
read_new_slice(currSlice) 获取slice。
slice相关的标记
enum {
EOS = 1, //!< End Of Sequence
SOP = 2, //!< Start Of Picture
SOS = 3, //!< Start Of Slice
SOS_CONT = 4
};
/*!
***********************************************************************
* \brief
* decodes one I- or P-frame
*
***********************************************************************
*/
int decode_one_frame(DecoderParams *pDecoder)
{
VideoParameters *p_Vid = pDecoder->p_Vid;
InputParameters *p_Inp = p_Vid->p_Inp;
int current_header, iRet;
Slice *currSlice; // = p_Vid->currentSlice;
Slice **ppSliceList = p_Vid->ppSliceList;
int iSliceNo;
//read one picture first;
p_Vid->iSliceNumOfCurrPic=0; //当前slice的序号
current_header=0;
p_Vid->iNumOfSlicesDecoded=0;
p_Vid->num_dec_mb = 0;
if(p_Vid->newframe)
{
if(p_Vid->pNextPPS->Valid)
{
//assert((int) p_Vid->pNextPPS->pic_parameter_set_id == p_Vid->pNextSlice->pic_parameter_set_id);
MakePPSavailable (p_Vid, p_Vid->pNextPPS->pic_parameter_set_id, p_Vid->pNextPPS);
p_Vid->pNextPPS->Valid=0;
}
//get the first slice from currentslice;
assert(ppSliceList[p_Vid->iSliceNumOfCurrPic]);
currSlice = ppSliceList[p_Vid->iSliceNumOfCurrPic];
ppSliceList[p_Vid->iSliceNumOfCurrPic] = p_Vid->pNextSlice;
p_Vid->pNextSlice = currSlice;
assert(ppSliceList[p_Vid->iSliceNumOfCurrPic]->current_slice_nr == 0);
currSlice = ppSliceList[p_Vid->iSliceNumOfCurrPic];
UseParameterSet (currSlice);
init_picture(p_Vid, currSlice, p_Inp);
p_Vid->iSliceNumOfCurrPic++;
current_header = SOS;
}
while(current_header != SOP && current_header !=EOS)
{
//no pending slices;
assert(p_Vid->iSliceNumOfCurrPic < p_Vid->iNumOfSlicesAllocated);
##ppSliceList是一个slice结构的指针数组,长度为16
if(!ppSliceList[p_Vid->iSliceNumOfCurrPic])
{
ppSliceList[p_Vid->iSliceNumOfCurrPic] = malloc_slice(p_Inp, p_Vid);
}
currSlice = ppSliceList[p_Vid->iSliceNumOfCurrPic];
//p_Vid->currentSlice = currSlice;
currSlice->p_Vid = p_Vid;
currSlice->p_Inp = p_Inp;
currSlice->p_Dpb = p_Vid->p_Dpb_layer[0]; //set default value;
currSlice->next_header = -8888;
currSlice->num_dec_mb = 0;
currSlice->coeff_ctr = -1;
currSlice->pos = 0;
currSlice->is_reset_coeff = FALSE;
currSlice->is_reset_coeff_cr = FALSE;
### 读取一个sliceheader
current_header = read_new_slice(currSlice);
//init;
currSlice->current_header = current_header;
// error tracking of primary and redundant slices.
Error_tracking(p_Vid, currSlice);
// If primary and redundant are received and primary is correct, discard the redundant
// else, primary slice will be replaced with redundant slice.
if(currSlice->frame_num == p_Vid->previous_frame_num && currSlice->redundant_pic_cnt !=0
&& p_Vid->Is_primary_correct !=0 && current_header != EOS)
{
continue;
}
#### 当slice为中间slice,或者是第一个slice时
if((current_header != SOP && current_header !=EOS) || (p_Vid->iSliceNumOfCurrPic==0 && current_header == SOP))
{
currSlice->current_slice_nr = (short) p_Vid->iSliceNumOfCurrPic;
p_Vid->dec_picture->max_slice_id = (short) imax(currSlice->current_slice_nr, p_Vid->dec_picture->max_slice_id);
if(p_Vid->iSliceNumOfCurrPic >0)
{
CopyPOC(*ppSliceList, currSlice);
ppSliceList[p_Vid->iSliceNumOfCurrPic-1]->end_mb_nr_plus1 = currSlice->start_mb_nr;
}
p_Vid->iSliceNumOfCurrPic++;
####当slicenum超过预分配的slicelist指针数组时,扩展空间,每次扩展的空间为16
if(p_Vid->iSliceNumOfCurrPic >= p_Vid->iNumOfSlicesAllocated)
{
Slice **tmpSliceList = (Slice **)realloc(p_Vid->ppSliceList, (p_Vid->iNumOfSlicesAllocated+MAX_NUM_DECSLICES)*sizeof(Slice*));
if(!tmpSliceList)
{
tmpSliceList = calloc((p_Vid->iNumOfSlicesAllocated+MAX_NUM_DECSLICES), sizeof(Slice*));
memcpy(tmpSliceList, p_Vid->ppSliceList, p_Vid->iSliceNumOfCurrPic*sizeof(Slice*));
//free;
free(p_Vid->ppSliceList);
ppSliceList = p_Vid->ppSliceList = tmpSliceList;
}
else
{
//assert(tmpSliceList == p_Vid->ppSliceList);
ppSliceList = p_Vid->ppSliceList = tmpSliceList;
memset(p_Vid->ppSliceList+p_Vid->iSliceNumOfCurrPic, 0, sizeof(Slice*)*MAX_NUM_DECSLICES);
}
p_Vid->iNumOfSlicesAllocated += MAX_NUM_DECSLICES;
}
current_header = SOS;
}
else
{
if(ppSliceList[p_Vid->iSliceNumOfCurrPic-1]->mb_aff_frame_flag)
ppSliceList[p_Vid->iSliceNumOfCurrPic-1]->end_mb_nr_plus1 = p_Vid->FrameSizeInMbs/2;
else
ppSliceList[p_Vid->iSliceNumOfCurrPic-1]->end_mb_nr_plus1 = p_Vid->FrameSizeInMbs/(1+ppSliceList[p_Vid->iSliceNumOfCurrPic-1]->field_pic_flag);
p_Vid->newframe = 1;
currSlice->current_slice_nr = 0;
//keep it in currentslice;
ppSliceList[p_Vid->iSliceNumOfCurrPic] = p_Vid->pNextSlice;
p_Vid->pNextSlice = currSlice;
}
copy_slice_info(currSlice, p_Vid->old_slice);
}
iRet = current_header;
init_picture_decoding(p_Vid);
{
for(iSliceNo=0; iSliceNo<p_Vid->iSliceNumOfCurrPic; iSliceNo++)
{
currSlice = ppSliceList[iSliceNo];
current_header = currSlice->current_header;
//p_Vid->currentSlice = currSlice;
assert(current_header != EOS);
assert(currSlice->current_slice_nr == iSliceNo);
init_slice(p_Vid, currSlice);
decode_slice(currSlice, current_header);
p_Vid->iNumOfSlicesDecoded++;
p_Vid->num_dec_mb += currSlice->num_dec_mb;
p_Vid->erc_mvperMB += currSlice->erc_mvperMB;
}
}
#if MVC_EXTENSION_ENABLE
p_Vid->last_dec_view_id = p_Vid->dec_picture->view_id;
#endif
if(p_Vid->dec_picture->structure == FRAME)
p_Vid->last_dec_poc = p_Vid->dec_picture->frame_poc;
else if(p_Vid->dec_picture->structure == TOP_FIELD)
p_Vid->last_dec_poc = p_Vid->dec_picture->top_poc;
else if(p_Vid->dec_picture->structure == BOTTOM_FIELD)
p_Vid->last_dec_poc = p_Vid->dec_picture->bottom_poc;
exit_picture(p_Vid, &p_Vid->dec_picture);
p_Vid->previous_frame_num = ppSliceList[0]->frame_num;
return (iRet);
}
malloc_slice
/*!
************************************************************************
* \brief
* Allocates the slice structure along with its dependent
* data structures
*
* \par Input:
* Input Parameters InputParameters *p_Inp, VideoParameters *p_Vid
************************************************************************
*/
Slice *malloc_slice(InputParameters *p_Inp, VideoParameters *p_Vid)
{
int i, j, memory_size = 0;
Slice *currSlice;
currSlice = (Slice *) calloc(1, sizeof(Slice));
if ( currSlice == NULL)
{
snprintf(errortext, ET_SIZE, "Memory allocation for Slice datastruct in NAL-mode %d failed", p_Inp->FileFormat);
error(errortext,100);
}
// create all context models
currSlice->mot_ctx = create_contexts_MotionInfo();
currSlice->tex_ctx = create_contexts_TextureInfo();
currSlice->max_part_nr = 3; //! assume data partitioning (worst case) for the following mallocs()
currSlice->partArr = AllocPartition(currSlice->max_part_nr);
memory_size += get_mem2Dwp (&(currSlice->wp_params), 2, MAX_REFERENCE_PICTURES);
memory_size += get_mem3Dint(&(currSlice->wp_weight), 2, MAX_REFERENCE_PICTURES, 3);
memory_size += get_mem3Dint(&(currSlice->wp_offset), 6, MAX_REFERENCE_PICTURES, 3);
memory_size += get_mem4Dint(&(currSlice->wbp_weight), 6, MAX_REFERENCE_PICTURES, MAX_REFERENCE_PICTURES, 3);
memory_size += get_mem3Dpel(&(currSlice->mb_pred), MAX_PLANE, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
memory_size += get_mem3Dpel(&(currSlice->mb_rec ), MAX_PLANE, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
memory_size += get_mem3Dint(&(currSlice->mb_rres), MAX_PLANE, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
memory_size += get_mem3Dint(&(currSlice->cof ), MAX_PLANE, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
// memory_size += get_mem3Dint(&(currSlice->fcf ), MAX_PLANE, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
allocate_pred_mem(currSlice);
#if (MVC_EXTENSION_ENABLE)
currSlice->view_id = MVC_INIT_VIEW_ID;
currSlice->inter_view_flag = 0;
currSlice->anchor_pic_flag = 0;
#endif
// reference flag initialization
for(i=0;i<17;++i)
{
currSlice->ref_flag[i] = 1;
}
for (i = 0; i < 6; i++)
{
currSlice->listX[i] = calloc(MAX_LIST_SIZE, sizeof (StorablePicture*)); // +1 for reordering
if (NULL==currSlice->listX[i])
no_mem_exit("malloc_slice: currSlice->listX[i]");
}
for (j = 0; j < 6; j++)
{
for (i = 0; i < MAX_LIST_SIZE; i++)
{
currSlice->listX[j][i] = NULL;
}
currSlice->listXsize[j]=0;
}
return currSlice;
}
获取一个slice header
准备解码
static void init_picture_decoding(VideoParameters *p_Vid)
{
Slice *pSlice = p_Vid->ppSliceList[0];
int j, i, iDeblockMode=1;
if(p_Vid->iSliceNumOfCurrPic >= MAX_NUM_SLICES)
{
error ("Maximum number of supported slices exceeded. \nPlease recompile with increased value for MAX_NUM_SLICES", 200);
}
if(p_Vid->pNextPPS->Valid && (int) p_Vid->pNextPPS->pic_parameter_set_id == pSlice->pic_parameter_set_id)
{
pic_parameter_set_rbsp_t tmpPPS;
memcpy(&tmpPPS, &(p_Vid->PicParSet[pSlice->pic_parameter_set_id]), sizeof (pic_parameter_set_rbsp_t));
(p_Vid->PicParSet[pSlice->pic_parameter_set_id]).slice_group_id = NULL;
MakePPSavailable (p_Vid, p_Vid->pNextPPS->pic_parameter_set_id, p_Vid->pNextPPS);
memcpy(p_Vid->pNextPPS, &tmpPPS, sizeof (pic_parameter_set_rbsp_t));
tmpPPS.slice_group_id = NULL;
}
UseParameterSet (pSlice);
if(pSlice->idr_flag)
p_Vid->number=0;
p_Vid->PicHeightInMbs = p_Vid->FrameHeightInMbs / ( 1 + pSlice->field_pic_flag );
p_Vid->PicSizeInMbs = p_Vid->PicWidthInMbs * p_Vid->PicHeightInMbs;
p_Vid->FrameSizeInMbs = p_Vid->PicWidthInMbs * p_Vid->FrameHeightInMbs;
p_Vid->structure = pSlice->structure;
fmo_init (p_Vid, pSlice);
#if (MVC_EXTENSION_ENABLE)
if((pSlice->layer_id>0) && (pSlice->svc_extension_flag == 0 && pSlice->NaluHeaderMVCExt.non_idr_flag == 0))
{
idr_memory_management(p_Vid->p_Dpb_layer[pSlice->layer_id], p_Vid->dec_picture);
}
update_ref_list(p_Vid->p_Dpb_layer[pSlice->view_id]);
update_ltref_list(p_Vid->p_Dpb_layer[pSlice->view_id]);
update_pic_num(pSlice);
i = pSlice->view_id;
#else
update_pic_num(pSlice);
i = 0;
#endif
init_Deblock(p_Vid, pSlice->mb_aff_frame_flag);
//init mb_data;
for(j=0; j<p_Vid->iSliceNumOfCurrPic; j++)
{
if(p_Vid->ppSliceList[j]->DFDisableIdc != 1)
iDeblockMode=0;
#if (MVC_EXTENSION_ENABLE)
assert(p_Vid->ppSliceList[j]->view_id == i);
#endif
}
p_Vid->iDeblockMode = iDeblockMode;
}
void update_pic_num(Slice *currSlice)
{
unsigned int i;
VideoParameters *p_Vid = currSlice->p_Vid;
DecodedPictureBuffer *p_Dpb = currSlice->p_Dpb;
seq_parameter_set_rbsp_t *active_sps = p_Vid->active_sps;
int add_top = 0, add_bottom = 0;
int max_frame_num = 1 << (active_sps->log2_max_frame_num_minus4 + 4);
if (currSlice->structure == FRAME)
{
for (i=0; i<p_Dpb->ref_frames_in_buffer; i++)
{
if ( p_Dpb->fs_ref[i]->is_used==3 )
{
if ((p_Dpb->fs_ref[i]->frame->used_for_reference)&&(!p_Dpb->fs_ref[i]->frame->is_long_term))
{
if( p_Dpb->fs_ref[i]->frame_num > currSlice->frame_num )
{
p_Dpb->fs_ref[i]->frame_num_wrap = p_Dpb->fs_ref[i]->frame_num - max_frame_num;
}
else
{
p_Dpb->fs_ref[i]->frame_num_wrap = p_Dpb->fs_ref[i]->frame_num;
}
p_Dpb->fs_ref[i]->frame->pic_num = p_Dpb->fs_ref[i]->frame_num_wrap;
}
}
}
// update long_term_pic_num
for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++)
{
if (p_Dpb->fs_ltref[i]->is_used==3)
{
if (p_Dpb->fs_ltref[i]->frame->is_long_term)
{
p_Dpb->fs_ltref[i]->frame->long_term_pic_num = p_Dpb->fs_ltref[i]->frame->long_term_frame_idx;
}
}
}
}
else
{
if (currSlice->structure == TOP_FIELD)
{
add_top = 1;
add_bottom = 0;
}
else
{
add_top = 0;
add_bottom = 1;
}
for (i=0; i<p_Dpb->ref_frames_in_buffer; i++)
{
if (p_Dpb->fs_ref[i]->is_reference)
{
if( p_Dpb->fs_ref[i]->frame_num > currSlice->frame_num )
{
p_Dpb->fs_ref[i]->frame_num_wrap = p_Dpb->fs_ref[i]->frame_num - max_frame_num;
}
else
{
p_Dpb->fs_ref[i]->frame_num_wrap = p_Dpb->fs_ref[i]->frame_num;
}
if (p_Dpb->fs_ref[i]->is_reference & 1)
{
p_Dpb->fs_ref[i]->top_field->pic_num = (2 * p_Dpb->fs_ref[i]->frame_num_wrap) + add_top;
}
if (p_Dpb->fs_ref[i]->is_reference & 2)
{
p_Dpb->fs_ref[i]->bottom_field->pic_num = (2 * p_Dpb->fs_ref[i]->frame_num_wrap) + add_bottom;
}
}
}
// update long_term_pic_num
for (i=0; i<p_Dpb->ltref_frames_in_buffer; i++)
{
if (p_Dpb->fs_ltref[i]->is_long_term & 1)
{
p_Dpb->fs_ltref[i]->top_field->long_term_pic_num = 2 * p_Dpb->fs_ltref[i]->top_field->long_term_frame_idx + add_top;
}
if (p_Dpb->fs_ltref[i]->is_long_term & 2)
{
p_Dpb->fs_ltref[i]->bottom_field->long_term_pic_num = 2 * p_Dpb->fs_ltref[i]->bottom_field->long_term_frame_idx + add_bottom;
}
}
}
}
void init_slice(VideoParameters *p_Vid, Slice *currSlice)
{
int i;
p_Vid->active_sps = currSlice->active_sps;
p_Vid->active_pps = currSlice->active_pps;
currSlice->init_lists (currSlice);
#if (MVC_EXTENSION_ENABLE)
if (currSlice->svc_extension_flag == 0 || currSlice->svc_extension_flag == 1)
reorder_lists_mvc (currSlice, currSlice->ThisPOC);
else
reorder_lists (currSlice);
if (currSlice->fs_listinterview0)
{
free(currSlice->fs_listinterview0);
currSlice->fs_listinterview0 = NULL;
}
if (currSlice->fs_listinterview1)
{
free(currSlice->fs_listinterview1);
currSlice->fs_listinterview1 = NULL;
}
#else
reorder_lists (currSlice);
#endif
if (currSlice->structure==FRAME)
{
init_mbaff_lists(p_Vid, currSlice);
}
//p_Vid->recovery_point = 0;
// update reference flags and set current p_Vid->ref_flag
if(!(currSlice->redundant_pic_cnt != 0 && p_Vid->previous_frame_num == currSlice->frame_num))
{
for(i=16;i>0;i--)
{
currSlice->ref_flag[i] = currSlice->ref_flag[i-1];
}
}
currSlice->ref_flag[0] = currSlice->redundant_pic_cnt==0 ? p_Vid->Is_primary_correct : p_Vid->Is_redundant_correct;
//p_Vid->previous_frame_num = currSlice->frame_num; //p_Vid->frame_num;
if((currSlice->active_sps->chroma_format_idc==0)||(currSlice->active_sps->chroma_format_idc==3))
{
currSlice->linfo_cbp_intra = linfo_cbp_intra_other;
currSlice->linfo_cbp_inter = linfo_cbp_inter_other;
}
else
{
currSlice->linfo_cbp_intra = linfo_cbp_intra_normal;
currSlice->linfo_cbp_inter = linfo_cbp_inter_normal;
}
}
void decode_slice(Slice *currSlice, int current_header)
{
if (currSlice->active_pps->entropy_coding_mode_flag)
{
init_contexts (currSlice);
cabac_new_slice(currSlice);
}
if ( (currSlice->active_pps->weighted_bipred_idc > 0 && (currSlice->slice_type == B_SLICE)) || (currSlice->active_pps->weighted_pred_flag && currSlice->slice_type !=I_SLICE))
fill_wp_params(currSlice);
//printf("frame picture %d %d %d\n",currSlice->structure,currSlice->ThisPOC,currSlice->direct_spatial_mv_pred_flag);
// decode main slice information
if ((current_header == SOP || current_header == SOS) && currSlice->ei_flag == 0)
decode_one_slice(currSlice);
// setMB-Nr in case this slice was lost
// if(currSlice->ei_flag)
// p_Vid->current_mb_nr = currSlice->last_mb_nr + 1;
}