📄 image.c
字号:
expected_slice_type = NALU_TYPE_DPA;
while (1)
{
ftell_position = ftell(bits);
if (input->FileFormat == PAR_OF_ANNEXB)
ret=GetAnnexbNALU (nalu);
else
ret=GetRTPNALU (nalu);
//In some cases, zero_byte shall be present. If current NALU is a VCL NALU, we can't tell
//whether it is the first VCL NALU at this point, so only non-VCL NAL unit is checked here.
CheckZeroByteNonVCL(nalu, &ret);
NALUtoRBSP(nalu);
// 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;
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;
currSlice->dp_mode = PAR_DP_3;
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 */
currSlice->dp_mode = PAR_DP_3;
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)
{
// picture error concealment
if(inp->conceal_mode !=0)
{
if((img->frame_num) < ((img->pre_frame_num + 1) % img->MaxFrameNum))
{
/* Conceal lost IDR frames and any frames immediately
following the IDR. Use frame copy for these since
lists cannot be formed correctly for motion copy*/
img->conceal_mode = 1;
img->IDR_concealment_flag = 1;
conceal_lost_frames(img);
//reset to original concealment mode for future drops
img->conceal_mode = inp->conceal_mode;
}
else
{
//reset to original concealment mode for future drops
img->conceal_mode = inp->conceal_mode;
img->IDR_concealment_flag = 0;
conceal_lost_frames(img);
}
}
else
{ /* Advanced Error Concealment would be called here to combat unintentional loss of pictures. */
error("An unintentional loss of pictures occurs! Exit\n", 100);
}
}
if(img->conceal_mode == 0)
fill_frame_num_gap(img);
}
if(img->nal_reference_idc)
{
img->pre_frame_num = img->frame_num;
}
//img->num_dec_mb = 0;
//calculate POC
decode_poc(img);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -