void_t H264DecodeInstance (ISVCDecoder* pDecoder, const char* kpH264FileName, const char* kpOuputFileName, int32_t& iWidth, int32_t& iHeight, void_t* 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_t* 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; static int32_t iFrameNum = 0; EDecodeMode eDecoderMode = AUTO_MODE; EBufferProperty eOutputProperty = BUFFER_DEVICE; 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 ((char*)pOptionFileName, "wb"); if (pOptionFile == NULL) { fprintf (stderr, "Can not open optional file for write..\n"); } else fprintf (stderr, "Extra optional file: %s..\n", (char*)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; } fread (pBuf, 1, iFileSize, pH264File); 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 (pDecoder->SetOption (DECODER_OPTION_MODE, &eDecoderMode)) { fprintf (stderr, "SetOption() failed, opt_id : %d ..\n", DECODER_OPTION_MODE); goto label_exit; } // set the output buffer property if (pYuvFile) { pDecoder->SetOption (DECODER_OPTION_OUTPUT_PROPERTY, &eOutputProperty); } #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_t*)&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 iSetMode; pDecoder->GetOption (DECODER_OPTION_MODE, &iSetMode); int32_t iDeviceInfo; pDecoder->GetOption (DECODER_OPTION_DEVICE_INFO, &iDeviceInfo); //~end for iStart = WelsTime(); pData[0] = NULL; pData[1] = NULL; pData[2] = NULL; memset (&sDstBufInfo, 0, sizeof (SBufferInfo)); pDecoder->DecodeFrame (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) { iFrameNum++; cOutputModule.Process ((void_t**)pDst, &sDstBufInfo, pYuvFile); if (sDstBufInfo.eBufferProperty == BUFFER_HOST) { iWidth = sDstBufInfo.UsrData.sSystemBuffer.iWidth; iHeight = sDstBufInfo.UsrData.sSystemBuffer.iHeight; } else { iWidth = sDstBufInfo.UsrData.sVideoBuffer.iSurfaceWidth; iHeight = sDstBufInfo.UsrData.sVideoBuffer.iSurfaceHeight; } 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->DecodeFrame (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_t**)pDst, &sDstBufInfo, pYuvFile); if (sDstBufInfo.eBufferProperty == BUFFER_HOST) { iWidth = sDstBufInfo.UsrData.sSystemBuffer.iWidth; iHeight = sDstBufInfo.UsrData.sSystemBuffer.iHeight; } else { iWidth = sDstBufInfo.UsrData.sVideoBuffer.iSurfaceWidth; iHeight = sDstBufInfo.UsrData.sVideoBuffer.iSurfaceHeight; } 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; } }
void H264DecodeInstance (ISVCDecoder* pDecoder, const char* kpH264FileName, const char* kpOuputFileName, int32_t& iWidth, int32_t& iHeight, const char* pOptionFileName, const char* pLengthFileName) { FILE* pH264File = NULL; FILE* pYuvFile = NULL; FILE* pOptionFile = NULL; // Lenght input mode support FILE* fpTrack = NULL; if (pLengthFileName != NULL) { fpTrack = fopen (pLengthFileName, "rb"); if (fpTrack == NULL) printf ("Length file open ERROR!\n"); } int32_t pInfo[4]; unsigned long long uiTimeStamp = 0; 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}; uint8_t* 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; //for coverage test purpose int32_t iErrorConMethod = (int32_t) ERROR_CON_SLICE_MV_COPY_CROSS_IDR_FREEZE_RES_CHANGE; pDecoder->SetOption (DECODER_OPTION_ERROR_CON_IDC, &iErrorConMethod); //~end for 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 = (int32_t) 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; } while (true) { if (iBufPos >= iFileSize) { iEndOfStreamFlag = true; if (iEndOfStreamFlag) pDecoder->SetOption (DECODER_OPTION_END_OF_STREAM, (void*)&iEndOfStreamFlag); break; } // Read length from file if needed if (fpTrack) { if (fread (pInfo, 4, sizeof (int32_t), fpTrack) < 4) return; iSliceSize = static_cast<int32_t> (pInfo[2]); } 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) || (pBuf[iBufPos + i] == 0 && pBuf[iBufPos + i + 1] == 0 && pBuf[iBufPos + i + 2] == 1 && i > 0)) { break; } } iSliceSize = i; } if (iSliceSize < 4) { //too small size, no effective data, ignore iBufPos += iSliceSize; continue; } //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); //~end for iStart = WelsTime(); pData[0] = NULL; pData[1] = NULL; pData[2] = NULL; uiTimeStamp ++; memset (&sDstBufInfo, 0, sizeof (SBufferInfo)); sDstBufInfo.uiInBsTimeStamp = uiTimeStamp; #ifndef NO_DELAY_DECODING pDecoder->DecodeFrameNoDelay (pBuf + iBufPos, iSliceSize, pData, &sDstBufInfo); #else pDecoder->DecodeFrame2 (pBuf + iBufPos, iSliceSize, pData, &sDstBufInfo); #endif if (sDstBufInfo.iBufferStatus == 1) { pDst[0] = pData[0]; pDst[1] = pData[1]; pDst[2] = 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; } #ifdef NO_DELAY_DECODING iStart = WelsTime(); pData[0] = NULL; pData[1] = NULL; pData[2] = NULL; memset (&sDstBufInfo, 0, sizeof (SBufferInfo)); sDstBufInfo.uiInBsTimeStamp = uiTimeStamp; pDecoder->DecodeFrame2 (NULL, 0, pData, &sDstBufInfo); if (sDstBufInfo.iBufferStatus == 1) { pDst[0] = pData[0]; pDst[1] = pData[1]; pDst[2] = 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; } #endif iBufPos += iSliceSize; ++ iSliceIndex; } if (fpTrack) { fclose (fpTrack); fpTrack = NULL; } 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"); #if defined (WINDOWS_PHONE) g_dDecTime = dElapsed; g_fDecFPS = (iFrameCount * 1.0f) / (float) dElapsed; g_iDecodedFrameNum = iFrameCount; #endif // 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; } }