📄 image.c
字号:
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(currSlice);
UseParameterSet (currSlice->pic_parameter_set_id);
BitsUsedByHeader += RestOfSliceHeader (currSlice);
FmoInit (active_pps, active_sps);
if(is_new_picture(dec_picture, currSlice, &old_slice))
{
init_picture(img, currSlice, params);
current_header = SOP;
CheckZeroByteVCL(nalu);
}
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
if (0 == read_next_nalu(nalu))
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);
currSlice->dpB_NotPresent = 0;
if ((slice_id_b != slice_id_a) || (nalu->lost_packets))
{
printf ("Waning: got a data partition B which does not match DP_A (DP loss!)\n");
currSlice->dpB_NotPresent =1;
currSlice->dpC_NotPresent =1;
}
else
{
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
if (0 == read_next_nalu(nalu))
return current_header;
}
}
else
{
currSlice->dpB_NotPresent =1;
}
// 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);
currSlice->dpC_NotPresent = 0;
slice_id_c = ue_v("NALU: DP_C slice_id", currStream);
if ((slice_id_c != slice_id_a)|| (nalu->lost_packets))
{
printf ("Warning: got a data partition C which does not match DP_A(DP loss!)\n");
//currSlice->dpB_NotPresent =1;
currSlice->dpC_NotPresent =1;
}
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;
}
else
{
currSlice->dpC_NotPresent =1;
}
// 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))
{
// we have a NALI that we can't process here, so restart processing
goto process_nalu;
// yes, "goto" should not be used, but it's really the best way here before we restructure the decoding loop
// (which should be taken care of anyway)
}
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", (int) 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", (int) nalu->nal_unit_type, (int) nalu->len);
break;
}
}
FreeNALU(nalu);
return current_header;
}
/*!
************************************************************************
* \brief
* finish decoding of a picture, conceal errors and store it
* into the DPB
************************************************************************
*/
void exit_picture(StorablePicture **dec_picture)
{
char yuv_types[4][6]= {"4:0:0","4:2:0","4:2:2","4:4:4"};
int ercStartMB;
int ercSegment;
frame recfr;
unsigned int i;
int structure, frame_poc, slice_type, refpic, qp, pic_num, chroma_format_idc, is_idr;
static char cslice_type[9];
int64 tmp_time; // time used by decoding the last frame
char yuvFormat[10];
int nplane;
// return if the last picture has already been finished
if (*dec_picture==NULL)
{
return;
}
//deblocking for frame or field
if( IS_INDEPENDENT(img) )
{
int colour_plane_id = img->colour_plane_id;
for( nplane=0; nplane<MAX_PLANE; nplane++ )
{
change_plane_JV( nplane );
DeblockPicture( img, *dec_picture );
}
img->colour_plane_id = colour_plane_id;
make_frame_picture_JV();
}
else
{
DeblockPicture( img, *dec_picture );
}
if ((*dec_picture)->MbaffFrameFlag)
MbAffPostProc();
recfr.yptr = &(*dec_picture)->imgY[0][0];
if ((*dec_picture)->chroma_format_idc != YUV400)
{
recfr.uptr = &(*dec_picture)->imgUV[0][0][0];
recfr.vptr = &(*dec_picture)->imgUV[1][0][0];
}
//! this is always true at the beginning of a picture
ercStartMB = 0;
ercSegment = 0;
//! mark the start of the first segment
if (!(*dec_picture)->MbaffFrameFlag)
{
ercStartSegment(0, ercSegment, 0 , erc_errorVar);
//! generate the segments according to the macroblock map
for(i = 1; i<(*dec_picture)->PicSizeInMbs; i++)
{
if(img->mb_data[i].ei_flag != img->mb_data[i-1].ei_flag)
{
ercStopSegment(i-1, ercSegment, 0, erc_errorVar); //! stop current segment
//! mark current segment as lost or OK
if(img->mb_data[i-1].ei_flag)
ercMarkCurrSegmentLost((*dec_picture)->size_x, erc_errorVar);
else
ercMarkCurrSegmentOK((*dec_picture)->size_x, erc_errorVar);
ercSegment++; //! next segment
ercStartSegment(i, ercSegment, 0 , erc_errorVar); //! start new segment
ercStartMB = i;//! save start MB for this segment
}
}
//! mark end of the last segment
ercStopSegment((*dec_picture)->PicSizeInMbs-1, ercSegment, 0, erc_errorVar);
if(img->mb_data[i-1].ei_flag)
ercMarkCurrSegmentLost((*dec_picture)->size_x, erc_errorVar);
else
ercMarkCurrSegmentOK((*dec_picture)->size_x, erc_errorVar);
//! call the right error concealment function depending on the frame type.
erc_mvperMB /= (*dec_picture)->PicSizeInMbs;
erc_img = img;
if((*dec_picture)->slice_type == I_SLICE || (*dec_picture)->slice_type == SI_SLICE) // I-frame
ercConcealIntraFrame(&recfr, (*dec_picture)->size_x, (*dec_picture)->size_y, erc_errorVar);
else
ercConcealInterFrame(&recfr, erc_object_list, (*dec_picture)->size_x, (*dec_picture)->size_y, erc_errorVar, (*dec_picture)->chroma_format_idc);
}
if (img->structure == FRAME) // buffer mgt. for frame mode
frame_postprocessing(img);
else
field_postprocessing(img); // reset all interlaced variables
structure = (*dec_picture)->structure;
slice_type = (*dec_picture)->slice_type;
frame_poc = (*dec_picture)->frame_poc;
refpic = (*dec_picture)->used_for_reference;
qp = (*dec_picture)->qp;
pic_num = (*dec_picture)->pic_num;
is_idr = (*dec_picture)->idr_flag;
chroma_format_idc = (*dec_picture)->chroma_format_idc;
store_picture_in_dpb(*dec_picture);
*dec_picture=NULL;
if (img->last_has_mmco_5)
{
img->pre_frame_num = 0;
}
if (params->silent == FALSE)
{
if (structure==TOP_FIELD || structure==FRAME)
{
if(slice_type == I_SLICE && is_idr) // IDR picture
strcpy(cslice_type,"IDR");
else if(slice_type == I_SLICE) // I picture
strcpy(cslice_type," I ");
else if(slice_type == P_SLICE) // P pictures
strcpy(cslice_type," P ");
else if(slice_type == SP_SLICE) // SP pictures
strcpy(cslice_type,"SP ");
else if (slice_type == SI_SLICE)
strcpy(cslice_type,"SI ");
else if(refpic) // stored B pictures
strcpy(cslice_type," B ");
else // B pictures
strcpy(cslice_type," b ");
if (structure==FRAME)
{
strncat(cslice_type,") ",8-strlen(cslice_type));
}
}
else if (structure==BOTTOM_FIELD)
{
if(slice_type == I_SLICE && is_idr) // IDR picture
strncat(cslice_type,"|IDR)",8-strlen(cslice_type));
else if(slice_type == I_SLICE) // I picture
strncat(cslice_type,"| I )",8-strlen(cslice_type));
else if(slice_type == P_SLICE) // P pictures
strncat(cslice_type,"| P )",8-strlen(cslice_type));
else if(slice_type == SP_SLICE) // SP pictures
strncat(cslice_type,"|SP )",8-strlen(cslice_type));
else if (slice_type == SI_SLICE)
strncat(cslice_type,"|SI )",8-strlen(cslice_type));
else if(refpic) // stored B pictures
strncat(cslice_type,"| B )",8-strlen(cslice_type));
else // B pictures
strncat(cslice_type,"| b )",8-strlen(cslice_type));
}
}
if ((structure==FRAME)||structure==BOTTOM_FIELD)
{
gettime (&(img->end_time)); // end time
tmp_time = timediff(&(img->start_time), &(img->end_time));
tot_time += tmp_time;
tmp_time = timenorm(tmp_time);
sprintf(yuvFormat,"%s", yuv_types[chroma_format_idc]);
if (params->silent == FALSE)
{
if (p_ref != -1)
fprintf(stdout,"%05d(%s%5d %5d %5d %8.4f %8.4f %8.4f %s %7d\n",
frame_no, cslice_type, frame_poc, pic_num, qp, snr->snr[0], snr->snr[1], snr->snr[2], yuvFormat, (int) tmp_time);
else
fprintf(stdout,"%05d(%s%5d %5d %5d %s %7d\n",
frame_no, cslice_type, frame_poc, pic_num, qp, yuvFormat, (int)tmp_time);
}
else
fprintf(stdout,"Completed Decoding frame %05d.\r",snr->frame_ctr);
fflush(stdout);
if(slice_type == I_SLICE || slice_type == SI_SLICE || slice_type == P_SLICE || refpic) // I or P pictures
img->number++;
else
Bframe_ctr++; // B pictures
snr->frame_ctr++;
g_nFrame++;
}
img->current_mb_nr = -4712; // impossible value for debugging, StW
img->current_slice_nr = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -