shithub: openh264

Download patch

ref: c08c0f85eb12f45a40f17a60ac33e00312799d18
parent: 3c4d151e03d61cbf2de82f8be22222dea550a5b7
author: ganyang <[email protected]>
date: Wed May 14 12:00:36 EDT 2014

This refine is to remove slice number limitation in the future. The changes contains:
1. add pNalLen in Structure SWelsEncoderOutput to store each nal length
2. rename iNalLengthInByte[MAX_NAL_UNITS_IN_LAYER] to pNalLengthInByte in Structure SLayerBSInfo, the pointer point to pNalLen, like pBSBuf point to pFrameBS.

--- a/codec/api/svc/codec_app_def.h
+++ b/codec/api/svc/codec_app_def.h
@@ -347,7 +347,7 @@
   unsigned char uiLayerType;
 
   int	iNalCount;					// Count number of NAL coded already
-  int	iNalLengthInByte[MAX_NAL_UNITS_IN_LAYER];	// Length of NAL size in byte from 0 to iNalCount-1
+  int*	pNalLengthInByte;	// Length of NAL size in byte from 0 to iNalCount-1
   unsigned char*	pBsBuf;		// Buffer of bitstream contained
 } SLayerBSInfo, *PLayerBSInfo;
 
--- a/codec/console/enc/src/welsenc.cpp
+++ b/codec/console/enc/src/welsenc.cpp
@@ -782,7 +782,7 @@
           int iLayerSize = 0;
           int iNalIdx = pLayerBsInfo->iNalCount - 1;
           do {
-            iLayerSize += pLayerBsInfo->iNalLengthInByte[iNalIdx];
+            iLayerSize += pLayerBsInfo->pNalLengthInByte[iNalIdx];
             -- iNalIdx;
           } while (iNalIdx >= 0);
 #if defined(COMPARE_DATA)
--- a/codec/encoder/core/inc/nal_encap.h
+++ b/codec/encoder/core/inc/nal_encap.h
@@ -71,6 +71,7 @@
 
 //	SWelsNalRaw		raw_nals[MAX_DEPENDENCY_LAYER*2+MAX_DEPENDENCY_LAYER*MAX_QUALITY_LEVEL]; // AVC: max up to SPS+PPS+max_slice_idc (2 + 8) for FMO;
   SWelsNalRaw*		sNalList;			// nal list, adaptive for AVC/SVC in case single slice, multiple slices or fmo
+  int32_t*      pNalLen;
   int32_t				iCountNals;			// count number of NAL in list
 // SVC: num_sps (MAX_D) + num_pps (MAX_D) + num_vcl (MAX_D * MAX_Q)
   int32_t				iNalIndex;			// coding NAL currently, 0 based
--- a/codec/encoder/core/src/encoder_ext.cpp
+++ b/codec/encoder/core/src/encoder_ext.cpp
@@ -1303,6 +1303,8 @@
   (*ppCtx)->pOut->uiSize      = iCountBsLen;
   (*ppCtx)->pOut->sNalList		= (SWelsNalRaw*)pMa->WelsMalloc (iCountNals * sizeof (SWelsNalRaw), "pOut->sNalList");
   WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pOut->sNalList), FreeMemorySvc (ppCtx))
+  (*ppCtx)->pOut->pNalLen     = (int32_t*)pMa->WelsMallocz(iCountNals * sizeof (int32_t), "pOut->pNalLen");
+  WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pOut->pNalLen), FreeMemorySvc(ppCtx))
   (*ppCtx)->pOut->iCountNals		= iCountNals;
   (*ppCtx)->pOut->iNalIndex		= 0;
 
@@ -1497,6 +1499,11 @@
         pMa->WelsFree (pCtx->pOut->sNalList, "pOut->sNalList");
         pCtx->pOut->sNalList = NULL;
       }
