📄 image.c
字号:
int redundant_pic_cnt_b, redundant_pic_cnt_c;
long ftell_position;
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);
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)
{
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:
if (img->recovery_point || nalu->nal_unit_type == NALU_TYPE_IDR)
{
if (img->recovery_point_found == 0)
{
if (nalu->nal_unit_type != NALU_TYPE_IDR)
{
printf("Warning: Decoding does not start with an IDR picture.\n");
non_conforming_stream = 1;
}
else
non_conforming_stream = 0;
}
img->recovery_point_found = 1;
}
if (img->recovery_point_found == 0)
break;
img->idr_flag = (nalu->nal_unit_type == NALU_TYPE_IDR);
img->nal_reference_idc = nalu->nal_reference_idc;
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 primary slice is replaced with redundant slice, set the correct image type
if(img->redundant_pic_cnt && Is_primary_correct==0 && Is_redundant_correct)
{
dec_picture->slice_type=img->type;
}
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);
img->recovery_point = 0;
return current_header;
break;
case NALU_TYPE_DPA:
// read DP_A
img->idr_flag = (nalu->nal_unit_type == NALU_TYPE_IDR);
if (img->idr_flag)
{
printf ("Data partiton A cannot have idr_flag set, trying anyway \n");
}
img->nal_reference_idc = nalu->nal_reference_idc;
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;
// Now I need to read the slice ID, which depends on the value of
// redundant_pic_cnt_present_flag
slice_id_a = ue_v("NALU: DP_A slice_id", currStream);
if (active_pps->entropy_coding_mode_flag)
error ("received data partition with CABAC, this is not allowed", 500);
// continue with reading next DP
ftell_position = ftell(bits);
if (input->FileFormat == PAR_OF_ANNEXB)
ret=GetAnnexbNALU (nalu);
else
ret=GetRTPNALU (nalu);
CheckZeroByteNonVCL(nalu, &ret);
NALUtoRBSP(nalu);
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)
return current_header;
if ( NALU_TYPE_DPB == nalu->nal_unit_type)
{
// we got a DPB
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: DP_B slice_id", currStream);
if (slice_id_b != slice_id_a)
{
printf ("got a data partition B which does not match DP_A\n");
// KS: needs error handling !!!
}
if (active_pps->redundant_pic_cnt_present_flag)
redundant_pic_cnt_b = ue_v("NALU: DP_B redudant_pic_cnt", currStream);
else
redundant_pic_cnt_b = 0;
// we're finished with DP_B, so let's continue with next DP
ftell_position = ftell(bits);
if (input->FileFormat == PAR_OF_ANNEXB)
ret=GetAnnexbNALU (nalu);
else
ret=GetRTPNALU (nalu);
CheckZeroByteNonVCL(nalu, &ret);
NALUtoRBSP(nalu);
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)
return current_header;
}
// check if we got DP_C
if ( NALU_TYPE_DPC == nalu->nal_unit_type)
{
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: DP_C slice_id", currStream);
if (slice_id_c != slice_id_a)
{
printf ("got a data partition C which does not match DP_A\n");
// KS: needs error handling !!!
}
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;
}
// check if we read anything else than the expected partitions
if ((nalu->nal_unit_type != NALU_TYPE_DPB) && (nalu->nal_unit_type != NALU_TYPE_DPC))
{
// reset bitstream position and read again in next call
fseek(bits, ftell_position, SEEK_SET);
}
FreeNALU(nalu);
return current_header;
break;
case NALU_TYPE_DPB:
printf ("found data partition B without matching DP A, discarding\n");
break;
case NALU_TYPE_DPC:
printf ("found data partition C without matching DP A, discarding\n");
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->recovery_point)
img->recovery_frame_num = (img->frame_num + img->recovery_frame_cnt) % img->MaxFrameNum;
if (img->idr_flag)
img->recovery_frame_num = img->frame_num;
if (img->recovery_point == 0 &&
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);
if (img->recovery_frame_num == img->frame_num &&
img->recovery_poc == 0x7fffffff)
img->recovery_poc = img->framepoc;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -