📄 slice.c
字号:
SetStateVariablesForFrameMode();
rdopt = &rddata_top_frame_mb; // store data in top frame MB
TopFrameIsSkipped = 0;
WriteFrameFieldMBInHeader = 1;
encode_one_macroblock (); // code the MB as frame
field_mb[img->mb_y][img->mb_x] = 0; // set the MB as field (for use in FindSkipMotionVector)
FrameRDCost = rdopt->min_rdcost;
//*** Top MB coded as frame MB ***//
// go to the bottom MB in the MB pair
CurrentMbInScanOrder = img->current_mb_nr + MBRowSize;
img->field_mode = 0; // MB coded as frame //GB
set_MB_parameters (CurrentMbInScanOrder);
start_macroblock ();
rdopt = &rddata_bot_frame_mb; // store data in top frame MB
WriteFrameFieldMBInHeader = TopFrameIsSkipped ? 1 : 0;
field_mb[img->mb_y][img->mb_x] = 0;
encode_one_macroblock (); // code the MB as frame
field_mb[img->mb_y][img->mb_x] = 0; // set the MB as field (for use in FindSkipMotionVector)
FrameRDCost += rdopt->min_rdcost;
//*** Bottom MB coded as frame MB ***//
// start coding the MB pair as a field MB pair
CurrentMbInScanOrder -= MBRowSize; //! FMO problem and generally dirty, just to go back like this
img->field_mode = 1; // MB coded as frame
img->top_field = 1; // Set top field to 1
set_MB_parameters (CurrentMbInScanOrder);
img->buf_cycle <<= 1;
input->num_reference_frames <<= 1;
img->num_ref_idx_l0_active <<= 1;
img->num_ref_idx_l0_active += 1;
start_macroblock ();
img->height = input->img_height >> 1;
rdopt = &rddata_top_field_mb; // store data in top frame MB
SetStateVariablesForFieldMode();
TopFieldIsSkipped = 0; // set the top field MB skipped flag to 0
WriteFrameFieldMBInHeader = 1;
encode_one_macroblock (); // code the MB as frame
field_mb[img->mb_y][img->mb_x] = 1; // set the MB as field (for use in FindSkipMotionVector)
FieldRDCost = rdopt->min_rdcost;
//*** Top MB coded as field MB ***//
CurrentMbInScanOrder += MBRowSize;
img->top_field = 0; // Set top field to 0
set_MB_parameters (CurrentMbInScanOrder);
start_macroblock ();
rdopt = &rddata_bot_field_mb; // store data in top frame MB
SetStateVariablesForFieldMode();
WriteFrameFieldMBInHeader = TopFieldIsSkipped ? 1 : 0;
encode_one_macroblock (); // code the MB as frame
field_mb[img->mb_y][img->mb_x] = 1; // set the MB as field (for use in FindSkipMotionVector)
FieldRDCost += rdopt->min_rdcost;
//*** Bottom MB coded as field MB ***//
// decide between frame/field MB pair
if (FrameRDCost < FieldRDCost)
{
img->field_mode = 0;
img->buf_cycle >>= 1;
input->num_reference_frames >>= 1;
MBPairIsField = 0;
SetStateVariablesForFrameMode();
img->num_ref_idx_l0_active -= 1;
img->num_ref_idx_l0_active >>= 1;
}
else
{
img->field_mode = 1;
MBPairIsField = 1;
SetStateVariablesForFieldMode();
img->height = input->img_height / 2; // set image height as frame height
}
if (MBPairIsField)
img->top_field = 1;
else
img->top_field = 0;
// go back to the Top MB in the MB pair
CurrentMbInScanOrder -= MBRowSize;
set_MB_parameters (CurrentMbInScanOrder);
start_macroblock ();
for (i=0;i<4;i++)
for (j=0;j<4;j++)
{
img->field_anchor[img->block_y+j][img->block_x+i] = 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
WriteFrameFieldMBInHeader = 1;
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 (CurrentMbInScanOrder); // Go to next macroblock
// go to the Bottom MB in the MB pair
CurrentMbInScanOrder += MBRowSize;
img->top_field = 0;
set_MB_parameters (CurrentMbInScanOrder);
start_macroblock ();
for (i=0;i<4;i++)
for (j=0;j<4;j++)
{
img->field_anchor[img->block_y+j][img->block_x+i] = 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
if (img->field_mode)
WriteFrameFieldMBInHeader = TopFieldIsSkipped ? 1 : 0;
else
WriteFrameFieldMBInHeader = TopFrameIsSkipped ? 1 : 0;
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 (CurrentMbInScanOrder); // Go to next macroblock
CurrentMbInScanOrder -= MBRowSize;
if (MBPairIsField) // if MB Pair was coded as field the buffer size variables back to frame mode
{
img->buf_cycle >>= 1;
input->num_reference_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
img->height = input->img_height; // reset the img->height
CurrentMbInScanOrder++; //! Breaks FMO
if (CurrentMbInScanOrder == img->total_number_mb - MBRowSize)
end_of_slice = TRUE; // just in case it does n't get set in terminate_macroblock
if (CurrentMbInScanOrder % MBRowSize == 0) //! Breaks FMO
CurrentMbInScanOrder += MBRowSize;
}
}
/*
// 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 i;
Picture *currPic = img->currentPicture;
Slice *curr_slice;
DataPartition *dataPart;
Bitstream *currStream;
// 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, incease MAXLSICESPERPICTURE in global.h, exitus", -1);
currPic->slices[currPic->no_slices-1] = malloc_slice();
curr_slice = currPic->slices[currPic->no_slices-1];
img->currentSlice = curr_slice;
curr_slice->picture_id = img->tr % 256;
curr_slice->qp = img->qp;
curr_slice->start_mb_nr = img->current_mb_nr;
curr_slice->slice_too_big = dummy_slice_too_big;
for (i = 0; i < curr_slice->max_part_nr; i++)
{
dataPart = &(curr_slice->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;
}
}
/*!
************************************************************************
* \brief
* Allocates a slice structure along with its dependentdata structures
* \return
* Pointer to a Slice
************************************************************************
*/
static Slice *malloc_slice()
{
int i;
DataPartition *dataPart;
Slice *slice;
const int buffer_size = (img->width * img->height * 4); // AH 190202: There can be data expansion with
// low QP values. So, we make sure that buffer
// does not everflow. 4 is probably safe multiplier.
if ((slice = (Slice *) calloc(1, sizeof(Slice))) == NULL) no_mem_exit ("malloc_slie: slice structure");
if (input->symbol_mode == CABAC)
{
// create all context models
slice->mot_ctx = create_contexts_MotionInfo();
slice->tex_ctx = create_contexts_TextureInfo();
}
slice->max_part_nr = input->partition_mode==0?1:3;
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
* 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;
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
* \para 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->streamBuffer != NULL)
free(dataPart->bitstream->streamBuffer);
if (dataPart->bitstream != NULL)
free(dataPart->bitstream);
}
}
if (slice->partArr != NULL)
free(slice->partArr);
if (input->symbol_mode == CABAC)
{
delete_contexts_MotionInfo(slice->mot_ctx);
delete_contexts_TextureInfo(slice->tex_ctx);
}
//free(img->currentSlice);
free(slice);
}
}
/*!
************************************************************************
* \brief
* This function set the value of a bit in a bitstream to 1
************************************************************************
*/
void modify_redundant_pic_cnt(unsigned char *buffer)
{
unsigned char tmp = 1 << (rpc_bits_to_go-1);
buffer[rpc_bytes_to_go] |= tmp;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -