📄 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"
#include "header.h"
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);
void gen_field_ref_ids(StorablePicture *p);
DecodedPictureBuffer dpb;
StorablePicture **listX[6];
ColocatedParams *Co_located = NULL;
extern StorablePicture *dec_picture;
int listXsize[6];
#define MAX_LIST_SIZE 33
/*!
************************************************************************
* \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 (%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");
}
}
/*!
************************************************************************
* \brief
* Returns the size of the dpb depending on level and picture size
*
*
************************************************************************
*/
int getDpbSize()
{
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 10:
size = 152064;
break;
case 11:
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 = 12582912;
break;
case 50:
size = 42393600;
break;
case 51:
size = 70778880;
break;
default:
error ("undefined level", 500);
break;
}
size /= pic_size;
return min( size, 16);
}
/*!
************************************************************************
* \brief
* Allocate memory for decoded picture buffer and initialize with sane values.
*
************************************************************************
*/
void init_dpb()
{
unsigned i,j;
if (dpb.init_done)
{
free_dpb();
}
dpb.size = getDpbSize();
dpb.num_ref_frames = active_sps->num_ref_frames;
if (0==dpb.size)
{
printf("warning: DPB size of zero frames at specified level / frame size. Decoding may fail.\n");
}
// dpb.size = input->dpb_size;
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()
{
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()
{
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;
}
/*!
************************************************************************
* \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");
if (structure!=FRAME)
{
size_y /= 2;
size_y_cr /= 2;
}
s->PicSizeInMbs = (size_x*size_y)/256;
get_mem2D (&(s->imgY), size_y, size_x);
get_mem3D (&(s->imgUV), 2, size_y_cr, size_x_cr );
s->mb_field = calloc (s->PicSizeInMbs, sizeof(int));
get_mem2Dint (&(s->slice_id), size_x / MB_BLOCK_SIZE, size_y / MB_BLOCK_SIZE);
get_mem3Dint (&(s->ref_idx), 2, size_x / BLOCK_SIZE, size_y / BLOCK_SIZE);
get_mem3Dint64 (&(s->ref_pic_id), 6, size_x / BLOCK_SIZE, size_y / BLOCK_SIZE);
get_mem3Dint64 (&(s->ref_id), 6, 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);
get_mem2D (&(s->field_frame), size_x / BLOCK_SIZE, size_y / 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->max_slice_id = 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->dec_ref_pic_marking_buffer = NULL;
s->coded_frame = 0;
s->MbaffFrameFlag = 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_mem2Dint (p->slice_id);
free_mem3Dint (p->ref_idx, 2);
free_mem3Dint64 (p->ref_pic_id, 6);
free_mem3Dint64 (p->ref_id, 6);
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->field_frame)
{
free_mem2D (p->field_frame);
p->field_frame=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);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -