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__ */