| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639 | 
/*! *********************************************************************** *  \mainpage *     This is the H.264/AVC decoder reference software. For detailed documentation *     see the comments in each file. * *     The JM software web site is located at: *     http://iphome.hhi.de/suehring/tml * *     For bug reporting and known issues see: *     https://ipbt.hhi.de * *  \author *     The main contributors are listed in contributors.h * *  \version *     JM 16.1 (FRExt) * *  \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() *  \author *     Main contributors (see contributors.h for copyright, address and affiliation details) *     - Inge Lille-Langøy       <[email protected]> *     - Rickard Sjoberg         <[email protected]> *     - Stephan Wenger          <[email protected]> *     - Jani Lainema            <[email protected]> *     - Sebastian Purreiter     <[email protected]> *     - Byeong-Moon Jeon        <[email protected]> *     - Gabi Blaettermann *     - Ye-Kui Wang             <[email protected]> *     - Valeri George           <[email protected]> *     - Karsten Suehring        <[email protected]> * *********************************************************************** */#include "contributors.h"#include <sys/stat.h>#include "global.h"#include "image.h"#include "memalloc.h"#include "mc_prediction.h"#include "mbuffer.h"#include "leaky_bucket.h"#include "fmo.h"#include "output.h"#include "cabac.h"#include "parset.h"#include "sei.h"#include "erc_api.h"#include "quant.h"#include "block.h"#include "nalu.h"#include "meminput.h"#define LOGFILE     "log.dec"#define DATADECFILE "dataDec.txt"#define TRACEFILE   "trace_dec.txt"// Decoder definition. This should be the only global variable in the entire// software. Global variables should be avoided.char errortext[ET_SIZE]; //!< buffer for error message for exit with error()#ifdef TRACEFILE *p_trace=0;int bitcounter=0;#endif// Prototypes of static functionsvoid init        (VideoParameters *p_Vid);void malloc_slice(InputParameters *p_Inp, VideoParameters *p_Vid);void free_slice  (Slice *currSlice);void init_frext(VideoParameters *p_Vid);/*! ************************************************************************ * \brief *    Error handling procedure. Print error message to stderr and exit *    with supplied code. * \param text *    Error message * \param code *    Exit code ************************************************************************ */void error(char *text, int code){	RaiseException(code, 0, 1, (ULONG_PTR *)text);  //fprintf(stderr, "%s\n", text); 	//flush_dpb(p_Dec->p_Vid);  //exit(code);}/*static */void Configure(VideoParameters *p_Vid, InputParameters *p_Inp){  p_Vid->p_Inp = p_Inp;  p_Inp->intra_profile_deblocking = 0;#ifdef _LEAKYBUCKET_  p_Inp->R_decoder=500000;          //! Decoder rate  p_Inp->B_decoder=104000;          //! Decoder buffer size  p_Inp->F_decoder=73000;           //! Decoder initial delay  strcpy(p_Inp->LeakyBucketParamFile,"leakybucketparam.cfg");    // file where Leaky Bucket parameters (computed by encoder) are stored#endif}/*! *********************************************************************** * \brief *    Allocate the Image structure * \par  Output: *    Image Parameters VideoParameters *p_Vid *********************************************************************** */static void alloc_img( VideoParameters **p_Vid){  if ((*p_Vid   =  (VideoParameters *) calloc(1, sizeof(VideoParameters)))==NULL)     no_mem_exit("alloc_img: p_Vid");  if (((*p_Vid)->old_slice = (OldSliceParams *) calloc(1, sizeof(OldSliceParams)))==NULL)     no_mem_exit("alloc_img: p_Vid->old_slice");  if (((*p_Vid)->p_Dpb =  (DecodedPictureBuffer*)calloc(1, sizeof(DecodedPictureBuffer)))==NULL)     no_mem_exit("alloc_img: p_Vid->p_Dpb");    (*p_Vid)->p_Dpb->init_done = 0;    (*p_Vid)->global_init_done = 0;#if (ENABLE_OUTPUT_TONEMAPPING)    if (((*p_Vid)->seiToneMapping =  (ToneMappingSEI*)calloc(1, sizeof(ToneMappingSEI)))==NULL)     no_mem_exit("alloc_img: (*p_Vid)->seiToneMapping");  #endif}/*! *********************************************************************** * \brief *    Allocate the Input structure * \par  Output: *    Input Parameters InputParameters *p_Vid *********************************************************************** */static void alloc_params( InputParameters **p_Inp ){  if ((*p_Inp = (InputParameters *) calloc(1, sizeof(InputParameters)))==NULL)     no_mem_exit("alloc_params: p_Inp");}  /*! *********************************************************************** * \brief *    Allocate the Decoder Structure * \par  Output: *    Decoder Parameters *********************************************************************** */DecoderParams *alloc_decoder(){	DecoderParams *decoder = (DecoderParams *) calloc(1, sizeof(DecoderParams));	if (decoder)	{		alloc_img(&(decoder->p_Vid));		alloc_params(&(decoder->p_Inp));#ifdef TRACE		p_trace = 0;		bitcounter = 0;#endif	}	return decoder;}/*! *********************************************************************** * \brief *    Free the Image structure * \par  Input: *    Image Parameters VideoParameters *p_Vid *********************************************************************** */void free_img( VideoParameters *p_Vid){  if (p_Vid != NULL)  {		free_mem_input(p_Vid);#if (ENABLE_OUTPUT_TONEMAPPING)      if (p_Vid->seiToneMapping != NULL)    {      free (p_Vid->seiToneMapping);      p_Vid->seiToneMapping = NULL;    }#endif    if (p_Vid->p_Dpb != NULL)    {      free (p_Vid->p_Dpb);      p_Vid->p_Dpb = NULL;    }    if (p_Vid->old_slice != NULL)    {      free (p_Vid->old_slice);      p_Vid->old_slice = NULL;    }    free (p_Vid);    p_Vid = NULL;  }}/*! *********************************************************************** * \brief *    main function for TML decoder *********************************************************************** */#if 0int main(int argc, char **argv){    DecoderParams  *p_Dec = alloc_decoder();  if (!p_Dec)	  return 1;  Configure(p_Dec->p_Vid, p_Dec->p_Inp, argc, argv);  initBitsFile(p_Dec->p_Vid, p_Dec->p_Inp->FileFormat);  p_Dec->p_Vid->bitsfile->OpenBitsFile(p_Dec->p_Vid, p_Dec->p_Inp->infile);    // Allocate Slice data struct  malloc_slice(p_Dec->p_Inp, p_Dec->p_Vid);  init_old_slice(p_Dec->p_Vid->old_slice);  init(p_Dec->p_Vid);   init_out_buffer(p_Dec->p_Vid);    while (decode_one_frame(p_Dec->p_Vid) != EOS)    ;  free_slice(p_Dec->p_Vid->currentSlice);  FmoFinit(p_Dec->p_Vid);  free_global_buffers(p_Dec->p_Vid);  flush_dpb(p_Dec->p_Vid);#if (PAIR_FIELDS_IN_OUTPUT)  flush_pending_output(p_Dec->p_Vid, p_Dec->p_Vid->p_out);#endif  p_Dec->p_Vid->bitsfile->CloseBitsFile(p_Dec->p_Vid);  close(p_Dec->p_Vid->p_out);  if (p_Dec->p_Vid->p_ref != -1)    close(p_Dec->p_Vid->p_ref);#if TRACE  fclose(p_trace);#endif  ercClose(p_Dec->p_Vid, p_Dec->p_Vid->erc_errorVar);  CleanUpPPS(p_Dec->p_Vid);  free_dpb(p_Dec->p_Vid);  uninit_out_buffer(p_Dec->p_Vid);  free (p_Dec->p_Inp);  free_img (p_Dec->p_Vid);  free(p_Dec);  return 0;}#endif/*! *********************************************************************** * \brief *    Initilize some arrays *********************************************************************** */void init(VideoParameters *p_Vid)  //!< image parameters{  int i;  InputParameters *p_Inp = p_Vid->p_Inp;  p_Vid->oldFrameSizeInMbs = -1;  p_Vid->recovery_point = 0;  p_Vid->recovery_point_found = 0;  p_Vid->recovery_poc = 0x7fffffff; /* set to a max value */  p_Vid->number = 0;  p_Vid->type = I_SLICE;  p_Vid->dec_ref_pic_marking_buffer = NULL;  p_Vid->dec_picture = NULL;  // reference flag initialization  for(i=0;i<17;++i)  {    p_Vid->ref_flag[i] = 1;  }  p_Vid->MbToSliceGroupMap = NULL;  p_Vid->MapUnitToSliceGroupMap = NULL;  p_Vid->LastAccessUnitExists  = 0;  p_Vid->NALUCount = 0;  p_Vid->out_buffer = NULL;  p_Vid->pending_output = NULL;  p_Vid->pending_output_state = FRAME;  p_Vid->recovery_flag = 0;#if (ENABLE_OUTPUT_TONEMAPPING)  init_tone_mapping_sei(p_Vid->seiToneMapping);#endif}/*! *********************************************************************** * \brief *    Initialize FREXT variables *********************************************************************** */void init_frext(VideoParameters *p_Vid)  //!< image parameters{  //pel bitdepth init  p_Vid->bitdepth_luma_qp_scale   = 6 * (p_Vid->bitdepth_luma - 8);  p_Vid->dc_pred_value_comp[0]    = 1<<(p_Vid->bitdepth_luma - 1);  p_Vid->max_pel_value_comp[0] = (1<<p_Vid->bitdepth_luma) - 1;  p_Vid->mb_size[IS_LUMA][0] = p_Vid->mb_size[IS_LUMA][1] = MB_BLOCK_SIZE;  if (p_Vid->active_sps->chroma_format_idc != YUV400)  {    //for chrominance part    p_Vid->bitdepth_chroma_qp_scale = 6 * (p_Vid->bitdepth_chroma - 8);    p_Vid->dc_pred_value_comp[1]    = (1 << (p_Vid->bitdepth_chroma - 1));    p_Vid->dc_pred_value_comp[2]    = p_Vid->dc_pred_value_comp[1];    p_Vid->max_pel_value_comp[1] = (1 << p_Vid->bitdepth_chroma) - 1;    p_Vid->max_pel_value_comp[2] = (1 << p_Vid->bitdepth_chroma) - 1;    p_Vid->num_blk8x8_uv = (1 << p_Vid->active_sps->chroma_format_idc) & (~(0x1));    p_Vid->num_uv_blocks = (p_Vid->num_blk8x8_uv >> 1);    p_Vid->num_cdc_coeff = (p_Vid->num_blk8x8_uv << 1);    p_Vid->mb_size[IS_CHROMA][0] = p_Vid->mb_size[2][0] = p_Vid->mb_cr_size_x  = (p_Vid->active_sps->chroma_format_idc==YUV420 || p_Vid->active_sps->chroma_format_idc==YUV422)?  8 : 16;    p_Vid->mb_size[IS_CHROMA][1] = p_Vid->mb_size[2][1] = p_Vid->mb_cr_size_y  = (p_Vid->active_sps->chroma_format_idc==YUV444 || p_Vid->active_sps->chroma_format_idc==YUV422)? 16 :  8;		p_Vid->subpel_x    = p_Vid->mb_cr_size_x == 8 ? 7 : 3;		p_Vid->subpel_y    = p_Vid->mb_cr_size_y == 8 ? 7 : 3;		p_Vid->shiftpel_x  = p_Vid->mb_cr_size_x == 8 ? 3 : 2;		p_Vid->shiftpel_y  = p_Vid->mb_cr_size_y == 8 ? 3 : 2;  }  else  {    p_Vid->bitdepth_chroma_qp_scale = 0;    p_Vid->max_pel_value_comp[1] = 0;    p_Vid->max_pel_value_comp[2] = 0;    p_Vid->num_blk8x8_uv = 0;    p_Vid->num_uv_blocks = 0;    p_Vid->num_cdc_coeff = 0;    p_Vid->mb_size[IS_CHROMA][0] = p_Vid->mb_size[2][0] = p_Vid->mb_cr_size_x  = 0;    p_Vid->mb_size[IS_CHROMA][1] = p_Vid->mb_size[2][1] = p_Vid->mb_cr_size_y  = 0;		p_Vid->subpel_x      = 0;		p_Vid->subpel_y      = 0;		p_Vid->shiftpel_x    = 0;		p_Vid->shiftpel_y    = 0;  }  p_Vid->mb_size_blk[0][0] = p_Vid->mb_size_blk[0][1] = p_Vid->mb_size[0][0] >> 2;  p_Vid->mb_size_blk[1][0] = p_Vid->mb_size_blk[2][0] = p_Vid->mb_size[1][0] >> 2;  p_Vid->mb_size_blk[1][1] = p_Vid->mb_size_blk[2][1] = p_Vid->mb_size[1][1] >> 2;  p_Vid->mb_size_shift[0][0] = p_Vid->mb_size_shift[0][1] = CeilLog2_sf (p_Vid->mb_size[0][0]);  p_Vid->mb_size_shift[1][0] = p_Vid->mb_size_shift[2][0] = CeilLog2_sf (p_Vid->mb_size[1][0]);  p_Vid->mb_size_shift[1][1] = p_Vid->mb_size_shift[2][1] = CeilLog2_sf (p_Vid->mb_size[1][1]);}/*! ************************************************************************ * \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));  if (partArr == NULL)  {    snprintf(errortext, ET_SIZE, "AllocPartition: Memory allocation for Data Partition failed");    error(errortext, 100);  }  for (i=0; i<n; ++i) // loop over all data partitions  {    dataPart = &(partArr[i]);    dataPart->bitstream = (Bitstream *) calloc(1, sizeof(Bitstream));    if (dataPart->bitstream == NULL)    {      snprintf(errortext, ET_SIZE, "AllocPartition: Memory allocation for Bitstream failed");      error(errortext, 100);    }		dataPart->bitstream->streamBuffer = 0;  }  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 InputParameters *p_Inp,  VideoParameters *p_Vid ************************************************************************ */void malloc_slice(InputParameters *p_Inp, VideoParameters *p_Vid){  int memory_size = 0;  Slice *currSlice;  p_Vid->currentSlice = (Slice *) _aligned_malloc(sizeof(Slice), 32);  if ( (currSlice = p_Vid->currentSlice) == NULL)  {    error("Memory allocation for Slice datastruct failed",100);  }	memset(p_Vid->currentSlice, 0, sizeof(Slice));  //  p_Vid->currentSlice->rmpni_buffer=NULL;  //! you don't know whether we do CABAC here, hence initialize CABAC anyway  // if (p_Inp->symbol_mode == CABAC)  // create all context models  currSlice->mot_ctx = create_contexts_MotionInfo();  currSlice->tex_ctx = create_contexts_TextureInfo();  currSlice->max_part_nr = 3;  //! assume data partitioning (worst case) for the following mallocs()  currSlice->partArr = AllocPartition(currSlice->max_part_nr);  currSlice->p_colocated = NULL;	currSlice->coeff_ctr = -1;  currSlice->pos       =  0;}/*! ************************************************************************ * \brief *    Memory frees of the Slice structure and of its dependent *    data structures * * \par Input: *    Input Parameters InputParameters *p_Inp,  VideoParameters *p_Vid ************************************************************************ */void free_slice(Slice *currSlice){  FreePartition (currSlice->partArr, 3);    if (1)  {    // delete all context models    delete_contexts_MotionInfo(currSlice->mot_ctx);    delete_contexts_TextureInfo(currSlice->tex_ctx);  }  _aligned_free(currSlice);  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 InputParameters *p_Inp, Image Parameters VideoParameters *p_Vid * *  \par Output: *     Number of allocated bytes *********************************************************************** */int init_global_buffers(VideoParameters *p_Vid){  int memory_size=0;  int i;  if (p_Vid->global_init_done)  {    free_global_buffers(p_Vid);  }  // allocate memory in structure p_Vid  if( IS_INDEPENDENT(p_Vid) )  {    for( i=0; i<MAX_PLANE; ++i )    {      if(((p_Vid->mb_data_JV[i]) = (Macroblock *) calloc(p_Vid->FrameSizeInMbs, sizeof(Macroblock))) == NULL)        no_mem_exit("init_global_buffers: p_Vid->mb_data");    }    p_Vid->mb_data = NULL;  }  else  {    if(((p_Vid->mb_data) = (Macroblock *) calloc(p_Vid->FrameSizeInMbs, sizeof(Macroblock))) == NULL)      no_mem_exit("init_global_buffers: p_Vid->mb_data");  }  if(((p_Vid->intra_block) = (int*)calloc(p_Vid->FrameSizeInMbs, sizeof(int))) == NULL)    no_mem_exit("init_global_buffers: p_Vid->intra_block");	p_Vid->PicPos = (h264_pic_position *)calloc(p_Vid->FrameSizeInMbs + 1, sizeof(h264_pic_position)); //! Helper array to access macroblock positions. We add 1 to also consider last MB.  for (i = 0; i < (int) p_Vid->FrameSizeInMbs + 1;++i)  {    p_Vid->PicPos[i][0] = (i % p_Vid->PicWidthInMbs);    p_Vid->PicPos[i][1] = (i / p_Vid->PicWidthInMbs);  }  memory_size += get_mem2D(&(p_Vid->ipredmode), 4*p_Vid->FrameHeightInMbs, 4*p_Vid->PicWidthInMbs);  // CAVLC mem	p_Vid->nz_coeff = (h264_nz_coefficient *)_aligned_malloc(p_Vid->FrameSizeInMbs*sizeof(h264_nz_coefficient), 32);	memset(p_Vid->nz_coeff, 0, p_Vid->FrameSizeInMbs*sizeof(h264_nz_coefficient));  //memory_size += get_mem4D(&(p_Vid->nz_coeff), p_Vid->FrameSizeInMbs, 3, BLOCK_SIZE, BLOCK_SIZE);  memory_size += get_mem2Dint(&(p_Vid->siblock), p_Vid->FrameHeightInMbs, p_Vid->PicWidthInMbs);  init_qp_process(p_Vid);  p_Vid->global_init_done = 1;  p_Vid->oldFrameSizeInMbs = p_Vid->FrameSizeInMbs;  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 InputParameters *p_Inp, Image Parameters VideoParameters *p_Vid * * \par Output: *    none * ************************************************************************ */void free_global_buffers(VideoParameters *p_Vid){    // CAVLC free mem  _aligned_free(p_Vid->nz_coeff);  free_mem2Dint(p_Vid->siblock);  // free mem, allocated for structure p_Vid  if (p_Vid->mb_data != NULL)    free(p_Vid->mb_data);  free(p_Vid->PicPos);  free (p_Vid->intra_block);  free_mem2D(p_Vid->ipredmode);  free_qp_matrices(p_Vid);  p_Vid->global_init_done = 0;}
 |