mbuffer.c
资源名称:chapter15.rar [点击查看]
上传用户:hjq518
上传日期:2021-12-09
资源大小:5084k
文件大小:136k
源码类别:
Audio
开发平台:
Visual C++
- /*!
- ***********************************************************************
- * file
- * mbuffer.c
- *
- * brief
- * Frame buffer functions
- *
- * author
- * Main contributors (see contributors.h for copyright, address and affiliation details)
- * - Karsten S黨ring <suehring@hhi.de>
- * - Alexis Tourapis <alexismt@ieee.org>
- ***********************************************************************
- */
- #include <limits.h>
- #include "global.h"
- #include "mbuffer.h"
- #include "memalloc.h"
- #include "output.h"
- #include "image.h"
- #include "nalucommon.h"
- extern void init_stats (StatParameters *stats);
- static void insert_picture_in_dpb(FrameStore* fs, StorablePicture* p);
- static void output_one_frame_from_dpb(void);
- static int is_used_for_reference(FrameStore* fs);
- static void get_smallest_poc(int *poc,int * pos);
- static int remove_unused_frame_from_dpb(void);
- static int is_short_term_reference(FrameStore* fs);
- static int is_long_term_reference(FrameStore* fs);
- void gen_field_ref_ids(StorablePicture *p);
- DecodedPictureBuffer dpb;
- StorablePicture **listX[6];
- ColocatedParams *Co_located = NULL;
- ColocatedParams *Co_located_JV[MAX_PLANE] = { NULL, NULL, NULL }; //!< Co_located to be used during 4:4:4 independent mode encoding
- int listXsize[6];
- #define MAX_LIST_SIZE 33
- /*!
- ************************************************************************
- * brief
- * Print out list of pictures in DPB. Used for debug purposes.
- ************************************************************************
- */
- void dump_dpb(void)
- {
- #if DUMP_DPB
- unsigned i;
- for (i=0; i<dpb.used_size;i++)
- {
- printf("(");
- printf("fn=%d ", dpb.fs[i]->frame_num);
- if (dpb.fs[i]->is_used & 1)
- {
- if (dpb.fs[i]->top_field)
- printf("T: poc=%d ", dpb.fs[i]->top_field->poc);
- else
- printf("T: poc=%d ", dpb.fs[i]->frame->top_poc);
- }
- if (dpb.fs[i]->is_used & 2)
- {
- if (dpb.fs[i]->bottom_field)
- printf("B: poc=%d ", dpb.fs[i]->bottom_field->poc);
- else
- printf("B: poc=%d ", dpb.fs[i]->frame->bottom_poc);
- }
- if (dpb.fs[i]->is_used == 3)
- printf("F: poc=%d ", dpb.fs[i]->frame->poc);
- printf("G: poc=%d) ", dpb.fs[i]->poc);
- if (dpb.fs[i]->is_reference) printf ("ref (%d) ", dpb.fs[i]->is_reference);
- if (dpb.fs[i]->is_long_term) printf ("lt_ref (%d) ", dpb.fs[i]->is_reference);
- if (dpb.fs[i]->is_output) printf ("out ");
- if (dpb.fs[i]->is_used == 3)
- {
- if (dpb.fs[i]->frame->non_existing) printf ("ne ");
- }
- printf ("n");
- }
- #endif
- }
- /*!
- ************************************************************************
- * brief
- * Returns the size of the dpb depending on level and picture size
- *
- *
- ************************************************************************
- */
- int getDpbSize(void)
- {
- int pic_size = (active_sps->pic_width_in_mbs_minus1 + 1) * (active_sps->pic_height_in_map_units_minus1 + 1) * (active_sps->frame_mbs_only_flag?1:2) * 384;
- int size = 0;
- switch (active_sps->level_idc)
- {
- case 9:
- size = 152064;
- break;
- case 10:
- size = 152064;
- break;
- case 11:
- if (!IS_FREXT_PROFILE(active_sps->profile_idc)&&(active_sps->constrained_set3_flag == 1))
- size = 152064;
- else
- size = 345600;
- break;
- case 12:
- size = 912384;
- break;
- case 13:
- size = 912384;
- break;
- case 20:
- size = 912384;
- break;
- case 21:
- size = 1824768;
- break;
- case 22:
- size = 3110400;
- break;
- case 30:
- size = 3110400;
- break;
- case 31:
- size = 6912000;
- break;
- case 32:
- size = 7864320;
- break;
- case 40:
- size = 12582912;
- break;
- case 41:
- size = 12582912;
- break;
- case 42:
- size = 13369344;
- break;
- case 50:
- size = 42393600;
- break;
- case 51:
- size = 70778880;
- break;
- default:
- error ("undefined level", 500);
- break;
- }
- size /= pic_size;
- return imin( size, 16);
- }
- /*!
- ************************************************************************
- * brief
- * Check then number of frames marked "used for reference" and break
- * if maximum is exceeded
- *
- ************************************************************************
- */
- void check_num_ref(void)
- {
- if ((int)(dpb.ltref_frames_in_buffer + dpb.ref_frames_in_buffer ) > (imax(1,img->num_ref_frames)))
- {
- error ("Max. number of reference frames exceeded. Invalid stream.", 500);
- }
- }
- /*!
- ************************************************************************
- * brief
- * Allocate memory for decoded picture buffer and initialize with sane values.
- *
- ************************************************************************
- */
- void init_dpb(void)
- {
- unsigned i,j;
- if (dpb.init_done)
- {
- free_dpb();
- }
- dpb.size = getDpbSize();
- if (dpb.size < (unsigned int)params->num_ref_frames)
- {
- error ("DPB size at specified level is smaller than the specified number of reference frames. This is not allowed.n", 1000);
- }
- dpb.used_size = 0;
- dpb.last_picture = NULL;
- dpb.ref_frames_in_buffer = 0;
- dpb.ltref_frames_in_buffer = 0;
- dpb.fs = calloc(dpb.size, sizeof (FrameStore*));
- if (NULL==dpb.fs)
- no_mem_exit("init_dpb: dpb->fs");
- dpb.fs_ref = calloc(dpb.size, sizeof (FrameStore*));
- if (NULL==dpb.fs_ref)
- no_mem_exit("init_dpb: dpb->fs_ref");
- dpb.fs_ltref = calloc(dpb.size, sizeof (FrameStore*));
- if (NULL==dpb.fs_ltref)
- no_mem_exit("init_dpb: dpb->fs_ltref");
- for (i = 0; i < dpb.size; i++)
- {
- dpb.fs[i] = alloc_frame_store();
- dpb.fs_ref[i] = NULL;
- dpb.fs_ltref[i] = NULL;
- }
- for (i = 0; i < 6; i++)
- {
- listX[i] = calloc(MAX_LIST_SIZE, sizeof (StorablePicture*)); // +1 for reordering
- if (NULL==listX[i])
- no_mem_exit("init_dpb: listX[i]");
- }
- for (j = 0; j < 6; j++)
- {
- for (i = 0; i < MAX_LIST_SIZE; i++)
- {
- listX[j][i] = NULL;
- }
- listXsize[j]=0;
- }
- dpb.last_output_poc = INT_MIN;
- img->last_has_mmco_5 = 0;
- dpb.init_done = 1;
- }
- /*!
- ************************************************************************
- * brief
- * Free memory for decoded picture buffer.
- ************************************************************************
- */
- void free_dpb(void)
- {
- unsigned i;
- if (dpb.fs)
- {
- for (i=0; i<dpb.size; i++)
- {
- free_frame_store(dpb.fs[i]);
- }
- free (dpb.fs);
- dpb.fs=NULL;
- }
- if (dpb.fs_ref)
- {
- free (dpb.fs_ref);
- }
- if (dpb.fs_ltref)
- {
- free (dpb.fs_ltref);
- }
- dpb.last_output_poc = INT_MIN;
- for (i=0; i<6; i++)
- if (listX[i])
- {
- free (listX[i]);
- listX[i] = NULL;
- }
- dpb.init_done = 0;
- }
- /*!
- ************************************************************************
- * brief
- * Allocate memory for decoded picture buffer frame stores an initialize with sane values.
- *
- * return
- * the allocated FrameStore structure
- ************************************************************************
- */
- FrameStore* alloc_frame_store(void)
- {
- FrameStore *f;
- f = calloc (1, sizeof(FrameStore));
- if (NULL==f)
- no_mem_exit("alloc_frame_store: f");
- f->is_used = 0;
- f->is_reference = 0;
- f->is_long_term = 0;
- f->is_orig_reference = 0;
- f->is_output = 0;
- f->frame = NULL;;
- f->top_field = NULL;
- f->bottom_field = NULL;
- return f;
- }
- void alloc_pic_motion(PicMotionParams *motion, int size_y, int size_x)
- {
- get_mem3Dint64 (&(motion->ref_pic_id), 6, size_y, size_x);
- get_mem3Dint64 (&(motion->ref_id), 6, size_y, size_x);
- get_mem4Dshort (&(motion->mv), 2, size_y, size_x, 2);
- get_mem3D ((byte****)(&(motion->ref_idx)), 2, size_y , size_x);
- motion->mb_field = calloc (size_y * size_x, sizeof(byte));
- if (motion->mb_field == NULL)
- no_mem_exit("alloc_storable_picture: motion->mb_field");
- get_mem2D (&(motion->field_frame), size_y, size_x);
- }
- /*!
- ************************************************************************
- * brief
- * Allocate memory for a stored picture.
- *
- * param structure
- * picture structure
- * param size_x
- * horizontal luma size
- * param size_y
- * vertical luma size
- * param size_x_cr
- * horizontal chroma size
- * param size_y_cr
- * vertical chroma size
- *
- * return
- * the allocated StorablePicture structure
- ************************************************************************
- */
- StorablePicture* alloc_storable_picture(PictureStructure structure, int size_x, int size_y, int size_x_cr, int size_y_cr)
- {
- StorablePicture *s;
- int nplane;
- int dec;
- int ndec = params->NoOfDecoders;
- //printf ("Allocating (%s) picture (x=%d, y=%d, x_cr=%d, y_cr=%d)n", (type == FRAME)?"FRAME":(type == TOP_FIELD)?"TOP_FIELD":"BOTTOM_FIELD", size_x, size_y, size_x_cr, size_y_cr);
- s = calloc (1, sizeof(StorablePicture));
- if (NULL==s)
- no_mem_exit("alloc_storable_picture: s");
- s->imgUV = NULL;
- s->imgY_sub = NULL;
- s->imgUV_sub = NULL;
- s->p_img_sub[0] = NULL;
- s->p_img_sub[1] = NULL;
- s->p_img_sub[2] = NULL;
- s->dec_imgY = NULL;
- s->dec_imgUV = NULL;
- s->mb_error_map = NULL;
- s->p_dec_img[0] = NULL;
- s->p_dec_img[1] = NULL;
- s->p_dec_img[2] = NULL;
- if ((params->rdopt == 3) && (ndec > 0)) //PPAHA_TODO: Need to verify whether both checks are necessary.
- {
- get_mem3D(&(s->mb_error_map), ndec, size_y/MB_BLOCK_SIZE, size_x/MB_BLOCK_SIZE);
- get_mem3Dpel(&(s->dec_imgY), ndec, size_y, size_x);
- // This seems somewhat inefficient. Why not allocate array as [ndec][x] where x goes from 0 to 2?
- if ((s->p_dec_img[0] = (imgpel***)calloc(ndec,sizeof(imgpel**))) == NULL)
- {
- no_mem_exit("mbuffer.c: p_dec_img[0]");
- }
- if (img->yuv_format != YUV400)
- {
- get_mem4Dpel(&(s->dec_imgUV), ndec, 2, size_y_cr, size_x_cr);
- if ((s->p_dec_img[1] = (imgpel***)calloc(ndec,sizeof(imgpel**))) == NULL)
- {
- no_mem_exit("mbuffer.c: p_dec_img[1]");
- }
- if ((s->p_dec_img[2] = (imgpel***)calloc(ndec,sizeof(imgpel**))) == NULL)
- {
- no_mem_exit("mbuffer.c: p_dec_img[2]");
- }
- }
- for (dec = 0; dec < ndec; dec++)
- {
- s->p_dec_img[0][dec] = s->dec_imgY[dec];
- }
- if (img->yuv_format != YUV400)
- {
- for (dec = 0; dec < ndec; dec++)
- {
- s->p_dec_img[1][dec] = s->dec_imgUV[dec][0];
- s->p_dec_img[2][dec] = s->dec_imgUV[dec][1];
- }
- }
- }
- get_mem2Dpel (&(s->imgY), size_y, size_x);
- s->p_img[0] = s->imgY;
- s->p_curr_img = s->p_img[0];
- if (img->yuv_format != YUV400)
- {
- get_mem3Dpel (&(s->imgUV), 2, size_y_cr, size_x_cr);
- s->p_img[1] = s->imgUV[0];
- s->p_img[2] = s->imgUV[1];
- }
- s->p_curr_img_sub = s->p_img_sub[0];
- if (params->MbInterlace)
- get_mem3Dmp (&s->mv_info, size_y, size_x, 6);
- else
- get_mem3Dmp (&s->mv_info, size_y, size_x, 2);
- alloc_pic_motion(&s->motion, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE);
- if( IS_INDEPENDENT(params) )
- {
- for( nplane=0; nplane<MAX_PLANE; nplane++ )
- {
- alloc_pic_motion(&s->JVmotion[nplane], size_y / BLOCK_SIZE, size_x / BLOCK_SIZE);
- }
- }
- s->pic_num=0;
- s->frame_num=0;
- s->long_term_frame_idx=0;
- s->long_term_pic_num=0;
- s->used_for_reference=0;
- s->is_long_term=0;
- s->non_existing=0;
- s->is_output = 0;
- s->structure=structure;
- s->size_x = size_x;
- s->size_y = size_y;
- s->size_x_padded = size_x + 2 * IMG_PAD_SIZE;
- s->size_y_padded = size_y + 2 * IMG_PAD_SIZE;
- s->size_x_pad = size_x + 2 * IMG_PAD_SIZE - 1 - MB_BLOCK_SIZE;
- s->size_y_pad = size_y + 2 * IMG_PAD_SIZE - 1 - MB_BLOCK_SIZE;
- s->size_x_cr = size_x_cr;
- s->size_y_cr = size_y_cr;
- s->size_x_cr_pad = (int) (size_x_cr - 1) + (img_pad_size_uv_x << 1) - (img->mb_cr_size_x);
- s->size_y_cr_pad = (int) (size_y_cr - 1) + (img_pad_size_uv_y << 1) - (img->mb_cr_size_y);
- s->top_field = NULL;
- s->bottom_field = NULL;
- s->frame = NULL;
- s->coded_frame = 0;
- s->MbaffFrameFlag = 0;
- init_stats(&s->stats);
- return s;
- }
- /*!
- ************************************************************************
- * brief
- * Free frame store memory.
- *
- * param f
- * FrameStore to be freed
- *
- ************************************************************************
- */
- void free_frame_store(FrameStore* f)
- {
- if (f)
- {
- if (f->frame)
- {
- free_storable_picture(f->frame);
- f->frame=NULL;
- }
- if (f->top_field)
- {
- free_storable_picture(f->top_field);
- f->top_field=NULL;
- }
- if (f->bottom_field)
- {
- free_storable_picture(f->bottom_field);
- f->bottom_field=NULL;
- }
- free(f);
- }
- }
- void free_pic_motion(PicMotionParams *motion)
- {
- if (motion->ref_pic_id)
- {
- free_mem3Dint64 (motion->ref_pic_id);
- motion->ref_pic_id = NULL;
- }
- if (motion->ref_id)
- {
- free_mem3Dint64 (motion->ref_id);
- motion->ref_id = NULL;
- }
- if (motion->mv)
- {
- free_mem4Dshort (motion->mv);
- motion->mv = NULL;
- }
- if (motion->ref_idx)
- {
- free_mem3D ((byte***)motion->ref_idx);
- motion->ref_idx = NULL;
- }
- if (motion->mb_field)
- {
- free(motion->mb_field);
- motion->mb_field=NULL;
- }
- if (motion->field_frame)
- {
- free_mem2D (motion->field_frame);
- motion->field_frame=NULL;
- }
- }
- /*!
- ************************************************************************
- * brief
- * Free picture memory.
- *
- * param p
- * Picture to be freed
- *
- ************************************************************************
- */
- void free_storable_picture(StorablePicture* p)
- {
- int nplane;
- if (p)
- {
- free_mem3Dmp (p->mv_info);
- free_pic_motion(&p->motion);
- if( IS_INDEPENDENT(params) )
- {
- for( nplane=0; nplane<MAX_PLANE; nplane++ )
- {
- free_pic_motion(&p->JVmotion[nplane]);
- }
- }
- if (p->imgY)
- {
- free_mem2Dpel (p->imgY);
- p->imgY=NULL;
- }
- if( IS_INDEPENDENT(params) )
- {
- if (p->imgY_sub)
- {
- free_mem4Dpel (p->imgY_sub);
- p->imgY_sub=NULL;
- }
- if (p->imgUV_sub)
- {
- free_mem5Dpel (p->imgUV_sub);
- p->imgUV_sub = NULL;
- }
- p->p_curr_img = NULL;
- p->p_curr_img_sub = NULL;
- p->p_img[0] = NULL;
- p->p_img[1] = NULL;
- p->p_img[2] = NULL;
- p->p_img_sub[0] = NULL;
- p->p_img_sub[1] = NULL;
- p->p_img_sub[2] = NULL;
- }
- else
- {
- if (p->imgY_sub)
- {
- free_mem4Dpel (p->imgY_sub);
- p->imgY_sub=NULL;
- }
- if ( p->imgUV_sub && img->yuv_format != YUV400 && params->ChromaMCBuffer )
- {
- free_mem5Dpel (p->imgUV_sub);
- p->imgUV_sub = NULL;
- }
- }
- if (p->imgUV)
- {
- free_mem3Dpel (p->imgUV);
- p->imgUV=NULL;
- }
- if (p->dec_imgY)
- {
- free_mem3Dpel(p->dec_imgY);
- }
- if (p->dec_imgUV)
- {
- free_mem4Dpel(p->dec_imgUV);
- }
- for (nplane = 0; nplane < 3; nplane++)
- {
- if (p->p_dec_img[nplane])
- {
- free(p->p_dec_img[nplane]);
- p->p_dec_img[nplane] = NULL;
- }
- }
- if (p->mb_error_map)
- {
- free_mem3D(p->mb_error_map);
- }
- p->mb_error_map = NULL;
- p->dec_imgY = NULL;
- p->dec_imgUV = NULL;
- free(p);
- p = NULL;
- }
- }
- /*!
- ************************************************************************
- * brief
- * mark FrameStore unused for reference
- *
- ************************************************************************
- */
- static void unmark_for_reference(FrameStore* fs)
- {
- if (fs->is_used & 1)
- {
- if (fs->top_field)
- {
- fs->top_field->used_for_reference = 0;
- }
- }
- if (fs->is_used & 2)
- {
- if (fs->bottom_field)
- {
- fs->bottom_field->used_for_reference = 0;
- }
- }
- if (fs->is_used == 3)
- {
- if (fs->top_field && fs->bottom_field)
- {
- fs->top_field->used_for_reference = 0;
- fs->bottom_field->used_for_reference = 0;
- }
- fs->frame->used_for_reference = 0;
- }
- fs->is_reference = 0;
- if(fs->frame)
- {
- if (fs->frame->imgY_sub)
- {
- free_mem4Dpel (fs->frame->imgY_sub);
- fs->frame->imgY_sub=NULL;
- }
- if (fs->frame->imgUV_sub)
- {
- free_mem5Dpel (fs->frame->imgUV_sub);
- fs->frame->imgUV_sub = NULL;
- }
- free_pic_motion(&fs->frame->motion);
- }
- if (fs->top_field)
- {
- if (fs->top_field->imgY_sub)
- {
- free_mem4Dpel (fs->top_field->imgY_sub);
- fs->top_field->imgY_sub=NULL;
- }
- if (fs->top_field->imgUV_sub)
- {
- free_mem5Dpel (fs->top_field->imgUV_sub);
- fs->top_field->imgUV_sub = NULL;
- }
- free_pic_motion(&fs->top_field->motion);
- }
- if (fs->bottom_field)
- {
- if (fs->bottom_field->imgY_sub)
- {
- free_mem4Dpel (fs->bottom_field->imgY_sub);
- fs->bottom_field->imgY_sub=NULL;
- }
- if (fs->bottom_field->imgUV_sub)
- {
- free_mem5Dpel (fs->bottom_field->imgUV_sub);
- fs->bottom_field->imgUV_sub = NULL;
- }
- free_pic_motion(&fs->bottom_field->motion);
- }
- }
- /*!
- ************************************************************************
- * brief
- * mark FrameStore unused for reference and reset long term flags
- *
- ************************************************************************
- */
- static void unmark_for_long_term_reference(FrameStore* fs)
- {
- if (fs->is_used & 1)
- {
- if (fs->top_field)
- {
- fs->top_field->used_for_reference = 0;
- fs->top_field->is_long_term = 0;
- }
- }
- if (fs->is_used & 2)
- {
- if (fs->bottom_field)
- {
- fs->bottom_field->used_for_reference = 0;
- fs->bottom_field->is_long_term = 0;
- }
- }
- if (fs->is_used == 3)
- {
- if (fs->top_field && fs->bottom_field)
- {
- fs->top_field->used_for_reference = 0;
- fs->top_field->is_long_term = 0;
- fs->bottom_field->used_for_reference = 0;
- fs->bottom_field->is_long_term = 0;
- }
- fs->frame->used_for_reference = 0;
- fs->frame->is_long_term = 0;
- }
- fs->is_reference = 0;
- fs->is_long_term = 0;
- }
- /*!
- ************************************************************************
- * brief
- * compares two stored pictures by picture number for qsort in descending order
- *
- ************************************************************************
- */
- static int compare_pic_by_pic_num_desc( const void *arg1, const void *arg2 )
- {
- if ( (*(StorablePicture**)arg1)->pic_num < (*(StorablePicture**)arg2)->pic_num)
- return 1;
- if ( (*(StorablePicture**)arg1)->pic_num > (*(StorablePicture**)arg2)->pic_num)
- return -1;
- else
- return 0;
- }
- /*!
- ************************************************************************
- * brief
- * compares two stored pictures by picture number for qsort in descending order
- *
- ************************************************************************
- */
- static int compare_pic_by_lt_pic_num_asc( const void *arg1, const void *arg2 )
- {
- if ( (*(StorablePicture**)arg1)->long_term_pic_num < (*(StorablePicture**)arg2)->long_term_pic_num)
- return -1;
- if ( (*(StorablePicture**)arg1)->long_term_pic_num > (*(StorablePicture**)arg2)->long_term_pic_num)
- return 1;
- else
- return 0;
- }
- /*!
- ************************************************************************
- * brief
- * compares two frame stores by pic_num for qsort in descending order
- *
- ************************************************************************
- */
- static int compare_fs_by_frame_num_desc( const void *arg1, const void *arg2 )
- {
- if ( (*(FrameStore**)arg1)->frame_num_wrap < (*(FrameStore**)arg2)->frame_num_wrap)
- return 1;
- if ( (*(FrameStore**)arg1)->frame_num_wrap > (*(FrameStore**)arg2)->frame_num_wrap)
- return -1;
- else
- return 0;
- }
- /*!
- ************************************************************************
- * brief
- * compares two frame stores by lt_pic_num for qsort in descending order
- *
- ************************************************************************
- */
- static int compare_fs_by_lt_pic_idx_asc( const void *arg1, const void *arg2 )
- {
- if ( (*(FrameStore**)arg1)->long_term_frame_idx < (*(FrameStore**)arg2)->long_term_frame_idx)
- return -1;
- if ( (*(FrameStore**)arg1)->long_term_frame_idx > (*(FrameStore**)arg2)->long_term_frame_idx)
- return 1;
- else
- return 0;
- }
- /*!
- ************************************************************************
- * brief
- * compares two stored pictures by poc for qsort in ascending order
- *
- ************************************************************************
- */
- static int compare_pic_by_poc_asc( const void *arg1, const void *arg2 )
- {
- if ( (*(StorablePicture**)arg1)->poc < (*(StorablePicture**)arg2)->poc)
- return -1;
- if ( (*(StorablePicture**)arg1)->poc > (*(StorablePicture**)arg2)->poc)
- return 1;
- else
- return 0;
- }
- /*!
- ************************************************************************
- * brief
- * compares two stored pictures by poc for qsort in descending order
- *
- ************************************************************************
- */
- static int compare_pic_by_poc_desc( const void *arg1, const void *arg2 )
- {
- if ( (*(StorablePicture**)arg1)->poc < (*(StorablePicture**)arg2)->poc)
- return 1;
- if ( (*(StorablePicture**)arg1)->poc > (*(StorablePicture**)arg2)->poc)
- return -1;
- else
- return 0;
- }
- /*!
- ************************************************************************
- * brief
- * compares two frame stores by poc for qsort in ascending order
- *
- ************************************************************************
- */
- static int compare_fs_by_poc_asc( const void *arg1, const void *arg2 )
- {
- if ( (*(FrameStore**)arg1)->poc < (*(FrameStore**)arg2)->poc)
- return -1;
- if ( (*(FrameStore**)arg1)->poc > (*(FrameStore**)arg2)->poc)
- return 1;
- else
- return 0;
- }
- /*!
- ************************************************************************
- * brief
- * compares two frame stores by poc for qsort in descending order
- *
- ************************************************************************
- */
- static int compare_fs_by_poc_desc( const void *arg1, const void *arg2 )
- {
- if ( (*(FrameStore**)arg1)->poc < (*(FrameStore**)arg2)->poc)
- return 1;
- if ( (*(FrameStore**)arg1)->poc > (*(FrameStore**)arg2)->poc)
- return -1;
- else
- return 0;
- }
- /*!
- ************************************************************************
- * brief
- * returns true, if picture is short term reference picture
- *
- ************************************************************************
- */
- int is_short_ref(StorablePicture *s)
- {
- return ((s->used_for_reference) && (!(s->is_long_term)));
- }
- /*!
- ************************************************************************
- * brief
- * returns true, if picture is long term reference picture
- *
- ************************************************************************
- */
- int is_long_ref(StorablePicture *s)
- {
- return ((s->used_for_reference) && (s->is_long_term));
- }
- /*!
- ************************************************************************
- * brief
- * Generates a alternating field list from a given FrameStore list
- *
- ************************************************************************
- */
- static void gen_pic_list_from_frame_list(PictureStructure currStrcture, FrameStore **fs_list, int list_idx, StorablePicture **list, int *list_size, int long_term)
- {
- int top_idx = 0;
- int bot_idx = 0;
- int (*is_ref)(StorablePicture *s);
- if (long_term)
- is_ref=is_long_ref;
- else
- is_ref=is_short_ref;
- if (currStrcture == TOP_FIELD)
- {
- while ((top_idx<list_idx)||(bot_idx<list_idx))
- {
- for ( ; top_idx<list_idx; top_idx++)
- {
- if(fs_list[top_idx]->is_used & 1)
- {
- if(is_ref(fs_list[top_idx]->top_field))
- {
- // short term ref pic
- list[*list_size] = fs_list[top_idx]->top_field;
- (*list_size)++;
- top_idx++;
- break;
- }
- }
- }
- for ( ; bot_idx<list_idx; bot_idx++)
- {
- if(fs_list[bot_idx]->is_used & 2)
- {
- if(is_ref(fs_list[bot_idx]->bottom_field))
- {
- // short term ref pic
- list[*list_size] = fs_list[bot_idx]->bottom_field;
- (*list_size)++;
- bot_idx++;
- break;
- }
- }
- }
- }
- }
- if (currStrcture == BOTTOM_FIELD)
- {
- while ((top_idx<list_idx)||(bot_idx<list_idx))
- {
- for ( ; bot_idx<list_idx; bot_idx++)
- {
- if(fs_list[bot_idx]->is_used & 2)
- {
- if(is_ref(fs_list[bot_idx]->bottom_field))
- {
- // short term ref pic
- list[*list_size] = fs_list[bot_idx]->bottom_field;
- (*list_size)++;
- bot_idx++;
- break;
- }
- }
- }
- for ( ; top_idx<list_idx; top_idx++)
- {
- if(fs_list[top_idx]->is_used & 1)
- {
- if(is_ref(fs_list[top_idx]->top_field))
- {
- // short term ref pic
- list[*list_size] = fs_list[top_idx]->top_field;
- (*list_size)++;
- top_idx++;
- break;
- }
- }
- }
- }
- }
- }
- /*!
- ************************************************************************
- * brief
- * Initialize listX[0] and list 1 depending on current picture type
- *
- ************************************************************************
- */
- void init_lists(int currSliceType, PictureStructure currPicStructure)
- {
- int add_top = 0, add_bottom = 0;
- unsigned int i;
- int j, diff;
- int list0idx = 0;
- int list0idx_1 = 0;
- int listltidx = 0;
- FrameStore **fs_list0;
- FrameStore **fs_list1;
- FrameStore **fs_listlt;
- StorablePicture *tmp_s;
- if (currPicStructure == FRAME)
- {
- for (i=0; i<dpb.ref_frames_in_buffer; i++)
- {
- if (dpb.fs_ref[i]->is_used==3)
- {
- if ((dpb.fs_ref[i]->frame->used_for_reference)&&(!dpb.fs_ref[i]->frame->is_long_term))
- {
- if( dpb.fs_ref[i]->frame_num > img->frame_num )
- {
- dpb.fs_ref[i]->frame_num_wrap = dpb.fs_ref[i]->frame_num - max_frame_num;
- }
- else
- {
- dpb.fs_ref[i]->frame_num_wrap = dpb.fs_ref[i]->frame_num;
- }
- dpb.fs_ref[i]->frame->pic_num = dpb.fs_ref[i]->frame_num_wrap;
- }
- }
- }
- // update long_term_pic_num
- for (i=0; i<dpb.ltref_frames_in_buffer; i++)
- {
- if (dpb.fs_ltref[i]->is_used==3)
- {
- if (dpb.fs_ltref[i]->frame->is_long_term)
- {
- dpb.fs_ltref[i]->frame->long_term_pic_num = dpb.fs_ltref[i]->frame->long_term_frame_idx;
- }
- }
- }
- }
- else
- {
- if (currPicStructure == TOP_FIELD)
- {
- add_top = 1;
- add_bottom = 0;
- }
- else
- {
- add_top = 0;
- add_bottom = 1;
- }
- for (i=0; i<dpb.ref_frames_in_buffer; i++)
- {
- if (dpb.fs_ref[i]->is_reference)
- {
- if( dpb.fs_ref[i]->frame_num > img->frame_num )
- {
- dpb.fs_ref[i]->frame_num_wrap = dpb.fs_ref[i]->frame_num - max_frame_num;
- }
- else
- {
- dpb.fs_ref[i]->frame_num_wrap = dpb.fs_ref[i]->frame_num;
- }
- if (dpb.fs_ref[i]->is_reference & 1)
- {
- dpb.fs_ref[i]->top_field->pic_num = (2 * dpb.fs_ref[i]->frame_num_wrap) + add_top;
- }
- if (dpb.fs_ref[i]->is_reference & 2)
- {
- dpb.fs_ref[i]->bottom_field->pic_num = (2 * dpb.fs_ref[i]->frame_num_wrap) + add_bottom;
- }
- }
- }
- // update long_term_pic_num
- for (i=0; i<dpb.ltref_frames_in_buffer; i++)
- {
- if (dpb.fs_ltref[i]->is_long_term & 1)
- {
- dpb.fs_ltref[i]->top_field->long_term_pic_num = 2 * dpb.fs_ltref[i]->top_field->long_term_frame_idx + add_top;
- }
- if (dpb.fs_ltref[i]->is_long_term & 2)
- {
- dpb.fs_ltref[i]->bottom_field->long_term_pic_num = 2 * dpb.fs_ltref[i]->bottom_field->long_term_frame_idx + add_bottom;
- }
- }
- }
- if ((currSliceType == I_SLICE)||(currSliceType == SI_SLICE))
- {
- listXsize[0] = 0;
- listXsize[1] = 0;
- return;
- }
- if ((currSliceType == P_SLICE)||(currSliceType == SP_SLICE))
- {
- // Calculate FrameNumWrap and PicNum
- if (currPicStructure == FRAME)
- {
- for (i=0; i<dpb.ref_frames_in_buffer; i++)
- {
- if (dpb.fs_ref[i]->is_used==3)
- {
- if ((dpb.fs_ref[i]->frame->used_for_reference)&&(!dpb.fs_ref[i]->frame->is_long_term))
- {
- listX[0][list0idx++] = dpb.fs_ref[i]->frame;
- }
- }
- }
- // order list 0 by PicNum
- qsort((void *)listX[0], list0idx, sizeof(StorablePicture*), compare_pic_by_pic_num_desc);
- listXsize[0] = list0idx;
- //printf("listX[0] (PicNum): "); for (i=0; i<list0idx; i++){printf ("%d ", listX[0][i]->pic_num);} printf("n");
- // long term handling
- for (i=0; i<dpb.ltref_frames_in_buffer; i++)
- {
- if (dpb.fs_ltref[i]->is_used==3)
- {
- if (dpb.fs_ltref[i]->frame->is_long_term)
- {
- listX[0][list0idx++]=dpb.fs_ltref[i]->frame;
- }
- }
- }
- qsort((void *)&listX[0][listXsize[0]], list0idx-listXsize[0], sizeof(StorablePicture*), compare_pic_by_lt_pic_num_asc);
- listXsize[0] = list0idx;
- //printf("listX[0] currPoc=%d (Poc): ", img->framepoc); for (i=0; i<listXsize[0]; i++){printf ("%d ", listX[0][i]->poc);} printf("n");
- }
- else
- {
- fs_list0 = calloc(dpb.size, sizeof (FrameStore*));
- if (NULL==fs_list0)
- no_mem_exit("init_lists: fs_list0");
- fs_listlt = calloc(dpb.size, sizeof (FrameStore*));
- if (NULL==fs_listlt)
- no_mem_exit("init_lists: fs_listlt");
- for (i=0; i<dpb.ref_frames_in_buffer; i++)
- {
- if (dpb.fs_ref[i]->is_reference)
- {
- fs_list0[list0idx++] = dpb.fs_ref[i];
- }
- }
- qsort((void *)fs_list0, list0idx, sizeof(FrameStore*), compare_fs_by_frame_num_desc);
- //printf("fs_list0 (FrameNum): "); for (i=0; i<list0idx; i++){printf ("%d ", fs_list0[i]->frame_num_wrap);} printf("n");
- listXsize[0] = 0;
- gen_pic_list_from_frame_list(currPicStructure, fs_list0, list0idx, listX[0], &listXsize[0], 0);
- //printf("listX[0] (PicNum): "); for (i=0; i<listXsize[0]; i++){printf ("%d ", listX[0][i]->pic_num);} printf("n");
- // long term handling
- for (i=0; i<dpb.ltref_frames_in_buffer; i++)
- {
- fs_listlt[listltidx++]=dpb.fs_ltref[i];
- }
- qsort((void *)fs_listlt, listltidx, sizeof(FrameStore*), compare_fs_by_lt_pic_idx_asc);
- gen_pic_list_from_frame_list(currPicStructure, fs_listlt, listltidx, listX[0], &listXsize[0], 1);
- free(fs_list0);
- free(fs_listlt);
- }
- listXsize[1] = 0;
- }
- else
- {
- // B-Slice
- if (currPicStructure == FRAME)
- {
- for (i=0; i<dpb.ref_frames_in_buffer; i++)
- {
- if (dpb.fs_ref[i]->is_used==3)
- {
- if ((dpb.fs_ref[i]->frame->used_for_reference)&&(!dpb.fs_ref[i]->frame->is_long_term))
- {
- if (img->framepoc > dpb.fs_ref[i]->frame->poc)
- {
- listX[0][list0idx++] = dpb.fs_ref[i]->frame;
- }
- }
- }
- }
- qsort((void *)listX[0], list0idx, sizeof(StorablePicture*), compare_pic_by_poc_desc);
- list0idx_1 = list0idx;
- for (i=0; i<dpb.ref_frames_in_buffer; i++)
- {
- if (dpb.fs_ref[i]->is_used==3)
- {
- if ((dpb.fs_ref[i]->frame->used_for_reference)&&(!dpb.fs_ref[i]->frame->is_long_term))
- {
- if (img->framepoc < dpb.fs_ref[i]->frame->poc)
- {
- listX[0][list0idx++] = dpb.fs_ref[i]->frame;
- }
- }
- }
- }
- qsort((void *)&listX[0][list0idx_1], list0idx-list0idx_1, sizeof(StorablePicture*), compare_pic_by_poc_asc);
- for (j=0; j<list0idx_1; j++)
- {
- listX[1][list0idx-list0idx_1+j]=listX[0][j];
- }
- for (j=list0idx_1; j<list0idx; j++)
- {
- listX[1][j-list0idx_1]=listX[0][j];
- }
- listXsize[0] = listXsize[1] = list0idx;
- // printf("listX[0] currPoc=%d (Poc): ", img->framepoc); for (i=0; i<listXsize[0]; i++){printf ("%d ", listX[0][i]->poc);} printf("n");
- // printf("listX[1] currPoc=%d (Poc): ", img->framepoc); for (i=0; i<listXsize[1]; i++){printf ("%d ", listX[1][i]->poc);} printf("n");
- // long term handling
- for (i=0; i<dpb.ltref_frames_in_buffer; i++)
- {
- if (dpb.fs_ltref[i]->is_used==3)
- {
- if (dpb.fs_ltref[i]->frame->is_long_term)
- {
- listX[0][list0idx] =dpb.fs_ltref[i]->frame;
- listX[1][list0idx++]=dpb.fs_ltref[i]->frame;
- }
- }
- }
- qsort((void *)&listX[0][listXsize[0]], list0idx-listXsize[0], sizeof(StorablePicture*), compare_pic_by_lt_pic_num_asc);
- qsort((void *)&listX[1][listXsize[0]], list0idx-listXsize[0], sizeof(StorablePicture*), compare_pic_by_lt_pic_num_asc);
- listXsize[0] = listXsize[1] = list0idx;
- }
- else
- {
- fs_list0 = calloc(dpb.size, sizeof (FrameStore*));
- if (NULL==fs_list0)
- no_mem_exit("init_lists: fs_list0");
- fs_list1 = calloc(dpb.size, sizeof (FrameStore*));
- if (NULL==fs_list1)
- no_mem_exit("init_lists: fs_list1");
- fs_listlt = calloc(dpb.size, sizeof (FrameStore*));
- if (NULL==fs_listlt)
- no_mem_exit("init_lists: fs_listlt");
- listXsize[0] = 0;
- listXsize[1] = 1;
- for (i=0; i<dpb.ref_frames_in_buffer; i++)
- {
- if (dpb.fs_ref[i]->is_used)
- {
- if (img->ThisPOC >= dpb.fs_ref[i]->poc)
- {
- fs_list0[list0idx++] = dpb.fs_ref[i];
- }
- }
- }
- qsort((void *)fs_list0, list0idx, sizeof(FrameStore*), compare_fs_by_poc_desc);
- list0idx_1 = list0idx;
- for (i=0; i<dpb.ref_frames_in_buffer; i++)
- {
- if (dpb.fs_ref[i]->is_used)
- {
- if (img->ThisPOC < dpb.fs_ref[i]->poc)
- {
- fs_list0[list0idx++] = dpb.fs_ref[i];
- }
- }
- }
- qsort((void *)&fs_list0[list0idx_1], list0idx-list0idx_1, sizeof(FrameStore*), compare_fs_by_poc_asc);
- for (j=0; j<list0idx_1; j++)
- {
- fs_list1[list0idx-list0idx_1+j]=fs_list0[j];
- }
- for (j=list0idx_1; j<list0idx; j++)
- {
- fs_list1[j-list0idx_1]=fs_list0[j];
- }
- // printf("fs_list0 currPoc=%d (Poc): ", img->ThisPOC); for (i=0; i<list0idx; i++){printf ("%d ", fs_list0[i]->poc);} printf("n");
- // printf("fs_list1 currPoc=%d (Poc): ", img->ThisPOC); for (i=0; i<list0idx; i++){printf ("%d ", fs_list1[i]->poc);} printf("n");
- listXsize[0] = 0;
- listXsize[1] = 0;
- gen_pic_list_from_frame_list(currPicStructure, fs_list0, list0idx, listX[0], &listXsize[0], 0);
- gen_pic_list_from_frame_list(currPicStructure, fs_list1, list0idx, listX[1], &listXsize[1], 0);
- // printf("listX[0] currPoc=%d (Poc): ", img->framepoc); for (i=0; i<listXsize[0]; i++){printf ("%d ", listX[0][i]->poc);} printf("n");
- // printf("listX[1] currPoc=%d (Poc): ", img->framepoc); for (i=0; i<listXsize[1]; i++){printf ("%d ", listX[1][i]->poc);} printf("n");
- // long term handling
- for (i=0; i<dpb.ltref_frames_in_buffer; i++)
- {
- fs_listlt[listltidx++]=dpb.fs_ltref[i];
- }
- qsort((void *)fs_listlt, listltidx, sizeof(FrameStore*), compare_fs_by_lt_pic_idx_asc);
- gen_pic_list_from_frame_list(currPicStructure, fs_listlt, listltidx, listX[0], &listXsize[0], 1);
- gen_pic_list_from_frame_list(currPicStructure, fs_listlt, listltidx, listX[1], &listXsize[1], 1);
- free(fs_list0);
- free(fs_list1);
- free(fs_listlt);
- }
- }
- if ((listXsize[0] == listXsize[1]) && (listXsize[0] > 1))
- {
- // check if lists are identical, if yes swap first two elements of listX[1]
- diff=0;
- for (j = 0; j< listXsize[0]; j++)
- {
- if (listX[0][j]!=listX[1][j])
- diff=1;
- }
- if (!diff)
- {
- tmp_s = listX[1][0];
- listX[1][0]=listX[1][1];
- listX[1][1]=tmp_s;
- }
- }
- // set max size
- listXsize[0] = imin (listXsize[0], img->num_ref_idx_l0_active);
- listXsize[1] = imin (listXsize[1], img->num_ref_idx_l1_active);
- // set the unused list entries to NULL
- for (i=listXsize[0]; i< (MAX_LIST_SIZE) ; i++)
- {
- listX[0][i] = NULL;
- }
- for (i=listXsize[1]; i< (MAX_LIST_SIZE) ; i++)
- {
- listX[1][i] = NULL;
- }
- }
- /*!
- ************************************************************************
- * brief
- * Initialize listX[2..5] from lists 0 and 1
- * listX[2]: list0 for current_field==top
- * listX[3]: list1 for current_field==top
- * listX[4]: list0 for current_field==bottom
- * listX[5]: list1 for current_field==bottom
- *
- ************************************************************************
- */
- void init_mbaff_lists(void)
- {
- unsigned j;
- int i;
- for (i=2;i<6;i++)
- {
- for (j=0; j<MAX_LIST_SIZE; j++)
- {
- listX[i][j] = NULL;
- }
- listXsize[i]=0;
- }
- for (i=0; i<listXsize[0]; i++)
- {
- listX[2][2*i] =listX[0][i]->top_field;
- listX[2][2*i+1]=listX[0][i]->bottom_field;
- listX[4][2*i] =listX[0][i]->bottom_field;
- listX[4][2*i+1]=listX[0][i]->top_field;
- }
- listXsize[2]=listXsize[4]=listXsize[0] * 2;
- for (i=0; i<listXsize[1]; i++)
- {
- listX[3][2*i] =listX[1][i]->top_field;
- listX[3][2*i+1]=listX[1][i]->bottom_field;
- listX[5][2*i] =listX[1][i]->bottom_field;
- listX[5][2*i+1]=listX[1][i]->top_field;
- }
- listXsize[3]=listXsize[5]=listXsize[1] * 2;
- }
- /*!
- ************************************************************************
- * brief
- * Returns short term pic with given picNum
- *
- ************************************************************************
- */
- static StorablePicture* get_short_term_pic(int picNum)
- {
- unsigned i;
- for (i=0; i<dpb.ref_frames_in_buffer; i++)
- {
- if (img->structure==FRAME)
- {
- if (dpb.fs_ref[i]->is_reference == 3)
- if ((!dpb.fs_ref[i]->frame->is_long_term)&&(dpb.fs_ref[i]->frame->pic_num == picNum))
- return dpb.fs_ref[i]->frame;
- }
- else
- {
- if (dpb.fs_ref[i]->is_reference & 1)
- if ((!dpb.fs_ref[i]->top_field->is_long_term)&&(dpb.fs_ref[i]->top_field->pic_num == picNum))
- return dpb.fs_ref[i]->top_field;
- if (dpb.fs_ref[i]->is_reference & 2)
- if ((!dpb.fs_ref[i]->bottom_field->is_long_term)&&(dpb.fs_ref[i]->bottom_field->pic_num == picNum))
- return dpb.fs_ref[i]->bottom_field;
- }
- }
- return NULL;
- }
- /*!
- ************************************************************************
- * brief
- * Returns short term pic with given LongtermPicNum
- *
- ************************************************************************
- */
- static StorablePicture* get_long_term_pic(int LongtermPicNum)
- {
- unsigned i;
- for (i=0; i<dpb.ltref_frames_in_buffer; i++)
- {
- if (img->structure==FRAME)
- {
- if (dpb.fs_ltref[i]->is_reference == 3)
- if ((dpb.fs_ltref[i]->frame->is_long_term)&&(dpb.fs_ltref[i]->frame->long_term_pic_num == LongtermPicNum))
- return dpb.fs_ltref[i]->frame;
- }
- else
- {
- if (dpb.fs_ltref[i]->is_reference & 1)
- if ((dpb.fs_ltref[i]->top_field->is_long_term)&&(dpb.fs_ltref[i]->top_field->long_term_pic_num == LongtermPicNum))
- return dpb.fs_ltref[i]->top_field;
- if (dpb.fs_ltref[i]->is_reference & 2)
- if ((dpb.fs_ltref[i]->bottom_field->is_long_term)&&(dpb.fs_ltref[i]->bottom_field->long_term_pic_num == LongtermPicNum))
- return dpb.fs_ltref[i]->bottom_field;
- }
- }
- return NULL;
- }
- /*!
- ************************************************************************
- * brief
- * Reordering process for short-term reference pictures
- *
- ************************************************************************
- */
- static void reorder_short_term(StorablePicture **RefPicListX, int num_ref_idx_lX_active_minus1, int picNumLX, int *refIdxLX)
- {
- int cIdx, nIdx;
- StorablePicture *picLX;
- picLX = get_short_term_pic(picNumLX);
- for( cIdx = num_ref_idx_lX_active_minus1+1; cIdx > *refIdxLX; cIdx-- )
- RefPicListX[ cIdx ] = RefPicListX[ cIdx - 1];
- RefPicListX[ (*refIdxLX)++ ] = picLX;
- nIdx = *refIdxLX;
- for( cIdx = *refIdxLX; cIdx <= num_ref_idx_lX_active_minus1+1; cIdx++ )
- if (RefPicListX[ cIdx ])
- if( (RefPicListX[ cIdx ]->is_long_term ) || (RefPicListX[ cIdx ]->pic_num != picNumLX ))
- RefPicListX[ nIdx++ ] = RefPicListX[ cIdx ];
- }
- /*!
- ************************************************************************
- * brief
- * Reordering process for short-term reference pictures
- *
- ************************************************************************
- */
- static void reorder_long_term(StorablePicture **RefPicListX, int num_ref_idx_lX_active_minus1, int LongTermPicNum, int *refIdxLX)
- {
- int cIdx, nIdx;
- StorablePicture *picLX;
- picLX = get_long_term_pic(LongTermPicNum);
- for( cIdx = num_ref_idx_lX_active_minus1+1; cIdx > *refIdxLX; cIdx-- )
- RefPicListX[ cIdx ] = RefPicListX[ cIdx - 1];
- RefPicListX[ (*refIdxLX)++ ] = picLX;
- nIdx = *refIdxLX;
- for( cIdx = *refIdxLX; cIdx <= num_ref_idx_lX_active_minus1+1; cIdx++ )
- if( (!RefPicListX[ cIdx ]->is_long_term ) || (RefPicListX[ cIdx ]->long_term_pic_num != LongTermPicNum ))
- RefPicListX[ nIdx++ ] = RefPicListX[ cIdx ];
- }
- /*!
- ************************************************************************
- * brief
- * Reordering process for reference picture lists
- *
- ************************************************************************
- */
- void reorder_ref_pic_list(StorablePicture **list, int *list_size, int num_ref_idx_lX_active_minus1, int *reordering_of_pic_nums_idc, int *abs_diff_pic_num_minus1, int *long_term_pic_idx)
- {
- int i;
- int maxPicNum, currPicNum, picNumLXNoWrap, picNumLXPred, picNumLX;
- int refIdxLX = 0;
- if (img->structure==FRAME)
- {
- maxPicNum = max_frame_num;
- currPicNum = img->frame_num;
- }
- else
- {
- maxPicNum = 2 * max_frame_num;
- currPicNum = 2 * img->frame_num + 1;
- }
- picNumLXPred = currPicNum;
- for (i=0; reordering_of_pic_nums_idc[i]!=3; i++)
- {
- if (reordering_of_pic_nums_idc[i]>3)
- error ("Invalid remapping_of_pic_nums_idc command", 500);
- if (reordering_of_pic_nums_idc[i] < 2)
- {
- if (reordering_of_pic_nums_idc[i] == 0)
- {
- if( picNumLXPred - ( abs_diff_pic_num_minus1[i] + 1 ) < 0 )
- picNumLXNoWrap = picNumLXPred - ( abs_diff_pic_num_minus1[i] + 1 ) + maxPicNum;
- else
- picNumLXNoWrap = picNumLXPred - ( abs_diff_pic_num_minus1[i] + 1 );
- }
- else // (reordering_of_pic_nums_idc[i] == 1)
- {
- if( picNumLXPred + ( abs_diff_pic_num_minus1[i] + 1 ) >= maxPicNum )
- picNumLXNoWrap = picNumLXPred + ( abs_diff_pic_num_minus1[i] + 1 ) - maxPicNum;
- else
- picNumLXNoWrap = picNumLXPred + ( abs_diff_pic_num_minus1[i] + 1 );
- }
- picNumLXPred = picNumLXNoWrap;
- if( picNumLXNoWrap > currPicNum )
- picNumLX = picNumLXNoWrap - maxPicNum;
- else
- picNumLX = picNumLXNoWrap;
- reorder_short_term(list, num_ref_idx_lX_active_minus1, picNumLX, &refIdxLX);
- }
- else //(reordering_of_pic_nums_idc[i] == 2)
- {
- reorder_long_term(list, num_ref_idx_lX_active_minus1, long_term_pic_idx[i], &refIdxLX);
- }
- }
- // that's a definition
- *list_size = num_ref_idx_lX_active_minus1 + 1;
- }
- /*!
- ************************************************************************
- * brief
- * Update the list of frame stores that contain reference frames/fields
- *
- ************************************************************************
- */
- void update_ref_list(void)
- {
- unsigned i, j;
- for (i=0, j=0; i<dpb.used_size; i++)
- {
- if (is_short_term_reference(dpb.fs[i]))
- {
- dpb.fs_ref[j++]=dpb.fs[i];
- }
- }
- dpb.ref_frames_in_buffer = j;
- while (j<dpb.size)
- {
- dpb.fs_ref[j++]=NULL;
- }
- }
- /*!
- ************************************************************************
- * brief
- * Update the list of frame stores that contain long-term reference
- * frames/fields
- *
- ************************************************************************
- */
- void update_ltref_list(void)
- {
- unsigned i, j;
- for (i=0, j=0; i<dpb.used_size; i++)
- {
- if (is_long_term_reference(dpb.fs[i]))
- {
- dpb.fs_ltref[j++]=dpb.fs[i];
- }
- }
- dpb.ltref_frames_in_buffer=j;
- while (j<dpb.size)
- {
- dpb.fs_ltref[j++]=NULL;
- }
- }
- /*!
- ************************************************************************
- * brief
- * Perform Memory management for idr pictures
- *
- ************************************************************************
- */
- static void idr_memory_management(StorablePicture* p)
- {
- unsigned i;
- assert (img->currentPicture->idr_flag);
- if (img->no_output_of_prior_pics_flag)
- {
- // free all stored pictures
- for (i=0; i<dpb.used_size; i++)
- {
- // reset all reference settings
- free_frame_store(dpb.fs[i]);
- dpb.fs[i] = alloc_frame_store();
- }
- for (i=0; i<dpb.ref_frames_in_buffer; i++)
- {
- dpb.fs_ref[i]=NULL;
- }
- for (i=0; i<dpb.ltref_frames_in_buffer; i++)
- {
- dpb.fs_ltref[i]=NULL;
- }
- dpb.used_size=0;
- }
- else
- {
- flush_dpb();
- }
- dpb.last_picture = NULL;
- update_ref_list();
- update_ltref_list();
- dpb.last_output_poc = INT_MIN;
- if (img->long_term_reference_flag)
- {
- dpb.max_long_term_pic_idx = 0;
- p->is_long_term = 1;
- p->long_term_frame_idx = 0;
- }
- else
- {
- dpb.max_long_term_pic_idx = -1;
- p->is_long_term = 0;
- }
- }
- /*!
- ************************************************************************
- * brief
- * Perform Sliding window decoded reference picture marking process
- *
- ************************************************************************
- */
- static void sliding_window_memory_management(StorablePicture* p)
- {
- unsigned i;
- assert (!img->currentPicture->idr_flag);
- // if this is a reference pic with sliding sliding window, unmark first ref frame
- if (dpb.ref_frames_in_buffer==active_sps->num_ref_frames - dpb.ltref_frames_in_buffer)
- {
- for (i=0; i<dpb.used_size;i++)
- {
- if (dpb.fs[i]->is_reference && (!(dpb.fs[i]->is_long_term)))
- {
- unmark_for_reference(dpb.fs[i]);
- update_ref_list();
- break;
- }
- }
- }
- p->is_long_term = 0;
- }
- /*!
- ************************************************************************
- * brief
- * Calculate picNumX
- ************************************************************************
- */
- static int get_pic_num_x (StorablePicture *p, int difference_of_pic_nums_minus1)
- {
- int currPicNum;
- if (p->structure == FRAME)
- currPicNum = p->frame_num;
- else
- currPicNum = 2 * p->frame_num + 1;
- return currPicNum - (difference_of_pic_nums_minus1 + 1);
- }
- /*!
- ************************************************************************
- * brief
- * Adaptive Memory Management: Mark short term picture unused
- ************************************************************************
- */
- static void mm_unmark_short_term_for_reference(StorablePicture *p, int difference_of_pic_nums_minus1)
- {
- int picNumX;
- unsigned i;
- picNumX = get_pic_num_x(p, difference_of_pic_nums_minus1);
- for (i=0; i<dpb.ref_frames_in_buffer; i++)
- {
- if (p->structure == FRAME)
- {
- if ((dpb.fs_ref[i]->is_reference==3) && (dpb.fs_ref[i]->is_long_term==0))
- {
- if (dpb.fs_ref[i]->frame->pic_num == picNumX)
- {
- unmark_for_reference(dpb.fs_ref[i]);
- return;
- }
- }
- }
- else
- {
- if ((dpb.fs_ref[i]->is_reference & 1) && (!(dpb.fs_ref[i]->is_long_term & 1)))
- {
- if (dpb.fs_ref[i]->top_field->pic_num == picNumX)
- {
- dpb.fs_ref[i]->top_field->used_for_reference = 0;
- dpb.fs_ref[i]->is_reference &= 2;
- if (dpb.fs_ref[i]->is_used == 3)
- {
- dpb.fs_ref[i]->frame->used_for_reference = 0;
- }
- return;
- }
- }
- if ((dpb.fs_ref[i]->is_reference & 2) && (!(dpb.fs_ref[i]->is_long_term & 2)))
- {
- if (dpb.fs_ref[i]->bottom_field->pic_num == picNumX)
- {
- dpb.fs_ref[i]->bottom_field->used_for_reference = 0;
- dpb.fs_ref[i]->is_reference &= 1;
- if (dpb.fs_ref[i]->is_used == 3)
- {
- dpb.fs_ref[i]->frame->used_for_reference = 0;
- }
- return;
- }
- }
- }
- }
- }
- /*!
- ************************************************************************
- * brief
- * Adaptive Memory Management: Mark long term picture unused
- ************************************************************************
- */
- static void mm_unmark_long_term_for_reference(StorablePicture *p, int long_term_pic_num)
- {
- unsigned i;
- for (i=0; i<dpb.ltref_frames_in_buffer; i++)
- {
- if (p->structure == FRAME)
- {
- if ((dpb.fs_ltref[i]->is_reference==3) && (dpb.fs_ltref[i]->is_long_term==3))
- {
- if (dpb.fs_ltref[i]->frame->long_term_pic_num == long_term_pic_num)
- {
- unmark_for_long_term_reference(dpb.fs_ltref[i]);
- }
- }
- }
- else
- {
- if ((dpb.fs_ltref[i]->is_reference & 1) && ((dpb.fs_ltref[i]->is_long_term & 1)))
- {
- if (dpb.fs_ltref[i]->top_field->long_term_pic_num == long_term_pic_num)
- {
- dpb.fs_ltref[i]->top_field->used_for_reference = 0;
- dpb.fs_ltref[i]->top_field->is_long_term = 0;
- dpb.fs_ltref[i]->is_reference &= 2;
- dpb.fs_ltref[i]->is_long_term &= 2;
- if (dpb.fs_ltref[i]->is_used == 3)
- {
- dpb.fs_ltref[i]->frame->used_for_reference = 0;
- dpb.fs_ltref[i]->frame->is_long_term = 0;
- }
- return;
- }
- }
- if ((dpb.fs_ltref[i]->is_reference & 2) && ((dpb.fs_ltref[i]->is_long_term & 2)))
- {
- if (dpb.fs_ltref[i]->bottom_field->long_term_pic_num == long_term_pic_num)
- {
- dpb.fs_ltref[i]->bottom_field->used_for_reference = 0;
- dpb.fs_ltref[i]->bottom_field->is_long_term = 0;
- dpb.fs_ltref[i]->is_reference &= 1;
- dpb.fs_ltref[i]->is_long_term &= 1;
- if (dpb.fs_ltref[i]->is_used == 3)
- {
- dpb.fs_ltref[i]->frame->used_for_reference = 0;
- dpb.fs_ltref[i]->frame->is_long_term = 0;
- }
- return;
- }
- }
- }
- }
- }
- /*!
- ************************************************************************
- * brief
- * Mark a long-term reference frame or complementary field pair unused for referemce
- ************************************************************************
- */
- static void unmark_long_term_frame_for_reference_by_frame_idx(int long_term_frame_idx)
- {
- unsigned i;
- for(i=0; i<dpb.ltref_frames_in_buffer; i++)
- {
- if (dpb.fs_ltref[i]->long_term_frame_idx == long_term_frame_idx)
- unmark_for_long_term_reference(dpb.fs_ltref[i]);
- }
- }
- /*!
- ************************************************************************
- * brief
- * Mark a long-term reference field unused for reference only if it's not
- * the complementary field of the picture indicated by picNumX
- ************************************************************************
- */
- static void unmark_long_term_field_for_reference_by_frame_idx(PictureStructure structure, int long_term_frame_idx, int mark_current, unsigned curr_frame_num, int curr_pic_num)
- {
- unsigned i;
- assert(structure!=FRAME);
- if (curr_pic_num<0)
- curr_pic_num+=(2*max_frame_num);
- for(i=0; i<dpb.ltref_frames_in_buffer; i++)
- {
- if (dpb.fs_ltref[i]->long_term_frame_idx == long_term_frame_idx)
- {
- if (structure == TOP_FIELD)
- {
- if ((dpb.fs_ltref[i]->is_long_term == 3))
- {
- unmark_for_long_term_reference(dpb.fs_ltref[i]);
- }
- else
- {
- if ((dpb.fs_ltref[i]->is_long_term == 1))
- {
- unmark_for_long_term_reference(dpb.fs_ltref[i]);
- }
- else
- {
- if (mark_current)
- {
- if (dpb.last_picture)
- {
- if ( ( dpb.last_picture != dpb.fs_ltref[i] )|| dpb.last_picture->frame_num != curr_frame_num)
- unmark_for_long_term_reference(dpb.fs_ltref[i]);
- }
- else
- {
- unmark_for_long_term_reference(dpb.fs_ltref[i]);
- }
- }
- else
- {
- if ((dpb.fs_ltref[i]->frame_num) != (unsigned)(curr_pic_num/2))
- {
- unmark_for_long_term_reference(dpb.fs_ltref[i]);
- }
- }
- }
- }
- }
- if (structure == BOTTOM_FIELD)
- {
- if ((dpb.fs_ltref[i]->is_long_term == 3))
- {
- unmark_for_long_term_reference(dpb.fs_ltref[i]);
- }
- else
- {
- if ((dpb.fs_ltref[i]->is_long_term == 2))
- {
- unmark_for_long_term_reference(dpb.fs_ltref[i]);
- }
- else
- {
- if (mark_current)
- {
- if (dpb.last_picture)
- {
- if ( ( dpb.last_picture != dpb.fs_ltref[i] )|| dpb.last_picture->frame_num != curr_frame_num)
- unmark_for_long_term_reference(dpb.fs_ltref[i]);
- }
- else
- {
- unmark_for_long_term_reference(dpb.fs_ltref[i]);
- }
- }
- else
- {
- if ((dpb.fs_ltref[i]->frame_num) != (unsigned)(curr_pic_num/2))
- {
- unmark_for_long_term_reference(dpb.fs_ltref[i]);
- }
- }
- }
- }
- }
- }
- }
- }
- /*!
- ************************************************************************
- * brief
- * mark a picture as long-term reference
- ************************************************************************
- */
- static void mark_pic_long_term(StorablePicture* p, int long_term_frame_idx, int picNumX)
- {
- unsigned i;
- int add_top, add_bottom;
- if (p->structure == FRAME)
- {
- for (i=0; i<dpb.ref_frames_in_buffer; i++)
- {
- if (dpb.fs_ref[i]->is_reference == 3)
- {
- if ((!dpb.fs_ref[i]->frame->is_long_term)&&(dpb.fs_ref[i]->frame->pic_num == picNumX))
- {
- dpb.fs_ref[i]->long_term_frame_idx = dpb.fs_ref[i]->frame->long_term_frame_idx
- = long_term_frame_idx;
- dpb.fs_ref[i]->frame->long_term_pic_num = long_term_frame_idx;
- dpb.fs_ref[i]->frame->is_long_term = 1;
- if (dpb.fs_ref[i]->top_field && dpb.fs_ref[i]->bottom_field)
- {
- dpb.fs_ref[i]->top_field->long_term_frame_idx = dpb.fs_ref[i]->bottom_field->long_term_frame_idx
- = long_term_frame_idx;
- dpb.fs_ref[i]->top_field->long_term_pic_num = long_term_frame_idx;
- dpb.fs_ref[i]->bottom_field->long_term_pic_num = long_term_frame_idx;
- dpb.fs_ref[i]->top_field->is_long_term = dpb.fs_ref[i]->bottom_field->is_long_term
- = 1;
- }
- dpb.fs_ref[i]->is_long_term = 3;
- return;
- }
- }
- }
- printf ("Warning: reference frame for long term marking not foundn");
- }
- else
- {
- if (p->structure == TOP_FIELD)
- {
- add_top = 1;
- add_bottom = 0;
- }
- else
- {
- add_top = 0;
- add_bottom = 1;
- }
- for (i=0; i<dpb.ref_frames_in_buffer; i++)
- {
- if (dpb.fs_ref[i]->is_reference & 1)
- {
- if ((!dpb.fs_ref[i]->top_field->is_long_term)&&(dpb.fs_ref[i]->top_field->pic_num == picNumX))
- {
- if ((dpb.fs_ref[i]->is_long_term) && (dpb.fs_ref[i]->long_term_frame_idx != long_term_frame_idx))
- {
- printf ("Warning: assigning long_term_frame_idx different from other fieldn");
- }
- dpb.fs_ref[i]->long_term_frame_idx = dpb.fs_ref[i]->top_field->long_term_frame_idx
- = long_term_frame_idx;
- dpb.fs_ref[i]->top_field->long_term_pic_num = 2 * long_term_frame_idx + add_top;
- dpb.fs_ref[i]->top_field->is_long_term = 1;
- dpb.fs_ref[i]->is_long_term |= 1;
- if (dpb.fs_ref[i]->is_long_term == 3)
- {
- dpb.fs_ref[i]->frame->is_long_term = 1;
- dpb.fs_ref[i]->frame->long_term_frame_idx = dpb.fs_ref[i]->frame->long_term_pic_num = long_term_frame_idx;
- }
- return;
- }
- }
- if (dpb.fs_ref[i]->is_reference & 2)
- {
- if ((!dpb.fs_ref[i]->bottom_field->is_long_term)&&(dpb.fs_ref[i]->bottom_field->pic_num == picNumX))
- {
- if ((dpb.fs_ref[i]->is_long_term) && (dpb.fs_ref[i]->long_term_frame_idx != long_term_frame_idx))
- {
- printf ("Warning: assigning long_term_frame_idx different from other fieldn");
- }
- dpb.fs_ref[i]->long_term_frame_idx = dpb.fs_ref[i]->bottom_field->long_term_frame_idx
- = long_term_frame_idx;
- dpb.fs_ref[i]->bottom_field->long_term_pic_num = 2 * long_term_frame_idx + add_bottom;
- dpb.fs_ref[i]->bottom_field->is_long_term = 1;
- dpb.fs_ref[i]->is_long_term |= 2;
- if (dpb.fs_ref[i]->is_long_term == 3)
- {
- dpb.fs_ref[i]->frame->is_long_term = 1;
- dpb.fs_ref[i]->frame->long_term_frame_idx = dpb.fs_ref[i]->frame->long_term_pic_num = long_term_frame_idx;
- }
- return;
- }
- }
- }
- printf ("Warning: reference field for long term marking not foundn");
- }
- }
- /*!
- ************************************************************************
- * brief
- * Assign a long term frame index to a short term picture
- ************************************************************************
- */
- static void mm_assign_long_term_frame_idx(StorablePicture* p, int difference_of_pic_nums_minus1, int long_term_frame_idx)
- {
- int picNumX;
- picNumX = get_pic_num_x(p, difference_of_pic_nums_minus1);
- // remove frames/fields with same long_term_frame_idx
- if (p->structure == FRAME)
- {
- unmark_long_term_frame_for_reference_by_frame_idx(long_term_frame_idx);
- }
- else
- {
- unsigned i;
- PictureStructure structure = FRAME;
- for (i=0; i<dpb.ref_frames_in_buffer; i++)
- {
- if (dpb.fs_ref[i]->is_reference & 1)
- {
- if (dpb.fs_ref[i]->top_field->pic_num == picNumX)
- {
- structure = TOP_FIELD;
- break;
- }
- }
- if (dpb.fs_ref[i]->is_reference & 2)
- {
- if (dpb.fs_ref[i]->bottom_field->pic_num == picNumX)
- {
- structure = BOTTOM_FIELD;
- break;
- }
- }
- }
- if (structure==FRAME)
- {
- error ("field for long term marking not found",200);
- }
- unmark_long_term_field_for_reference_by_frame_idx(structure, long_term_frame_idx, 0, 0, picNumX);
- }
- mark_pic_long_term(p, long_term_frame_idx, picNumX);
- }
- /*!
- ************************************************************************
- * brief
- * Set new max long_term_frame_idx
- ************************************************************************
- */
- void mm_update_max_long_term_frame_idx(int max_long_term_frame_idx_plus1)
- {
- unsigned i;