/*! * \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;}
/*!
* \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 uninitial
label_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[]) {
#else
int32_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;
}