⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hrd.c

📁 davinci avs.......................................................
💻 C
字号:
/*!
 *************************************************************************************
 * \file 
 *     HRD.h
 * \brief
 *     Hypothesis Reference Decoder
 *************************************************************************************
 */

#include <stdlib.h>
#include <stdio.h>


#include "HRD.h"
#include "vlc.h"
#include "memalloc.h"


unsigned int seq_parameter_set_id;
unsigned int cpb_dpb_cnt_minus1;
unsigned int *cpb_underflow_allowable_flag;
unsigned int *bit_rate_value_minus1_lsb;
unsigned int *bit_rate_value_minus1_msb;
unsigned int *cpb_size_value_minus1_lsb;
unsigned int *cpb_size_value_minus1_msb;
unsigned int *dpb_size_value_minus1_lsb;
unsigned int *dpb_size_value_minus1_msb;
unsigned int *initial_cpb_removal_delay_lsb;
unsigned int *initial_cpb_removal_delay_msb;
unsigned int *initial_cpb_removal_delay;
unsigned int *initial_dpb_output_delay_lsb;
unsigned int *initial_dpb_output_delay_msb;
unsigned int *initial_dpb_output_delay;


unsigned int *Bit_Buffer;

unsigned int *ROT;
struct DecodedPictureBuffer dpb;
struct FrameBuffer outframe;
struct FrameBuffer decframe;

unsigned int outputtimer;
int pre_picture_distance;




 /*! 
 *************************************************************************************
 * \brief :
 *    to get unsigned long word from a file.
 * \param :
 *    FILE *fp : File should be opened to read in binary format.
 * \return :
 *    unsigned long double word
 *************************************************************************************
 */
unsigned long GetBigDoubleWord(FILE *fp)
{
    register unsigned int dw;
    dw =  (unsigned int) (fgetc(fp) & 0xFF);
    dw = ((unsigned int) (fgetc(fp) & 0xFF)) | (dw << 0x08);
    dw = ((unsigned int) (fgetc(fp) & 0xFF)) | (dw << 0x08);
    dw = ((unsigned int) (fgetc(fp) & 0xFF)) | (dw << 0x08);
    return(dw);
}

 /*! 
 *************************************************************************************
 * \brief :
 *    Calculates if decoder leaky bucket parameters meets HRD constraints specified by encoder
 *    Failure if LeakyBucketParam file is missing or if it does not have the correct number of entries
 *************************************************************************************
 */
