447 lines · 14.3 KB · C++
RawDownload
/*! * \copy *     Copyright (c)  2004-2013, Cisco Systems *     All rights reserved. * *     Redistribution and use in source and binary forms, with or without *     modification, are permitted provided that the following conditions *     are met: * *        * Redistributions of source code must retain the above copyright *          notice, this list of conditions and the following disclaimer. * *        * Redistributions in binary form must reproduce the above copyright *          notice, this list of conditions and the following disclaimer in *          the documentation and/or other materials provided with the *          distribution. * *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *     "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS *     FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE *     COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, *     BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER *     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT *     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN *     ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *     POSSIBILITY OF SUCH DAMAGE. * * h264dec.cpp:		Wels Decoder Console Implementation file */ #if defined (_WIN32)#define _CRT_SECURE_NO_WARNINGS#include <windows.h>#include <tchar.h>#else#include <string.h>#endif#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#if defined (ANDROID_NDK)#include <android/log.h>#endif#include "codec_def.h"#include "codec_app_def.h"#include "codec_api.h"#include "read_config.h"#include "typedefs.h"#include "measure_time.h"#include "d3d9_utils.h"#include "logging.h"  using namespace std;#if defined(ANDROID_NDK)#define LOG_TAG "welsdec"#define LOGI(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)#define printf LOGI#define fprintf(a, ...) LOGI(__VA_ARGS__)#endif//using namespace WelsDec; //#define STICK_STREAM_SIZE	// For Demo interfaces test with track file of integrated frames void H264DecodeInstance (ISVCDecoder* pDecoder, const char* kpH264FileName, const char* kpOuputFileName,                         int32_t& iWidth, int32_t& iHeight, const char* pOptionFileName) {  FILE* pH264File	  = NULL;  FILE* pYuvFile	  = NULL;  FILE* pOptionFile = NULL;  int64_t iStart = 0, iEnd = 0, iTotal = 0;  int32_t iSliceSize;  int32_t iSliceIndex = 0;  uint8_t* pBuf = NULL;  uint8_t uiStartCode[4] = {0, 0, 0, 1};   void* pData[3] = {NULL};  uint8_t* pDst[3] = {NULL};  SBufferInfo sDstBufInfo;   int32_t iBufPos = 0;  int32_t iFileSize;  int32_t i = 0;  int32_t iLastWidth = 0, iLastHeight = 0;  int32_t iFrameCount = 0;  int32_t iEndOfStreamFlag = 0;  int32_t iColorFormat = videoFormatInternal;   CUtils cOutputModule;  double dElapsed = 0;   if (pDecoder == NULL) return;  if (kpH264FileName) {    pH264File = fopen (kpH264FileName, "rb");    if (pH264File == NULL) {      fprintf (stderr, "Can not open h264 source file, check its legal path related please..\n");      return;    }    fprintf (stderr, "H264 source file name: %s..\n", kpH264FileName);  } else {    fprintf (stderr, "Can not find any h264 bitstream file to read..\n");    fprintf (stderr, "----------------decoder return------------------------\n");    return;  }   if (kpOuputFileName) {    pYuvFile = fopen (kpOuputFileName, "wb");    if (pYuvFile == NULL) {      fprintf (stderr, "Can not open yuv file to output result of decoding..\n");      // any options      //return;	// can let decoder work in quiet mode, no writing any output    } else      fprintf (stderr, "Sequence output file name: %s..\n", kpOuputFileName);  } else {    fprintf (stderr, "Can not find any output file to write..\n");    // any options  }   if (pOptionFileName) {    pOptionFile = fopen (pOptionFileName, "wb");    if (pOptionFile == NULL) {      fprintf (stderr, "Can not open optional file for write..\n");    } else      fprintf (stderr, "Extra optional file: %s..\n", pOptionFileName);  }   printf ("------------------------------------------------------\n");   fseek (pH264File, 0L, SEEK_END);  iFileSize = ftell (pH264File);  if (iFileSize <= 0) {    fprintf (stderr, "Current Bit Stream File is too small, read error!!!!\n");    goto label_exit;  }  fseek (pH264File, 0L, SEEK_SET);   pBuf = new uint8_t[iFileSize + 4];  if (pBuf == NULL) {    fprintf (stderr, "new buffer failed!\n");    goto label_exit;  }   if (fread (pBuf, 1, iFileSize, pH264File) != (uint32_t)iFileSize) {    fprintf (stderr, "Unable to read whole file\n");    goto label_exit;  }   memcpy (pBuf + iFileSize, &uiStartCode[0], 4); //confirmed_safe_unsafe_usage   if (pDecoder->SetOption (DECODER_OPTION_DATAFORMAT,  &iColorFormat)) {    fprintf (stderr, "SetOption() failed, opt_id : %d  ..\n", DECODER_OPTION_DATAFORMAT);    goto label_exit;  } #if defined ( STICK_STREAM_SIZE )  FILE* fpTrack = fopen ("3.len", "rb"); #endif// STICK_STREAM_SIZE    while (true) {     if (iBufPos >= iFileSize) {      iEndOfStreamFlag = true;      if (iEndOfStreamFlag)        pDecoder->SetOption (DECODER_OPTION_END_OF_STREAM, (void*)&iEndOfStreamFlag);      break;    } #if defined ( STICK_STREAM_SIZE )    if (fpTrack)      fread (&iSliceSize, 1, sizeof (int32_t), fpTrack);#else    for (i = 0; i < iFileSize; i++) {      if (pBuf[iBufPos + i] == 0 && pBuf[iBufPos + i + 1] == 0 && pBuf[iBufPos + i + 2] == 0 &&          pBuf[iBufPos + i + 3] == 1 && i > 0) {        break;      }    }    iSliceSize = i;#endif //for coverage test purpose    int32_t iOutputColorFormat;    pDecoder->GetOption (DECODER_OPTION_DATAFORMAT, &iOutputColorFormat);    int32_t iEndOfStreamFlag;    pDecoder->GetOption (DECODER_OPTION_END_OF_STREAM, &iEndOfStreamFlag);    int32_t iCurIdrPicId;    pDecoder->GetOption (DECODER_OPTION_IDR_PIC_ID, &iCurIdrPicId);    int32_t iFrameNum;    pDecoder->GetOption (DECODER_OPTION_FRAME_NUM, &iFrameNum);    int32_t bCurAuContainLtrMarkSeFlag;    pDecoder->GetOption (DECODER_OPTION_LTR_MARKING_FLAG, &bCurAuContainLtrMarkSeFlag);    int32_t iFrameNumOfAuMarkedLtr;    pDecoder->GetOption (DECODER_OPTION_LTR_MARKED_FRAME_NUM, &iFrameNumOfAuMarkedLtr);    int32_t iFeedbackVclNalInAu;    pDecoder->GetOption (DECODER_OPTION_VCL_NAL, &iFeedbackVclNalInAu);    int32_t iFeedbackTidInAu;    pDecoder->GetOption (DECODER_OPTION_TEMPORAL_ID, &iFeedbackTidInAu);    int32_t iErrorConMethod = ERROR_CON_SLICE_COPY;    pDecoder->SetOption (DECODER_OPTION_ERROR_CON_IDC, &iErrorConMethod);//~end for     iStart = WelsTime();    pData[0] = NULL;    pData[1] = NULL;    pData[2] = NULL;    memset (&sDstBufInfo, 0, sizeof (SBufferInfo));     pDecoder->DecodeFrame2 (pBuf + iBufPos, iSliceSize, pData, &sDstBufInfo);     if (sDstBufInfo.iBufferStatus == 1) {      pDst[0] = (uint8_t*)pData[0];      pDst[1] = (uint8_t*)pData[1];      pDst[2] = (uint8_t*)pData[2];    }    iEnd	= WelsTime();    iTotal	+= iEnd - iStart;    if (sDstBufInfo.iBufferStatus == 1) {      cOutputModule.Process ((void**)pDst, &sDstBufInfo, pYuvFile);      iWidth  = sDstBufInfo.UsrData.sSystemBuffer.iWidth;      iHeight = sDstBufInfo.UsrData.sSystemBuffer.iHeight;       if (pOptionFile != NULL) {        if (iWidth != iLastWidth && iHeight != iLastHeight) {          fwrite (&iFrameCount, sizeof (iFrameCount), 1, pOptionFile);          fwrite (&iWidth , sizeof (iWidth) , 1, pOptionFile);          fwrite (&iHeight, sizeof (iHeight), 1, pOptionFile);          iLastWidth  = iWidth;          iLastHeight = iHeight;        }      }      ++ iFrameCount;    }     iBufPos += iSliceSize;    ++ iSliceIndex;  }   // Get pending last frame  pData[0] = NULL;  pData[1] = NULL;  pData[2] = NULL;  memset (&sDstBufInfo, 0, sizeof (SBufferInfo));   pDecoder->DecodeFrame2 (NULL, 0, pData, &sDstBufInfo);  if (sDstBufInfo.iBufferStatus == 1) {    pDst[0] = (uint8_t*)pData[0];    pDst[1] = (uint8_t*)pData[1];    pDst[2] = (uint8_t*)pData[2];  }   if (sDstBufInfo.iBufferStatus == 1) {    cOutputModule.Process ((void**)pDst, &sDstBufInfo, pYuvFile);    iWidth  = sDstBufInfo.UsrData.sSystemBuffer.iWidth;    iHeight = sDstBufInfo.UsrData.sSystemBuffer.iHeight;     if (pOptionFile != NULL) {      /* Anyway, we need write in case of final frame decoding */      fwrite (&iFrameCount, sizeof (iFrameCount), 1, pOptionFile);      fwrite (&iWidth , sizeof (iWidth) , 1, pOptionFile);      fwrite (&iHeight, sizeof (iHeight), 1, pOptionFile);      iLastWidth	= iWidth;      iLastHeight	= iHeight;    }    ++ iFrameCount;  }  #if defined ( STICK_STREAM_SIZE )  if (fpTrack) {    fclose (fpTrack);    fpTrack = NULL;  }#endif// STICK_STREAM_SIZE   dElapsed = iTotal / 1e6;  fprintf (stderr, "-------------------------------------------------------\n");  fprintf (stderr, "iWidth:		%d\nheight:		%d\nFrames:		%d\ndecode time:	%f sec\nFPS:		%f fps\n",           iWidth, iHeight, iFrameCount, dElapsed, (iFrameCount * 1.0) / dElapsed);  fprintf (stderr, "-------------------------------------------------------\n");   // coverity scan uninitiallabel_exit:  if (pBuf) {    delete[] pBuf;    pBuf = NULL;  }  if (pH264File) {    fclose (pH264File);    pH264File = NULL;  }  if (pYuvFile) {    fclose (pYuvFile);    pYuvFile = NULL;  }  if (pOptionFile) {    fclose (pOptionFile);    pOptionFile = NULL;  }} #if (defined(ANDROID_NDK)||defined(APPLE_IOS))int32_t DecMain(int32_t iArgC, char* pArgV[]) {#elseint32_t main (int32_t iArgC, char* pArgV[]) {#endif  ISVCDecoder* pDecoder = NULL;   SDecodingParam sDecParam = {0};  string strInputFile (""), strOutputFile (""), strOptionFile ("");   sDecParam.sVideoProperty.size = sizeof (sDecParam.sVideoProperty);   if (iArgC < 2) {    printf ("usage 1: h264dec.exe welsdec.cfg\n");    printf ("usage 2: h264dec.exe welsdec.264 out.yuv\n");    printf ("usage 3: h264dec.exe welsdec.264\n");    return 1;  } else if (iArgC == 2) {    if (strstr (pArgV[1], ".cfg")) { // read config file //confirmed_safe_unsafe_usage      CReadConfig cReadCfg (pArgV[1]);      string strTag[4];      string strReconFile ("");       if (!cReadCfg.ExistFile()) {        printf ("Specified file: %s not exist, maybe invalid path or parameter settting.\n", cReadCfg.GetFileName().c_str());        return 1;      }       while (!cReadCfg.EndOfFile()) {        long nRd = cReadCfg.ReadLine (&strTag[0]);        if (nRd > 0) {          if (strTag[0].compare ("InputFile") == 0) {            strInputFile	= strTag[1];          } else if (strTag[0].compare ("OutputFile") == 0) {            strOutputFile	= strTag[1];          } else if (strTag[0].compare ("RestructionFile") == 0) {            strReconFile	= strTag[1];            int32_t iLen = strReconFile.length();            sDecParam.pFileNameRestructed	= new char[iLen + 1];            if (sDecParam.pFileNameRestructed != NULL) {              sDecParam.pFileNameRestructed[iLen] = 0;            }             strncpy (sDecParam.pFileNameRestructed, strReconFile.c_str(), iLen); //confirmed_safe_unsafe_usage          } else if (strTag[0].compare ("TargetDQID") == 0) {            sDecParam.uiTargetDqLayer	= (uint8_t)atol (strTag[1].c_str());          } else if (strTag[0].compare ("OutColorFormat") == 0) {            sDecParam.iOutputColorFormat = atol (strTag[1].c_str());          } else if (strTag[0].compare ("ErrorConcealmentFlag") == 0) {            sDecParam.uiEcActiveFlag	= (uint8_t)atol (strTag[1].c_str());          } else if (strTag[0].compare ("CPULoad") == 0) {            sDecParam.uiCpuLoad	= (uint32_t)atol (strTag[1].c_str());          } else if (strTag[0].compare ("VideoBitstreamType") == 0) {            sDecParam.sVideoProperty.eVideoBsType = (VIDEO_BITSTREAM_TYPE)atol (strTag[1].c_str());          }        }      }      if (strOutputFile.empty()) {        printf ("No output file specified in configuration file.\n");        return 1;      }    } else if (strstr (pArgV[1],                       ".264")) { // no output dump yuv file, just try to render the decoded pictures //confirmed_safe_unsafe_usage      strInputFile	= pArgV[1];      sDecParam.iOutputColorFormat          = videoFormatI420;      sDecParam.uiTargetDqLayer	          = (uint8_t) - 1;      sDecParam.uiEcActiveFlag	          = 1;      sDecParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;    }  } else { //iArgC > 2    strInputFile	= pArgV[1];    strOutputFile	= pArgV[2];    sDecParam.iOutputColorFormat	= videoFormatI420;    sDecParam.uiTargetDqLayer	= (uint8_t) - 1;    sDecParam.uiEcActiveFlag	= 1;    sDecParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;    if (iArgC > 3) {      for (int i = 3; i < iArgC; i++) {        char* cmd = pArgV[i];         if (!strcmp (cmd, "-options")) {          if (i + 1 < iArgC)            strOptionFile = pArgV[i++];          else {            printf ("options file not specified.\n");            return 1;          }        } else if (!strcmp (cmd, "-trace")) {          if (i + 1 < iArgC)            WelsStderrSetTraceLevel (atoi (pArgV[i++]));          else {            printf ("trace level not specified.\n");            return 1;          }        }      }    }     if (strOutputFile.empty()) {      printf ("No output file specified in configuration file.\n");      return 1;    }  }   if (strInputFile.empty()) {    printf ("No input file specified in configuration file.\n");    return 1;  }      if (WelsCreateDecoder (&pDecoder)  || (NULL == pDecoder)) {    printf ("Create Decoder failed.\n");    return 1;  }   if (pDecoder->Initialize (&sDecParam)) {    printf ("Decoder initialization failed.\n");    return 1;  }    int32_t iWidth = 0;  int32_t iHeight = 0;    H264DecodeInstance (pDecoder, strInputFile.c_str(), !strOutputFile.empty() ? strOutputFile.c_str() : NULL, iWidth, iHeight,                      (!strOptionFile.empty() ? strOptionFile.c_str() : NULL));   if (sDecParam.pFileNameRestructed != NULL) {    delete []sDecParam.pFileNameRestructed;    sDecParam.pFileNameRestructed = NULL;  }   if (pDecoder) {    pDecoder->Uninitialize();     WelsDestroyDecoder (pDecoder);  }   return 0;}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t