Add new output format OUTPUT_NALLENGTHS_PREFIXED

BZ: 156038

this new format structure is like:
    [out-band data] + bitstream
[out-band data] is fixed 256 bytes, contains:
     'nall' + nalnum + nallength[nalnum]
each one is 4 bytes aligned, out-band data is marked with offset.
VideoEncOutputBuffer structure is also extended to support offset.

Change-Id: I572c547be606afe3f7e658e2ef08507f97ff2f3f
Signed-off-by: Zhao Liang <leo.zhao@intel.com>
diff --git a/videoencoder/VideoEncoderAVC.cpp b/videoencoder/VideoEncoderAVC.cpp
index 0c021dc..85c1315 100644
--- a/videoencoder/VideoEncoderAVC.cpp
+++ b/videoencoder/VideoEncoderAVC.cpp
@@ -326,6 +326,13 @@
             break;
         }
 
+        case OUTPUT_NALULENGTHS_PREFIXED: {
+            // Output nalu lengths ahead of bitstream
+            ret = outputNaluLengthsPrefixed(outBuffer);
+            CHECK_ENCODE_STATUS_CLEANUP("outputNaluLengthsPrefixed");
+            break;
+        }
+
         default:
             LOG_E("Invalid buffer mode\n");
             ret = ENCODE_FAIL;
@@ -496,8 +503,8 @@
 
     if (headerSize <= outBuffer->bufferSize) {
         memcpy(outBuffer->data, (uint8_t *)mCurSegment->buf + mOffsetInSeg, headerSize);
-//        mTotalSizeCopied += headerSize;
-//        mOffsetInSeg += headerSize;
+        mTotalSizeCopied += headerSize;
+        mOffsetInSeg += headerSize;
         outBuffer->dataSize = headerSize;
         outBuffer->remainingSize = 0;
         outBuffer->flag |= ENCODE_BUFFERFLAG_ENDOFFRAME;
@@ -642,6 +649,84 @@
     return ENCODE_SUCCESS;
 }
 
+Encode_Status VideoEncoderAVC::outputNaluLengthsPrefixed(VideoEncOutputBuffer *outBuffer) {
+
+    Encode_Status ret = ENCODE_SUCCESS;
+    uint32_t nalType = 0;
+    uint32_t nalSize = 0;
+    uint32_t nalOffset = 0;
+    uint32_t sizeCopiedHere = 0;
+    const uint32_t NALUINFO_OFFSET = 256;
+    uint32_t nalNum = 0;
+
+    CHECK_NULL_RETURN_IFFAIL(mCurSegment->buf);
+	LOG_I("outputNaluLengthsPrefixed\n");
+
+    while (1) {
+
+        if (mCurSegment->size < mOffsetInSeg || outBuffer->bufferSize < sizeCopiedHere) {
+            LOG_E("mCurSegment->size < mOffsetInSeg  || outBuffer->bufferSize < sizeCopiedHere\n");
+            return ENCODE_FAIL;
+        }
+
+        // we need to handle the whole bitstream NAL by NAL
+        ret = getOneNALUnit(
+                (uint8_t *)mCurSegment->buf + mOffsetInSeg,
+                mCurSegment->size - mOffsetInSeg, &nalSize, &nalType, &nalOffset, mCurSegment->status);
+        CHECK_ENCODE_STATUS_RETURN("getOneNALUnit");
+
+        if (nalSize + 4 <= outBuffer->bufferSize - NALUINFO_OFFSET - sizeCopiedHere) {
+			LOG_I("zhaoliang nalSize=%d, nalOffset=%d\n", nalSize, nalOffset);
+
+            memcpy(outBuffer->data + NALUINFO_OFFSET + sizeCopiedHere,
+                   (uint8_t *)mCurSegment->buf + mOffsetInSeg, nalSize + nalOffset);
+
+            sizeCopiedHere += nalSize + nalOffset;
+            mTotalSizeCopied += nalSize + nalOffset;
+            mOffsetInSeg += (nalSize + nalOffset);
+
+        } else {
+            outBuffer->dataSize = sizeCopiedHere;
+            // In case the start code is 3-byte length but we use 4-byte for length prefixed
+            // so the remainingSize size may larger than the remaining data size
+            outBuffer->remainingSize = mTotalSize - mTotalSizeCopied + 100;
+            outBuffer->flag |= ENCODE_BUFFERFLAG_PARTIALFRAME;
+            LOG_E("Buffer size too small\n");
+            return ENCODE_BUFFER_TOO_SMALL;
+        }
+
+        nalNum ++;
+        uint32_t *nalLength = (uint32_t *) (outBuffer->data + (nalNum+1) * 4);
+
+        *nalLength = nalSize + nalOffset;
+
+		LOG_I("nalLength=%d\n", nalSize + nalOffset);
+
+        // check if all data in current segment has been copied out
+        if (mCurSegment->size == mOffsetInSeg) {
+            if (mCurSegment->next != NULL) {
+                mCurSegment = (VACodedBufferSegment *)mCurSegment->next;
+                mOffsetInSeg = 0;
+            } else {
+                LOG_V("End of stream\n");
+                outBuffer->dataSize = sizeCopiedHere;
+                outBuffer->remainingSize = 0;
+                outBuffer->flag |= ENCODE_BUFFERFLAG_ENDOFFRAME;
+                mCurSegment = NULL;
+                break;
+            }
+        }
+    }
+
+    outBuffer->offset = NALUINFO_OFFSET;
+    uint32_t *nalHead = (uint32_t *) outBuffer->data;
+    LOG_I("zhaoliang nalHead =%x\n", nalHead);
+    *nalHead = 0x4E414C4C; //'nall'
+    *(++nalHead) = nalNum;
+
+    return ENCODE_SUCCESS;
+}
+
 Encode_Status VideoEncoderAVC::sendEncodeCommand(EncodeTask *task) {
     Encode_Status ret = ENCODE_SUCCESS;
 
diff --git a/videoencoder/VideoEncoderAVC.h b/videoencoder/VideoEncoderAVC.h
index f33755b..c66acc3 100644
--- a/videoencoder/VideoEncoderAVC.h
+++ b/videoencoder/VideoEncoderAVC.h
@@ -37,6 +37,7 @@
     Encode_Status outputCodecData(VideoEncOutputBuffer *outBuffer);
     Encode_Status outputOneNALU(VideoEncOutputBuffer *outBuffer, bool startCode);
     Encode_Status outputLengthPrefixed(VideoEncOutputBuffer *outBuffer);
+    Encode_Status outputNaluLengthsPrefixed(VideoEncOutputBuffer *outBuffer);
 
     Encode_Status renderMaxSliceSize();
     Encode_Status renderAIR();
diff --git a/videoencoder/VideoEncoderBase.cpp b/videoencoder/VideoEncoderBase.cpp
index 52e68a1..47b3f19 100644
--- a/videoencoder/VideoEncoderBase.cpp
+++ b/videoencoder/VideoEncoderBase.cpp
@@ -489,6 +489,7 @@
     CHECK_ENCODE_STATUS_CLEANUP("prepareForOutput");
 
     //copy all flags to outBuffer
+    outBuffer->offset = 0;
     outBuffer->flag = mCurOutputTask->flag;
     outBuffer->type = mCurOutputTask->type;
     outBuffer->timeStamp = mCurOutputTask->timestamp;
diff --git a/videoencoder/VideoEncoderDef.h b/videoencoder/VideoEncoderDef.h
index 0b11b05..2b48104 100644
--- a/videoencoder/VideoEncoderDef.h
+++ b/videoencoder/VideoEncoderDef.h
@@ -45,6 +45,7 @@
     OUTPUT_ONE_NAL_WITHOUT_STARTCODE = 8,
     OUTPUT_LENGTH_PREFIXED = 16,
     OUTPUT_CODEDBUFFER = 32,
+    OUTPUT_NALULENGTHS_PREFIXED = 64,
     OUTPUT_BUFFER_LAST
 } VideoOutputFormat;
 
@@ -138,7 +139,8 @@
 typedef struct {
     uint8_t *data;
     uint32_t bufferSize; //buffer size
-    uint32_t dataSize; //actuall size
+    uint32_t dataSize; //actual size
+    uint32_t offset; //buffer offset
     uint32_t remainingSize;
     int flag; //Key frame, Codec Data etc
     VideoOutputFormat format; //output format