📄 image.c
字号:
// printf ("nalu->len %d\n", nalu->len);
if (ret < 0)
printf ("Error while getting the NALU in file format %s, exit\n", input->FileFormat==PAR_OF_ANNEXB?"Annex B":"RTP");
if (ret == 0)
{
// printf ("read_new_slice: returning %s\n", "EOS");
if(expected_slice_type != NALU_TYPE_DPA)
{
/* oops... we found the next slice, go back! */
fseek(bits, ftell_position, SEEK_SET);
FreeNALU(nalu);
return current_header;
}
else
return EOS;
}
// Got a NALU
if (nalu->forbidden_bit)
{
printf ("Found NALU w/ forbidden_bit set, bit error? Let's try...\n");
}
switch (nalu->nal_unit_type)
{
case NALU_TYPE_SLICE:
case NALU_TYPE_IDR:
img->idr_flag = (nalu->nal_unit_type == NALU_TYPE_IDR);
img->nal_reference_idc = nalu->nal_reference_idc;
img->disposable_flag = (nalu->nal_reference_idc == NALU_PRIORITY_DISPOSABLE);
currSlice->dp_mode = PAR_DP_1;
currSlice->max_part_nr = 1;
currSlice->ei_flag = 0;
currStream = currSlice->partArr[0].bitstream;
currStream->ei_flag = 0;
currStream->frame_bitoffset = currStream->read_len = 0;
memcpy (currStream->streamBuffer, &nalu->buf[1], nalu->len-1);
currStream->code_len = currStream->bitstream_length = RBSPtoSODB(currStream->streamBuffer, nalu->len-1);
// Some syntax of the Slice Header depends on the parameter set, which depends on
// the parameter set ID of the SLice header. Hence, read the pic_parameter_set_id
// of the slice header first, then setup the active parameter sets, and then read
// the rest of the slice header
BitsUsedByHeader = FirstPartOfSliceHeader();
UseParameterSet (currSlice->pic_parameter_set_id);
BitsUsedByHeader+= RestOfSliceHeader ();
FmoInit (active_pps, active_sps);
AssignQuantParam (active_pps, active_sps);
if(is_new_picture())
{
init_picture(img, input);
current_header = SOP;
//check zero_byte if it is also the first NAL unit in the access unit
CheckZeroByteVCL(nalu, &ret);
}
else
current_header = SOS;
init_lists(img->type, img->currentSlice->structure);
reorder_lists (img->type, img->currentSlice);
/*
if (img->structure==FRAME)
{
init_mbaff_lists();
}
*/
/* if (img->frame_num==1) // write a reference list
{
count ++;
if (count==1)
for (i=0; i<listXsize[0]; i++)
write_picture(listX[0][i], p_out2);
}
*/
// From here on, active_sps, active_pps and the slice header are valid
/*
if (img->MbaffFrameFlag)
img->current_mb_nr = currSlice->start_mb_nr << 1;
else
img->current_mb_nr = currSlice->start_mb_nr;
*/
img->current_mb_nr = currSlice->start_mb_nr;
/*
if (active_pps->entropy_coding_mode_flag)
{
int ByteStartPosition = currStream->frame_bitoffset/8;
if (currStream->frame_bitoffset%8 != 0)
{
ByteStartPosition++;
}
arideco_start_decoding (&currSlice->partArr[0].de_cabac, currStream->streamBuffer, ByteStartPosition, &currStream->read_len, img->type);
}
*/
// printf ("read_new_slice: returning %s\n", current_header == SOP?"SOP":"SOS");
FreeNALU(nalu);
return current_header;
break;
/*
case NALU_TYPE_DPA:
//! The state machine here should follow the same ideas as the old readSliceRTP()
//! basically:
//! work on DPA (as above)
//! read and process all following SEI/SPS/PPS/PD/Filler NALUs
//! if next video NALU is dpB,
//! then read and check whether it belongs to DPA, if yes, use it
//! else
//! ; // nothing
//! read and process all following SEI/SPS/PPS/PD/Filler NALUs
//! if next video NALU is dpC
//! then read and check whether it belongs to DPA (and DPB, if present), if yes, use it, done
//! else
//! use the DPA (and the DPB if present)
//
// LC: inserting the code related to DP processing, mainly copying some of the parts
// related to NALU_TYPE_SLICE, NALU_TYPE_IDR.
//
if(expected_slice_type != NALU_TYPE_DPA)
{
/// oops... we found the next slice, go back!
fseek(bits, ftell_position, SEEK_SET);
FreeNALU(nalu);
return current_header;
}
img->idr_flag = (nalu->nal_unit_type == NALU_TYPE_IDR);
img->nal_reference_idc = nalu->nal_reference_idc;
img->disposable_flag = (nalu->nal_reference_idc == NALU_PRIORITY_DISPOSABLE);
currSlice->dp_mode = PAR_DP_3;
currSlice->max_part_nr = 3;
currSlice->ei_flag = 0;
currStream = currSlice->partArr[0].bitstream;
currStream->ei_flag = 0;
currStream->frame_bitoffset = currStream->read_len = 0;
memcpy (currStream->streamBuffer, &nalu->buf[1], nalu->len-1);
currStream->code_len = currStream->bitstream_length = RBSPtoSODB(currStream->streamBuffer, nalu->len-1);
BitsUsedByHeader = FirstPartOfSliceHeader();
UseParameterSet (currSlice->pic_parameter_set_id);
BitsUsedByHeader += RestOfSliceHeader ();
FmoInit (active_pps, active_sps);
if(is_new_picture())
{
init_picture(img, input);
current_header = SOP;
CheckZeroByteVCL(nalu, &ret);
}
else
current_header = SOS;
init_lists(img->type, img->currentSlice->structure);
reorder_lists (img->type, img->currentSlice);
if (img->structure==FRAME)
{
init_mbaff_lists();
}
// From here on, active_sps, active_pps and the slice header are valid
if (img->MbaffFrameFlag)
img->current_mb_nr = currSlice->start_mb_nr << 1;
else
img->current_mb_nr = currSlice->start_mb_nr;
// LC:
// Now I need to read the slice ID, which depends on the value of
// redundant_pic_cnt_present_flag (pag.49).
//
slice_id_a = ue_v("NALU:SLICE_A slice_idr", currStream);
if (active_pps->entropy_coding_mode_flag)
{
int ByteStartPosition = currStream->frame_bitoffset/8;
if (currStream->frame_bitoffset%8 != 0)
{
ByteStartPosition++;
}
arideco_start_decoding (&currSlice->partArr[0].de_cabac, currStream->streamBuffer, ByteStartPosition, &currStream->read_len, img->type);
}
// printf ("read_new_slice: returning %s\n", current_header == SOP?"SOP":"SOS");
break;
case NALU_TYPE_DPB:
// LC: inserting the code related to DP processing
currStream = currSlice->partArr[1].bitstream;
currStream->ei_flag = 0;
currStream->frame_bitoffset = currStream->read_len = 0;
memcpy (currStream->streamBuffer, &nalu->buf[1], nalu->len-1);
currStream->code_len = currStream->bitstream_length = RBSPtoSODB(currStream->streamBuffer, nalu->len-1);
slice_id_b = ue_v("NALU:SLICE_B slice_idr", currStream);
if (active_pps->redundant_pic_cnt_present_flag)
redundant_pic_cnt_b = ue_v("NALU:SLICE_B redudand_pic_cnt", currStream);
else
redundant_pic_cnt_b = 0;
/// LC: Initializing CABAC for the current data stream.
if (active_pps->entropy_coding_mode_flag)
{
int ByteStartPosition = currStream->frame_bitoffset/8;
if (currStream->frame_bitoffset % 8 != 0)
ByteStartPosition++;
arideco_start_decoding (&currSlice->partArr[1].de_cabac, currStream->streamBuffer,
ByteStartPosition, &currStream->read_len, img->type);
}
// LC: resilience code to be inserted //
/// FreeNALU(nalu);
/// return current_header;
break;
case NALU_TYPE_DPC:
/// LC: inserting the code related to DP processing
currStream = currSlice->partArr[2].bitstream;
currStream->ei_flag = 0;
currStream->frame_bitoffset = currStream->read_len = 0;
memcpy (currStream->streamBuffer, &nalu->buf[1], nalu->len-1);
currStream->code_len = currStream->bitstream_length = RBSPtoSODB(currStream->streamBuffer, nalu->len-1);
slice_id_c = ue_v("NALU:SLICE_C slice_idr", currStream);
if (active_pps->redundant_pic_cnt_present_flag)
redundant_pic_cnt_c = ue_v("NALU:SLICE_C redudand_pic_cnt", currStream);
else
redundant_pic_cnt_c = 0;
/ LC: Initializing CABAC for the current data stream.
if (active_pps->entropy_coding_mode_flag)
{
int ByteStartPosition = currStream->frame_bitoffset/8;
if (currStream->frame_bitoffset % 8 != 0)
ByteStartPosition++;
arideco_start_decoding (&currSlice->partArr[2].de_cabac, currStream->streamBuffer,
ByteStartPosition, &currStream->read_len, img->type);
}
/ LC: resilience code to be inserted
FreeNALU(nalu);
return current_header;
break;
case NALU_TYPE_SEI:
printf ("read_new_slice: Found NALU_TYPE_SEI, len %d\n", nalu->len);
InterpretSEIMessage(nalu->buf,nalu->len,img);
break;
*/
case NALU_TYPE_PPS:
ProcessPPS(nalu);
break;
case NALU_TYPE_SPS:
ProcessSPS(nalu);
break;
/*
case NALU_TYPE_AUD:
// printf ("read_new_slice: Found 'Access Unit Delimiter' NAL unit, len %d, ignored\n", nalu->len);
break;
case NALU_TYPE_EOSEQ:
// printf ("read_new_slice: Found 'End of Sequence' NAL unit, len %d, ignored\n", nalu->len);
break;
case NALU_TYPE_EOSTREAM:
// printf ("read_new_slice: Found 'End of Stream' NAL unit, len %d, ignored\n", nalu->len);
break;
case NALU_TYPE_FILL:
printf ("read_new_slice: Found NALU_TYPE_FILL, len %d\n", nalu->len);
printf ("Skipping these filling bits, proceeding w/ next NALU\n");
break;
*/
default:
printf ("Found NALU type %d, len %d undefined, ignore NALU, moving on\n", nalu->nal_unit_type, nalu->len);
}
}
FreeNALU(nalu);
return current_header;
}
/*!
************************************************************************
* \brief
* Initializes the parameters for a new picture
************************************************************************
*/
void init_picture(struct img_par *img, struct inp_par *inp)
{
int i,k,l;
Slice *currSlice = img->currentSlice;
if (dec_picture)
{
// this may only happen on slice loss
exit_picture();
}
/*
if (img->frame_num != img->pre_frame_num && img->frame_num != (img->pre_frame_num + 1) % img->MaxFrameNum)
{
if (active_sps->gaps_in_frame_num_value_allowed_flag == 0)
{
///Advanced Error Concealment would be called here to combat unintentional loss of pictures. /
error("An unintentional loss of pictures occurs! Exit\n", 100);
}
fill_frame_num_gap(img);
}
*/
img->pre_frame_num = img->frame_num;
img->num_dec_mb = 0;
//calculate POC
decode_poc(img);
// dumppoc (img);
if (img->structure==FRAME ||img->structure==TOP_FIELD)
{
/*
#ifdef WIN32
_ftime (&(img->tstruct_start)); // start time ms
#else
ftime (&(img->tstruct_start)); // start time ms
#endif
time( &(img->ltime_start)); // start time s
*/
}
dec_picture = alloc_storable_picture (img->structure, img->width, img->height, img->width_cr, img->height_cr);
dec_picture->top_poc=img->toppoc;
dec_picture->bottom_poc=img->bottompoc;
dec_picture->frame_poc=img->framepoc;
dec_picture->qp=img->qp;
dec_picture->slice_qp_delta=currSlice->slice_qp_delta;
dec_picture->chroma_qp_offset[0] = active_pps->chroma_qp_index_offset;
dec_picture->chroma_qp_offset[1] = active_pps->second_chroma_qp_index_offset;
// reset all variables of the error concealment instance before decoding of every frame.
// here the third parameter should, if perfectly, be equal to the number of slices per frame.
// using little value is ok, the code will allocate more memory if the slice number is larger
ercReset(erc_errorVar, img->PicSizeInMbs, img->PicSizeInMbs, dec_picture->size_x);
erc_mvperMB = 0;
/*
switch (img->structure )
{
/*
case TOP_FIELD:
{
dec_picture->poc=img->toppoc;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -