shithub: openh264

Download patch

ref: 4e57a46ca5efb3c7a94810f9d7996b9e1b7ac0dd
parent: a3bdf4ffc9dc4ed6c9d6cc4430210dcf5359e228
parent: f8d2ae42efd4643fae06485a94023952e8c066f8
author: ruil2 <ruil2@cisco.com>
date: Wed Sep 24 09:47:02 EDT 2014

Merge pull request #1382 from huili2/dataformat_bugfix

add protection for decoder and data format

--- a/codec/decoder/core/src/decoder.cpp
+++ b/codec/decoder/core/src/decoder.cpp
@@ -273,9 +273,10 @@
 /*!
  * \brief	Open decoder
  */
-void WelsOpenDecoder (PWelsDecoderContext pCtx) {
+int32_t WelsOpenDecoder (PWelsDecoderContext pCtx) {
   // function pointers
   //initial MC function pointer--
+  int iRet = ERR_NONE;
   InitMcFunc (& (pCtx->sMcFunc), pCtx->uiCpuFlag);
   InitErrorCon (pCtx);
 
@@ -286,8 +287,9 @@
   InitVlcTable (&pCtx->sVlcTable);
 
   // startup memory
-  if (ERR_NONE != WelsInitMemory (pCtx))
-    return;
+  iRet = WelsInitMemory (pCtx);
+  if (ERR_NONE != iRet)
+    return iRet;
 
 #ifdef LONG_TERM_REF
   pCtx->bParamSetsLostFlag = true;
@@ -298,6 +300,7 @@
   pCtx->bDecErrorConedFlag = false; //default: decoder normal status
   pCtx->bPrintFrameErrorTraceFlag = true;
   pCtx->iIgnoredErrorInfoPacketCount = 0;
+  return iRet;
 }
 
 /*!
@@ -333,6 +336,9 @@
 
   memcpy (pCtx->pParam, kpParam, sizeof (SDecodingParam));
   pCtx->eOutputColorFormat	= pCtx->pParam->eOutputColorFormat;
+  int32_t iRet = DecoderSetCsp (pCtx, pCtx->pParam->eOutputColorFormat);
+  if (iRet)
+    return iRet;
   pCtx->eErrorConMethod = pCtx->pParam->eEcActiveIdc;
 
   if (VIDEO_BITSTREAM_SVC == pCtx->pParam->sVideoProperty.eVideoBsType ||
@@ -368,10 +374,7 @@
   WelsDecoderDefaults (pCtx, pLogCtx);
 
   // open decoder
-  WelsOpenDecoder (pCtx);
-
-
-  return ERR_NONE;
+  return WelsOpenDecoder (pCtx);
 }
 
 /*!
@@ -596,9 +599,12 @@
   }
 
   //For now, support only videoFormatI420!
-  if (kiColorFormat != (int32_t) videoFormatI420) {
+  if (kiColorFormat == (int32_t) videoFormatInternal) {
+    pCtx->pParam->eOutputColorFormat = pCtx->eOutputColorFormat = videoFormatI420;
+  } else if (kiColorFormat != (int32_t) videoFormatI420) {
     WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "Support I420 output only for now! Change to I420...");
     pCtx->pParam->eOutputColorFormat = pCtx->eOutputColorFormat = videoFormatI420;
+    return cmUnsupportedData;
   }
 
   return 0;
--- a/codec/decoder/plus/inc/welsDecoderExt.h
+++ b/codec/decoder/plus/inc/welsDecoderExt.h
@@ -101,7 +101,7 @@
 PWelsDecoderContext 				m_pDecContext;
 welsCodecTrace*			m_pWelsTrace;
 
-void InitDecoder (void);
+int32_t InitDecoder (void);
 void UninitDecoder (void);
 
 #ifdef OUTPUT_BIT_STREAM
--- a/codec/decoder/plus/src/welsDecoderExt.cpp
+++ b/codec/decoder/plus/src/welsDecoderExt.cpp
@@ -185,6 +185,7 @@
 }
 
 long CWelsDecoder::Initialize (const SDecodingParam* pParam) {
+  int iRet = ERR_NONE;
   if (m_pWelsTrace == NULL) {
     return cmMallocMemeError;
   }
@@ -195,9 +196,13 @@
   }
 
   // H.264 decoder initialization,including memory allocation,then open it ready to decode
-  InitDecoder();
+  iRet = InitDecoder();
+  if (iRet)
+    return iRet;
 
-  DecoderConfigParam (m_pDecContext, pParam);
+  iRet = DecoderConfigParam (m_pDecContext, pParam);
+  if (iRet)
+    return iRet;
 
   return cmResultSuccess;
 }
@@ -226,15 +231,16 @@
 }
 
 // the return value of this function is not suitable, it need report failure info to upper layer.
-void CWelsDecoder::InitDecoder (void) {
+int32_t CWelsDecoder::InitDecoder (void) {
 
   WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsDecoder::init_decoder(), openh264 codec version = %s",
            VERSION_NUMBER);
 
   m_pDecContext	= (PWelsDecoderContext)WelsMalloc (sizeof (SWelsDecoderContext), "m_pDecContext");
+  if (NULL == m_pDecContext)
+    return cmMallocMemeError;
 
-  WelsInitDecoder (m_pDecContext, &m_pWelsTrace->m_sLogCtx);
-
+  return WelsInitDecoder (m_pDecContext, &m_pWelsTrace->m_sLogCtx);
 }
 
 /*
--- a/test/decoder/DecUT_DecExt.cpp
+++ b/test/decoder/DecUT_DecExt.cpp
@@ -86,7 +86,11 @@
   m_szBuffer[3] = 1;
   m_iBufLength = 4;
   CM_RETURN eRet = (CM_RETURN) m_pDec->Initialize (&m_sDecParam);
-  ASSERT_EQ (eRet, cmResultSuccess);
+  if ((m_sDecParam.eOutputColorFormat != videoFormatI420) ||
+      (m_sDecParam.eOutputColorFormat != videoFormatInternal))
+    ASSERT_EQ (eRet, cmUnsupportedData);
+  else
+    ASSERT_EQ (eRet, cmResultSuccess);
 }
 
 void DecoderInterfaceTest::Uninit() {
@@ -154,7 +158,7 @@
   m_pDec->Initialize (&m_sDecParam);
   eRet = (CM_RETURN) m_pDec->GetOption (DECODER_OPTION_DATAFORMAT, &iOutput);
   EXPECT_EQ (eRet, cmResultSuccess);
-  EXPECT_EQ (20, iOutput);
+  EXPECT_EQ ((int32_t) videoFormatI420, iOutput);
 
   //Uninitialize, no GetOption can be done
   m_pDec->Uninitialize();
@@ -180,7 +184,10 @@
 
   //valid input
   eRet = (CM_RETURN) m_pDec->SetOption (DECODER_OPTION_DATAFORMAT, &iTmp);
-  EXPECT_EQ (eRet, cmResultSuccess);
+  if ((iTmp != (int32_t) videoFormatI420) && (iTmp != (int32_t) videoFormatInternal))
+    EXPECT_EQ (eRet, cmUnsupportedData);
+  else
+    EXPECT_EQ (eRet, cmResultSuccess);
   eRet = (CM_RETURN) m_pDec->GetOption (DECODER_OPTION_DATAFORMAT, &iOut);
   EXPECT_EQ (eRet, cmResultSuccess);