📄 image.c
字号:
//! 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);
init_lists(img->type, img->currentSlice->structure);
reorder_lists (img->type, img->currentSlice);
if (img->MbaffFrameFlag)
{
init_mbaff_lists();
}
if (img->currentSlice->structure!=0)
{
img->height /=2 ;
img->height_cr /=2;
}
// From here on, active_sps, active_pps and the slice header are valid
img->current_mb_nr = currSlice->start_mb_nr;
if (img->tr_old != img->ThisPOC)
{
newframe=1;
img->tr_old = img->ThisPOC;
}
else
newframe = 0;
if (newframe)
current_header = SOP;
else
current_header = SOS;
if(img->structure != img->structure_old)
newframe |= 1;
img->structure_old = img->structure;
//! new stuff StW
if(newframe || g_new_frame)
{
current_header = SOP;
g_new_frame=0;
}
else
current_header = SOS;
/*
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->redundant_pic_cnt_present_flag)
redundant_pic_cnt_a = ue_v("NALU:SLICE_A redudand_pic_cnt", currStream);
else
redundant_pic_cnt_a = 0;
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_PD:
// 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 frame
************************************************************************
*/
void init_frame(struct img_par *img, struct inp_par *inp)
{
int i,k,l,j;
if (dec_picture)
{
// this may only happen on slice loss
store_picture_in_dpb(dec_picture);
}
dec_picture = alloc_storable_picture (FRAME, img->width, img->height, img->width_cr, img->height_cr);
dec_picture->poc=img->framepoc;
dec_picture->top_poc=img->toppoc;
dec_picture->bottom_poc=img->bottompoc;
dec_picture->pic_num = img->frame_num;
dec_picture->coded_frame = (img->structure==FRAME);
// dec_picture->mb_adaptive_frame_field_flag = img->MbaffFrameFlag;
for (i=0;i<listXsize[LIST_0];i++)
{
dec_picture->ref_pic_num[LIST_0][i]=listX[LIST_0][i]->poc;
}
for (i=0;i<listXsize[LIST_1];i++)
{
dec_picture->ref_pic_num[LIST_1][i]=listX[LIST_1][i]->poc;
}
if (img->MbaffFrameFlag)
for (j=2;j<6;j++)
for (i=0;i<listXsize[j];i++)
{
dec_picture->ref_pic_num[j][i]=listX[j][i]->poc;
}
img->current_slice_nr=0;
if (img->type > SI_SLICE)
{
set_ec_flag(SE_PTYPE);
img->type = P_SLICE; // concealed element
}
// allocate memory for frame buffers
if (img->number == 0)
{
init_global_buffers(inp, img);
}
// CAVLC init
for (i=0;i < (int)img->PicSizeInMbs; i++)
for (k=0;k<4;k++)
for (l=0;l<6;l++)
img->nz_coeff[i][k][l]=-1; // CAVLC
if(img->constrained_intra_pred_flag)
{
for (i=0; i<(int)img->PicSizeInMbs; i++)
{
img->intra_block[i] = 1;
}
}
// WYK: Oct. 8, 2001. Set the slice_nr member of each MB to -1, to ensure correct when packet loss occurs
// TO set Macroblock Map (mark all MBs as 'have to be concealed')
for(i=0; i<(int)img->PicSizeInMbs; i++)
{
img->mb_data[i].slice_nr = -1;
img->mb_data[i].ei_flag = 1;
}
}
/*!
************************************************************************
* \brief
* exit a frame
************************************************************************
*/
void exit_frame(struct img_par *img, struct inp_par *inp)
{
// !!!KS: hmm, nothing remaining here
}
/*!
************************************************************************
* \brief
* write the encoding mode and motion vectors of current
* MB to the buffer of the error concealment module.
************************************************************************
*/
void ercWriteMBMODEandMV(struct img_par *img,struct inp_par *inp)
{
extern objectBuffer_t *erc_object_list;
int i, ii, jj, currMBNum = img->current_mb_nr;
int mbx = xPosMB(currMBNum,img->width), mby = yPosMB(currMBNum,img->width);
objectBuffer_t *currRegion, *pRegion;
Macroblock *currMB = &img->mb_data[currMBNum];
int*** mv;
currRegion = erc_object_list + (currMBNum<<2);
if(img->type != B_SLICE) //non-B frame
{
for (i=0; i<4; i++)
{
pRegion = currRegion + i;
pRegion->regionMode = (currMB->mb_type ==I16MB ? REGMODE_INTRA :
currMB->b8mode[i]==IBLOCK ? REGMODE_INTRA_8x8 :
currMB->b8mode[i]==0 ? REGMODE_INTER_COPY :
currMB->b8mode[i]==1 ? REGMODE_INTER_PRED : REGMODE_INTER_PRED_8x8);
if (currMB->b8mode[i]==0 || currMB->b8mode[i]==IBLOCK) // INTRA OR COPY
{
pRegion->mv[0] = 0;
pRegion->mv[1] = 0;
pRegion->mv[2] = 0;
}
else
{
if (currMB->b8mode[i]>=5 && currMB->b8mode[i]<=7) // SMALL BLOCKS
{
ii = 4*mbx + (i%2)*2 + BLOCK_SIZE;
jj = 4*mby + (i/2)*2;
pRegion->mv[0] = (dec_picture->mv[LIST_0][ii][jj][0] + dec_picture->mv[LIST_0][ii+1][jj][0] + dec_picture->mv[LIST_0][ii][jj+1][0] + dec_picture->mv[LIST_0][ii+1][jj+1][0] + 2)/4;
pRegion->mv[1] = (dec_picture->mv[LIST_0][ii][jj][1] + dec_picture->mv[LIST_0][ii+1][jj][1] + dec_picture->mv[LIST_0][ii][jj+1][1] + dec_picture->mv[LIST_0][ii+1][jj+1][1] + 2)/4;
}
else // 16x16, 16x8, 8x16, 8x8
{
pRegion->mv[0] = dec_picture->mv[LIST_0][4*mbx+(i%2)*2+BLOCK_SIZE][4*mby+(i/2)*2][0];
pRegion->mv[1] = dec_picture->mv[LIST_0][4*mbx+(i%2)*2+BLOCK_SIZE][4*mby+(i/2)*2][1];
}
erc_mvperMB += mabs(pRegion->mv[0]) + mabs(pRegion->mv[1]);
pRegion->mv[2] = refFrArr[4*mby+(i/2)*2][4*mbx+(i%2)*2];
}
}
}
else //B-frame
{
for (i=0; i<4; i++)
{
ii = 4*mbx + (i%2)*2 + BLOCK_SIZE;
jj = 4*mby + (i/2)*2;
pRegion = currRegion + i;
pRegion->regionMode = (currMB->mb_type ==I16MB ? REGMODE_INTRA :
currMB->b8mode[i]==IBLOCK ? REGMODE_INTRA_8x8 : REGMODE_INTER_PRED_8x8);
if (currMB->mb_type==I16MB || currMB->b8mode[i]==IBLOCK) // INTRA
{
pRegion->mv[0] = 0;
pRegion->mv[1] = 0;
pRegion->mv[2] = 0;
}
else
{
mv = (currMB->b8mode[i]==0 && currMB->b8pdir[i]==2 ? 0/*img->dbMV*/ : currMB->b8pdir[i]==1 ? dec_picture->mv[LIST_1] : dec_picture->mv[LIST_0]);
pRegion->mv[0] = (mv[ii][jj][0] + mv[ii+1][jj][0] + mv[ii][jj+1][0] + mv[ii+1][jj+1][0] + 2)/4;
pRegion->mv[1] = (mv[ii][jj][1] + mv[ii+1][jj][1] + mv[ii][jj+1][1] + mv[ii+1][jj+1][1] + 2)/4;
erc_mvperMB += mabs(pRegion->mv[0]) + mabs(pRegion->mv[1]);
if (currMB->b8pdir[i]==0 || (currMB->b8pdir[i]==2 && currMB->b8mode[i]!=0)) // forward or bidirect
{
pRegion->mv[2] = (dec_picture->ref_idx[LIST_1][ii-4][jj]-1);
///???? is it right, not only "img->fw_refFrArr[jj][ii-4]"
}
else
{
pRegion->mv[2] = 0;
}
}
}
}
}
/*!
************************************************************************
* \brief
* decodes one slice
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -