📄 slice.c
字号:
FrameRDCost = rdopt->min_rdcost;
//*** Top MB coded as frame MB ***//
//Rate control
img->bot_MB = 1; //for Rate control
// go to the bottom MB in the MB pair
img->field_mode = 0; // MB coded as frame //GB
start_macroblock (CurrentMbAddr+1, FALSE);
rdopt = &rddata_bot_frame_mb; // store data in top frame MB
encode_one_macroblock (); // code the MB as frame
FrameRDCost += rdopt->min_rdcost;
//*** Bottom MB coded as frame MB ***//
}
if ((input->MbInterlace == ADAPTIVE_CODING) || (input->MbInterlace == FIELD_CODING))
{
//Rate control
img->bot_MB = 0;
//=========== start coding the MB pair as a field MB pair =============
//---------------------------------------------------------------------
img->field_mode = 1; // MB coded as frame
img->top_field = 1; // Set top field to 1
img->buf_cycle <<= 1;
input->num_ref_frames <<= 1;
img->num_ref_idx_l0_active <<= 1;
img->num_ref_idx_l0_active += 1;
start_macroblock (CurrentMbAddr, TRUE);
rdopt = &rddata_top_field_mb; // store data in top frame MB
// TopFieldIsSkipped = 0; // set the top field MB skipped flag to 0
encode_one_macroblock (); // code the MB as frame
FieldRDCost = rdopt->min_rdcost;
//*** Top MB coded as field MB ***//
//Rate control
img->bot_MB = 1;//for Rate control
img->top_field = 0; // Set top field to 0
start_macroblock (CurrentMbAddr+1, TRUE);
rdopt = &rddata_bot_field_mb; // store data in top frame MB
encode_one_macroblock (); // code the MB as frame
FieldRDCost += rdopt->min_rdcost;
//*** Bottom MB coded as field MB ***//
}
//Rate control
img->write_macroblock_frame = 0; //Rate control
//=========== decide between frame/field MB pair ============
//-----------------------------------------------------------
if ((input->MbInterlace == ADAPTIVE_CODING) && (FrameRDCost < FieldRDCost))
{
img->field_mode = 0;
img->buf_cycle >>= 1;
input->num_ref_frames >>= 1;
MBPairIsField = 0;
img->num_ref_idx_l0_active -= 1;
img->num_ref_idx_l0_active >>= 1;
//Rate control
img->write_macroblock_frame = 1; //for Rate control
}
else
{
img->field_mode = 1;
MBPairIsField = 1;
}
//Rate control
img->write_macroblock = 1;//Rate control
if (MBPairIsField)
img->top_field = 1;
else
img->top_field = 0;
//Rate control
img->bot_MB = 0;// for Rate control
// go back to the Top MB in the MB pair
start_macroblock (CurrentMbAddr, img->field_mode);
rdopt = img->field_mode ? &rddata_top_field_mb : &rddata_top_frame_mb;
copy_rdopt_data (0); // copy the MB data for Top MB from the temp buffers
write_one_macroblock (1); // write the Top MB data to the bitstream
NumberOfCodedMBs++; // only here we are sure that the coded MB is actually included in the slice
terminate_macroblock (&end_of_slice, &recode_macroblock); // done coding the Top MB
proceed2nextMacroblock (CurrentMbAddr); // Go to next macroblock
//Rate control
img->bot_MB = 1;//for Rate control
// go to the Bottom MB in the MB pair
img->top_field = 0;
start_macroblock (CurrentMbAddr+1, img->field_mode);
rdopt = img->field_mode ? &rddata_bot_field_mb : &rddata_bot_frame_mb;
copy_rdopt_data (1); // copy the MB data for Bottom MB from the temp buffers
write_one_macroblock (0); // write the Bottom MB data to the bitstream
NumberOfCodedMBs++; // only here we are sure that the coded MB is actually included in the slice
terminate_macroblock (&end_of_slice, &recode_macroblock); // done coding the Top MB
proceed2nextMacroblock (CurrentMbAddr); // Go to next macroblock
if (MBPairIsField) // if MB Pair was coded as field the buffer size variables back to frame mode
{
img->buf_cycle >>= 1;
input->num_ref_frames >>= 1;
img->num_ref_idx_l0_active -= 1;
img->num_ref_idx_l0_active >>= 1;
}
img->field_mode = img->top_field = 0; // reset to frame mode
// go to next MB pair, not next MB
CurrentMbAddr = FmoGetNextMBNr (CurrentMbAddr);
CurrentMbAddr = FmoGetNextMBNr (CurrentMbAddr);
if (CurrentMbAddr == FmoGetLastCodedMBOfSliceGroup (FmoMB2SliceGroup (CurrentMbAddr)))
end_of_slice = TRUE; // just in case it does n't get set in terminate_macroblock
}
}
/*
// Tian Dong: June 7, 2002 JVT-B042
// Restore the short_used
if (input->NumFramesInELSubSeq)
{
fb->short_used = short_used;
img->nb_references = img_ref;
}
*/
terminate_slice ();
return NumberOfCodedMBs;
}
/*!
************************************************************************
* \brief
* Initializes the parameters for a new slice and
* allocates the memory for the coded slice in the Picture structure
* \par Side effects:
* Adds slice/partition header symbols to the symbol buffer
* increments Picture->no_slices, allocates memory for the
* slice, sets img->currSlice
************************************************************************
*/
static void init_slice (int start_mb_addr)
{
int i;
Picture *currPic = img->currentPicture;
DataPartition *dataPart;
Bitstream *currStream;
Slice *currSlice;
img->current_mb_nr = start_mb_addr;
// Allocate new Slice in the current Picture, and set img->currentSlice
assert (currPic != NULL);
currPic->no_slices++;
if (currPic->no_slices >= MAXSLICEPERPICTURE)
error ("Too many slices per picture, increase MAXLSICESPERPICTURE in global.h.", -1);
currPic->slices[currPic->no_slices-1] = malloc_slice();
currSlice = currPic->slices[currPic->no_slices-1];
img->currentSlice = currSlice;
currSlice->picture_id = img->tr % 256;
currSlice->qp = img->qp;
currSlice->start_mb_nr = start_mb_addr;
currSlice->slice_too_big = dummy_slice_too_big;
for (i = 0; i < currSlice->max_part_nr; i++)
{
dataPart = &(currSlice->partArr[i]);
if (input->symbol_mode == UVLC)
dataPart->writeSyntaxElement = writeSyntaxElement_UVLC;
else
dataPart->writeSyntaxElement = writeSyntaxElement_CABAC;
currStream = dataPart->bitstream;
currStream->bits_to_go = 8;
currStream->byte_pos = 0;
currStream->byte_buf = 0;
}
// restrict list 1 size
// img->num_ref_idx_l0_active = max(1, (img->type==B_SLICE ? active_pps->num_ref_idx_l0_active_minus1 + 1: active_pps->num_ref_idx_l0_active_minus1 +1 ));
// img->num_ref_idx_l1_active = (img->type==B_SLICE ? active_pps->num_ref_idx_l1_active_minus1 + 1 : 0);
img->num_ref_idx_l0_active = active_pps->num_ref_idx_l0_active_minus1 + 1;
img->num_ref_idx_l1_active = active_pps->num_ref_idx_l1_active_minus1 + 1;
// generate reference picture lists
init_lists(img->type, img->structure);
// assign list 0 size from list size
img->num_ref_idx_l0_active = listXsize[0];
img->num_ref_idx_l1_active = listXsize[1];
//if (!img->MbaffFrameFlag)
{
if ((img->type == P_SLICE || img->type == SP_SLICE) && input->P_List0_refs)
{
img->num_ref_idx_l0_active = min(img->num_ref_idx_l0_active, input->P_List0_refs);
listXsize[0] = min(listXsize[0], input->P_List0_refs);
}
if (img->type == B_SLICE )
{
if (input->B_List0_refs)
{
img->num_ref_idx_l0_active = min(img->num_ref_idx_l0_active, input->B_List0_refs);
listXsize[0] = min(listXsize[0], input->B_List0_refs);
}
if (input->B_List1_refs)
{
img->num_ref_idx_l1_active = min(img->num_ref_idx_l1_active, input->B_List1_refs);
listXsize[1] = min(listXsize[1], input->B_List1_refs);
}
}
}
//Perform memory management based on poc distances for PyramidCoding
if (img->nal_reference_idc && input->PyramidCoding && input->PocMemoryManagement && dpb.used_size == dpb.size)
{
poc_based_ref_management(img->frame_num);
}
init_ref_pic_list_reordering();
//Perform reordering based on poc distances for PyramidCoding
if (img->type==P_SLICE && input->PyramidCoding && input->PyramidRefReorder)
{
int i, num_ref;
alloc_ref_pic_list_reordering_buffer(currSlice);
if ((img->type != I_SLICE) && (img->type !=SI_SLICE))
{
for (i=0; i<img->num_ref_idx_l0_active + 1; i++)
{
currSlice->remapping_of_pic_nums_idc_l0[i] = 3;
currSlice->abs_diff_pic_num_minus1_l0[i] = 0;
currSlice->long_term_pic_idx_l0[i] = 0;
}
if (img->type == B_SLICE)
{
for (i=0; i<img->num_ref_idx_l1_active + 1; i++)
{
currSlice->remapping_of_pic_nums_idc_l1[i] = 3;
currSlice->abs_diff_pic_num_minus1_l1[i] = 0;
currSlice->long_term_pic_idx_l1[i] = 0;
}
}
}
if ((img->type != I_SLICE) && (img->type !=SI_SLICE))
{
num_ref = img->num_ref_idx_l0_active;
poc_ref_pic_reorder(listX[LIST_0],
num_ref,
currSlice->remapping_of_pic_nums_idc_l0,
currSlice->abs_diff_pic_num_minus1_l0,
currSlice->long_term_pic_idx_l0, 0, LIST_0);
//reference picture reordering
reorder_ref_pic_list(listX[LIST_0], &listXsize[LIST_0],
img->num_ref_idx_l0_active - 1,
currSlice->remapping_of_pic_nums_idc_l0,
currSlice->abs_diff_pic_num_minus1_l0,
currSlice->long_term_pic_idx_l0);
// This is not necessary since order is already poc based...
if (img->type == B_SLICE)
{
num_ref = img->num_ref_idx_l1_active;
poc_ref_pic_reorder(listX[LIST_1],
num_ref,
currSlice->remapping_of_pic_nums_idc_l1,
currSlice->abs_diff_pic_num_minus1_l1,
currSlice->long_term_pic_idx_l1, 0, LIST_1);
//reference picture reordering
reorder_ref_pic_list(listX[LIST_1], &listXsize[LIST_1],
img->num_ref_idx_l1_active - 1,
currSlice->remapping_of_pic_nums_idc_l1,
currSlice->abs_diff_pic_num_minus1_l1,
currSlice->long_term_pic_idx_l1);
}
}
}
//if (img->MbaffFrameFlag)
if (img->structure==FRAME)
init_mbaff_lists();
if (img->type != I_SLICE && (input->WeightedPrediction == 1 || (input->WeightedBiprediction > 0 && (img->type == B_SLICE))))
{
if (img->type==P_SLICE || img->type==SP_SLICE)
estimate_weighting_factor_P_slice ();
else
estimate_weighting_factor_B_slice ();
}
set_ref_pic_num();
if (img->type == B_SLICE)
compute_collocated(Co_located, listX);
}
/*!
************************************************************************
* \brief
* Allocates a slice structure along with its dependent data structures
* \return
* Pointer to a Slice
************************************************************************
*/
static Slice *malloc_slice()
{
int i;
DataPartition *dataPart;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -