slice.c
来自「the newest JM software by h.264 JVT offi」· C语言 代码 · 共 1,870 行 · 第 1/4 页
C
1,870 行
if (img->type != I_SLICE && (active_pps->weighted_pred_flag == 1 || (active_pps->weighted_bipred_idc > 0 && (img->type == B_SLICE))))
{
if (img->type==P_SLICE || img->type==SP_SLICE)
{
int wp_type = (params->GenerateMultiplePPS && params->RDPictureDecision) && (enc_picture != enc_frame_picture[1]);
EstimateWPPSlice (img, params, wp_type);
}
else
EstimateWPBSlice (img, params);
}
set_ref_pic_num();
if (img->type == B_SLICE)
{
if( IS_INDEPENDENT(params) )
{
compute_colocated_JV(Co_located, listX);
}
else
{
compute_colocated(Co_located, listX);
}
}
if (img->type != I_SLICE && params->SearchMode == EPZS)
EPZSSliceInit(params, img, EPZSCo_located, listX);
if ((*currSlice)->symbol_mode == CAVLC)
{
writeMB_typeInfo = writeSE_UVLC;
writeIntraPredMode = writeIntraPredMode_CAVLC;
writeB8_typeInfo = writeSE_UVLC;
for (i=0; i<6; i++)
{
switch (listXsize[i])
{
case 0:
writeRefFrame[i] = NULL;
break;
case 1:
writeRefFrame[i] = writeSE_Dummy;
break;
case 2:
writeRefFrame[i] = writeSE_invFlag;
break;
default:
writeRefFrame[i] = writeSE_UVLC;
break;
}
}
writeMVD = writeSE_SVLC;
writeCBP = writeCBP_VLC;
writeDquant = writeSE_SVLC;
writeCIPredMode = writeSE_UVLC;
writeFieldModeInfo = writeSE_Flag;
writeMB_transform_size = writeSE_Flag;
}
else
{
writeMB_typeInfo = writeMB_typeInfo_CABAC;
writeIntraPredMode = writeIntraPredMode_CABAC;
writeB8_typeInfo = writeB8_typeInfo_CABAC;
for (i=0; i<6; i++)
{
switch (listXsize[i])
{
case 0:
writeRefFrame[i] = NULL;
break;
case 1:
writeRefFrame[i] = writeSE_Dummy;
break;
default:
writeRefFrame[i] = writeRefFrame_CABAC;
}
}
writeMVD = writeMVD_CABAC;
writeCBP = writeCBP_CABAC;
writeDquant = writeDquant_CABAC;
writeCIPredMode = writeCIPredMode_CABAC;
writeFieldModeInfo = writeFieldModeInfo_CABAC;
writeMB_transform_size = writeMB_transform_size_CABAC;
}
// assign luma common reference picture pointers to be used for ME/sub-pel interpolation
for(i = 0; i < active_ref_lists; i++)
{
for(j = 0; j < listXsize[i]; j++)
{
if( listX[i][j] )
{
listX[i][j]->p_curr_img = listX[i][j]->p_img [img->colour_plane_id];
listX[i][j]->p_curr_img_sub = listX[i][j]->p_img_sub[img->colour_plane_id];
}
}
}
if (params->UseRDOQuant)
init_rdoq_slice(img->type, (*currSlice)->symbol_mode);
}
/*!
************************************************************************
* \brief
* Allocates a slice structure along with its dependent data structures
* \return
* Pointer to a Slice
************************************************************************
*/
static Slice *malloc_slice()
{
int i;
DataPartition *dataPart;
Slice *slice;
int cr_size = IS_INDEPENDENT( params ) ? 0 : 512;
int buffer_size;
switch (params->slice_mode)
{
case 2:
//buffer_size = imax(2 * params->slice_argument, 500 + (128 + 256 * img->bitdepth_luma + 512 * img->bitdepth_chroma));
buffer_size = imax(2 * params->slice_argument, 764);
break;
case 1:
buffer_size = 500 + params->slice_argument * (128 + 256 * img->bitdepth_luma + cr_size * img->bitdepth_chroma);
break;
default:
buffer_size = 500 + img->FrameSizeInMbs * (128 + 256 * img->bitdepth_luma + cr_size * img->bitdepth_chroma);
break;
}
// KS: this is approx. max. allowed code picture size
if ((slice = (Slice *) calloc(1, sizeof(Slice))) == NULL) no_mem_exit ("malloc_slice: slice structure");
slice->symbol_mode = params->symbol_mode;
cs_mb->symbol_mode = params->symbol_mode;
cs_b8->symbol_mode = params->symbol_mode;
cs_cm->symbol_mode = params->symbol_mode;
cs_ib8->symbol_mode = params->symbol_mode;
cs_ib4->symbol_mode = params->symbol_mode;
if (slice->symbol_mode == CABAC)
{
// create all context models
slice->mot_ctx = create_contexts_MotionInfo();
slice->tex_ctx = create_contexts_TextureInfo();
}
slice->max_part_nr = params->partition_mode==0?1:3;
//for IDR img there should be only one partition
if(img->currentPicture->idr_flag)
slice->max_part_nr = 1;
assignSE2partition[0] = assignSE2partition_NoDP;
//ZL
//for IDR img all the syntax element should be mapped to one partition
if(!img->currentPicture->idr_flag && params->partition_mode == 1)
assignSE2partition[1] = assignSE2partition_DP;
else
assignSE2partition[1] = assignSE2partition_NoDP;
slice->num_mb = 0; // no coded MBs so far
if ((slice->partArr = (DataPartition *) calloc(slice->max_part_nr, sizeof(DataPartition))) == NULL)
no_mem_exit ("malloc_slice: partArr");
for (i=0; i<slice->max_part_nr; i++) // loop over all data partitions
{
dataPart = &(slice->partArr[i]);
if ((dataPart->bitstream = (Bitstream *) calloc(1, sizeof(Bitstream))) == NULL)
no_mem_exit ("malloc_slice: Bitstream");
if ((dataPart->bitstream->streamBuffer = (byte *) calloc(buffer_size, sizeof(byte))) == NULL)
no_mem_exit ("malloc_slice: StreamBuffer");
dataPart->bitstream->buffer_size = buffer_size;
// Initialize storage of bitstream parameters
}
return slice;
}
/*!
************************************************************************
* \brief
* This function frees nal units
*
************************************************************************
*/
static void free_nal_unit(Picture *pic)
{
int partition, slice;
Slice *currSlice;
// loop over all slices of the picture
for (slice=0; slice < pic->no_slices; slice++)
{
currSlice = pic->slices[slice];
// loop over the partitions
if (currSlice != NULL)
{
for (partition=0; partition < currSlice->max_part_nr; partition++)
{
// free only if the partition has content
if (currSlice->partArr[partition].bitstream->write_flag )
{
if (currSlice->partArr[partition].nal_unit != NULL)
{
FreeNALU(currSlice->partArr[partition].nal_unit);
currSlice->partArr[partition].nal_unit = NULL;
}
}
}
}
}
}
/*!
************************************************************************
* \brief
* Memory frees of all Slice structures and of its dependent
* data structures
* \par Input:
* Image Parameters struct struct img_par *img
************************************************************************
*/
void free_slice_list(Picture *currPic)
{
int i;
if (currPic != NULL)
{
free_nal_unit(currPic);
for (i = 0; i < currPic->no_slices; i++)
{
free_slice (currPic->slices[i]);
currPic->slices[i] = NULL;
}
}
}
/*!
************************************************************************
* \brief
* Memory frees of the Slice structure and of its dependent
* data structures
* \param slice:
* Slice to be freed
************************************************************************
*/
static void free_slice(Slice *slice)
{
if (slice != NULL)
{
int i;
DataPartition *dataPart;
for (i=0; i<slice->max_part_nr; i++) // loop over all data partitions
{
dataPart = &(slice->partArr[i]);
if (dataPart != NULL)
{
if (dataPart->bitstream != NULL)
{
if (dataPart->bitstream->streamBuffer != NULL)
{
free(dataPart->bitstream->streamBuffer);
dataPart->bitstream->streamBuffer = NULL;
}
free(dataPart->bitstream);
dataPart->bitstream = NULL;
}
}
}
if (slice->partArr != NULL)
{
free(slice->partArr);
slice->partArr = NULL;
}
if (slice->symbol_mode == CABAC)
{
delete_contexts_MotionInfo(slice->mot_ctx);
delete_contexts_TextureInfo(slice->tex_ctx);
}
free(slice);
}
}
static void set_ref_pic_num()
{
int i,j;
StorablePicture *this_ref;
//! need to add field ref_pic_num that handles field pair.
for (i=0;i<listXsize[LIST_0];i++)
{
this_ref = listX[LIST_0][i];
enc_picture->ref_pic_num [LIST_0][i] = this_ref->poc * 2 + ((this_ref->structure==BOTTOM_FIELD)?1:0) ;
enc_picture->frm_ref_pic_num [LIST_0][i] = this_ref->frame_poc * 2;
enc_picture->top_ref_pic_num [LIST_0][i] = this_ref->top_poc * 2;
enc_picture->bottom_ref_pic_num [LIST_0][i] = this_ref->bottom_poc * 2 + 1;
}
for (i=0;i<listXsize[LIST_1];i++)
{
this_ref = listX[LIST_1][i];
enc_picture->ref_pic_num [LIST_1][i] = this_ref->poc * 2 + ((this_ref->structure==BOTTOM_FIELD)?1:0);
enc_picture->frm_ref_pic_num [LIST_1][i] = this_ref->frame_poc * 2;
enc_picture->top_ref_pic_num [LIST_1][i] = this_ref->top_poc * 2;
enc_picture->bottom_ref_pic_num [LIST_1][i] = this_ref->bottom_poc * 2 + 1;
}
if (!active_sps->frame_mbs_only_flag && img->structure==FRAME)
{
for (j=2;j<6;j++)
{
for (i=0;i<listXsize[j];i++)
{
this_ref = listX[j][i];
enc_picture->ref_pic_num[j][i] = this_ref->poc * 2 + ((this_ref->structure==BOTTOM_FIELD)?1:0);
enc_picture->frm_ref_pic_num[j][i] = this_ref->frame_poc * 2 ;
enc_picture->top_ref_pic_num[j][i] = this_ref->top_poc * 2 ;
enc_picture->bottom_ref_pic_num[j][i] = this_ref->bottom_poc * 2 + 1;
}
}
}
}
/*!
************************************************************************
* \brief
* decide reference picture reordering, Frame only
************************************************************************
*/
void poc_ref_pic_reorder_frame(Slice *currSlice, StorablePicture **list, unsigned num_ref_idx_lX_active, int *reordering_of_pic_nums_idc, int *abs_diff_pic_num_minus1, int *long_term_pic_idx, int list_no)
{
unsigned int i,j,k;
int currPicNum, picNumLXPred;
int default_order[32];
int re_order[32];
int tmp_reorder[32];
int list_sign[32];
int reorder_stop, no_reorder;
int poc_diff[32];
int tmp_value, diff;
int abs_poc_dist;
int maxPicNum;
unsigned int numRefs;
maxPicNum = max_frame_num;
currPicNum = img->frame_num;
picNumLXPred = currPicNum;
// First assign default list order.
for (i=0; i<num_ref_idx_lX_active; i++)
{
default_order[i] = list[i]->pic_num;
}
// Now access all references in buffer and assign them
// to a potential reordering list. For each one of these
// references compute the poc distance compared to current
// frame.
numRefs = dpb.ref_frames_in_buffer;
for (i=0; i<dpb.ref_frames_in_buffer; i++)
{
poc_diff[i] = 0xFFFF;
re_order[i] = dpb.fs_ref[i]->frame->pic_num;
if (dpb.fs_ref[i]->is_used==3 && (dpb.fs_ref[i]->frame->used_for_reference)&&(!dpb.fs_ref[i]->frame->is_long_term))
{
abs_poc_dist = iabs(dpb.fs_ref[i]->frame->poc - enc_picture->poc) ;
poc_diff[i] = abs_poc_dist;
if (list_no == LIST_0)
{
list_sign[i] = (enc_picture->poc < dpb.fs_ref[i]->frame->poc) ? +1 : -1;
}
else
{
list_sign[i] = (enc_picture->poc > dpb.fs_ref[i]->frame->poc) ? +1 : -1;
}
}
}
// now sort these references based on poc (temporal) distance
for (i = 0; i < (numRefs - 1); i++)
{
for (j = i + 1; j < numRefs; j++)
{
if (poc_diff[i]>poc_diff[j] || (poc_diff[i] == poc_diff[j] && list_sign[j] > list_sign[i]))
{
tmp_value = poc_diff[i];
poc_diff[i] = poc_diff[j];
poc_diff[j] = tmp_value;
tmp_value = re_order[i];
re_order[i] = re_order[j];
re_order[j] = tmp_value ;
tmp_value = list_sign[i];
list_sign[i] = list_sign[j];
list_sign[j] = tmp_value ;
}
}
}
// populate list with selections from the pre-analysis stage
if ( params->WPMCPrecision
&& pWPX->curr_wp_rd_pass->algorithm != WP_REGULAR
&& pWPX->num_wp_ref_list[list_no] )
{
for (i=0; i<num_ref_idx_lX_active; i++)
{
re_order[i] = pWPX->wp_ref_list[list_no][i].PicNum;
}
}
// Check versus default list to see if any
// change has happened
no_reorder = 1;
for (i=0; i<num_ref_idx_lX_active; i++)
{
if (default_order[i] != re_order[i])
{
no_reorder = 0;
}
}
// If different, then signal reordering
if (no_reorder==0)
{
for (i=0; i<num_ref_idx_lX_active; i++)
{
diff = re_order[i]-picNumLXPred;
if (diff <= 0)
{
reordering_of_pic_nums_idc[i] = 0;
abs_diff_pic_num_minus1[i] = iabs(diff)-1;
if (abs_diff_pic_num_minus1[i] < 0)
abs_diff_pic_num_minus1[i] = maxPicNum -1;
}
else
{
reordering_of_pic_nums_idc[i] = 1;
abs_diff_pic_num_minus1[i] = iabs(diff)-1;
}
picNumLXPred = re_order[i];
tmp_reorder[i] = re_order[i];
k = i;
for (j=i; j<num_ref_idx_lX_active; j++)
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?