+      // NALs len
+      if (NULL != pCtx->pOut->pNalLen) {
+        pMa->WelsFree (pCtx->pOut->pNalLen, "pOut->pNalLen");
+				pCtx->pOut->pNalLen = NULL;
+      }
       pMa->WelsFree (pCtx->pOut, "SWelsEncoderOutput");
       pCtx->pOut = NULL;
     }
@@ -2733,7 +2740,6 @@
     iPayloadSize = pNalLen[*pNalIdxInLayer];
 
     pCtx->iPosBsBuffer							+= iPayloadSize;
-    pLayerBsInfo->iNalLengthInByte[*pNalIdxInLayer]	= iPayloadSize;
 
     (*pNalIdxInLayer) ++;
   } else { // No Prefix NAL Unit RBSP syntax here, but need add NAL Unit Header extension
@@ -2750,7 +2756,6 @@
     iPayloadSize = pNalLen[*pNalIdxInLayer];
 
     pCtx->iPosBsBuffer							+= iPayloadSize;
-    pLayerBsInfo->iNalLengthInByte[*pNalIdxInLayer]	= iPayloadSize;
 
     (*pNalIdxInLayer) ++;
   }
@@ -2816,13 +2821,13 @@
 int32_t WelsEncoderEncodeParameterSets (sWelsEncCtx* pCtx, void* pDst) {
   SFrameBSInfo* pFbi          = (SFrameBSInfo*)pDst;
   SLayerBSInfo* pLayerBsInfo  = &pFbi->sLayerInfo[0];
-  int32_t iNalLen[128]        = {0};
   int32_t iCountNal           = 0;
 
   pLayerBsInfo->pBsBuf = pCtx->pFrameBs;
+  pLayerBsInfo->pNalLengthInByte = pCtx->pOut->pNalLen;
   InitBits (&pCtx->pOut->sBsWrite, pCtx->pOut->pBsBuffer, pCtx->pOut->uiSize);
 
-  int32_t iReturn = WelsWriteParameterSets (pCtx, &iNalLen[0], &iCountNal);
+  int32_t iReturn = WelsWriteParameterSets (pCtx, &pLayerBsInfo->pNalLengthInByte[0], &iCountNal);
   WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS)
 
   pLayerBsInfo->uiPriorityId  = 0;
@@ -2831,9 +2836,6 @@
   pLayerBsInfo->uiQualityId   = 0;
   pLayerBsInfo->uiLayerType   = NON_VIDEO_CODING_LAYER;
   pLayerBsInfo->iNalCount     = iCountNal;
-  for (int32_t iNalIndex      = 0; iNalIndex < iCountNal; ++ iNalIndex) {
-    pLayerBsInfo->iNalLengthInByte[iNalIndex] = iNalLen[iNalIndex];
-  }
 
   pCtx->eLastNalPriority      = NRI_PRI_HIGHEST;
   pFbi->iLayerNum             = 1;
@@ -2865,7 +2867,6 @@
   int32_t iSpatialNum					= 0; // available count number of spatial layers due to frame size changed in this given frame
   int32_t iSpatialIdx					= 0; // iIndex of spatial layers due to frame size changed in this given frame
   int32_t iFrameSize					= 0;
-  int32_t iNalLen[128]				= {0};
   int32_t iNalIdxInLayer			= 0;
   int32_t iCountNal					= 0;
   EVideoFrameType eFrameType				= videoFrameTypeInvalid;
@@ -2909,6 +2910,7 @@
   pCtx->uiTemporalId	= iCurTid;
 
   pLayerBsInfo->pBsBuf	= pCtx->pFrameBs ;
+  pLayerBsInfo->pNalLengthInByte = pCtx->pOut->pNalLen;
 
   if (eFrameType == videoFrameTypeIDR) {
     ++ pCtx->sPSOVector.uiIdrPicId;
@@ -2915,7 +2917,7 @@
     //if ( pSvcParam->bEnableSSEI )
 
     // write parameter sets bitstream here
-    pCtx->iEncoderError = WelsWriteParameterSets (pCtx, &iNalLen[0], &iCountNal);
+    pCtx->iEncoderError = WelsWriteParameterSets (pCtx, &pLayerBsInfo->pNalLengthInByte[0], &iCountNal);
     WELS_VERIFY_RETURN_IFNEQ (pCtx->iEncoderError, ENC_RETURN_SUCCESS)
 
     pLayerBsInfo->uiPriorityId	= 0;
@@ -2924,12 +2926,10 @@
     pLayerBsInfo->uiQualityId		= 0;
     pLayerBsInfo->uiLayerType		= NON_VIDEO_CODING_LAYER;
     pLayerBsInfo->iNalCount		= iCountNal;
-    for (int32_t iNalIndex	= 0; iNalIndex < iCountNal; ++ iNalIndex) {
-      pLayerBsInfo->iNalLengthInByte[iNalIndex]	= iNalLen[iNalIndex];
-    }
 
     ++ pLayerBsInfo;
     pLayerBsInfo->pBsBuf			= pCtx->pFrameBs + pCtx->iPosBsBuffer;
+    pLayerBsInfo->pNalLengthInByte = (pLayerBsInfo - 1)->pNalLengthInByte + iCountNal;
     ++ iLayerNum;
   }
 
@@ -3050,7 +3050,7 @@
       int32_t iPayloadSize	= 0;
 
       if (pCtx->bNeedPrefixNalFlag) {
-        pCtx->iEncoderError = AddPrefixNal (pCtx, pLayerBsInfo, &iNalLen[0], &iNalIdxInLayer, eNalType, eNalRefIdc,
+        pCtx->iEncoderError = AddPrefixNal (pCtx, pLayerBsInfo, &pLayerBsInfo->pNalLengthInByte[0], &iNalIdxInLayer, eNalType, eNalRefIdc,
                                             iPayloadSize);
         WELS_VERIFY_RETURN_IFNEQ (pCtx->iEncoderError, ENC_RETURN_SUCCESS)
         iLayerSize += iPayloadSize;
@@ -3067,9 +3067,9 @@
                                            &pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt,
                                            pCtx->iFrameBsSize - pCtx->iPosBsBuffer,
                                            pCtx->pFrameBs + pCtx->iPosBsBuffer,
-                                           &iNalLen[iNalIdxInLayer]);
+                                           &pLayerBsInfo->pNalLengthInByte[iNalIdxInLayer]);
       WELS_VERIFY_RETURN_IFNEQ (pCtx->iEncoderError, ENC_RETURN_SUCCESS)
-      iSliceSize = iNalLen[iNalIdxInLayer];
+      iSliceSize = pLayerBsInfo->pNalLengthInByte[iNalIdxInLayer];
 
       iLayerSize += iSliceSize;
       pCtx->iPosBsBuffer	+= iSliceSize;
@@ -3078,7 +3078,6 @@
       pLayerBsInfo->uiTemporalId	= iCurTid;
       pLayerBsInfo->uiQualityId		= 0;
       pLayerBsInfo->uiPriorityId	= 0;
-      pLayerBsInfo->iNalLengthInByte[iNalIdxInLayer]	= iSliceSize;
       pLayerBsInfo->iNalCount		= ++ iNalIdxInLayer;
     }
     // for dynamic slicing single threading..
@@ -3221,7 +3220,7 @@
           int32_t iSliceSize	= 0;
           int32_t iPayloadSize	= 0;
           if (bNeedPrefix) {
-            pCtx->iEncoderError = AddPrefixNal (pCtx, pLayerBsInfo, &iNalLen[0], &iNalIdxInLayer, eNalType, eNalRefIdc,
+            pCtx->iEncoderError = AddPrefixNal (pCtx, pLayerBsInfo, &pLayerBsInfo->pNalLengthInByte[0], &iNalIdxInLayer, eNalType, eNalRefIdc,
                                                 iPayloadSize);
             WELS_VERIFY_RETURN_IFNEQ (pCtx->iEncoderError, ENC_RETURN_SUCCESS)
             iLayerSize += iPayloadSize;
@@ -3236,13 +3235,12 @@
           pCtx->iEncoderError = WelsEncodeNal (&pCtx->pOut->sNalList[pCtx->pOut->iNalIndex - 1],
                                                &pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt,
                                                pCtx->iFrameBsSize - pCtx->iPosBsBuffer,
-                                               pCtx->pFrameBs + pCtx->iPosBsBuffer, &iNalLen[iNalIdxInLayer]);
+                                               pCtx->pFrameBs + pCtx->iPosBsBuffer, &pLayerBsInfo->pNalLengthInByte[iNalIdxInLayer]);
           WELS_VERIFY_RETURN_IFNEQ (pCtx->iEncoderError, ENC_RETURN_SUCCESS)
-          iSliceSize = iNalLen[iNalIdxInLayer];
+          iSliceSize = pLayerBsInfo->pNalLengthInByte[iNalIdxInLayer];
 
           pCtx->iPosBsBuffer	+= iSliceSize;
           iLayerSize	+= iSliceSize;
-          pLayerBsInfo->iNalLengthInByte[iNalIdxInLayer]	= iSliceSize;
 
 #if defined(SLICE_INFO_OUTPUT)
           fprintf (stderr,
@@ -3374,10 +3372,12 @@
     }
 #endif//STAT_OUTPUT
 
+    iCountNal = pLayerBsInfo->iNalCount;
     ++ iLayerNum;
     ++ pLayerBsInfo;
 
     pLayerBsInfo->pBsBuf	= pCtx->pFrameBs + pCtx->iPosBsBuffer;
+    pLayerBsInfo->pNalLengthInByte = (pLayerBsInfo - 1)->pNalLengthInByte + iCountNal;
 
     if (pSvcParam->iPaddingFlag && pCtx->pWelsSvcRc[pCtx->uiDependencyId].iPaddingSize > 0) {
       int32_t iPaddingNalSize = 0;
@@ -3401,9 +3401,10 @@
       pLayerBsInfo->uiQualityId		= 0;
       pLayerBsInfo->uiLayerType		= NON_VIDEO_CODING_LAYER;
       pLayerBsInfo->iNalCount		= 1;
-      pLayerBsInfo->iNalLengthInByte[0] = iPaddingNalSize;
+      pLayerBsInfo->pNalLengthInByte[0] = iPaddingNalSize;
       ++ pLayerBsInfo;
       pLayerBsInfo->pBsBuf	= pCtx->pFrameBs + pCtx->iPosBsBuffer;
+      pLayerBsInfo->pNalLengthInByte = (pLayerBsInfo - 1)->pNalLengthInByte + 1;
       ++ iLayerNum;
     }
 
@@ -3657,7 +3658,6 @@
 
   SDqLayer* pCurLayer			= pCtx->pCurDqLayer;
   SSliceCtx* pSliceCtx		= pCurLayer->pSliceEncCtx;
-  int32_t iNalLen[MAX_NAL_UNITS_IN_LAYER]			= {0};
   int32_t iNalIdxInLayer		= *pNalIdxInLayer;
   int32_t iSliceIdx				= iStartSliceIdx;
   const int32_t kiSliceStep		= pCtx->iActiveThreadsNum;
@@ -3688,7 +3688,7 @@
     }
 
     if (kbNeedPrefix) {
-      iReturn = AddPrefixNal (pCtx, pLayerBsInfo, &iNalLen[0], &iNalIdxInLayer, keNalType, keNalRefIdc, iPayloadSize);
+      iReturn = AddPrefixNal (pCtx, pLayerBsInfo, &pLayerBsInfo->pNalLengthInByte[0], &iNalIdxInLayer, keNalType, keNalRefIdc, iPayloadSize);
       WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS)
       iPartitionBsSize += iPayloadSize;
     }
@@ -3702,13 +3702,12 @@
                              &pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt,
                              pCtx->iFrameBsSize - pCtx->iPosBsBuffer,
                              pCtx->pFrameBs + pCtx->iPosBsBuffer,
-                             &iNalLen[iNalIdxInLayer]);
+                             &pLayerBsInfo->pNalLengthInByte[iNalIdxInLayer]);
     WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS)
-    iSliceSize = iNalLen[iNalIdxInLayer];
+    iSliceSize = pLayerBsInfo->pNalLengthInByte[iNalIdxInLayer];
 
     pCtx->iPosBsBuffer	+= iSliceSize;
     iPartitionBsSize	+= iSliceSize;
-    pLayerBsInfo->iNalLengthInByte[iNalIdxInLayer]	= iSliceSize;
 
 #if defined(SLICE_INFO_OUTPUT)
     fprintf (stderr,
--- a/codec/encoder/core/src/slice_multi_threading.cpp
+++ b/codec/encoder/core/src/slice_multi_threading.cpp
@@ -548,7 +548,7 @@
         iLayerSize += pSliceBs->uiBsPos;
 
         while (iNalIdx < iCountNal) {
-          pLbi->iNalLengthInByte[iNalIdxBase + iNalIdx]	= pSliceBs->iNalLen[iNalIdx];
+          pLbi->pNalLengthInByte[iNalIdxBase + iNalIdx]	= pSliceBs->iNalLen[iNalIdx];
           ++ iNalIdx;
         }
         pLbi->iNalCount	+= iCountNal;
@@ -580,7 +580,7 @@
             iLayerSize += pSliceBs->uiBsPos;
 
             while (iNalIdx < iCountNal) {
-              pLbi->iNalLengthInByte[iNalIdxBase + iNalIdx]	= pSliceBs->iNalLen[iNalIdx];
+              pLbi->pNalLengthInByte[iNalIdxBase + iNalIdx]	= pSliceBs->iNalLen[iNalIdx];
               ++ iNalIdx;
             }
             pLbi->iNalCount	+= iCountNal;
@@ -621,7 +621,7 @@
     WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS)
     iSliceSize += iNalSize;
     pDst += iNalSize;
-    pLbi->iNalLengthInByte[iNalBase + iNalIdx]	= iNalSize;
+    pLbi->pNalLengthInByte[iNalBase + iNalIdx]	= iNalSize;
 
     ++ iNalIdx;
   }
--- a/codec/encoder/plus/src/welsEncoderExt.cpp
+++ b/codec/encoder/plus/src/welsEncoderExt.cpp
@@ -479,7 +479,7 @@
 
       iCurLayerBits = 0;
       for (j = 0; j < pLayer->iNalCount; j++) {
-        iCurLayerBits += pLayer->iNalLengthInByte[j];
+        iCurLayerBits += pLayer->pNalLengthInByte[j];
       }
       total_bits += iCurLayerBits;
       if (m_pFileBs != NULL)
--- a/test/api/decode_encode_test.cpp
+++ b/test/api/decode_encode_test.cpp
@@ -11,7 +11,7 @@
     const SLayerBSInfo& layerInfo = info.sLayerInfo[i];
     int layerSize = 0;
     for (int j = 0; j < layerInfo.iNalCount; ++j) {
-      layerSize += layerInfo.iNalLengthInByte[j];
+      layerSize += layerInfo.pNalLengthInByte[j];
     }
     SHA1Input(ctx, layerInfo.pBsBuf, layerSize);
   }
--- a/test/api/encoder_test.cpp
+++ b/test/api/encoder_test.cpp
@@ -7,7 +7,7 @@
     const SLayerBSInfo& layerInfo = info.sLayerInfo[i];
     int layerSize = 0;
     for (int j = 0; j < layerInfo.iNalCount; ++j) {
-      layerSize += layerInfo.iNalLengthInByte[j];
+      layerSize += layerInfo.pNalLengthInByte[j];
     }
     SHA1Input(ctx, layerInfo.pBsBuf, layerSize);
   }