void calc_buffer(struct inp_par *inp)
{
    unsigned int NumberLeakyBuckets, *Rmin, *Bmin, *Fmin;
    float B_interp,  F_interp;
    unsigned int iBucket;
    float dnr, frac1, frac2;
    unsigned int R_decoder, B_decoder, F_decoder;
    FILE *outf;

    unsigned int *InitCpbDelay;
    
    if ((outf=fopen(inp->LeakyBucketParamFile,"rb"))==NULL)
    {
        printf("Error open file %s \n", inp->LeakyBucketParamFile);
        exit(0);
		return;
    }
    
    NumberLeakyBuckets = GetBigDoubleWord(outf);
    printf(" Number Leaky Buckets: %8ld \n", NumberLeakyBuckets);
    Rmin = calloc(sizeof(unsigned int), NumberLeakyBuckets);
    Bmin = calloc(sizeof(unsigned int), NumberLeakyBuckets);
    Fmin = calloc(sizeof(unsigned int), NumberLeakyBuckets);
    InitCpbDelay = calloc(sizeof(unsigned int), NumberLeakyBuckets);;
    

    printf(" BitRate(b/s)     CbpSize(b)    InitCbpDelay(1/90000 s)\n");
    for(iBucket =0; iBucket < NumberLeakyBuckets; iBucket++) 
    {
        Rmin[iBucket] = GetBigDoubleWord(outf);
        Bmin[iBucket] = GetBigDoubleWord(outf);
        Fmin[iBucket] = GetBigDoubleWord(outf);
        InitCpbDelay[iBucket] = (unsigned int)( ((float)Fmin[iBucket] / Rmin[iBucket]) * 90000 + 0.5 );

        
       
        printf("%10d    %10d      %10d\n", Rmin[iBucket], Bmin[iBucket], InitCpbDelay[iBucket]);
    }
    fclose(outf);
    
    R_decoder = inp->R_decoder;
    F_decoder = inp->F_decoder;
    B_decoder = inp->B_decoder;
    
    for( iBucket =0; iBucket < NumberLeakyBuckets; iBucket++) 
    {
        if(R_decoder < Rmin[iBucket])
		{
            break;
		}
    }
    
    printf("\n");
    if(iBucket > 0 ) 
    {
        if(iBucket < NumberLeakyBuckets) 
        {
            dnr = (float) (Rmin[iBucket] - Rmin[iBucket-1]);
            frac1 = (float) (R_decoder - Rmin[iBucket-1]);
            frac2 = (float) (Rmin[iBucket] - R_decoder);
            B_interp = (float) (Bmin[iBucket] * frac1 + Bmin[iBucket-1] * frac2) /dnr;
            F_interp = (float) (Fmin[iBucket] * frac1 + Fmin[iBucket-1] * frac2) /dnr;
        }
        else 
        {
            B_interp = (float) Bmin[iBucket-1];
            F_interp = (float) Fmin[iBucket-1];
        }
        printf(" Min.buffer %8.2f Decoder buffer size %ld \n Minimum Delay %8.2f DecoderDelay %ld \n", B_interp, B_decoder, F_interp, F_decoder);
        if(B_decoder > B_interp && F_decoder > F_interp)
        {
            printf(" HRD Compliant \n"); 
        }
        else
        {
            printf(" HRD Non Compliant \n");
        }
    }
    else 
    { 
        printf(" Decoder Rate is too small; HRD cannot be verified \n");
    }
    
    free(Rmin);
    free(Bmin);
    free(Fmin);
    free(InitCpbDelay);
    return;
}

 /*! 
 *************************************************************************************
 * \brief :
 *    allocate memeory for hrd variables
 *************************************************************************************
 */
void init_hrd(int NumberLeakyBuckets)
{
  cpb_underflow_allowable_flag  = calloc(NumberLeakyBuckets, sizeof(int));
  bit_rate_value_minus1_lsb     = calloc(NumberLeakyBuckets, sizeof(int));
	bit_rate_value_minus1_msb     = calloc(NumberLeakyBuckets, sizeof(int));
  cpb_size_value_minus1_lsb     = calloc(NumberLeakyBuckets, sizeof(int));
	cpb_size_value_minus1_msb     = calloc(NumberLeakyBuckets, sizeof(int));
  dpb_size_value_minus1_lsb     = calloc(NumberLeakyBuckets, sizeof(int));
	dpb_size_value_minus1_msb     = calloc(NumberLeakyBuckets, sizeof(int));
  initial_cpb_removal_delay_lsb = calloc(NumberLeakyBuckets, sizeof(int));
	initial_cpb_removal_delay_msb = calloc(NumberLeakyBuckets, sizeof(int));
	initial_cpb_removal_delay     = calloc(NumberLeakyBuckets, sizeof(int));
  initial_dpb_output_delay_lsb  = calloc(NumberLeakyBuckets, sizeof(int));
	initial_dpb_output_delay_msb  = calloc(NumberLeakyBuckets, sizeof(int));
	initial_dpb_output_delay      = calloc(NumberLeakyBuckets, sizeof(int));
}
 /*! 
 *************************************************************************************
 * \brief :
 *    
 *************************************************************************************
 */
