📄 slice.c
字号:
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;
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;
// const int buffer_size = (img->size * 4); // AH 190202: There can be data expansion with
// low QP values. So, we make sure that buffer
// does not overflow. 4 is probably safe multiplier.
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");
// 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;
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)
{
int i;
DataPartition *dataPart;
if (slice != NULL)
{
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);
free(dataPart->bitstream);
}
}
}
if (slice->partArr != NULL)
free(slice->partArr);
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(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++)
{
if (default_order[j] != re_order[i])
{
++k;
tmp_reorder[k] = default_order[j];
}
}
reorder_stop = 1;
for(j=i+1; j<num_ref_idx_lX_active; j++)
{
if (tmp_reorder[j] != re_order[j])
{
reorder_stop = 0;
break;
}
}
if (reorder_stop==1)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -