📄 ldecod.cpp
字号:
/*!
***********************************************************************
* \mainpage
* This is the H.264/AVC decoder reference software. For detailed documentation
* see the comments in each file.
*
* \author
* The main contributors are listed in contributors.h
*
* \version
* JM 7.6
*
* \note
* tags are used for document system "doxygen"
* available at http://www.doxygen.org
*/
/*!
* \file
* ldecod.c
* \brief
* H.264/AVC reference decoder project main()
***********************************************************************
*/
#include "contributors.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <assert.h>
#include "global.h"
#include "rtp.h"
#include "memalloc.h"
#include "mbuffer.h"
#include "fmo.h"
#include "annexb.h"
#include "output.h"
#include "Win.h"
extern char *saveFile;
extern int FileFormat;
extern int dpb_size;
extern FILE *p_out; //<! pointer to output YUV file
extern int g_new_frame;
extern bool winFlag,picFormat;
// I have started to move the inp and img structures into global variables.
// They are declared in the following lines. Since inp is defined in conio.h
// and cannot be overridden globally, it is defined here as input
//
// Everywhere, input-> and img-> can now be used either globally or with
// the local override through the formal parameter mechanism
extern FILE* bits;
extern StorablePicture* dec_picture;
struct img_par *img; //!< image parameters
int beginTime,Total;
/*!
***********************************************************************
* \brief
* main function for TML decoder
***********************************************************************
*/
int h264dec(char *filename/*, char *saveFile*/)
{
// allocate memory for the structures
if ((img = (struct img_par *)calloc(1, sizeof(struct img_par)))==NULL) error ("main: Could not allocate img memory", 100);
#define NAL 0
g_new_frame=1;
if (NULL == (bits=fopen(filename, "rb")))
{
free (img);
return -1;
}
if(saveFile=="")
p_out = NULL;
else if ((p_out=fopen(saveFile,"wb"))==0)
{
free (img);
fclose (bits);
return -1;
}
dpb_size=2;
FileFormat=(NAL==0? PAR_OF_ANNEXB:PAR_OF_RTP);
// initiate the display fuction
if(winFlag)
closeDisplay();
picFormat? initDisplay (176,144): initDisplay (352,288);
winFlag = TRUE;
// Allocate Slice data struct
malloc_slice(img);
dec_picture = NULL;
init_dpb();
init_out_buffer();
img->number=0;
img->type = I_SLICE;
img->tr_old = -1; // WYK: Oct. 8, 2001, for detection of a new frame
img->dec_ref_pic_marking_buffer = NULL;
beginTime = clock();
while (decode_one_frame(img) != EOS)
;
free_slice(img);
FmoFinit();
free_global_buffers(img);
flush_dpb();
fclose (bits);
if(p_out)
fclose(p_out);
if(winFlag)
{
closeDisplay();
winFlag = FALSE;
}
free_dpb();
uninit_out_buffer();
free (img);
return 0;
}
/*!
************************************************************************
* \brief
* Allocates a stand-alone partition structure. Structure should
* be freed by FreePartition();
* data structures
*
* \par Input:
* n: number of partitions in the array
* \par return
* pointer to DataPartition Structure, zero-initialized
************************************************************************
*/
DataPartition *AllocPartition(int n)
{
DataPartition *partArr, *dataPart;
int i;
partArr = (DataPartition *) calloc(n, sizeof(DataPartition));
for (i=0; i<n; i++) // loop over all data partitions
{
dataPart = &(partArr[i]);
dataPart->bitstream = (Bitstream *) calloc(1, sizeof(Bitstream));
dataPart->bitstream->streamBuffer = (byte *) calloc(MAX_CODED_FRAME_SIZE, sizeof(byte));
}
return partArr;
}
/*!
************************************************************************
* \brief
* Frees a partition structure (array).
*
* \par Input:
* Partition to be freed, size of partition Array (Number of Partitions)
*
* \par return
* None
*
* \note
* n must be the same as for the corresponding call of AllocPartition
************************************************************************
*/
void FreePartition (DataPartition *dp, int n)
{
int i;
assert (dp != NULL);
assert (dp->bitstream != NULL);
assert (dp->bitstream->streamBuffer != NULL);
for (i=0; i<n; i++)
{
free (dp[i].bitstream->streamBuffer);
free (dp[i].bitstream);
}
free (dp);
}
/*!
************************************************************************
* \brief
* Allocates the slice structure along with its dependent
* data structures
*
* \par Input:
* Input Parameters struct inp_par *inp, struct img_par *img
************************************************************************
*/
void malloc_slice(struct img_par *img)
{
img->currentSlice = (Slice *) calloc(1, sizeof(Slice));
assert( img->currentSlice != NULL);
img->currentSlice->max_part_nr = 3; //! assume data partitioning (worst case) for the following mallocs()
img->currentSlice->partArr = AllocPartition(img->currentSlice->max_part_nr);
}
/*!
************************************************************************
* \brief
* Memory frees of the Slice structure and of its dependent
* data structures
*
* \par Input:
* Input Parameters struct inp_par *inp, struct img_par *img
************************************************************************
*/
void free_slice(struct img_par *img)
{
Slice *currSlice = img->currentSlice;
FreePartition (currSlice->partArr, 3);
free(img->currentSlice);
currSlice = NULL;
}
/*!
************************************************************************
* \brief
* Dynamic memory allocation of frame size related global buffers
* buffers are defined in global.h, allocated memory must be freed in
* void free_global_buffers()
*
* \par Input:
* Input Parameters struct inp_par *inp, Image Parameters struct img_par *img
*
* \par Output:
* Number of allocated bytes
***********************************************************************
*/
int init_global_buffers(struct img_par *img)
{
int memory_size=0;
// allocate memory in structure img
if(((img->mb_data) = (Macroblock *) calloc((img->width>>4) * (img->height>>4),sizeof(Macroblock))) == NULL)
error ("init_global_buffers:Could not allocate img->mb_data memory", 100);
if(((img->intra_block) = (int*)calloc((img->width>>4) * (img->height>>4),sizeof(int))) == NULL)
error ("init_global_buffers: Could not allocate img->intra_block memory", 100);
memory_size += get_mem2Dint(&(img->ipredmode),img->width>>2 , img->height>>2);
memory_size += get_mem3Dint(&(img->wp_weight), 2, MAX_REFERENCE_PICTURES, 3);
memory_size += get_mem3Dint(&(img->wp_offset), 2, MAX_REFERENCE_PICTURES, 3);
// CAVLC mem
memory_size += get_mem3Dint(&(img->nz_coeff), img->FrameSizeInMbs, 4, 6);
return (memory_size);
}
/*!
************************************************************************
* \brief
* Free allocated memory of frame size related global buffers
* buffers are defined in global.h, allocated memory is allocated in
* int init_global_buffers()
*
* \par Input:
* Input Parameters struct inp_par *inp, Image Parameters struct img_par *img
*
* \par Output:
* none
*
************************************************************************
*/
void free_global_buffers(struct img_par *img)
{
// CAVLC free mem
free_mem3Dint(img->nz_coeff, img->FrameSizeInMbs);
// free mem, allocated for structure img
if (img->mb_data != NULL) free(img->mb_data);
free (img->intra_block);
free_mem2Dint (img->ipredmode);
free_mem3Dint(img->wp_weight, 2);
free_mem3Dint(img->wp_offset, 2);
}
int getState()
{
if(img)
{
Total = clock() - beginTime;
return img->number*1000/Total;
}
else
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -