Implement VP8 temporal layer encode in libmix

BZ: 165682

Implement VP8 temporal layer encode in libmix
Fix some code style issues;
Fix data structure overflow issue.

Change-Id: I14958416381597c4b47b74a6cd99d83880028b29
Signed-off-by: liubolun <bolun.liu@intel.com>
diff --git a/videoencoder/VideoEncoderBase.cpp b/videoencoder/VideoEncoderBase.cpp
index 99c2606..6110343 100644
--- a/videoencoder/VideoEncoderBase.cpp
+++ b/videoencoder/VideoEncoderBase.cpp
@@ -894,6 +894,7 @@
     mComParams.disableDeblocking = 2;
     mComParams.syncEncMode = false;
     mComParams.codedBufNum = 2;
+    mComParams.numberOfLayer = 1;
 
     mHrdParam.bufferSize = 0;
     mHrdParam.initBufferFullness = 0;
@@ -906,7 +907,7 @@
 
     Encode_Status ret = ENCODE_SUCCESS;
     CHECK_NULL_RETURN_IFFAIL(videoEncParams);
-    LOG_I("Config type = %d\n", (int)videoEncParams->type);
+    LOG_I("Config type = %x\n", (int)videoEncParams->type);
 
     if (mStarted) {
         LOG_E("Encoder has been initialized, should use setConfig to change configurations\n");
@@ -975,6 +976,18 @@
             break;
         }
 
+        case VideoParamsTypeTemporalLayerNumber:{
+            VideoParamsTemporalLayerNumber *numberoflayer =
+                    reinterpret_cast <VideoParamsTemporalLayerNumber *> (videoEncParams);
+
+            if (numberoflayer->size != sizeof(VideoParamsTemporalLayerNumber)) {
+                 return ENCODE_INVALID_PARAMS;
+            }
+
+            mComParams.numberOfLayer = numberoflayer->numberOfLayer;
+            break;
+        }
+
         case VideoParamsTypeAVC:
         case VideoParamsTypeH263:
         case VideoParamsTypeMP4:
@@ -1086,6 +1099,19 @@
             }
         }
 
+        case VideoParamsTypeTemporalLayerNumber:{
+            VideoParamsTemporalLayerNumber *numberoflayer =
+                reinterpret_cast <VideoParamsTemporalLayerNumber *> (videoEncParams);
+
+            if(numberoflayer->size != sizeof(VideoParamsTemporalLayerNumber)) {
+                return ENCODE_INVALID_PARAMS;
+            }
+
+            numberoflayer->numberOfLayer = mComParams.numberOfLayer;
+
+            break;
+        }
+
         case VideoParamsTypeAVC:
         case VideoParamsTypeH263:
         case VideoParamsTypeMP4:
@@ -1200,7 +1226,8 @@
         case VideoConfigTypeSliceNum:
         case VideoConfigTypeVP8:
         case VideoConfigTypeVP8ReferenceFrame:
-        case VideoConfigTypeVP8MaxFrameSizeRatio:{
+        case VideoConfigTypeVP8MaxFrameSizeRatio:
+        case VideoConfigTypeVP8TemporalBitRateFrameRate:{
             ret = derivedSetConfig(videoEncConfig);
             break;
         }
diff --git a/videoencoder/VideoEncoderBase.h b/videoencoder/VideoEncoderBase.h
index 692162f..f4e58e0 100644
--- a/videoencoder/VideoEncoderBase.h
+++ b/videoencoder/VideoEncoderBase.h
@@ -121,6 +121,7 @@
     bool mRenderBitRate;
     bool mRenderHrd;
     bool mRenderMaxFrameSize;
+    bool mRenderMultiTemporal;
 
     VABufferID mSeqParamBuf;
     VABufferID mRcParamBuf;
diff --git a/videoencoder/VideoEncoderDef.h b/videoencoder/VideoEncoderDef.h
index 9c8737d..c116412 100644
--- a/videoencoder/VideoEncoderDef.h
+++ b/videoencoder/VideoEncoderDef.h
@@ -315,6 +315,7 @@
     VideoParamsTypeStoreMetaDataInBuffers,
     VideoParamsTypeProfileLevel,
     VideoParamsTypeVP8,
+    VideoParamsTypeTemporalLayerNumber,
 
     VideoConfigTypeFrameRate,
     VideoConfigTypeBitRate,
@@ -330,6 +331,7 @@
     VideoConfigTypeVP8ReferenceFrame,
     VideoConfigTypeCIR,
     VideoConfigTypeVP8MaxFrameSizeRatio,
+    VideoConfigTypeVP8TemporalBitRateFrameRate,
 
     VideoParamsConfigExtension
 };
@@ -364,6 +366,7 @@
     bool syncEncMode;
     //CodedBuffer properties
     uint32_t codedBufNum;
+    uint32_t numberOfLayer;
 
     VideoParamsCommon() {
         type = VideoParamsTypeCommon;
@@ -388,6 +391,7 @@
         this->disableDeblocking = other.disableDeblocking;
         this->syncEncMode = other.syncEncMode;
         this->codedBufNum = other.codedBufNum;
+        this->numberOfLayer = other.numberOfLayer;
         return *this;
     }
 };
@@ -520,6 +524,17 @@
     bool isSupported;
 };
 
+struct VideoParamsTemporalLayerNumber : VideoParamConfigSet {
+
+    VideoParamsTemporalLayerNumber() {
+        type = VideoParamsTypeTemporalLayerNumber;
+        size = sizeof(VideoParamsTemporalLayerNumber);
+    }
+
+    int32_t numberOfLayer;
+};
+
+
 struct VideoConfigFrameRate : VideoParamConfigSet {
 
     VideoConfigFrameRate() {
@@ -684,6 +699,19 @@
     uint32_t max_frame_size_ratio;
 };
 
+struct VideoConfigVP8TemporalBitRateFrameRate : VideoParamConfigSet {
+
+    VideoConfigVP8TemporalBitRateFrameRate() {
+        type = VideoConfigTypeVP8TemporalBitRateFrameRate;
+        size = sizeof(VideoConfigVP8TemporalBitRateFrameRate);
+    }
+
+    uint32_t layerID;
+    uint32_t bitRate;
+    uint32_t frameRate;
+};
+
+
 
 
 #endif /*  __VIDEO_ENCODER_DEF_H__ */
diff --git a/videoencoder/VideoEncoderVP8.cpp b/videoencoder/VideoEncoderVP8.cpp
index 45655bd..4892cf0 100644
--- a/videoencoder/VideoEncoderVP8.cpp
+++ b/videoencoder/VideoEncoderVP8.cpp
@@ -44,6 +44,16 @@
         mVideoConfigVP8ReferenceFrame.refresh_golden_frame = 1;
         mVideoConfigVP8ReferenceFrame.refresh_alternate_frame = 1;
 
+        mVideoConfigVP8TemporalBitRateFrameRate[0].bitRate = 0;
+        mVideoConfigVP8TemporalBitRateFrameRate[0].frameRate = 0;
+        mVideoConfigVP8TemporalBitRateFrameRate[0].layerID = 0;
+        mVideoConfigVP8TemporalBitRateFrameRate[1].bitRate = 0;
+        mVideoConfigVP8TemporalBitRateFrameRate[1].frameRate = 0;
+        mVideoConfigVP8TemporalBitRateFrameRate[1].layerID = 0;
+        mVideoConfigVP8TemporalBitRateFrameRate[2].bitRate = 0;
+        mVideoConfigVP8TemporalBitRateFrameRate[2].frameRate = 0;
+        mVideoConfigVP8TemporalBitRateFrameRate[2].layerID = 0;
+
         mComParams.profile = VAProfileVP8Version0_3;
 }
 
@@ -116,13 +126,13 @@
     CHECK_VA_STATUS_RETURN("vaRenderPicture");
 
     LOG_V( "End\n");
-	return ret;
+    return ret;
 }
 
 Encode_Status VideoEncoderVP8::renderRCParams(void)
 {
     VABufferID rc_param_buf;
-	VAStatus vaStatus = VA_STATUS_SUCCESS;
+    VAStatus vaStatus = VA_STATUS_SUCCESS;
     VAEncMiscParameterBuffer *misc_param;
     VAEncMiscParameterRateControl *misc_rate_ctrl;
 
@@ -172,6 +182,7 @@
     misc_framerate = (VAEncMiscParameterFrameRate *)misc_param->data;
     memset(misc_framerate, 0, sizeof(*misc_framerate));
     misc_framerate->framerate = (unsigned int) (frameRateNum + frameRateDenom /2) / frameRateDenom;
+
     vaUnmapBuffer(mVADisplay, framerate_param_buf);
 
     vaStatus = vaRenderPicture(mVADisplay,mVAContext, &framerate_param_buf, 1);
@@ -237,6 +248,69 @@
     return 0;
 }
 
+Encode_Status VideoEncoderVP8::renderMultiTemporalBitRateFrameRate(void)
+{
+    VABufferID rc_param_buf;
+    VABufferID framerate_param_buf;
+    VAStatus vaStatus = VA_STATUS_SUCCESS;
+    VAEncMiscParameterBuffer *misc_param;
+    VAEncMiscParameterRateControl *misc_rate_ctrl;
+    VAEncMiscParameterFrameRate *misc_framerate;
+
+    int i;
+
+    vaStatus = vaCreateBuffer(mVADisplay, mVAContext,
+			      VAEncMiscParameterBufferType,
+                              sizeof(VAEncMiscParameterBuffer) + sizeof(VAEncMiscParameterRateControl),
+                              1,NULL,&rc_param_buf);
+
+    CHECK_VA_STATUS_RETURN("vaCreateBuffer");
+
+    for(i=0;i<mComParams.numberOfLayer;i++)
+    {
+        vaMapBuffer(mVADisplay, rc_param_buf,(void **)&misc_param);
+
+	misc_param->type = VAEncMiscParameterTypeRateControl;
+        misc_rate_ctrl = (VAEncMiscParameterRateControl *)misc_param->data;
+        memset(misc_rate_ctrl, 0, sizeof(*misc_rate_ctrl));
+        misc_rate_ctrl->bits_per_second = mVideoConfigVP8TemporalBitRateFrameRate[i].bitRate;
+        misc_rate_ctrl->rc_flags.bits.temporal_id = 0;
+        misc_rate_ctrl->target_percentage = 100;
+        misc_rate_ctrl->window_size = 1000;
+        misc_rate_ctrl->initial_qp = mVideoParamsVP8.init_qp;
+        misc_rate_ctrl->min_qp = mVideoParamsVP8.min_qp;
+        misc_rate_ctrl->basic_unit_size = 0;
+        misc_rate_ctrl->max_qp = mVideoParamsVP8.max_qp;
+        vaUnmapBuffer(mVADisplay, rc_param_buf);
+
+        vaStatus = vaRenderPicture(mVADisplay,mVAContext, &rc_param_buf, 1);
+    }
+
+    vaStatus = vaCreateBuffer(mVADisplay, mVAContext,
+                              VAEncMiscParameterBufferType,
+                              sizeof(VAEncMiscParameterBuffer) + sizeof(VAEncMiscParameterFrameRate),
+                              1,NULL,&framerate_param_buf);
+    CHECK_VA_STATUS_RETURN("vaCreateBuffer");
+
+    for(i=0;i<mComParams.numberOfLayer;i++)
+    {
+	vaMapBuffer(mVADisplay, framerate_param_buf,(void **)&misc_param);
+	misc_param->type = VAEncMiscParameterTypeFrameRate;
+	misc_framerate = (VAEncMiscParameterFrameRate *)misc_param->data;
+	memset(misc_framerate, 0, sizeof(*misc_framerate));
+	misc_framerate->framerate_flags.bits.temporal_id = i;
+	misc_framerate->framerate = mVideoConfigVP8TemporalBitRateFrameRate[i].frameRate;
+
+        vaUnmapBuffer(mVADisplay, framerate_param_buf);
+
+	vaStatus = vaRenderPicture(mVADisplay,mVAContext, &framerate_param_buf, 1);
+    }
+
+    CHECK_VA_STATUS_RETURN("vaRenderPicture");;
+
+    return 0;
+}
+
 Encode_Status VideoEncoderVP8::sendEncodeCommand(EncodeTask *task) {
 
     Encode_Status ret = ENCODE_SUCCESS;
@@ -272,6 +346,13 @@
         mRenderMaxFrameSize = false;
     }
 
+    if (mRenderMultiTemporal) {
+        ret = renderMultiTemporalBitRateFrameRate();
+        CHECK_ENCODE_STATUS_RETURN("renderMultiTemporalBitRateFrameRate");
+
+        mRenderMultiTemporal = false;
+    }
+
     ret = renderPictureParams(task);
     CHECK_ENCODE_STATUS_RETURN("renderPictureParams");
 
@@ -308,6 +389,7 @@
 
 Encode_Status VideoEncoderVP8::derivedGetConfig(VideoParamConfigSet *videoEncConfig) {
 
+		int layer_id;
         CHECK_NULL_RETURN_IFFAIL(videoEncConfig);
 
         switch (videoEncConfig->type)
@@ -351,6 +433,20 @@
                 }
                 break;
 
+		case VideoConfigTypeVP8TemporalBitRateFrameRate:{
+		        VideoConfigVP8TemporalBitRateFrameRate *encConfigVP8TemporalBitRateFrameRate =
+			        reinterpret_cast<VideoConfigVP8TemporalBitRateFrameRate*>(videoEncConfig);
+
+			if(encConfigVP8TemporalBitRateFrameRate->size != sizeof(VideoConfigVP8TemporalBitRateFrameRate)) {
+			        return ENCODE_INVALID_PARAMS;
+			}
+			layer_id = encConfigVP8TemporalBitRateFrameRate->layerID % 3;
+			encConfigVP8TemporalBitRateFrameRate->bitRate= mVideoConfigVP8TemporalBitRateFrameRate[layer_id].bitRate;
+		        encConfigVP8TemporalBitRateFrameRate->frameRate = mVideoConfigVP8TemporalBitRateFrameRate[layer_id].frameRate;
+		}
+	        break;
+
+
                 default: {
                    LOG_E ("Invalid Config Type");
                    break;
@@ -362,6 +458,7 @@
 
 Encode_Status VideoEncoderVP8::derivedSetConfig(VideoParamConfigSet *videoEncConfig) {
 
+        int layer_id;
         CHECK_NULL_RETURN_IFFAIL(videoEncConfig);
 
         //LOGE ("%s begin",__func__);
@@ -406,6 +503,21 @@
 		}
                 break;
 
+		case VideoConfigTypeVP8TemporalBitRateFrameRate:{
+		        VideoConfigVP8TemporalBitRateFrameRate *encConfigVP8TemporalBitRateFrameRate =
+                                reinterpret_cast<VideoConfigVP8TemporalBitRateFrameRate*>(videoEncConfig);
+
+			if (encConfigVP8TemporalBitRateFrameRate->size != sizeof(VideoConfigVP8TemporalBitRateFrameRate)) {
+			        return ENCODE_INVALID_PARAMS;
+			}
+			layer_id = encConfigVP8TemporalBitRateFrameRate->layerID % 3;
+			mVideoConfigVP8TemporalBitRateFrameRate[layer_id].layerID = layer_id;
+			mVideoConfigVP8TemporalBitRateFrameRate[layer_id].bitRate = encConfigVP8TemporalBitRateFrameRate->bitRate;
+			mVideoConfigVP8TemporalBitRateFrameRate[layer_id].frameRate = encConfigVP8TemporalBitRateFrameRate->frameRate;
+			mRenderMultiTemporal = true;
+		}
+		break;
+
                 default: {
             LOG_E ("Invalid Config Type");
             break;
diff --git a/videoencoder/VideoEncoderVP8.h b/videoencoder/VideoEncoderVP8.h
index 60ddca8..6a036f7 100644
--- a/videoencoder/VideoEncoderVP8.h
+++ b/videoencoder/VideoEncoderVP8.h
@@ -39,11 +39,13 @@
 	Encode_Status renderHRDParams(void);
 	Encode_Status renderFrameRateParams(void);
 	Encode_Status renderMaxFrameSizeParams(void);
+        Encode_Status renderMultiTemporalBitRateFrameRate(void);
 
 
 	VideoConfigVP8 mVideoConfigVP8;
 	VideoParamsVP8 mVideoParamsVP8;
 	VideoConfigVP8ReferenceFrame mVideoConfigVP8ReferenceFrame;
+	VideoConfigVP8TemporalBitRateFrameRate mVideoConfigVP8TemporalBitRateFrameRate[3];
 };
 
 #endif /* __VIDEO_ENCODER_VP8_H__ */