void end_hrd()
{
  if (cpb_underflow_allowable_flag)
    free(cpb_underflow_allowable_flag);
   	
	if (bit_rate_value_minus1_lsb)
	  free(bit_rate_value_minus1_lsb);
	
	if (bit_rate_value_minus1_msb)
		free(bit_rate_value_minus1_msb);
	
	if (cpb_size_value_minus1_lsb)
		free(cpb_size_value_minus1_lsb);
	
  if (cpb_size_value_minus1_msb)
		free(cpb_size_value_minus1_msb);
	
	if (dpb_size_value_minus1_lsb)
		free(dpb_size_value_minus1_lsb);	
	
	if (dpb_size_value_minus1_msb)
	{
		free(dpb_size_value_minus1_msb);	
	}
	if (initial_cpb_removal_delay_lsb)
	{
		free(initial_cpb_removal_delay_lsb);	
	}
	if (initial_cpb_removal_delay_msb)
	{
		free(initial_cpb_removal_delay_msb);	
	}
	if (initial_cpb_removal_delay)
	{
		free(initial_cpb_removal_delay);	
	}
	if (initial_dpb_output_delay_lsb)
	{
		free(initial_dpb_output_delay_lsb);		
	} 
	if (initial_dpb_output_delay_msb)
	{
		free(initial_dpb_output_delay_msb);		
	} 
	if (initial_dpb_output_delay)
	{
		free(initial_dpb_output_delay);		
	}    

}
 /*! 
 *************************************************************************************
 * \brief :
 *    allocate memory for DPB and related variables
 *************************************************************************************
 */
void init_dpb()
{
    unsigned int i;
    outputtimer = 0;

    dpb.size = 3;  // the max number of reference frame is 2, so I set 3 to dpb.size.
    dpb.used_size = 0;
    dpb.fb = (struct FrameBuffer **)calloc(dpb.size, sizeof (struct FrameBuffer *));
    for (i = 0; i < dpb.size; i++)
    {
        dpb.fb[i] = (struct FrameBuffer *)calloc(1, sizeof (struct FrameBuffer));
    }

    for (i = 0; i < dpb.size; i++)
    {
        get_mem2D(&(dpb.fb[i]->imgY), pgImage->height, pgImage->width);
        get_mem3D(&(dpb.fb[i]->imgUV), 2, pgImage->height/2, pgImage->width/2);         
    }
    ROT = calloc(MAX_FRAME_NUM, sizeof (int));
    for (i = 0; i < MAX_FRAME_NUM; i++)
    {
        ROT[i] = 0;
    }
    
    get_mem2D(&(outframe.imgY), pgImage->height, pgImage->width);
    get_mem3D(&(outframe.imgUV), 2, pgImage->height / 2, pgImage->width / 2);

    get_mem2D(&(decframe.imgY), pgImage->height, pgImage->width);
    get_mem3D(&(decframe.imgUV), 2, pgImage->height / 2, pgImage->width / 2);

}

 /*! 
 *************************************************************************************
 * \brief :
 *    free DPB and related variables
 *************************************************************************************
 */
void free_dpb()
{
    unsigned int i;
    for (i = 0; i < dpb.size; i++)
    {
        free_mem2D (dpb.fb[i]->imgY);
        free_mem3D (dpb.fb[i]->imgUV, 2);
        free(dpb.fb[i]);
    }
    free(dpb.fb);
    free_mem2D(outframe.imgY);
    free_mem3D(outframe.imgUV, 2);

    free_mem2D(decframe.imgY);
    free_mem3D(decframe.imgUV, 2);

    free(ROT);

}


 /*! 
 *************************************************************************************
 * \brief :
 *    insert the decoded picture into DPB
 *************************************************************************************
 */
void Insert_OneFrame_Into_DPB(struct FrameBuffer *pDecFrame)
{
    int i, j;
    struct FrameBuffer *p;
    if (dpb.used_size == dpb.size)
    {
        printf("Decoded Picture Buffer Overflow, decoded failed\n");
        exit(0);
    }
    if (dpb.used_size > 0)
    {
        p = dpb.fb[dpb.used_size];
        for (i = dpb.used_size; i > 0; i--)
        {
            dpb.fb[i] = dpb.fb[i - 1];
        }
        dpb.fb[0] = p;
    }
    

    for (j = 0; j < pgImage->height; j++)
    {
        for (i = 0; i < pgImage->width; i++)
        {
            dpb.fb[0]->imgY[j][i] = pDecFrame->imgY[j][i];
        }
    }
    for (j = 0; j < pgImage->height / 2; j++)
    {
        for (i = 0; i < pgImage->width / 2; i++)
        {
            dpb.fb[0]->imgUV[0][j][i] = pDecFrame->imgUV[0][j][i];
            dpb.fb[0]->imgUV[1][j][i] = pDecFrame->imgUV[1][j][i];
        }
    }
    dpb.fb[0]->frmnum = pDecFrame->frmnum;
    dpb.fb[0]->outputted = pDecFrame->outputted;
    dpb.fb[0]->rotvalue = pDecFrame->rotvalue;
    dpb.fb[0]->used_for_ref = pDecFrame->used_for_ref;
  	dpb.fb[0]->number_of_bytes=pDecFrame->number_of_bytes;
    dpb.used_size++;
}

 /*! 
 *************************************************************************************
 * \brief :
 *    output some frames which are to be displayed from DPB
 *************************************************************************************
 */
void Output_Frame_From_DPB(unsigned int timer)
{
    unsigned int rotvalue = 0;
    int i, x, y;
    for (i = dpb.used_size - 1; i >= 0; i--)
    {
        rotvalue = dpb.fb[i]->rotvalue;
        if (timer >= rotvalue)
        {
            dpb.fb[i]->outputted = 1;
            for (y = 0; y < pgImage->height; y++)
            {
                for (x = 0; x < pgImage->width; x++)
                {
                    outframe.imgY[y][x] = dpb.fb[i]->imgY[y][x];
                }
            }
            for (y = 0; y < pgImage->height / 2; y++)
            {
                for (x = 0; x < pgImage->width / 2; x++)
                {
                    outframe.imgUV[0][y][x] = dpb.fb[i]->imgUV[0][y][x];
                    outframe.imgUV[1][y][x] = dpb.fb[i]->imgUV[1][y][x];
                }
            }
        }
    }
    
}

 /*! 
 *************************************************************************************
 * \brief :
 *    remove one frame from DPB
 *************************************************************************************
 */
void Remove_OneFrame_From_DPB(int num)
{

    unsigned int i;
    for (i = num; i < dpb.used_size - 1; i++)
    {
        dpb.fb[i] = dpb.fb[i + 1];
    }
    dpb.used_size--;
    
}

 /*! 
 *************************************************************************************
 * \brief :
 *    remove some frames from DPB
 *************************************************************************************
 */
int Remove_Frame_From_DPB()
{
    int i;
    int ret = 0;
    for (i = dpb.used_size - 1; i >= 0; i--)
    {
        if (dpb.fb[i]->outputted && !dpb.fb[i]->used_for_ref)
        {
			
           Remove_OneFrame_From_DPB(i);
            ret++;
        }
    }
    return ret;
}

 /*! 
 *************************************************************************************
 * \brief :
 *    store the decoded picture into DPB and update some information
 *************************************************************************************
 */
void Store_OneFrame_Into_DPB(struct FrameBuffer *pDecFrame)
{
    int ret;
    if (dpb.used_size == dpb.size)
    {
        ret = 0;
        ret = Remove_Frame_From_DPB();
        if (ret == 0)
        {
            printf("Decoded Picture Buffer Overflow, decoded failed\n");
            exit(0);
        }
    }
    Insert_OneFrame_Into_DPB(pDecFrame);

    Output_Frame_From_DPB(outputtimer);

    Remove_Frame_From_DPB(); 
}

 /*! 
 *************************************************************************************
 * \brief :
 *   update the information which indicates wheather frames are used as reference frame
 *************************************************************************************
 */
void UpdateRefFrameBufFlag()
{
    unsigned int i, j;
    int count = 0;
    for (i = 0; i < dpb.used_size; i++)
    {
        if (dpb.fb[i]->used_for_ref)
        {
            count++;
        }
        if (count == 2) // the max reference frame number in AVS_M is 2.
        {
            break;
        }
    }
    for (j = i + 1; j < dpb.used_size; j++)
    {
        dpb.fb[j]->used_for_ref = 0;
    }
}

















⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -