📄 mbuffer.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 <stdlib.h>
#include <assert.h>
#include <limits.h>
#include <string.h>
#include "global.h"
#include "mbuffer.h"
#include "memalloc.h"
#include "output.h"
#include "image.h"
//-------- start new Buffer code -----------------------------
static void insert_picture_in_dpb(FrameStore* fs, StorablePicture* p);
static void output_one_frame_from_dpb();
static int is_used_for_reference(FrameStore* fs);
static void get_smallest_poc(int *poc,int * pos);
static int remove_unused_frame_from_dpb();
static int is_short_term_reference(FrameStore* fs);
static int is_long_term_reference(FrameStore* fs);
DecodedPictureBuffer dpb;
StorablePicture **listX[6];
extern StorablePicture *dec_picture;
int listXsize[6];
/*!
************************************************************************
* \brief
* Print out list of pictures in DPB. Used for debug purposes.
************************************************************************
*/
void dump_dpb()
{
unsigned i;
return;
for (i=0; i<dpb.used_size;i++)
{
printf("(");
printf("fn=%d ", dpb.fs[i]->frame_num);
if (dpb.fs[i]->is_used & 1)
printf("T: poc=%d ", dpb.fs[i]->top_field->poc);
if (dpb.fs[i]->is_used & 2)
printf("B: poc=%d ", dpb.fs[i]->bottom_field->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 ");
if (dpb.fs[i]->is_output) printf ("out ");
printf ("\n");
}
}
/*!
************************************************************************
* \brief
* Allocate memory for decoded picture buffer an initialize with sane values.
*
* \param inp
* Input Parameters
*
************************************************************************
*/
void init_dpb(struct inp_par *inp)
{
unsigned i,j;
dpb.size = inp->dpb_size;
dpb.used_size = 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(dpb.size * 2 + 1, 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<(2*dpb.size)+1; i++)
{
listX[j][i] = NULL;
}
listXsize[j]=0;
}
dpb.last_output_poc = INT_MIN;
}
/*!
************************************************************************
* \brief
* Free memory for decoded picture buffer.
************************************************************************
*/
void free_dpb()
{
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;
}
}
/*!
************************************************************************
* \brief
* Allocate memory for decoded picture buffer frame stores an initialize with sane values.
*
* \return
* the allocated FrameStore structure
************************************************************************
*/
FrameStore* alloc_frame_store()
{
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_output = 0;
f->frame = NULL;;
f->top_field = NULL;
f->bottom_field = NULL;
return f;
}
/*!
************************************************************************
* \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;
//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");
get_mem2D (&(s->imgY), size_y, size_x);
get_mem3D (&(s->imgUV), 2, size_y_cr, size_x_cr );
s->mb_field = calloc (img->PicSizeInMbs, sizeof(int));
get_mem3Dint (&(s->ref_idx), 2, size_x / BLOCK_SIZE, size_y / BLOCK_SIZE);
get_mem3Dint (&(s->ref_pic_id), 2, size_x / BLOCK_SIZE, size_y / BLOCK_SIZE);
get_mem4Dint (&(s->mv), 2, size_x / BLOCK_SIZE, size_y / BLOCK_SIZE,2 );
get_mem2D (&(s->moving_block), size_x / BLOCK_SIZE, size_y / BLOCK_SIZE);
s->pic_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->structure=structure;
s->size_x = size_x;
s->size_y = size_y;
s->size_x_cr = size_x_cr;
s->size_y_cr = size_y_cr;
s->top_field = NULL;
s->bottom_field = NULL;
s->frame = NULL;
s->coded_frame = 0;
s->mb_adaptive_frame_field_flag = 0;
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);
}
}
/*!
************************************************************************
* \brief
* Free picture memory.
*
* \param p
* Picture to be freed
*
************************************************************************
*/
void free_storable_picture(StorablePicture* p)
{
if (p)
{
free_mem3Dint (p->ref_idx, 2);
free_mem3Dint (p->ref_pic_id, 2);
free_mem4Dint (p->mv, 2, p->size_x / BLOCK_SIZE);
if (p->moving_block)
{
free_mem2D (p->moving_block);
p->moving_block=NULL;
}
if (p->imgY)
{
free_mem2D (p->imgY);
p->imgY=NULL;
}
if (p->imgUV)
{
free_mem3D (p->imgUV, 2);
p->imgUV=NULL;
}
free(p->mb_field);
free(p);
}
}
/*!
************************************************************************
* \brief
* mark FrameStore unused for reference
*
************************************************************************
*/
static void unmark_for_reference(FrameStore* fs)
{
if (fs->is_used & 1)
{
fs->top_field->used_for_reference = 0;
}
if (fs->is_used & 2)
{
fs->bottom_field->used_for_reference = 0;
}
if (fs->is_used == 3)
{
fs->frame->used_for_reference = 0;
}
fs->is_reference = 0;
}
/*!
************************************************************************
* \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)
{
fs->top_field->used_for_reference = 0;
fs->top_field->is_long_term = 0;
}
if (fs->is_used & 2)
{
fs->bottom_field->used_for_reference = 0;
fs->bottom_field->is_long_term = 0;
}
if (fs->is_used == 3)
{
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;
}
/*!
************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -