Revert "initial version for MRFLD HiP support"
BZ: 76823
This reverts commit fc61070b3ace2bfeed85908672a41b0258fda363.
This reverts patch http://android.intel.com:8080/#/c/71392/
Change-Id: I113db91ee644d1ee8b0b4cb21f9c0ded74a9037f
Orig-Change-Id: I8aeb006ec09d10379707c412df21b5a1d2426d17
Reviewed-on: http://android.intel.com:8080/86747
Reviewed-by: Gozalvez Herrero, Juan AntonioX <juan.antoniox.gozalvez.herrero@intel.com>
Tested-by: Gozalvez Herrero, Juan AntonioX <juan.antoniox.gozalvez.herrero@intel.com>
Reviewed-by: cactus <cactus@intel.com>
Tested-by: cactus <cactus@intel.com>
diff --git a/test/Android.mk b/test/Android.mk
index abded5d..2f4d6a8 100644
--- a/test/Android.mk
+++ b/test/Android.mk
@@ -45,10 +45,6 @@
libva-android \
libva-tpi \
libgui \
- libui \
- libutils \
- libcutils \
- libhardware \
libbinder
LOCAL_MODULE_TAGS := optional
diff --git a/test/mix_encoder.cpp b/test/mix_encoder.cpp
index 4662947..464b759 100644
--- a/test/mix_encoder.cpp
+++ b/test/mix_encoder.cpp
@@ -257,7 +257,7 @@
memset(&tmpStoreMetaDataInBuffers,0x00,sizeof(VideoParamsStoreMetaDataInBuffers));
gVideoEncoder->getParameters(&tmpStoreMetaDataInBuffers);
gVideoEncoder->setParameters(&tmpStoreMetaDataInBuffers);
-#if 0
+
VideoParamsUpstreamBuffer tmpVideoParamsUpstreamBuffer;
tmpVideoParamsUpstreamBuffer.bufCnt = 0;
gVideoEncoder->setParameters(&tmpVideoParamsUpstreamBuffer);
@@ -275,7 +275,7 @@
VideoParamsUsrptrBuffer tmpVideoParamsUsrptrBuffer;
tmpVideoParamsUsrptrBuffer.width = 0;
gVideoEncoder->getParameters(&tmpVideoParamsUsrptrBuffer);
-#endif
+
//---------------------add for libmix encode code coverage test
// VideoEncodeBase.cpp file setConfig && getConfig code coverage test
// only for VCM mode
@@ -346,9 +346,6 @@
// for VideoConfigTypeAVCIntraPeriod derivedSetConfig && derivedGetConfig
VideoConfigAVCIntraPeriod configAVCIntraPeriod;
gVideoEncoder->getConfig(&configAVCIntraPeriod);
- configAVCIntraPeriod.ipPeriod = 1;
- configAVCIntraPeriod.intraPeriod = 30;
- configAVCIntraPeriod.idrInterval = 1;
gVideoEncoder->setConfig(&configAVCIntraPeriod);
VideoConfigTypeIDRReq tmpVideoConfigTypeIDRReq;
gVideoEncoder->setConfig(&tmpVideoConfigTypeIDRReq);
@@ -992,24 +989,30 @@
InBuf.data = data;
InBuf.size = size;
InBuf.bufAvailable = true;
- InBuf.type = FTYPE_UNKNOWN;
- InBuf.flag = 0;
ret = gVideoEncoder->encode(&InBuf);
CHECK_ENCODE_STATUS("encode");
- if (i > 0) {
ret = gVideoEncoder->getOutput(&OutBuf);
CHECK_ENCODE_STATUS("getOutput");
-// printf("OutBuf.dataSize = %d, flag=0x%08x .........\n", OutBuf.dataSize, OutBuf.flag);
+ CHECK_ENCODE_STATUS_RETURN("getOutput");
+ // printf("OutBuf.dataSize = %d .........\n", OutBuf.dataSize);
fwrite(OutBuf.data, 1, OutBuf.dataSize, file);
- }
+
printf("Encoding %d Frames \r", i+1);
fflush(stdout);
}
- ret = gVideoEncoder->getOutput(&OutBuf);
fclose(file);
+ VideoStatistics stat;
+ if (gVideoEncoder->getStatistics(&stat) == ENCODE_SUCCESS)
+ {
+ printf("\nVideoStatistics\n");
+ printf("Encoded %d frames, Skip %d frames, encode time: average( %d us), max( %d us/Frame %d), min( %d us/Frame %d)\n", \
+ stat.total_frames, stat.skipped_frames, stat.average_encode_time, stat.max_encode_time, stat.max_encode_frame, \
+ stat.min_encode_time, stat.min_encode_frame );
+ }
+
gVideoEncoder->stop();
releaseVideoEncoder(gVideoEncoder);
gVideoEncoder = NULL;
diff --git a/videoencoder/Android.mk b/videoencoder/Android.mk
index 0b13e7e..7c8314a 100644
--- a/videoencoder/Android.mk
+++ b/videoencoder/Android.mk
@@ -2,6 +2,7 @@
include $(CLEAR_VARS)
#VIDEO_ENC_LOG_ENABLE := true
+#VIDEO_ENC_STATISTICS_ENABLE := true
LOCAL_SRC_FILES := \
VideoEncoderBase.cpp \
@@ -15,13 +16,11 @@
LOCAL_C_INCLUDES := \
$(LOCAL_PATH) \
$(TARGET_OUT_HEADERS)/libva \
- $(TOPDIR)/frameworks/native/include \
#LOCAL_LDLIBS += -lpthread
LOCAL_SHARED_LIBRARIES := \
libcutils \
- libutils \
libva \
libva-android \
libva-tpi \
diff --git a/videoencoder/VideoEncoderAVC.cpp b/videoencoder/VideoEncoderAVC.cpp
index bf88da7..c4bf805 100644
--- a/videoencoder/VideoEncoderAVC.cpp
+++ b/videoencoder/VideoEncoderAVC.cpp
@@ -20,7 +20,6 @@
mVideoParamsAVC.sliceNum.iSliceNum = 2;
mVideoParamsAVC.sliceNum.pSliceNum = 2;
mVideoParamsAVC.idrInterval = 2;
- mVideoParamsAVC.ipPeriod = 1;
mVideoParamsAVC.maxSliceSize = 0;
mVideoParamsAVC.delimiterType = AVC_DELIMITER_ANNEXB;
mSliceNum = 2;
@@ -95,7 +94,6 @@
}
mVideoParamsAVC.idrInterval = configAVCIntraPeriod->idrInterval;
- mVideoParamsAVC.ipPeriod = configAVCIntraPeriod->ipPeriod;
mComParams.intraPeriod = configAVCIntraPeriod->intraPeriod;
mNewHeader = true;
break;
@@ -156,7 +154,6 @@
configAVCIntraPeriod->idrInterval = mVideoParamsAVC.idrInterval;
configAVCIntraPeriod->intraPeriod = mComParams.intraPeriod;
- configAVCIntraPeriod->ipPeriod = mVideoParamsAVC.ipPeriod;
break;
}
@@ -195,68 +192,30 @@
return ENCODE_SUCCESS;
}
-Encode_Status VideoEncoderAVC::updateFrameInfo(EncodeTask* task) {
- uint32_t idrPeroid = mComParams.intraPeriod * mVideoParamsAVC.idrInterval;
- FrameType frametype;
- uint32_t frame_num = mFrameNum;
-
- if (mVideoParamsAVC.idrInterval != 0) {
- if(mVideoParamsAVC.ipPeriod > 1)
- frame_num = frame_num % (idrPeroid + 1);
- else if(mComParams.intraPeriod != 0)
- frame_num = frame_num % idrPeroid ;
- }
-
- if(frame_num ==0){
- frametype = FTYPE_IDR;
- }else if(mComParams.intraPeriod ==0)
- // only I frame need intraPeriod=idrInterval=ipPeriod=0
- frametype = FTYPE_I;
- else if(mVideoParamsAVC.ipPeriod == 1){ // no B frame
- if(mComParams.intraPeriod != 0 && (frame_num > 1) &&((frame_num -1)%mComParams.intraPeriod == 0))
- frametype = FTYPE_I;
- else
- frametype = FTYPE_P;
- } else {
- if(mComParams.intraPeriod != 0 &&((frame_num-1)%mComParams.intraPeriod == 0)&&(frame_num >mComParams.intraPeriod))
- frametype = FTYPE_I;
- else{
- frame_num = frame_num%mComParams.intraPeriod;
- if(frame_num == 0)
- frametype = FTYPE_B;
- else if((frame_num-1)%mVideoParamsAVC.ipPeriod == 0)
- frametype = FTYPE_P;
- else
- frametype = FTYPE_B;
- }
- }
-
- if (frametype == FTYPE_IDR || frametype == FTYPE_I)
- task->flag |= ENCODE_BUFFERFLAG_SYNCFRAME;
-
- if (frametype != task->type) {
- const char* FrameTypeStr[10] = {"UNKNOWN", "I", "P", "B", "SI", "SP", "EI", "EP", "S", "IDR"};
- if ((uint32_t) task->type < 9)
- LOG_V("libMIX thinks it is %s Frame, the input is %s Frame", FrameTypeStr[frametype], FrameTypeStr[task->type]);
- else
- LOG_V("Wrong Frame type %d, type may not be initialized ?\n", task->type);
- }
-
-//temparily comment out to avoid uninitialize error
-// if (task->type == FTYPE_UNKNOWN || (uint32_t) task->type > 9)
- task->type = frametype;
-
- return ENCODE_SUCCESS;
-}
-
-Encode_Status VideoEncoderAVC::getExtFormatOutput(VideoEncOutputBuffer *outBuffer) {
+Encode_Status VideoEncoderAVC::getOutput(VideoEncOutputBuffer *outBuffer) {
Encode_Status ret = ENCODE_SUCCESS;
VAStatus vaStatus = VA_STATUS_SUCCESS;
+ bool useLocalBuffer = false;
+ uint32_t idrPeroid = mComParams.intraPeriod * mVideoParamsAVC.idrInterval;
LOG_V("Begin\n");
+ CHECK_NULL_RETURN_IFFAIL(outBuffer);
+
+ setKeyFrame(idrPeroid);
+
+ // prepare for output, map the coded buffer
+ ret = VideoEncoderBase::prepareForOutput(outBuffer, &useLocalBuffer);
+ CHECK_ENCODE_STATUS_CLEANUP("prepareForOutput");
switch (outBuffer->format) {
+ case OUTPUT_EVERYTHING:
+ case OUTPUT_FRAME_DATA: {
+ // Output whatever we have
+ ret = VideoEncoderBase::outputAllData(outBuffer);
+ CHECK_ENCODE_STATUS_CLEANUP("outputAllData");
+ break;
+ }
case OUTPUT_CODEC_DATA: {
// Output the codec data
ret = outputCodecData(outBuffer);
@@ -292,10 +251,26 @@
LOG_I("out size is = %d\n", outBuffer->dataSize);
+ // cleanup, unmap the coded buffer if all
+ // data has been copied out
+ ret = VideoEncoderBase::cleanupForOutput();
CLEAN_UP:
+ if (ret < ENCODE_SUCCESS) {
+ if (outBuffer->data && (useLocalBuffer == true)) {
+ delete[] outBuffer->data;
+ outBuffer->data = NULL;
+ useLocalBuffer = false;
+ }
+ // error happens, unmap the buffer
+ if (mCodedBufferMapped) {
+ vaStatus = vaUnmapBuffer(mVADisplay, mOutCodedBuffer);
+ mCodedBufferMapped = false;
+ mCurSegment = NULL;
+ }
+ }
LOG_V("End\n");
return ret;
}
@@ -506,6 +481,7 @@
mOffsetInSeg += (nalSize + nalOffset);
outBuffer->dataSize = sizeToBeCopied;
outBuffer->flag |= ENCODE_BUFFERFLAG_PARTIALFRAME;
+ if (mKeyFrame) outBuffer->flag |= ENCODE_BUFFERFLAG_SYNCFRAME;
outBuffer->remainingSize = 0;
} else {
// if nothing to be copied out, set flag to invalid
@@ -524,6 +500,7 @@
} else {
LOG_V("End of stream\n");
outBuffer->flag |= ENCODE_BUFFERFLAG_ENDOFFRAME;
+ if (mKeyFrame) outBuffer->flag |= ENCODE_BUFFERFLAG_SYNCFRAME;
mCurSegment = NULL;
}
}
@@ -577,6 +554,7 @@
// so the remainingSize size may larger than the remaining data size
outBuffer->remainingSize = mTotalSize - mTotalSizeCopied + 100;
outBuffer->flag |= ENCODE_BUFFERFLAG_PARTIALFRAME;
+ if (mKeyFrame) outBuffer->flag |= ENCODE_BUFFERFLAG_SYNCFRAME;
LOG_E("Buffer size too small\n");
return ENCODE_BUFFER_TOO_SMALL;
}
@@ -591,6 +569,7 @@
outBuffer->dataSize = sizeCopiedHere;
outBuffer->remainingSize = 0;
outBuffer->flag |= ENCODE_BUFFERFLAG_ENDOFFRAME;
+ if (mKeyFrame) outBuffer->flag |= ENCODE_BUFFERFLAG_SYNCFRAME;
mCurSegment = NULL;
break;
}
@@ -600,7 +579,7 @@
return ENCODE_SUCCESS;
}
-Encode_Status VideoEncoderAVC::sendEncodeCommand(EncodeTask *task) {
+Encode_Status VideoEncoderAVC::sendEncodeCommand(void) {
Encode_Status ret = ENCODE_SUCCESS;
LOG_V( "Begin\n");
@@ -613,7 +592,7 @@
CHECK_ENCODE_STATUS_RETURN("renderHrd");
}
- ret = renderSequenceParams(task);
+ ret = renderSequenceParams();
CHECK_ENCODE_STATUS_RETURN("renderSequenceParams");
mNewHeader = false; //Set to require new header filed to false
}
@@ -649,10 +628,10 @@
mRenderFrameRate = false;
}
- ret = renderPictureParams(task);
+ ret = renderPictureParams();
CHECK_ENCODE_STATUS_RETURN("renderPictureParams");
- ret = renderSliceParams(task);
+ ret = renderSliceParams();
CHECK_ENCODE_STATUS_RETURN("renderSliceParams");
LOG_V( "End\n");
@@ -766,7 +745,7 @@
return level;
}
-Encode_Status VideoEncoderAVC::renderSequenceParams(EncodeTask *task) {
+Encode_Status VideoEncoderAVC::renderSequenceParams() {
VAStatus vaStatus = VA_STATUS_SUCCESS;
VAEncSequenceParameterBufferH264 avcSeqParams = {};
@@ -788,7 +767,7 @@
CHECK_VA_STATUS_RETURN("vaCreateBuffer");
vaStatus = vaMapBuffer(mVADisplay, mRcParamBuf, (void **)&miscEncRCParamBuf);
CHECK_VA_STATUS_RETURN("vaMapBuffer");
-
+
vaStatus = vaCreateBuffer(mVADisplay, mVAContext,
VAEncMiscParameterBufferType,
sizeof (VAEncMiscParameterBuffer) + sizeof (VAEncMiscParameterFrameRate),
@@ -797,7 +776,7 @@
CHECK_VA_STATUS_RETURN("vaCreateBuffer");
vaStatus = vaMapBuffer(mVADisplay, mFrameRateParamBuf, (void **)&miscEncFrameRateParamBuf);
CHECK_VA_STATUS_RETURN("vaMapBuffer");
-
+
miscEncRCParamBuf->type = VAEncMiscParameterTypeRateControl;
rcMiscParam = (VAEncMiscParameterRateControl *)miscEncRCParamBuf->data;
miscEncFrameRateParamBuf->type = VAEncMiscParameterTypeFrameRate;
@@ -806,7 +785,6 @@
// avcSeqParams.level_idc = mLevel;
avcSeqParams.intra_period = mComParams.intraPeriod;
avcSeqParams.intra_idr_period = mVideoParamsAVC.idrInterval;
- avcSeqParams.ip_period = mVideoParamsAVC.ipPeriod;
avcSeqParams.picture_width_in_mbs = (mComParams.resolution.width + 15) / 16;
avcSeqParams.picture_height_in_mbs = (mComParams.resolution.height + 15) / 16;
@@ -844,9 +822,7 @@
}
// This is a temporary fix suggested by Binglin for bad encoding quality issue
- avcSeqParams.max_num_ref_frames = 1;
- if(avcSeqParams.ip_period > 1)
- avcSeqParams.max_num_ref_frames = 2;
+ avcSeqParams.max_num_ref_frames = 1; // TODO: We need a long term design for this field
LOG_V("===h264 sequence params===\n");
LOG_I( "seq_parameter_set_id = %d\n", (uint32_t)avcSeqParams.seq_parameter_set_id);
@@ -871,27 +847,28 @@
sizeof(avcSeqParams), 1, &avcSeqParams,
&mSeqParamBuf);
CHECK_VA_STATUS_RETURN("vaCreateBuffer");
+
+ vaStatus = vaRenderPicture(mVADisplay, mVAContext, &mRcParamBuf, 1);
+ CHECK_VA_STATUS_RETURN("vaRenderPicture");
vaStatus = vaRenderPicture(mVADisplay, mVAContext, &mFrameRateParamBuf, 1);
CHECK_VA_STATUS_RETURN("vaRenderPicture");
vaStatus = vaRenderPicture(mVADisplay, mVAContext, &mSeqParamBuf, 1);
CHECK_VA_STATUS_RETURN("vaRenderPicture");
- vaStatus = vaRenderPicture(mVADisplay, mVAContext, &mRcParamBuf, 1);
- CHECK_VA_STATUS_RETURN("vaRenderPicture");
return ENCODE_SUCCESS;
}
-Encode_Status VideoEncoderAVC::renderPictureParams(EncodeTask *task) {
+Encode_Status VideoEncoderAVC::renderPictureParams() {
VAStatus vaStatus = VA_STATUS_SUCCESS;
VAEncPictureParameterBufferH264 avcPicParams = {};
LOG_V( "Begin\n\n");
// set picture params for HW
- avcPicParams.ReferenceFrames[0].picture_id= task->ref_surface[0];
- avcPicParams.CurrPic.picture_id= task->rec_surface;
- avcPicParams.coded_buf = task->coded_buffer;
+ avcPicParams.ReferenceFrames[0].picture_id= mRefSurface;
+ avcPicParams.CurrPic.picture_id= mRecSurface;
+ avcPicParams.coded_buf = mVACodedBuffer [mCodedBufIndex];
//avcPicParams.picture_width = mComParams.resolution.width;
//avcPicParams.picture_height = mComParams.resolution.height;
avcPicParams.last_picture = 0;
@@ -899,7 +876,7 @@
LOG_V("======h264 picture params======\n");
LOG_I( "reference_picture = 0x%08x\n", avcPicParams.ReferenceFrames[0].picture_id);
LOG_I( "reconstructed_picture = 0x%08x\n", avcPicParams.CurrPic.picture_id);
-// LOG_I( "coded_buf_index = %d\n", mCodedBufIndex);
+ LOG_I( "coded_buf_index = %d\n", mCodedBufIndex);
LOG_I( "coded_buf = 0x%08x\n", avcPicParams.coded_buf);
//LOG_I( "picture_width = %d\n", avcPicParams.picture_width);
//LOG_I( "picture_height = %d\n\n", avcPicParams.picture_height);
@@ -920,7 +897,7 @@
}
-Encode_Status VideoEncoderAVC::renderSliceParams(EncodeTask *task) {
+Encode_Status VideoEncoderAVC::renderSliceParams() {
VAStatus vaStatus = VA_STATUS_SUCCESS;
@@ -929,8 +906,8 @@
uint32_t sliceHeightInMB = 0;
uint32_t maxSliceNum = 0;
uint32_t minSliceNum = 0;
- uint32_t actualSliceHeightInMB = 0;
- uint32_t startRowInMB = 0;
+ int actualSliceHeightInMB = 0;
+ int startRowInMB = 0;
uint32_t modulus = 0;
LOG_V( "Begin\n\n");
@@ -938,7 +915,7 @@
maxSliceNum = (mComParams.resolution.height + 15) / 16;
minSliceNum = 1;
- if (task->type == FTYPE_I || task->type == FTYPE_IDR) {
+ if (mIsIntra) {
sliceNum = mVideoParamsAVC.sliceNum.iSliceNum;
} else {
sliceNum = mVideoParamsAVC.sliceNum.pSliceNum;
@@ -961,18 +938,14 @@
vaStatus = vaCreateBuffer(
mVADisplay, mVAContext,
VAEncSliceParameterBufferType,
- sizeof(VAEncSliceParameterBufferH264),
+ sizeof(VAEncSliceParameterBuffer),
sliceNum, NULL,
&mSliceParamBuf);
CHECK_VA_STATUS_RETURN("vaCreateBuffer");
- VAEncSliceParameterBufferH264 *sliceParams, *currentSlice;
-
+ VAEncSliceParameterBuffer *sliceParams, *currentSlice;
vaStatus = vaMapBuffer(mVADisplay, mSliceParamBuf, (void **)&sliceParams);
CHECK_VA_STATUS_RETURN("vaMapBuffer");
- memset(sliceParams, 0 , sizeof(VAEncSliceParameterBufferH264));
- if(!sliceParams)
- return ENCODE_NULL_PTR;
currentSlice = sliceParams;
startRowInMB = 0;
@@ -983,29 +956,25 @@
actualSliceHeightInMB ++;
}
- // starting MB row number for this slice, suppose macroblock 16x16
- currentSlice->macroblock_address = startRowInMB * mComParams.resolution.width /16;
+ // starting MB row number for this slice
+ currentSlice->start_row_number = startRowInMB;
// slice height measured in MB
- currentSlice->num_macroblocks = actualSliceHeightInMB * mComParams.resolution.width /16;
- if(task->type == FTYPE_I||task->type == FTYPE_IDR)
- currentSlice->slice_type = 2;
- else if(task->type == FTYPE_P)
- currentSlice->slice_type = 0;
- else if(task->type == FTYPE_B)
- currentSlice->slice_type = 1;
- currentSlice->disable_deblocking_filter_idc = mComParams.disableDeblocking;
+ currentSlice->slice_height = actualSliceHeightInMB;
+ currentSlice->slice_flags.bits.is_intra = mIsIntra;
+ currentSlice->slice_flags.bits.disable_deblocking_filter_idc
+ = mComParams.disableDeblocking;
// This is a temporary fix suggested by Binglin for bad encoding quality issue
// TODO: We need a long term design for this field
- //currentSlice->slice_flags.bits.uses_long_term_ref = 0;
- //currentSlice->slice_flags.bits.is_long_term_ref = 0;
+ currentSlice->slice_flags.bits.uses_long_term_ref = 0;
+ currentSlice->slice_flags.bits.is_long_term_ref = 0;
LOG_V("======AVC slice params======\n");
LOG_I( "slice_index = %d\n", (int) sliceIndex);
- LOG_I( "macroblock_address = %d\n", (int) currentSlice->macroblock_address);
- LOG_I( "slice_height_in_mb = %d\n", (int) currentSlice->num_macroblocks);
- LOG_I( "slice.type = %d\n", (int) currentSlice->slice_type);
- LOG_I("disable_deblocking_filter_idc = %d\n\n", (int) currentSlice->disable_deblocking_filter_idc);
+ LOG_I( "start_row_number = %d\n", (int) currentSlice->start_row_number);
+ LOG_I( "slice_height_in_mb = %d\n", (int) currentSlice->slice_height);
+ LOG_I( "slice.is_intra = %d\n", (int) currentSlice->slice_flags.bits.is_intra);
+ LOG_I("disable_deblocking_filter_idc = %d\n\n", (int) currentSlice->slice_flags.bits.disable_deblocking_filter_idc);
startRowInMB += actualSliceHeightInMB;
}
diff --git a/videoencoder/VideoEncoderAVC.h b/videoencoder/VideoEncoderAVC.h
index 1248a3e..b57ef67 100644
--- a/videoencoder/VideoEncoderAVC.h
+++ b/videoencoder/VideoEncoderAVC.h
@@ -18,6 +18,7 @@
~VideoEncoderAVC() {};
virtual Encode_Status start();
+ virtual Encode_Status getOutput(VideoEncOutputBuffer *outBuffer);
virtual Encode_Status derivedSetParams(VideoParamConfigSet *videoEncParams);
virtual Encode_Status derivedGetParams(VideoParamConfigSet *videoEncParams);
@@ -26,9 +27,8 @@
protected:
- virtual Encode_Status sendEncodeCommand(EncodeTask *task);
- virtual Encode_Status getExtFormatOutput(VideoEncOutputBuffer *outBuffer);
- virtual Encode_Status updateFrameInfo(EncodeTask* task);
+ virtual Encode_Status sendEncodeCommand(void);
+
private:
// Local Methods
@@ -40,9 +40,9 @@
Encode_Status renderMaxSliceSize();
Encode_Status renderAIR();
- Encode_Status renderSequenceParams(EncodeTask *task);
- Encode_Status renderPictureParams(EncodeTask *task);
- Encode_Status renderSliceParams(EncodeTask *task);
+ Encode_Status renderSequenceParams();
+ Encode_Status renderPictureParams();
+ Encode_Status renderSliceParams();
int calcLevel(int numMbs);
public:
diff --git a/videoencoder/VideoEncoderBase.cpp b/videoencoder/VideoEncoderBase.cpp
index b52cbd1..55012d7 100644
--- a/videoencoder/VideoEncoderBase.cpp
+++ b/videoencoder/VideoEncoderBase.cpp
@@ -12,6 +12,7 @@
#include <va/va_tpi.h>
#include <va/va_android.h>
+#undef DUMP_SRC_DATA // To dump source data
// API declaration
extern "C" {
VAStatus vaLockSurface(VADisplay dpy,
@@ -32,36 +33,48 @@
);
}
VideoEncoderBase::VideoEncoderBase()
- :mInitialized(true)
- ,mStarted(false)
+ :mInitialized(false)
,mVADisplay(NULL)
- ,mVAContext(VA_INVALID_ID)
- ,mVAConfig(VA_INVALID_ID)
+ ,mVAContext(0)
+ ,mVAConfig(0)
,mVAEntrypoint(VAEntrypointEncSlice)
- ,mCodedBufSize(0)
+ ,mCurSegment(NULL)
+ ,mOffsetInSeg(0)
+ ,mTotalSize(0)
+ ,mTotalSizeCopied(0)
+ ,mForceKeyFrame(false)
,mNewHeader(false)
- //,mAutoReference(17 /*VAConfigAttribEncAutoReference*/)
+ ,mFirstFrame (true)
,mRenderMaxSliceSize(false)
,mRenderQP (false)
,mRenderAIR(false)
,mRenderFrameRate(false)
,mRenderBitRate(false)
,mRenderHrd(false)
+ ,mLastCodedBuffer(0)
+ ,mOutCodedBuffer(0)
,mSeqParamBuf(0)
,mPicParamBuf(0)
,mSliceParamBuf(0)
+ ,mSurfaces(NULL)
+ ,mSurfaceCnt(0)
+ ,mSrcSurfaceMapList(NULL)
+ ,mCurSurface(VA_INVALID_SURFACE)
,mRefSurface(VA_INVALID_SURFACE)
,mRecSurface(VA_INVALID_SURFACE)
+ ,mLastSurface(VA_INVALID_SURFACE)
+ ,mLastInputRawBuffer(NULL)
+ ,mEncodedFrames(0)
,mFrameNum(0)
+ ,mCodedBufSize(0)
+ ,mCodedBufIndex(0)
+ ,mPicSkipped(false)
+ ,mIsIntra(true)
,mSliceSizeOverflow(false)
- ,mCurOutputTask(NULL)
- ,mOutCodedBuffer(0)
,mCodedBufferMapped(false)
- ,mCurSegment(NULL)
- ,mOffsetInSeg(0)
- ,mTotalSize(0)
- ,mTotalSizeCopied(0)
- ,mFrameSkipped(false){
+ ,mDataCopiedOut(false)
+ ,mKeyFrame(true)
+ ,mInitCheck(true) {
VAStatus vaStatus = VA_STATUS_SUCCESS;
// here the display can be any value, use following one
@@ -71,6 +84,8 @@
int minorVersion = -1;
setDefaultParams();
+ mVACodedBuffer [0] = 0;
+ mVACodedBuffer [1] = 0;
LOG_V("vaGetDisplay \n");
mVADisplay = vaGetDisplay(&display);
@@ -82,17 +97,19 @@
LOG_V("vaInitialize \n");
if (vaStatus != VA_STATUS_SUCCESS) {
LOG_E( "Failed vaInitialize, vaStatus = %d\n", vaStatus);
- mInitialized = false;
+ mInitCheck = false;
}
+#ifdef VIDEO_ENC_STATISTICS_ENABLE
+ memset(&mVideoStat, 0, sizeof(VideoStatistics));
+ mVideoStat.min_encode_time = 0xFFFFFFFF;
+#endif
+
}
VideoEncoderBase::~VideoEncoderBase() {
VAStatus vaStatus = VA_STATUS_SUCCESS;
-
- stop();
-
vaStatus = vaTerminate(mVADisplay);
LOG_V( "vaTerminate\n");
if (vaStatus != VA_STATUS_SUCCESS) {
@@ -106,24 +123,32 @@
Encode_Status ret = ENCODE_SUCCESS;
VAStatus vaStatus = VA_STATUS_SUCCESS;
+ VASurfaceID surfaces[2];
+ int32_t index = -1;
+ SurfaceMap *map = mSrcSurfaceMapList;
+ uint32_t stride_aligned = 0;
+ uint32_t height_aligned = 0;
- if (!mInitialized) {
- LOGE("Encoder Initialize fail can not start");
- return ENCODE_DRIVER_FAIL;
- }
+ VAConfigAttrib vaAttrib[2];
+ uint32_t maxSize = 0;
- if (mStarted) {
+ if (mInitialized) {
LOG_V("Encoder has been started\n");
return ENCODE_ALREADY_INIT;
}
- VAConfigAttrib vaAttrib[2];
+ if (!mInitCheck) {
+ LOGE("Encoder Initialize fail can not start");
+ return ENCODE_DRIVER_FAIL;
+ }
+
vaAttrib[0].type = VAConfigAttribRTFormat;
vaAttrib[1].type = VAConfigAttribRateControl;
vaAttrib[0].value = VA_RT_FORMAT_YUV420;
vaAttrib[1].value = mComParams.rcMode;
LOG_V( "======VA Configuration======\n");
+
LOG_I( "profile = %d\n", mComParams.profile);
LOG_I( "mVAEntrypoint = %d\n", mVAEntrypoint);
LOG_I( "vaAttrib[0].type = %d\n", vaAttrib[0].type);
@@ -136,9 +161,10 @@
vaStatus = vaCreateConfig(
mVADisplay, mComParams.profile, mVAEntrypoint,
&vaAttrib[0], 2, &(mVAConfig));
- CHECK_VA_STATUS_RETURN("vaCreateConfig");
+ CHECK_VA_STATUS_GOTO_CLEANUP("vaCreateConfig");
if (mComParams.rcMode == VA_RC_VCM) {
+
// Following three features are only enabled in VCM mode
mRenderMaxSliceSize = true;
mRenderAIR = true;
@@ -147,10 +173,10 @@
LOG_V( "======VA Create Surfaces for Rec/Ref frames ======\n");
- VASurfaceID surfaces[2];
VASurfaceAttributeTPI attribute_tpi;
- uint32_t stride_aligned = ((mComParams.resolution.width + 15) / 16 ) * 16;
- uint32_t height_aligned = ((mComParams.resolution.height + 15) / 16 ) * 16;
+
+ stride_aligned = ((mComParams.resolution.width + 15) / 16 ) * 16;
+ height_aligned = ((mComParams.resolution.height + 15) / 16 ) * 16;
attribute_tpi.size = stride_aligned * height_aligned * 3 / 2;
attribute_tpi.luma_stride = stride_aligned;
@@ -162,218 +188,358 @@
attribute_tpi.pixel_format = VA_FOURCC_NV12;
attribute_tpi.type = VAExternalMemoryNULL;
-#ifndef AUTO_REFERENCE
- vaCreateSurfacesWithAttribute(mVADisplay, stride_aligned, height_aligned,
- VA_RT_FORMAT_YUV420, 2, surfaces, &attribute_tpi);
- CHECK_VA_STATUS_RETURN("vaCreateSurfacesWithAttribute");
- mRefSurface = surfaces[0];
- mRecSurface = surfaces[1];
-#endif
+ vaCreateSurfacesWithAttribute(mVADisplay, stride_aligned, height_aligned,
+ VA_RT_FORMAT_YUV420, 2, surfaces, &attribute_tpi);
+ CHECK_VA_STATUS_RETURN("vaCreateSurfacesWithAttribute");
- //Prepare all Surfaces to be added into Context
- uint32_t contextSurfaceCnt;
-#ifndef AUTO_REFERENCE
- contextSurfaceCnt = 2 + mSrcSurfaceMapList.size();
-#else
- contextSurfaceCnt = mSrcSurfaceMapList.size();
-#endif
+ mRefSurface = surfaces[0];
+ mRecSurface = surfaces[1];
- VASurfaceID *contextSurfaces = new VASurfaceID[contextSurfaceCnt];
- int32_t index = -1;
- SurfaceMap *map = NULL;
- android::List<SurfaceMap *>::iterator map_node;
-
- for(map_node = mSrcSurfaceMapList.begin(); map_node != mSrcSurfaceMapList.end(); map_node++)
- {
- contextSurfaces[++index] = (*map_node)->surface;
- (*map_node)->added = true;
+ //count total surface id already allocated
+ mSurfaceCnt = 2;
+
+ while(map) {
+ mSurfaceCnt ++;
+ map = map->next;
}
-#ifndef AUTO_REFERENCE
- contextSurfaces[++index] = mRefSurface;
- contextSurfaces[++index] = mRecSurface;
-#endif
+ mSurfaces = new VASurfaceID[mSurfaceCnt];
+ map = mSrcSurfaceMapList;
+ while(map) {
+ mSurfaces[++index] = map->surface;
+ map->added = true;
+ map = map->next;
+ }
+ mSurfaces[++index] = mRefSurface;
+ mSurfaces[++index] = mRecSurface;
//Initialize and save the VA context ID
LOG_V( "vaCreateContext\n");
+
vaStatus = vaCreateContext(mVADisplay, mVAConfig,
mComParams.resolution.width,
mComParams.resolution.height,
- 0, contextSurfaces, contextSurfaceCnt,
+ 0, mSurfaces, mSurfaceCnt,
&(mVAContext));
+ CHECK_VA_STATUS_GOTO_CLEANUP("vaCreateContext");
- delete [] contextSurfaces;
-
- CHECK_VA_STATUS_RETURN("vaCreateContext");
-
- LOG_I("Success to create libva context width %d, height %d\n",
+ LOG_I("Created libva context width %d, height %d\n",
mComParams.resolution.width, mComParams.resolution.height);
- uint32_t maxSize = 0;
ret = getMaxOutSize(&maxSize);
- CHECK_ENCODE_STATUS_RETURN("getMaxOutSize");
+ CHECK_ENCODE_STATUS_CLEANUP("getMaxOutSize");
- // Create CodedBuffer for output
- VABufferID VACodedBuffer;
+ // Create coded buffer for output
+ vaStatus = vaCreateBuffer(mVADisplay, mVAContext,
+ VAEncCodedBufferType,
+ mCodedBufSize,
+ 1, NULL,
+ &(mVACodedBuffer[0]));
- for(uint32_t i = 0; i <mComParams.codedBufNum; i++) {
- vaStatus = vaCreateBuffer(mVADisplay, mVAContext,
- VAEncCodedBufferType,
- mCodedBufSize,
- 1, NULL,
- &VACodedBuffer);
- CHECK_VA_STATUS_RETURN("vaCreateBuffer::VAEncCodedBufferType");
+ CHECK_VA_STATUS_GOTO_CLEANUP("vaCreateBuffer::VAEncCodedBufferType");
- mVACodedBufferList.push_back(VACodedBuffer);
+ // Create coded buffer for output
+ vaStatus = vaCreateBuffer(mVADisplay, mVAContext,
+ VAEncCodedBufferType,
+ mCodedBufSize,
+ 1, NULL,
+ &(mVACodedBuffer[1]));
+
+ CHECK_VA_STATUS_GOTO_CLEANUP("vaCreateBuffer::VAEncCodedBufferType");
+
+ mFirstFrame = true;
+
+CLEAN_UP:
+
+ if (ret == ENCODE_SUCCESS) {
+ mInitialized = true;
}
- if (ret == ENCODE_SUCCESS)
- mStarted = true;
-
LOG_V( "end\n");
return ret;
}
-Encode_Status VideoEncoderBase::encode(VideoEncRawBuffer *inBuffer, uint32_t timeout) {
+Encode_Status VideoEncoderBase::encode(VideoEncRawBuffer *inBuffer) {
- Encode_Status ret = ENCODE_SUCCESS;
- VAStatus vaStatus = VA_STATUS_SUCCESS;
-
- if (!mStarted) {
+ if (!mInitialized) {
LOG_E("Encoder has not initialized yet\n");
return ENCODE_NOT_INIT;
}
CHECK_NULL_RETURN_IFFAIL(inBuffer);
- //======Prepare all resources encoder needed=====.
+#ifdef VIDEO_ENC_STATISTICS_ENABLE
+ struct timespec ts1;
+ clock_gettime(CLOCK_MONOTONIC, &ts1);
- //Prepare encode vaSurface
- VASurfaceID sid = VA_INVALID_SURFACE;
- ret = manageSrcSurface(inBuffer, &sid);
- CHECK_ENCODE_STATUS_RETURN("manageSrcSurface");
-
- //Prepare CodedBuffer
- mCodedBuffer_Lock.lock();
- if(mVACodedBufferList.empty()){
- if(timeout == FUNC_BLOCK)
- mCodedBuffer_Cond.wait(mCodedBuffer_Lock);
- else if (timeout > 0)
- if(NO_ERROR != mEncodeTask_Cond.waitRelative(mCodedBuffer_Lock, 1000000*timeout)){
- mCodedBuffer_Lock.unlock();
- LOG_E("Time out wait for Coded buffer.\n");
- return ENCODE_DEVICE_BUSY;
- }
- else {//Nonblock
- mCodedBuffer_Lock.unlock();
- LOG_E("Coded buffer is not ready now.\n");
- return ENCODE_DEVICE_BUSY;
- }
- }
-
- if(mVACodedBufferList.empty()){
- mCodedBuffer_Lock.unlock();
- return ENCODE_DEVICE_BUSY;
- }
- VABufferID coded_buf = (VABufferID) *(mVACodedBufferList.begin());
- mVACodedBufferList.erase(mVACodedBufferList.begin());
- mCodedBuffer_Lock.unlock();
-
- LOG_V("CodedBuffer ID 0x%08x\n", coded_buf);
-
- //All resources are ready, start to assemble EncodeTask
- EncodeTask* task = new EncodeTask();
-
- task->completed = false;
- task->enc_surface = sid;
- task->coded_buffer = coded_buf;
- task->timestamp = inBuffer->timeStamp;
- task->in_data = inBuffer->data;
-
- //Setup frame info, like flag ( SYNCFRAME), frame number, type etc
- task->type = inBuffer->type;
- task->flag = inBuffer->flag;
- PrepareFrameInfo(task);
-
-#ifndef AUTO_REFERENCE
- //Setup ref /rec frames
- //TODO: B frame support, temporary use same logic
- switch (inBuffer->type) {
- case FTYPE_UNKNOWN:
- case FTYPE_IDR:
- case FTYPE_I:
- case FTYPE_P:
- {
- if(!mFrameSkipped) {
- VASurfaceID tmpSurface = mRecSurface;
- mRecSurface = mRefSurface;
- mRefSurface = tmpSurface;
- }
-
- task->ref_surface[0] = mRefSurface;
- task->ref_surface[1] = VA_INVALID_SURFACE;
- task->rec_surface = mRecSurface;
-
- break;
- }
- case FTYPE_B:
- default:
- LOG_V("Something wrong, B frame may not be supported in this mode\n");
- ret = ENCODE_NOT_SUPPORTED;
- goto CLEAN_UP;
- }
-#else
- task->ref_surface[0] = VA_INVALID_SURFACE;
- task->ref_surface[1] = VA_INVALID_SURFACE;
- task->rec_surface = VA_INVALID_SURFACE;
#endif
- //======Start Encoding, add task to list======
- LOG_V("Start Encoding vaSurface=0x%08x\n", task->enc_surface);
+ Encode_Status status;
- vaStatus = vaBeginPicture(mVADisplay, mVAContext, task->enc_surface);
- CHECK_VA_STATUS_GOTO_CLEANUP("vaBeginPicture");
+ if (mComParams.syncEncMode) {
+ LOG_I("Sync Enocde Mode, no optimization, no one frame delay\n");
+ status = syncEncode(inBuffer);
+ } else {
+ LOG_I("Async Enocde Mode, HW/SW works in parallel, introduce one frame delay\n");
+ status = asyncEncode(inBuffer);
+ }
- ret = sendEncodeCommand(task);
- CHECK_ENCODE_STATUS_CLEANUP("sendEncodeCommand");
+#ifdef VIDEO_ENC_STATISTICS_ENABLE
+ struct timespec ts2;
+ clock_gettime(CLOCK_MONOTONIC, &ts2);
- vaStatus = vaEndPicture(mVADisplay, mVAContext);
- CHECK_VA_STATUS_GOTO_CLEANUP("vaEndPicture");
+ uint32_t encode_time = (ts2.tv_sec - ts1.tv_sec) * 1000000 + (ts2.tv_nsec - ts1.tv_nsec) / 1000;
+ if (encode_time > mVideoStat.max_encode_time) {
+ mVideoStat.max_encode_time = encode_time;
+ mVideoStat.max_encode_frame = mFrameNum;
+ }
- LOG_V("Add Task %p into Encode Task list\n", task);
- mEncodeTask_Lock.lock();
- mEncodeTaskList.push_back(task);
- mEncodeTask_Cond.signal();
- mEncodeTask_Lock.unlock();
+ if (encode_time < mVideoStat.min_encode_time) {
+ mVideoStat.min_encode_time = encode_time;
+ mVideoStat.min_encode_frame = mFrameNum;
+ }
- mFrameNum ++;
+ mVideoStat.average_encode_time += encode_time;
+#endif
- LOG_V("encode return Success\n");
-
- return ENCODE_SUCCESS;
-
-CLEAN_UP:
-
- delete task;
- mCodedBuffer_Lock.lock();
- mVACodedBufferList.push_back(coded_buf); //push to CodedBuffer pool again since it is not used
- mCodedBuffer_Cond.signal();
- mCodedBuffer_Lock.unlock();
-
- LOG_V("encode return error=%x\n", ret);
-
- return ret;
+ return status;
}
-/*
- 1. Firstly check if one task is outputting data, if yes, continue outputting, if not try to get one from list.
- 2. Due to block/non-block/block with timeout 3 modes, if task is not completed, then sync surface, if yes,
- start output data
- 3. Use variable curoutputtask to record task which is getOutput() working on to avoid push again when get failure
- on non-block/block with timeout modes.
- 4. if complete all output data, curoutputtask should be set NULL
-*/
-Encode_Status VideoEncoderBase::getOutput(VideoEncOutputBuffer *outBuffer, uint32_t timeout) {
+Encode_Status VideoEncoderBase::asyncEncode(VideoEncRawBuffer *inBuffer) {
+
+ Encode_Status ret = ENCODE_SUCCESS;
+ VAStatus vaStatus = VA_STATUS_SUCCESS;
+ uint8_t *buf = NULL;
+
+ inBuffer->bufAvailable = false;
+ if (mNewHeader) mFrameNum = 0;
+
+ // current we use one surface for source data,
+ // one for reference and one for reconstructed
+ decideFrameType();
+ ret = manageSrcSurface(inBuffer);
+ CHECK_ENCODE_STATUS_RETURN("manageSrcSurface");
+
+ // Start encoding process
+ LOG_V( "vaBeginPicture\n");
+ LOG_I( "mVAContext = 0x%08x\n",(uint32_t) mVAContext);
+ LOG_I( "Surface = 0x%08x\n",(uint32_t) mCurSurface);
+ LOG_I( "mVADisplay = 0x%08x\n",(uint32_t)mVADisplay);
+
+#ifdef DUMP_SRC_DATA
+
+ if (mBufferMode == BUFFER_SHARING_SURFACE && mFirstFrame){
+
+ FILE *fp = fopen("/data/data/dump_encoder.yuv", "wb");
+ VAImage image;
+ uint8_t *usrptr = NULL;
+ uint32_t stride = 0;
+ uint32_t frameSize = 0;
+
+ vaStatus = vaDeriveImage(mVADisplay, mCurSurface, &image);
+ CHECK_VA_STATUS_RETURN("vaDeriveImage");
+
+ LOG_V( "vaDeriveImage Done\n");
+
+ frameSize = image.data_size;
+ stride = image.pitches[0];
+
+ LOG_I("Source Surface/Image information --- start ---- :");
+ LOG_I("surface = 0x%08x\n",(uint32_t)mCurFrame->surface);
+ LOG_I("image->pitches[0] = %d\n", image.pitches[0]);
+ LOG_I("image->pitches[1] = %d\n", image.pitches[1]);
+ LOG_I("image->offsets[0] = %d\n", image.offsets[0]);
+ LOG_I("image->offsets[1] = %d\n", image.offsets[1]);
+ LOG_I("image->num_planes = %d\n", image.num_planes);
+ LOG_I("image->width = %d\n", image.width);
+ LOG_I("image->height = %d\n", image.height);
+ LOG_I ("frameSize= %d\n", image.data_size);
+ LOG_I("Source Surface/Image information ----end ----");
+
+ vaStatus = vaMapBuffer(mVADisplay, image.buf, (void **) &usrptr);
+ CHECK_VA_STATUS_RETURN("vaMapBuffer");
+
+ fwrite(usrptr, frameSize, 1, fp);
+ fflush(fp);
+ fclose(fp);
+
+ vaStatus = vaUnmapBuffer(mVADisplay, image.buf);
+ CHECK_VA_STATUS_RETURN("vaUnmapBuffer");
+
+ vaStatus = vaDestroyImage(mVADisplay, image.image_id);
+ CHECK_VA_STATUS_RETURN("vaDestroyImage");
+ }
+#endif
+
+ vaStatus = vaBeginPicture(mVADisplay, mVAContext, mCurSurface);
+ CHECK_VA_STATUS_RETURN("vaBeginPicture");
+
+ ret = sendEncodeCommand();
+ CHECK_ENCODE_STATUS_RETURN("sendEncodeCommand");
+
+ vaStatus = vaEndPicture(mVADisplay, mVAContext);
+ CHECK_VA_STATUS_RETURN("vaEndPicture");
+
+ LOG_V( "vaEndPicture\n");
+
+ if (mFirstFrame) {
+ updateProperities();
+ decideFrameType();
+ }
+
+ LOG_I ("vaSyncSurface ID = 0x%08x\n", mLastSurface);
+ vaStatus = vaSyncSurface(mVADisplay, mLastSurface);
+ if (vaStatus != VA_STATUS_SUCCESS) {
+ LOG_W( "Failed vaSyncSurface\n");
+ }
+
+ mOutCodedBuffer = mLastCodedBuffer;
+
+ // Need map buffer before calling query surface below to get
+ // the right skip frame flag for current frame
+ // It is a requirement of video driver
+ vaStatus = vaMapBuffer (mVADisplay, mOutCodedBuffer, (void **)&buf);
+ vaStatus = vaUnmapBuffer(mVADisplay, mOutCodedBuffer);
+
+ if (mFirstFrame) {
+ vaStatus = vaBeginPicture(mVADisplay, mVAContext, mCurSurface);
+ CHECK_VA_STATUS_RETURN("vaBeginPicture");
+
+ ret = sendEncodeCommand();
+ CHECK_ENCODE_STATUS_RETURN("sendEncodeCommand");
+
+ vaStatus = vaEndPicture(mVADisplay, mVAContext);
+ CHECK_VA_STATUS_RETURN("vaEndPicture");
+
+ mKeyFrame = true;
+ }
+
+ // Query the status of last surface to check if its next frame is skipped
+ VASurfaceStatus vaSurfaceStatus;
+ vaStatus = vaQuerySurfaceStatus(mVADisplay, mLastSurface, &vaSurfaceStatus);
+ CHECK_VA_STATUS_RETURN("vaQuerySurfaceStatus");
+
+ mPicSkipped = vaSurfaceStatus & VASurfaceSkipped;
+
+#ifdef VIDEO_ENC_STATISTICS_ENABLE
+ if (mPicSkipped)
+ mVideoStat.skipped_frames ++;
+#endif
+
+ mLastSurface = VA_INVALID_SURFACE;
+ updateProperities();
+ mCurSurface = VA_INVALID_SURFACE;
+
+ if (mLastInputRawBuffer) mLastInputRawBuffer->bufAvailable = true;
+
+ LOG_V("ref the current inBuffer\n");
+
+ mLastInputRawBuffer = inBuffer;
+ mFirstFrame = false;
+
+ return ENCODE_SUCCESS;
+}
+
+Encode_Status VideoEncoderBase::syncEncode(VideoEncRawBuffer *inBuffer) {
+
+ Encode_Status ret = ENCODE_SUCCESS;
+ VAStatus vaStatus = VA_STATUS_SUCCESS;
+ uint8_t *buf = NULL;
+ VASurfaceID tmpSurface = VA_INVALID_SURFACE;
+
+ inBuffer->bufAvailable = false;
+ if (mNewHeader) mFrameNum = 0;
+
+ // current we use one surface for source data,
+ // one for reference and one for reconstructed
+ decideFrameType();
+ ret = manageSrcSurface(inBuffer);
+ CHECK_ENCODE_STATUS_RETURN("manageSrcSurface");
+
+ vaStatus = vaBeginPicture(mVADisplay, mVAContext, mCurSurface);
+ CHECK_VA_STATUS_RETURN("vaBeginPicture");
+
+ ret = sendEncodeCommand();
+ CHECK_ENCODE_STATUS_RETURN("sendEncodeCommand");
+
+ vaStatus = vaEndPicture(mVADisplay, mVAContext);
+ CHECK_VA_STATUS_RETURN("vaEndPicture");
+
+ LOG_I ("vaSyncSurface ID = 0x%08x\n", mCurSurface);
+ vaStatus = vaSyncSurface(mVADisplay, mCurSurface);
+ if (vaStatus != VA_STATUS_SUCCESS) {
+ LOG_W( "Failed vaSyncSurface\n");
+ }
+
+ mOutCodedBuffer = mVACodedBuffer[mCodedBufIndex];
+
+ // Need map buffer before calling query surface below to get
+ // the right skip frame flag for current frame
+ // It is a requirement of video driver
+ vaStatus = vaMapBuffer (mVADisplay, mOutCodedBuffer, (void **)&buf);
+ vaStatus = vaUnmapBuffer(mVADisplay, mOutCodedBuffer);
+
+ mPicSkipped = false;
+ if (!mFirstFrame) {
+ // Query the status of last surface to check if its next frame is skipped
+ VASurfaceStatus vaSurfaceStatus;
+ vaStatus = vaQuerySurfaceStatus(mVADisplay, mLastSurface, &vaSurfaceStatus);
+ CHECK_VA_STATUS_RETURN("vaQuerySurfaceStatus");
+ mPicSkipped = vaSurfaceStatus & VASurfaceSkipped;
+ }
+
+ mLastSurface = mCurSurface;
+ mCurSurface = VA_INVALID_SURFACE;
+
+ mEncodedFrames ++;
+ mFrameNum ++;
+
+ if (!mPicSkipped) {
+ tmpSurface = mRecSurface;
+ mRecSurface = mRefSurface;
+ mRefSurface = tmpSurface;
+ }
+
+#ifdef VIDEO_ENC_STATISTICS_ENABLE
+ if (mPicSkipped)
+ mVideoStat.skipped_frames ++;
+#endif
+
+ inBuffer->bufAvailable = true;
+ return ENCODE_SUCCESS;
+}
+
+void VideoEncoderBase::setKeyFrame(int32_t keyFramePeriod) {
+
+ // For first getOutput async mode, the mFrameNum already increased to 2, and of course is key frame
+ // frame 0 is already encoded and will be outputed here
+ // frame 1 is encoding now, frame 2 will be sent to encoder for next encode() call
+ if (!mComParams.syncEncMode) {
+ if (mFrameNum > 2) {
+ if (keyFramePeriod != 0 &&
+ (((mFrameNum - 2) % keyFramePeriod) == 0)) {
+ mKeyFrame = true;
+ } else {
+ mKeyFrame = false;
+ }
+ } else if (mFrameNum == 2) {
+ mKeyFrame = true;
+ }
+ } else {
+ if (mFrameNum > 1) {
+ if (keyFramePeriod != 0 &&
+ (((mFrameNum - 1) % keyFramePeriod) == 0)) {
+ mKeyFrame = true;
+ } else {
+ mKeyFrame = false;
+ }
+ } else if (mFrameNum == 1) {
+ mKeyFrame = true;
+ }
+ }
+}
+
+Encode_Status VideoEncoderBase::getOutput(VideoEncOutputBuffer *outBuffer) {
Encode_Status ret = ENCODE_SUCCESS;
VAStatus vaStatus = VA_STATUS_SUCCESS;
@@ -381,138 +547,56 @@
CHECK_NULL_RETURN_IFFAIL(outBuffer);
- if (mCurOutputTask == NULL) {
- mEncodeTask_Lock.lock();
- if(mEncodeTaskList.empty()) {
- LOG_V("getOutput CurrentTask is NULL\n");
- if(timeout == FUNC_BLOCK) {
- LOG_V("waiting for task....\n");
- mEncodeTask_Cond.wait(mEncodeTask_Lock);
- } else if (timeout > 0) {
- LOG_V("waiting for task in % ms....\n", timeout);
- if(NO_ERROR != mEncodeTask_Cond.waitRelative(mEncodeTask_Lock, 1000000*timeout)) {
- mEncodeTask_Lock.unlock();
- LOG_E("Time out wait for encode task.\n");
- return ENCODE_DATA_NOT_READY;
- }
- } else {//Nonblock
- mEncodeTask_Lock.unlock();
- return ENCODE_DATA_NOT_READY;
- }
- }
+ LOG_V("Begin\n");
- if(mEncodeTaskList.empty()){
- mEncodeTask_Lock.unlock();
- return ENCODE_DATA_NOT_READY;
- }
- mCurOutputTask = *(mEncodeTaskList.begin());
- mEncodeTaskList.erase(mEncodeTaskList.begin());
- mEncodeTask_Lock.unlock();
+ if (outBuffer->format != OUTPUT_EVERYTHING && outBuffer->format != OUTPUT_FRAME_DATA) {
+ LOG_E("Output buffer mode not supported\n");
+ goto CLEAN_UP;
}
- //sync/query/wait task if not completed
- if (mCurOutputTask->completed == false) {
- uint8_t *buf = NULL;
- VASurfaceStatus vaSurfaceStatus;
+ setKeyFrame(mComParams.intraPeriod);
- if (timeout == FUNC_BLOCK) {
- //block mode, direct sync surface to output data
-
- LOG_I ("block mode, vaSyncSurface ID = 0x%08x\n", mCurOutputTask->enc_surface);
- vaStatus = vaSyncSurface(mVADisplay, mCurOutputTask->enc_surface);
- CHECK_VA_STATUS_GOTO_CLEANUP("vaSyncSurface");
-
- mOutCodedBuffer = mCurOutputTask->coded_buffer;
-
- // Check frame skip
- // Need map buffer before calling query surface below to get the right skip frame flag for current frame
- // It is a requirement of video driver
- vaStatus = vaMapBuffer (mVADisplay, mOutCodedBuffer, (void **)&buf);
- vaStatus = vaUnmapBuffer(mVADisplay, mOutCodedBuffer);
-
- vaStatus = vaQuerySurfaceStatus(mVADisplay, mCurOutputTask->enc_surface, &vaSurfaceStatus);
- CHECK_VA_STATUS_RETURN("vaQuerySurfaceStatus");
- mFrameSkipped = vaSurfaceStatus & VASurfaceSkipped;
-
- mCurOutputTask->completed = true;
-
- } else {
- //For both block with timeout and non-block mode, query surface, if ready, output data
- LOG_I ("non-block mode, vaQuerySurfaceStatus ID = 0x%08x\n", mCurOutputTask->enc_surface);
-
- vaStatus = vaQuerySurfaceStatus(mVADisplay, mCurOutputTask->enc_surface, &vaSurfaceStatus);
- if (vaSurfaceStatus & VASurfaceReady) {
- mOutCodedBuffer = mCurOutputTask->coded_buffer;
- mFrameSkipped = vaSurfaceStatus & VASurfaceSkipped;
- mCurOutputTask->completed = true;
- //if need to call SyncSurface again ?
-
- } else {//not ready yet
- ret = ENCODE_DATA_NOT_READY;
- goto CLEAN_UP;
- }
-
- }
-
- }
-
- //start to output data
ret = prepareForOutput(outBuffer, &useLocalBuffer);
CHECK_ENCODE_STATUS_CLEANUP("prepareForOutput");
- //copy all flags to outBuffer
- outBuffer->flag = mCurOutputTask->flag;
- outBuffer->type = mCurOutputTask->type;
- outBuffer->timeStamp = mCurOutputTask->timestamp;
-
- if (outBuffer->format == OUTPUT_EVERYTHING || outBuffer->format == OUTPUT_FRAME_DATA) {
- ret = outputAllData(outBuffer);
- CHECK_ENCODE_STATUS_CLEANUP("outputAllData");
- }else {
- ret = getExtFormatOutput(outBuffer);
- CHECK_ENCODE_STATUS_CLEANUP("getExtFormatOutput");
- }
+ ret = outputAllData(outBuffer);
+ CHECK_ENCODE_STATUS_CLEANUP("outputAllData");
LOG_I("out size for this getOutput call = %d\n", outBuffer->dataSize);
ret = cleanupForOutput();
CHECK_ENCODE_STATUS_CLEANUP("cleanupForOutput");
- LOG_V("getOutput return Success, Frame skip is %d\n", mFrameSkipped);
-
- return ENCODE_SUCCESS;
-
CLEAN_UP:
- if (outBuffer->data && (useLocalBuffer == true)) {
- delete[] outBuffer->data;
- outBuffer->data = NULL;
- useLocalBuffer = false;
+ if (ret < ENCODE_SUCCESS) {
+ if (outBuffer->data && (useLocalBuffer == true)) {
+ delete[] outBuffer->data;
+ outBuffer->data = NULL;
+ useLocalBuffer = false;
+ }
+
+ if (mCodedBufferMapped) {
+ vaStatus = vaUnmapBuffer(mVADisplay, mOutCodedBuffer);
+ mCodedBufferMapped = false;
+ mCurSegment = NULL;
+ }
}
- if (mCodedBufferMapped) {
- vaStatus = vaUnmapBuffer(mVADisplay, mOutCodedBuffer);
- mCodedBufferMapped = false;
- mCurSegment = NULL;
- }
-
- delete mCurOutputTask;
- mCurOutputTask = NULL;
- mCodedBuffer_Lock.lock();
- mVACodedBufferList.push_back(mOutCodedBuffer);
- mCodedBuffer_Cond.signal();
- mCodedBuffer_Lock.unlock();
-
- LOG_V("getOutput return error=%x\n", ret);
+ LOG_V("End\n");
return ret;
}
+
void VideoEncoderBase::flush() {
LOG_V( "Begin\n");
// reset the properities
+ mEncodedFrames = 0;
mFrameNum = 0;
+ mPicSkipped = false;
+ mIsIntra = true;
LOG_V( "end\n");
}
@@ -522,69 +606,57 @@
VAStatus vaStatus = VA_STATUS_SUCCESS;
Encode_Status ret = ENCODE_SUCCESS;
SurfaceMap *map = NULL;
- EncodeTask *task = NULL;
LOG_V( "Begin\n");
+ if (mSurfaces) {
+ delete [] mSurfaces;
+ mSurfaces = NULL;
+ }
+
// It is possible that above pointers have been allocated
- // before we set mStarted to true
- if (!mStarted) {
+ // before we set mInitialized to true
+ if (!mInitialized) {
LOG_V("Encoder has been stopped\n");
return ENCODE_SUCCESS;
}
- mCodedBuffer_Lock.lock();
- mVACodedBufferList.clear();
- mCodedBuffer_Lock.unlock();
- mCodedBuffer_Cond.broadcast();
-
- //Delete all uncompleted tasks
- mEncodeTask_Lock.lock();
- while(! mEncodeTaskList.empty())
- {
- delete *mEncodeTaskList.begin();
- mEncodeTaskList.erase(mEncodeTaskList.begin());
- }
- mEncodeTask_Lock.unlock();
- mEncodeTask_Cond.broadcast();
-
- //Release Src Surface Buffer Map, destroy surface manually since it is not added into context
- LOG_V( "Rlease Src Surface Map\n");
- while(! mSrcSurfaceMapList.empty())
- {
- if (! (*mSrcSurfaceMapList.begin())->added) {
- LOG_V( "Rlease the Src Surface Buffer not added into vaContext\n");
- vaDestroySurfaces(mVADisplay, &((*mSrcSurfaceMapList.begin())->surface), 1);
- }
- delete (*mSrcSurfaceMapList.begin());
- mSrcSurfaceMapList.erase(mSrcSurfaceMapList.begin());
- }
-
LOG_V( "vaDestroyContext\n");
- if (mVAContext != VA_INVALID_ID) {
- vaStatus = vaDestroyContext(mVADisplay, mVAContext);
- CHECK_VA_STATUS_GOTO_CLEANUP("vaDestroyContext");
- }
+ vaStatus = vaDestroyContext(mVADisplay, mVAContext);
+ CHECK_VA_STATUS_GOTO_CLEANUP("vaDestroyContext");
LOG_V( "vaDestroyConfig\n");
- if (mVAConfig != VA_INVALID_ID) {
- vaStatus = vaDestroyConfig(mVADisplay, mVAConfig);
- CHECK_VA_STATUS_GOTO_CLEANUP("vaDestroyConfig");
+ vaStatus = vaDestroyConfig(mVADisplay, mVAConfig);
+ CHECK_VA_STATUS_GOTO_CLEANUP("vaDestroyConfig");
+
+ // Release Src Surface Buffer Map
+ LOG_V( "Rlease Src Surface Map\n");
+
+ map = mSrcSurfaceMapList;
+ while(map) {
+ if (! map->added) {
+ //destroy surface by itself
+ LOG_V( "Rlease Src Surface Buffer not added into vaContext\n");
+ vaDestroySurfaces(mVADisplay, &map->surface, 1);
+ }
+ SurfaceMap *tmp = map;
+ map = map->next;
+ delete tmp;
}
CLEAN_UP:
+ mInitialized = false;
- mStarted = false;
- mSliceSizeOverflow = false;
- mCurOutputTask= NULL;
- mOutCodedBuffer = 0;
- mCodedBufferMapped = false;
- mCurSegment = NULL;
- mOffsetInSeg =0;
- mTotalSize = 0;
- mTotalSizeCopied = 0;
- mFrameSkipped = false;
+#ifdef VIDEO_ENC_STATISTICS_ENABLE
+ LOG_V("Encoder Statistics:\n");
+ LOG_V(" %d frames Encoded, %d frames Skipped\n", mEncodedFrames, mVideoStat.skipped_frames);
+ LOG_V(" Encode time: Average(%d us), Max(%d us @Frame No.%d), Min(%d us @Frame No.%d)\n", \
+ mVideoStat.average_encode_time / mEncodedFrames, mVideoStat.max_encode_time, \
+ mVideoStat.max_encode_frame, mVideoStat.min_encode_time, mVideoStat.min_encode_frame);
+ memset(&mVideoStat, 0, sizeof(VideoStatistics));
+ mVideoStat.min_encode_time = 0xFFFFFFFF;
+#endif
LOG_V( "end\n");
return ret;
}
@@ -681,23 +753,13 @@
vaStatus = vaUnmapBuffer(mVADisplay, mOutCodedBuffer);
CHECK_VA_STATUS_RETURN("vaUnmapBuffer");
mCodedBufferMapped = false;
- mTotalSize = 0;
- mOffsetInSeg = 0;
- mTotalSizeCopied = 0;
-
- delete mCurOutputTask;
- mCurOutputTask = NULL;
- mCodedBuffer_Lock.lock();
- mVACodedBufferList.push_back(mOutCodedBuffer);
- mCodedBuffer_Cond.signal();
- mCodedBuffer_Lock.unlock();
-
- LOG_V("All data has been outputted, return CodedBuffer 0x%08x to pool\n", mOutCodedBuffer);
}
return ENCODE_SUCCESS;
}
-Encode_Status VideoEncoderBase::outputAllData(VideoEncOutputBuffer *outBuffer) {
+
+Encode_Status VideoEncoderBase::outputAllData(
+ VideoEncOutputBuffer *outBuffer) {
// Data size been copied for every single call
uint32_t sizeCopiedHere = 0;
@@ -732,6 +794,7 @@
outBuffer->dataSize = outBuffer->bufferSize;
outBuffer->remainingSize = mTotalSize - mTotalSizeCopied;
outBuffer->flag |= ENCODE_BUFFERFLAG_PARTIALFRAME;
+ if (mKeyFrame) outBuffer->flag |= ENCODE_BUFFERFLAG_SYNCFRAME;
return ENCODE_BUFFER_TOO_SMALL;
}
@@ -739,6 +802,7 @@
outBuffer->dataSize = sizeCopiedHere;
outBuffer->remainingSize = 0;
outBuffer->flag |= ENCODE_BUFFERFLAG_ENDOFFRAME;
+ if (mKeyFrame) outBuffer->flag |= ENCODE_BUFFERFLAG_SYNCFRAME;
mCurSegment = NULL;
return ENCODE_SUCCESS;
}
@@ -774,7 +838,6 @@
mComParams.airParams.airAuto = 1;
mComParams.disableDeblocking = 2;
mComParams.syncEncMode = false;
- mComParams.codedBufNum = 2;
mHrdParam.bufferSize = 0;
mHrdParam.initBufferFullness = 0;
@@ -789,7 +852,7 @@
CHECK_NULL_RETURN_IFFAIL(videoEncParams);
LOG_I("Config type = %d\n", (int)videoEncParams->type);
- if (mStarted) {
+ if (mInitialized) {
LOG_E("Encoder has been initialized, should use setConfig to change configurations\n");
return ENCODE_ALREADY_INIT;
}
@@ -799,11 +862,10 @@
VideoParamsCommon *paramsCommon =
reinterpret_cast <VideoParamsCommon *> (videoEncParams);
+
if (paramsCommon->size != sizeof (VideoParamsCommon)) {
return ENCODE_INVALID_PARAMS;
}
- if(paramsCommon->codedBufNum < 2)
- paramsCommon->codedBufNum =2;
mComParams = *paramsCommon;
break;
}
@@ -967,7 +1029,7 @@
// workaround
#if 0
- if (!mStarted) {
+ if (!mInitialized) {
LOG_E("Encoder has not initialized yet, can't call setConfig\n");
return ENCODE_NOT_INIT;
}
@@ -1138,29 +1200,51 @@
return ret;
}
-void VideoEncoderBase:: PrepareFrameInfo (EncodeTask* task) {
- if (mNewHeader) mFrameNum = 0;
- LOG_I( "mFrameNum = %d ", mFrameNum);
+void VideoEncoderBase:: decideFrameType () {
- updateFrameInfo(task) ;
-}
-
-Encode_Status VideoEncoderBase:: updateFrameInfo (EncodeTask* task) {
-
- task->type = FTYPE_P;
+ LOG_I( "mEncodedFrames = %d\n", mEncodedFrames);
+ LOG_I( "mFrameNum = %d\n", mFrameNum);
+ LOG_I( "mIsIntra = %d\n", mIsIntra);
// determine the picture type
- if (mFrameNum == 0)
- task->type = FTYPE_I;
- if (mComParams.intraPeriod != 0 && ((mFrameNum % mComParams.intraPeriod) == 0))
- task->type = FTYPE_I;
+ if (mComParams.intraPeriod == 0) {
+ if (mFrameNum == 0)
+ mIsIntra = true;
+ else
+ mIsIntra = false;
+ } else if ((mFrameNum % mComParams.intraPeriod) == 0) {
+ mIsIntra = true;
+ } else {
+ mIsIntra = false;
+ }
- if (task->type == FTYPE_I)
- task->flag |= ENCODE_BUFFERFLAG_SYNCFRAME;
-
- return ENCODE_SUCCESS;
+ LOG_I( "mIsIntra = %d\n",mIsIntra);
}
+
+void VideoEncoderBase:: updateProperities () {
+
+ VASurfaceID tmp = VA_INVALID_SURFACE;
+ LOG_V( "Begin\n");
+
+ mEncodedFrames ++;
+ mFrameNum ++;
+ mLastCodedBuffer = mVACodedBuffer[mCodedBufIndex];
+ mCodedBufIndex ++;
+ mCodedBufIndex %=2;
+
+ mLastSurface = mCurSurface;
+
+ if (!mPicSkipped) {
+ tmp = mRecSurface;
+ mRecSurface = mRefSurface;
+ mRefSurface = tmp;
+ }
+
+ LOG_V( "End\n");
+}
+
+
Encode_Status VideoEncoderBase::getMaxOutSize (uint32_t *maxSize) {
uint32_t size = mComParams.resolution.width * mComParams.resolution.height;
@@ -1198,6 +1282,25 @@
return ENCODE_SUCCESS;
}
+Encode_Status VideoEncoderBase::getStatistics (VideoStatistics *videoStat) {
+
+#ifdef VIDEO_ENC_STATISTICS_ENABLE
+ if (videoStat != NULL) {
+ videoStat->total_frames = mEncodedFrames;
+ videoStat->skipped_frames = mVideoStat.skipped_frames;
+ videoStat->average_encode_time = mVideoStat.average_encode_time / mEncodedFrames;
+ videoStat->max_encode_time = mVideoStat.max_encode_time;
+ videoStat->max_encode_frame = mVideoStat.max_encode_frame;
+ videoStat->min_encode_time = mVideoStat.min_encode_time;
+ videoStat->min_encode_frame = mVideoStat.min_encode_frame;
+ }
+
+ return ENCODE_SUCCESS;
+#else
+ return ENCODE_NOT_SUPPORTED;
+#endif
+}
+
Encode_Status VideoEncoderBase::getNewUsrptrFromSurface(
uint32_t width, uint32_t height, uint32_t format,
uint32_t expectedSize, uint32_t *outsize, uint32_t *stride, uint8_t **usrptr) {
@@ -1214,7 +1317,7 @@
LOG_V( "Begin\n");
// If encode session has been configured, we can not request surface creation anymore
- if (mStarted) {
+ if (mInitialized) {
LOG_E( "Already Initialized, can not request VA surface anymore\n");
return ENCODE_WRONG_STATE;
}
@@ -1284,8 +1387,9 @@
map->vinfo.format = VA_FOURCC_NV12;
map->vinfo.s3dformat = 0xffffffff;
map->added = false;
+ map->next = NULL;
- mSrcSurfaceMapList.push_back(map);
+ mSrcSurfaceMapList = appendSurfaceMap(mSrcSurfaceMapList, map);
LOG_I( "surface = 0x%08x\n",(uint32_t)surface);
LOG_I("image->pitches[0] = %d\n", image.pitches[0]);
@@ -1332,7 +1436,7 @@
}
for(unsigned int i=0; i < upStreamBuffer->bufCnt; i++) {
- if (findSurfaceMapByValue(upStreamBuffer->bufList[i]) != NULL) //already mapped
+ if (findSurfaceMapByValue(mSrcSurfaceMapList, upStreamBuffer->bufList[i]) != NULL) //already mapped
continue;
//wrap upstream buffer into vaSurface
@@ -1352,12 +1456,18 @@
}
map->vinfo.s3dformat = 0xFFFFFFFF;
map->added = false;
+ map->next = NULL;
status = surfaceMapping(map);
if (status == ENCODE_SUCCESS)
- mSrcSurfaceMapList.push_back(map);
+ mSrcSurfaceMapList = appendSurfaceMap(mSrcSurfaceMapList, map);
else
delete map;
+
+ if (mSrcSurfaceMapList == NULL) {
+ LOG_E ("mSrcSurfaceMapList should not be NULL now, maybe meet mapping error\n");
+ return ENCODE_NO_MEMORY;
+ }
}
return status;
@@ -1383,7 +1493,7 @@
VASurfaceAttributeTPI vaSurfaceAttrib;
uint32_t buf;
-
+
vaSurfaceAttrib.buffers = &buf;
vaStatus = vaLockSurface(
@@ -1426,7 +1536,7 @@
LOG_I("Surface ID created from Kbuf = 0x%08x", surface);
map->surface = surface;
-
+
return ret;
}
@@ -1498,12 +1608,12 @@
uint32_t lumaOffset = 0;
uint32_t chromaUOffset = map->vinfo.height * map->vinfo.lumaStride;
uint32_t chromaVOffset = chromaUOffset + 1;
-
+
VASurfaceAttributeTPI vaSurfaceAttrib;
uint32_t buf;
vaSurfaceAttrib.buffers = &buf;
-
+
vaSurfaceAttrib.count = 1;
vaSurfaceAttrib.size = map->vinfo.lumaStride * map->vinfo.height * 3 / 2;
vaSurfaceAttrib.luma_stride = map->vinfo.lumaStride;
@@ -1525,7 +1635,7 @@
LOG_I("Surface ID created from Kbuf = 0x%08x", map->value);
map->surface = surface;
-
+
return ret;
}
@@ -1557,7 +1667,7 @@
CHECK_VA_STATUS_RETURN("vaCreateSurfacesWithAttribute");
map->surface = surface;
-
+
return ret;
}
@@ -1635,9 +1745,9 @@
return status;
}
-Encode_Status VideoEncoderBase::manageSrcSurface(VideoEncRawBuffer *inBuffer, VASurfaceID *sid) {
+Encode_Status VideoEncoderBase::manageSrcSurface(VideoEncRawBuffer *inBuffer) {
- Encode_Status ret = ENCODE_SUCCESS;
+ Encode_Status ret = ENCODE_SUCCESS;
MetadataBufferType type;
int32_t value;
ValueInfo vinfo;
@@ -1647,13 +1757,13 @@
IntelMetadataBuffer imb;
SurfaceMap *map = NULL;
-
- if (mStoreMetaDataInBuffers.isEnabled) {
+
+ if (mStoreMetaDataInBuffers.isEnabled) {
//metadatabuffer mode
LOG_I("in metadata mode, data=%p, size=%d\n", inBuffer->data, inBuffer->size);
if (imb.UnSerialize(inBuffer->data, inBuffer->size) != IMB_SUCCESS) {
//fail to parse buffer
- return ENCODE_NO_REQUEST_DATA;
+ return ENCODE_NO_REQUEST_DATA;
}
imb.GetType(type);
@@ -1662,21 +1772,20 @@
//raw mode
LOG_I("in raw mode, data=%p, size=%d\n", inBuffer->data, inBuffer->size);
if (! inBuffer->data || inBuffer->size == 0) {
- return ENCODE_NULL_PTR;
+ return ENCODE_NULL_PTR;
}
type = MetadataBufferTypeUser;
value = (int32_t)inBuffer->data;
}
-
-
+
//find if mapped
- map = (SurfaceMap*) findSurfaceMapByValue(value);
+ map = findSurfaceMapByValue(mSrcSurfaceMapList, value);
- if (map) {
+ if (map) {
//has mapped, get surfaceID directly
LOG_I("direct find surface %d from value %x\n", map->surface, value);
- *sid = map->surface;
+ mCurSurface = map->surface;
return ret;
}
@@ -1684,8 +1793,8 @@
//if no found from list, then try to map value with parameters
LOG_I("not find surface from cache with value %x, start mapping if enough information\n", value);
- if (mStoreMetaDataInBuffers.isEnabled) {
-
+ if (mStoreMetaDataInBuffers.isEnabled) {
+
//if type is MetadataBufferTypeGrallocSource, use default parameters
if (type == MetadataBufferTypeGrallocSource) {
vinfo.mode = MEM_MODE_GFXHANDLE;
@@ -1697,15 +1806,15 @@
vinfo.chromStride = mComParams.resolution.width;
vinfo.format = VA_FOURCC_NV12;
vinfo.s3dformat = 0xFFFFFFFF;
- } else {
+ } else {
//get all info mapping needs
imb.GetValueInfo(pvinfo);
imb.GetExtraValues(extravalues, extravalues_count);
}
-
+
} else {
- //raw mode
+ //raw mode
vinfo.mode = MEM_MODE_MALLOC;
vinfo.handle = 0;
vinfo.size = inBuffer->size;
@@ -1727,25 +1836,26 @@
map->value = value;
memcpy(&(map->vinfo), pvinfo, sizeof(ValueInfo));
map->added = false;
+ map->next = NULL;
ret = surfaceMapping(map);
if (ret == ENCODE_SUCCESS) {
LOG_I("surface mapping success, map value %x into surface %d\n", value, map->surface);
- mSrcSurfaceMapList.push_back(map);
+ mSrcSurfaceMapList = appendSurfaceMap(mSrcSurfaceMapList, map);
} else {
delete map;
LOG_E("surface mapping failed, wrong info or meet serious error\n");
return ret;
- }
+ }
- *sid = map->surface;
+ mCurSurface = map->surface;
} else {
//can't map due to no info
LOG_E("surface mapping failed, missing information\n");
return ENCODE_NO_REQUEST_DATA;
}
-
+
if (extravalues) {
//map more using same ValueInfo
for(unsigned int i=0; i<extravalues_count; i++) {
@@ -1754,11 +1864,12 @@
map->value = extravalues[i];
memcpy(&(map->vinfo), pvinfo, sizeof(ValueInfo));
map->added = false;
+ map->next = NULL;
ret = surfaceMapping(map);
if (ret == ENCODE_SUCCESS) {
LOG_I("surface mapping extravalue success, map value %x into surface %d\n", extravalues[i], map->surface);
- mSrcSurfaceMapList.push_back(map);
+ mSrcSurfaceMapList = appendSurfaceMap(mSrcSurfaceMapList, map);
} else {
delete map;
map = NULL;
@@ -1766,10 +1877,69 @@
}
}
}
-
+
return ret;
}
+SurfaceMap *VideoEncoderBase::appendSurfaceMap(
+ SurfaceMap *head, SurfaceMap *map) {
+
+ if (head == NULL) {
+ return map;
+ }
+
+ SurfaceMap *node = head;
+ SurfaceMap *tail = NULL;
+
+ while (node != NULL) {
+ tail = node;
+ node = node->next;
+ }
+ tail->next = map;
+
+ return head;
+}
+
+SurfaceMap *VideoEncoderBase::removeSurfaceMap(
+ SurfaceMap *head, SurfaceMap *map) {
+
+ SurfaceMap *node = head;
+ SurfaceMap *tmpNode = NULL;
+
+ if (head == map) {
+ tmpNode = head->next;
+ map->next = NULL;
+ return tmpNode;
+ }
+
+ while (node != NULL) {
+ if (node->next == map)
+ break;
+ node = node->next;
+ }
+
+ if (node != NULL) {
+ node->next = map->next;
+ }
+
+ map->next = NULL;
+ return head;
+}
+
+SurfaceMap *VideoEncoderBase::findSurfaceMapByValue(
+ SurfaceMap *head, int32_t value) {
+
+ SurfaceMap *node = head;
+
+ while (node != NULL) {
+ if (node->value == value)
+ break;
+ node = node->next;
+ }
+
+ return node;
+}
+
Encode_Status VideoEncoderBase::renderDynamicBitrate() {
VAStatus vaStatus = VA_STATUS_SUCCESS;
@@ -1893,17 +2063,3 @@
return ENCODE_SUCCESS;
}
-
-SurfaceMap *VideoEncoderBase::findSurfaceMapByValue(int32_t value) {
- android::List<SurfaceMap *>::iterator node;
-
- for(node = mSrcSurfaceMapList.begin(); node != mSrcSurfaceMapList.end(); node++)
- {
- if ((*node)->value == value)
- return *node;
- else
- continue;
- }
-
- return NULL;
-}
diff --git a/videoencoder/VideoEncoderBase.h b/videoencoder/VideoEncoderBase.h
index 924c4da..9ab7bc6 100644
--- a/videoencoder/VideoEncoderBase.h
+++ b/videoencoder/VideoEncoderBase.h
@@ -14,30 +14,15 @@
#include "VideoEncoderDef.h"
#include "VideoEncoderInterface.h"
#include "IntelMetadataBuffer.h"
-#include <utils/List.h>
-#include <utils/threads.h>
-//#define AUTO_REFERENCE
struct SurfaceMap {
VASurfaceID surface;
MetadataBufferType type;
int32_t value;
ValueInfo vinfo;
+ uint32_t index;
bool added;
-};
-
-struct EncodeTask {
- VASurfaceID enc_surface;
- VASurfaceID ref_surface[2];
- VASurfaceID rec_surface;
- VABufferID coded_buffer;
-
- FrameType type;
- int flag;
- int64_t timestamp; //corresponding input frame timestamp
- uint8_t *in_data; //input buffer data
-
- bool completed; //if encode task is done complet by HW
+ SurfaceMap *next;
};
class VideoEncoderBase : IVideoEncoder {
@@ -49,7 +34,7 @@
virtual Encode_Status start(void);
virtual void flush(void);
virtual Encode_Status stop(void);
- virtual Encode_Status encode(VideoEncRawBuffer *inBuffer, uint32_t timeout);
+ virtual Encode_Status encode(VideoEncRawBuffer *inBuffer);
/*
* getOutput can be called several time for a frame (such as first time codec data, and second time others)
@@ -57,26 +42,30 @@
* If the buffer passed to encoded is not big enough, this API call will return ENCODE_BUFFER_TOO_SMALL
* and caller should provide a big enough buffer and call again
*/
- virtual Encode_Status getOutput(VideoEncOutputBuffer *outBuffer, uint32_t timeout);
+ virtual Encode_Status getOutput(VideoEncOutputBuffer *outBuffer);
virtual Encode_Status getParameters(VideoParamConfigSet *videoEncParams);
virtual Encode_Status setParameters(VideoParamConfigSet *videoEncParams);
virtual Encode_Status setConfig(VideoParamConfigSet *videoEncConfig);
virtual Encode_Status getConfig(VideoParamConfigSet *videoEncConfig);
+
virtual Encode_Status getMaxOutSize(uint32_t *maxSize);
+ virtual Encode_Status getStatistics(VideoStatistics *videoStat);
protected:
- virtual Encode_Status sendEncodeCommand(EncodeTask* task) = 0;
+ virtual Encode_Status sendEncodeCommand(void) = 0;
virtual Encode_Status derivedSetParams(VideoParamConfigSet *videoEncParams) = 0;
virtual Encode_Status derivedGetParams(VideoParamConfigSet *videoEncParams) = 0;
virtual Encode_Status derivedGetConfig(VideoParamConfigSet *videoEncConfig) = 0;
virtual Encode_Status derivedSetConfig(VideoParamConfigSet *videoEncConfig) = 0;
- virtual Encode_Status getExtFormatOutput(VideoEncOutputBuffer *outBuffer) = 0;
- virtual Encode_Status updateFrameInfo(EncodeTask* task) ;
+ Encode_Status prepareForOutput(VideoEncOutputBuffer *outBuffer, bool *useLocalBuffer);
+ Encode_Status cleanupForOutput();
+ Encode_Status outputAllData(VideoEncOutputBuffer *outBuffer);
Encode_Status renderDynamicFrameRate();
Encode_Status renderDynamicBitrate();
Encode_Status renderHrd();
+ void setKeyFrame(int32_t keyFramePeriod);
private:
void setDefaultParams(void);
@@ -89,29 +78,41 @@
Encode_Status surfaceMappingForKbufHandle(SurfaceMap *map);
Encode_Status surfaceMappingForMalloc(SurfaceMap *map);
Encode_Status surfaceMapping(SurfaceMap *map);
- SurfaceMap *findSurfaceMapByValue(int32_t value);
- Encode_Status manageSrcSurface(VideoEncRawBuffer *inBuffer, VASurfaceID *sid);
- void PrepareFrameInfo(EncodeTask* task);
- Encode_Status prepareForOutput(VideoEncOutputBuffer *outBuffer, bool *useLocalBuffer);
- Encode_Status cleanupForOutput();
- Encode_Status outputAllData(VideoEncOutputBuffer *outBuffer);
+ SurfaceMap *appendSurfaceMap(
+ SurfaceMap *head, SurfaceMap *map);
+ SurfaceMap *removeSurfaceMap(
+ SurfaceMap *head, SurfaceMap *map);
+ SurfaceMap *findSurfaceMapByValue(
+ SurfaceMap *head, int32_t value);
+
+ Encode_Status manageSrcSurface(VideoEncRawBuffer *inBuffer);
+ void updateProperities(void);
+ void decideFrameType(void);
+// Encode_Status uploadDataToSurface(VideoEncRawBuffer *inBuffer);
+ Encode_Status syncEncode(VideoEncRawBuffer *inBuffer);
+ Encode_Status asyncEncode(VideoEncRawBuffer *inBuffer);
protected:
bool mInitialized;
- bool mStarted;
VADisplay mVADisplay;
VAContextID mVAContext;
VAConfigID mVAConfig;
VAEntrypoint mVAEntrypoint;
+ VACodedBufferSegment *mCurSegment;
+ uint32_t mOffsetInSeg;
+ uint32_t mTotalSize;
+ uint32_t mTotalSizeCopied;
VideoParamsCommon mComParams;
VideoParamsHRD mHrdParam;
VideoParamsStoreMetaDataInBuffers mStoreMetaDataInBuffers;
+ bool mForceKeyFrame;
bool mNewHeader;
+ bool mFirstFrame;
bool mRenderMaxSliceSize; //Max Slice Size
bool mRenderQP;
@@ -120,36 +121,50 @@
bool mRenderBitRate;
bool mRenderHrd;
+ VABufferID mVACodedBuffer[2];
+ VABufferID mLastCodedBuffer;
+ VABufferID mOutCodedBuffer;
VABufferID mSeqParamBuf;
VABufferID mRcParamBuf;
VABufferID mFrameRateParamBuf;
VABufferID mPicParamBuf;
VABufferID mSliceParamBuf;
- android::List <SurfaceMap *> mSrcSurfaceMapList; //all mapped surface info list from input buffer
- android::List <EncodeTask *> mEncodeTaskList; //all encode tasks list
- android::List <VABufferID> mVACodedBufferList; //all available codedbuffer list
+ VASurfaceID *mSurfaces;
+ uint32_t mSurfaceCnt;
- VASurfaceID mRefSurface; //reference surface, only used in base
- VASurfaceID mRecSurface; //reconstructed surface, only used in base
+ SurfaceMap *mSrcSurfaceMapList;
+
+ //for new design
+ VASurfaceID mCurSurface; //current input surface to be encoded
+ VASurfaceID mRefSurface; //reference surface
+ VASurfaceID mRecSurface; //reconstructed surface
+ VASurfaceID mLastSurface; //last surface
+
+ VideoEncRawBuffer *mLastInputRawBuffer;
+
+ uint32_t mEncodedFrames;
uint32_t mFrameNum;
uint32_t mCodedBufSize;
+ uint32_t mCodedBufIndex;
+ bool mPicSkipped;
+ bool mIsIntra;
bool mSliceSizeOverflow;
-
- //Current Outputting task
- EncodeTask *mCurOutputTask;
-
- //Current outputting CodedBuffer status
- VABufferID mOutCodedBuffer;
bool mCodedBufferMapped;
- VACodedBufferSegment *mCurSegment;
- uint32_t mOffsetInSeg;
- uint32_t mTotalSize;
- uint32_t mTotalSizeCopied;
- android::Mutex mCodedBuffer_Lock, mEncodeTask_Lock;
- android::Condition mCodedBuffer_Cond, mEncodeTask_Cond;
+ bool mDataCopiedOut;
+ bool mKeyFrame;
- bool mFrameSkipped;
+ int32_t mInitCheck;
+
+#ifdef VIDEO_ENC_STATISTICS_ENABLE
+ VideoStatistics mVideoStat;
+#endif
+
+ // Constants
+ static const uint32_t VENCODER_NUMBER_EXTRA_SURFACES_SHARED_MODE = 2;
+ static const uint32_t VENCODER_NUMBER_EXTRA_SURFACES_NON_SHARED_MODE = 8;
};
+
+
#endif /* __VIDEO_ENCODER_BASE_H__ */
diff --git a/videoencoder/VideoEncoderDef.h b/videoencoder/VideoEncoderDef.h
index f5174aa..b9feca2 100644
--- a/videoencoder/VideoEncoderDef.h
+++ b/videoencoder/VideoEncoderDef.h
@@ -32,9 +32,7 @@
ENCODE_SUCCESS = 0,
ENCODE_ALREADY_INIT = 1,
ENCODE_SLICESIZE_OVERFLOW = 2,
- ENCODE_BUFFER_TOO_SMALL = 3, // The buffer passed to encode is too small to contain encoded data
- ENCODE_DEVICE_BUSY = 4,
- ENCODE_DATA_NOT_READY = 5,
+ ENCODE_BUFFER_TOO_SMALL = 3 // The buffer passed to encode is too small to contain encoded data
};
typedef enum {
@@ -44,7 +42,6 @@
OUTPUT_ONE_NAL = 4,
OUTPUT_ONE_NAL_WITHOUT_STARTCODE = 8,
OUTPUT_LENGTH_PREFIXED = 16,
- OUTPUT_CODEDBUFFER = 32,
OUTPUT_BUFFER_LAST
} VideoOutputFormat;
@@ -105,23 +102,6 @@
BUFFER_LAST
};
-typedef enum {
- FTYPE_UNKNOWN = 0, // Unknown
- FTYPE_I = 1, // General I-frame type
- FTYPE_P = 2, // General P-frame type
- FTYPE_B = 3, // General B-frame type
- FTYPE_SI = 4, // H.263 SI-frame type
- FTYPE_SP = 5, // H.263 SP-frame type
- FTYPE_EI = 6, // H.264 EI-frame type
- FTYPE_EP = 7, // H.264 EP-frame type
- FTYPE_S = 8, // MPEG-4 S-frame type
- FTYPE_IDR = 9, // IDR-frame type
-}FrameType;
-
-//function call mode
-#define FUNC_BLOCK 0xFFFFFFFF
-#define FUNC_NONBLOCK 0
-
// Output buffer flag
#define ENCODE_BUFFERFLAG_ENDOFFRAME 0x00000001
#define ENCODE_BUFFERFLAG_PARTIALFRAME 0x00000002
@@ -130,8 +110,6 @@
#define ENCODE_BUFFERFLAG_DATACORRUPT 0x00000010
#define ENCODE_BUFFERFLAG_DATAINVALID 0x00000020
#define ENCODE_BUFFERFLAG_SLICEOVERFOLOW 0x00000040
-#define ENCODE_BUFFERFLAG_ENDOFSTREAM 0x00000080
-#define ENCODE_BUFFERFLAG_NSTOPFRAME 0x00000100
typedef struct {
uint8_t *data;
@@ -140,18 +118,14 @@
uint32_t remainingSize;
int flag; //Key frame, Codec Data etc
VideoOutputFormat format; //output format
- int64_t timeStamp; //reserved
- FrameType type;
- uint8_t *in_data; //indicate corresponding input data
+ uint64_t timeStamp; //reserved
} VideoEncOutputBuffer;
typedef struct {
uint8_t *data;
uint32_t size;
bool bufAvailable; //To indicate whether this buffer can be reused
- int64_t timeStamp; //reserved
- FrameType type; //frame type expected to be encoded
- int flag; // flag to indicate buffer property
+ uint64_t timeStamp; //reserved
} VideoEncRawBuffer;
struct VideoEncSurfaceBuffer {
@@ -330,8 +304,6 @@
AirParams airParams;
uint32_t disableDeblocking;
bool syncEncMode;
- //CodedBuffer properties
- uint32_t codedBufNum;
VideoParamsCommon() {
type = VideoParamsTypeCommon;
@@ -355,7 +327,6 @@
this->airParams = other.airParams;
this->disableDeblocking = other.disableDeblocking;
this->syncEncMode = other.syncEncMode;
- this->codedBufNum = other.codedBufNum;
return *this;
}
};
@@ -365,23 +336,10 @@
uint8_t VUIFlag;
int32_t maxSliceSize;
uint32_t idrInterval;
- uint32_t ipPeriod;
- uint32_t refFrames;
SliceNum sliceNum;
AVCDelimiterType delimiterType;
Cropping crop;
SamplingAspectRatio SAR;
- uint32_t refIdx10ActiveMinus1;
- uint32_t refIdx11ActiveMinus1;
- bool bFrameMBsOnly;
- bool bMBAFF;
- bool bEntropyCodingCABAC;
- bool bWeightedPPrediction;
- uint32_t weightedBipredicitonMode;
- bool bConstIpred ;
- bool bDirect8x8Inference;
- bool bDirectSpatialTemporal;
- uint32_t cabacInitIdc;
VideoParamsAVC() {
type = VideoParamsTypeAVC;
@@ -396,8 +354,6 @@
this->VUIFlag = other.VUIFlag;
this->maxSliceSize = other.maxSliceSize;
this->idrInterval = other.idrInterval;
- this->ipPeriod = other.ipPeriod;
- this->refFrames = other.refFrames;
this->sliceNum = other.sliceNum;
this->delimiterType = other.delimiterType;
this->crop.LeftOffset = other.crop.LeftOffset;
@@ -407,17 +363,6 @@
this->SAR.SarWidth = other.SAR.SarWidth;
this->SAR.SarHeight = other.SAR.SarHeight;
- this->refIdx10ActiveMinus1 = other.refIdx10ActiveMinus1;
- this->refIdx11ActiveMinus1 = other.refIdx11ActiveMinus1;
- this->bFrameMBsOnly = other.bFrameMBsOnly;
- this->bMBAFF = other.bMBAFF;
- this->bEntropyCodingCABAC = other.bEntropyCodingCABAC;
- this->bWeightedPPrediction = other.bWeightedPPrediction;
- this->weightedBipredicitonMode = other.weightedBipredicitonMode;
- this->bConstIpred = other.bConstIpred;
- this->bDirect8x8Inference = other.bDirect8x8Inference;
- this->bDirectSpatialTemporal = other.bDirectSpatialTemporal;
- this->cabacInitIdc = other.cabacInitIdc;
return *this;
}
};
@@ -505,7 +450,6 @@
uint32_t idrInterval; //How many Intra frame will have a IDR frame
uint32_t intraPeriod;
- uint32_t ipPeriod;
};
struct VideoConfigNALSize : VideoParamConfigSet {
@@ -568,4 +512,14 @@
SliceNum sliceNum;
};
+typedef struct {
+ uint32_t total_frames;
+ uint32_t skipped_frames;
+ uint32_t average_encode_time;
+ uint32_t max_encode_time;
+ uint32_t max_encode_frame;
+ uint32_t min_encode_time;
+ uint32_t min_encode_frame;
+}VideoStatistics;
+
#endif /* __VIDEO_ENCODER_DEF_H__ */
diff --git a/videoencoder/VideoEncoderH263.cpp b/videoencoder/VideoEncoderH263.cpp
index b9b9c99..7371d7a 100644
--- a/videoencoder/VideoEncoderH263.cpp
+++ b/videoencoder/VideoEncoderH263.cpp
@@ -16,20 +16,20 @@
mComParams.profile = (VAProfile)PROFILE_H263BASELINE;
}
-Encode_Status VideoEncoderH263::sendEncodeCommand(EncodeTask *task) {
+Encode_Status VideoEncoderH263::sendEncodeCommand(void) {
Encode_Status ret = ENCODE_SUCCESS;
LOG_V( "Begin\n");
if (mFrameNum == 0) {
- ret = renderSequenceParams(task);
+ ret = renderSequenceParams();
CHECK_ENCODE_STATUS_RETURN("renderSequenceParams");
}
- ret = renderPictureParams(task);
+ ret = renderPictureParams();
CHECK_ENCODE_STATUS_RETURN("renderPictureParams");
- ret = renderSliceParams(task);
+ ret = renderSliceParams();
CHECK_ENCODE_STATUS_RETURN("renderSliceParams");
LOG_V( "End\n");
@@ -37,7 +37,7 @@
}
-Encode_Status VideoEncoderH263::renderSequenceParams(EncodeTask *task) {
+Encode_Status VideoEncoderH263::renderSequenceParams() {
VAStatus vaStatus = VA_STATUS_SUCCESS;
VAEncSequenceParameterBufferH263 h263SequenceParam = {};
@@ -78,7 +78,7 @@
return ENCODE_SUCCESS;
}
-Encode_Status VideoEncoderH263::renderPictureParams(EncodeTask *task) {
+Encode_Status VideoEncoderH263::renderPictureParams() {
VAStatus vaStatus = VA_STATUS_SUCCESS;
VAEncPictureParameterBufferH263 h263PictureParams = {};
@@ -86,18 +86,18 @@
LOG_V( "Begin\n\n");
// set picture params for HW
- h263PictureParams.reference_picture = task->ref_surface[0];
- h263PictureParams.reconstructed_picture = task->rec_surface;
- h263PictureParams.coded_buf = task->coded_buffer;
+ h263PictureParams.reference_picture = mRefSurface;
+ h263PictureParams.reconstructed_picture = mRecSurface;
+ h263PictureParams.coded_buf = mVACodedBuffer [mCodedBufIndex];
h263PictureParams.picture_width = mComParams.resolution.width;
h263PictureParams.picture_height = mComParams.resolution.height;
- h263PictureParams.picture_type = (task->type == FTYPE_I) ? VAEncPictureTypeIntra : VAEncPictureTypePredictive;
+ h263PictureParams.picture_type = mIsIntra ? VAEncPictureTypeIntra : VAEncPictureTypePredictive;
LOG_V("======h263 picture params======\n");
LOG_I( "reference_picture = 0x%08x\n", h263PictureParams.reference_picture);
LOG_I( "reconstructed_picture = 0x%08x\n", h263PictureParams.reconstructed_picture);
LOG_I( "coded_buf = 0x%08x\n", h263PictureParams.coded_buf);
-// LOG_I( "coded_buf_index = %d\n", mCodedBufIndex);
+ LOG_I( "coded_buf_index = %d\n", mCodedBufIndex);
LOG_I( "picture_width = %d\n", h263PictureParams.picture_width);
LOG_I( "picture_height = %d\n",h263PictureParams.picture_height);
LOG_I( "picture_type = %d\n\n",h263PictureParams.picture_type);
@@ -117,7 +117,7 @@
return ENCODE_SUCCESS;
}
-Encode_Status VideoEncoderH263::renderSliceParams(EncodeTask *task) {
+Encode_Status VideoEncoderH263::renderSliceParams() {
VAStatus vaStatus = VA_STATUS_SUCCESS;
uint32_t sliceHeight;
@@ -145,7 +145,7 @@
sliceParams->start_row_number = 0;
// slice height measured in MB
sliceParams->slice_height = sliceHeightInMB;
- sliceParams->slice_flags.bits.is_intra = (task->type == FTYPE_I)?1:0;
+ sliceParams->slice_flags.bits.is_intra = mIsIntra;
sliceParams->slice_flags.bits.disable_deblocking_filter_idc = 0;
LOG_V("======h263 slice params======\n");
diff --git a/videoencoder/VideoEncoderH263.h b/videoencoder/VideoEncoderH263.h
index a8578dd..2113e2f 100644
--- a/videoencoder/VideoEncoderH263.h
+++ b/videoencoder/VideoEncoderH263.h
@@ -20,7 +20,7 @@
virtual ~VideoEncoderH263() {};
protected:
- virtual Encode_Status sendEncodeCommand(EncodeTask *task);
+ virtual Encode_Status sendEncodeCommand(void);
virtual Encode_Status derivedSetParams(VideoParamConfigSet *videoEncParams) {
return ENCODE_SUCCESS;
}
@@ -33,16 +33,12 @@
virtual Encode_Status derivedSetConfig(VideoParamConfigSet *videoEncConfig) {
return ENCODE_SUCCESS;
}
- virtual Encode_Status getExtFormatOutput(VideoEncOutputBuffer *outBuffer) {
- return ENCODE_NOT_SUPPORTED;
- }
- //virtual Encode_Status updateFrameInfo(EncodeTask* task);
// Local Methods
private:
- Encode_Status renderSequenceParams(EncodeTask *task);
- Encode_Status renderPictureParams(EncodeTask *task);
- Encode_Status renderSliceParams(EncodeTask *task);
+ Encode_Status renderSequenceParams();
+ Encode_Status renderPictureParams();
+ Encode_Status renderSliceParams();
};
#endif /* __VIDEO_ENCODER_H263_H__ */
diff --git a/videoencoder/VideoEncoderInterface.h b/videoencoder/VideoEncoderInterface.h
index da1c6ec..243e4a1 100644
--- a/videoencoder/VideoEncoderInterface.h
+++ b/videoencoder/VideoEncoderInterface.h
@@ -17,13 +17,14 @@
virtual Encode_Status start(void) = 0;
virtual Encode_Status stop(void) = 0;
virtual void flush(void) = 0;
- virtual Encode_Status encode(VideoEncRawBuffer *inBuffer, uint32_t timeout = FUNC_BLOCK) = 0;
- virtual Encode_Status getOutput(VideoEncOutputBuffer *outBuffer, uint32_t timeout = FUNC_BLOCK) = 0;
+ virtual Encode_Status encode(VideoEncRawBuffer *inBuffer) = 0;
+ virtual Encode_Status getOutput(VideoEncOutputBuffer *outBuffer) = 0;
virtual Encode_Status getParameters(VideoParamConfigSet *videoEncParams) = 0;
virtual Encode_Status setParameters(VideoParamConfigSet *videoEncParams) = 0;
virtual Encode_Status getConfig(VideoParamConfigSet *videoEncConfig) = 0;
virtual Encode_Status setConfig(VideoParamConfigSet *videoEncConfig) = 0;
virtual Encode_Status getMaxOutSize(uint32_t *maxSize) = 0;
+ virtual Encode_Status getStatistics(VideoStatistics *videoStat) = 0;
};
#endif /* VIDEO_ENCODER_INTERFACE_H_ */
diff --git a/videoencoder/VideoEncoderLog.h b/videoencoder/VideoEncoderLog.h
index 0f0eeae..49c34df 100644
--- a/videoencoder/VideoEncoderLog.h
+++ b/videoencoder/VideoEncoderLog.h
@@ -23,8 +23,7 @@
__android_log_print(level, comp, "%s():%d: "format, \
__FUNCTION__, __LINE__, ##__VA_ARGS__)
-#define VIDEO_ENC_LOG_ENABLE
-#if 1
+#if 1
#ifdef VIDEO_ENC_LOG_ENABLE
#define LOG_V(format, ...) mix_log(VIDEO_ENC_COMP, VIDEO_ENC_LOG_LEVEL_VERBOSE, format, ##__VA_ARGS__)
#define LOG_I(format, ...) mix_log(VIDEO_ENC_COMP, VIDEO_ENC_LOG_LEVEL_INFO, format, ##__VA_ARGS__)
diff --git a/videoencoder/VideoEncoderMP4.cpp b/videoencoder/VideoEncoderMP4.cpp
index 1bedc63..6e0263b 100644
--- a/videoencoder/VideoEncoderMP4.cpp
+++ b/videoencoder/VideoEncoderMP4.cpp
@@ -85,15 +85,30 @@
return ret;
}
-Encode_Status VideoEncoderMP4::getExtFormatOutput(VideoEncOutputBuffer *outBuffer) {
+
+Encode_Status VideoEncoderMP4::getOutput(VideoEncOutputBuffer *outBuffer) {
Encode_Status ret = ENCODE_SUCCESS;
VAStatus vaStatus = VA_STATUS_SUCCESS;
+ bool useLocalBuffer = false;
LOG_V("Begin\n");
CHECK_NULL_RETURN_IFFAIL(outBuffer);
+ setKeyFrame(mComParams.intraPeriod);
+
+ // prepare for output, map the coded buffer
+ ret = VideoEncoderBase::prepareForOutput(outBuffer, &useLocalBuffer);
+ CHECK_ENCODE_STATUS_CLEANUP("prepareForOutput");
+
switch (outBuffer->format) {
+ case OUTPUT_EVERYTHING:
+ case OUTPUT_FRAME_DATA: {
+ // Output whatever we have
+ ret = VideoEncoderBase::outputAllData(outBuffer);
+ CHECK_ENCODE_STATUS_CLEANUP("outputAllData");
+ break;
+ }
case OUTPUT_CODEC_DATA: {
// Output the codec config data
ret = outputConfigData(outBuffer);
@@ -108,14 +123,32 @@
LOG_I("out size is = %d\n", outBuffer->dataSize);
+ // cleanup, unmap the coded buffer if all
+ // data has been copied out
+ ret = VideoEncoderBase::cleanupForOutput();
CLEAN_UP:
+ if (ret < ENCODE_SUCCESS) {
+ if (outBuffer->data && (useLocalBuffer == true)) {
+ delete[] outBuffer->data;
+ outBuffer->data = NULL;
+ useLocalBuffer = false;
+ }
+
+ // error happens, unmap the buffer
+ if (mCodedBufferMapped) {
+ vaStatus = vaUnmapBuffer(mVADisplay, mOutCodedBuffer);
+ mCodedBufferMapped = false;
+ mCurSegment = NULL;
+ }
+ }
LOG_V("End\n");
return ret;
}
-Encode_Status VideoEncoderMP4::renderSequenceParams(EncodeTask *task) {
+
+Encode_Status VideoEncoderMP4::renderSequenceParams() {
VAStatus vaStatus = VA_STATUS_SUCCESS;
VAEncSequenceParameterBufferMPEG4 mp4SequenceParams = {};
@@ -169,26 +202,26 @@
return ENCODE_SUCCESS;
}
-Encode_Status VideoEncoderMP4::renderPictureParams(EncodeTask *task) {
+Encode_Status VideoEncoderMP4::renderPictureParams() {
VAStatus vaStatus = VA_STATUS_SUCCESS;
VAEncPictureParameterBufferMPEG4 mpeg4_pic_param = {};
LOG_V( "Begin\n\n");
// set picture params for HW
- mpeg4_pic_param.reference_picture = task->ref_surface[0];
- mpeg4_pic_param.reconstructed_picture = task->rec_surface;
- mpeg4_pic_param.coded_buf = task->coded_buffer;
+ mpeg4_pic_param.reference_picture = mRefSurface;
+ mpeg4_pic_param.reconstructed_picture = mRecSurface;
+ mpeg4_pic_param.coded_buf = mVACodedBuffer[mCodedBufIndex];
mpeg4_pic_param.picture_width = mComParams.resolution.width;
mpeg4_pic_param.picture_height = mComParams.resolution.height;
mpeg4_pic_param.vop_time_increment= mFrameNum;
- mpeg4_pic_param.picture_type = (task->type == FTYPE_I) ? VAEncPictureTypeIntra : VAEncPictureTypePredictive;
+ mpeg4_pic_param.picture_type = mIsIntra ? VAEncPictureTypeIntra : VAEncPictureTypePredictive;
LOG_V("======mpeg4 picture params======\n");
LOG_I("reference_picture = 0x%08x\n", mpeg4_pic_param.reference_picture);
LOG_I("reconstructed_picture = 0x%08x\n", mpeg4_pic_param.reconstructed_picture);
LOG_I("coded_buf = 0x%08x\n", mpeg4_pic_param.coded_buf);
-// LOG_I("coded_buf_index = %d\n", mCodedBufIndex);
+ LOG_I("coded_buf_index = %d\n", mCodedBufIndex);
LOG_I("picture_width = %d\n", mpeg4_pic_param.picture_width);
LOG_I("picture_height = %d\n", mpeg4_pic_param.picture_height);
LOG_I("vop_time_increment = %d\n", mpeg4_pic_param.vop_time_increment);
@@ -209,7 +242,7 @@
}
-Encode_Status VideoEncoderMP4::renderSliceParams(EncodeTask *task) {
+Encode_Status VideoEncoderMP4::renderSliceParams() {
VAStatus vaStatus = VA_STATUS_SUCCESS;
uint32_t sliceHeight;
@@ -226,7 +259,7 @@
sliceParams.start_row_number = 0;
sliceParams.slice_height = sliceHeightInMB;
- sliceParams.slice_flags.bits.is_intra = (task->type == FTYPE_I)?1:0;
+ sliceParams.slice_flags.bits.is_intra = mIsIntra;
sliceParams.slice_flags.bits.disable_deblocking_filter_idc = 0;
LOG_V("======mpeg4 slice params======\n");
@@ -249,19 +282,19 @@
return ENCODE_SUCCESS;
}
-Encode_Status VideoEncoderMP4::sendEncodeCommand(EncodeTask *task) {
+Encode_Status VideoEncoderMP4::sendEncodeCommand(void) {
Encode_Status ret = ENCODE_SUCCESS;
LOG_V( "Begin\n");
if (mFrameNum == 0) {
- ret = renderSequenceParams(task);
+ ret = renderSequenceParams();
CHECK_ENCODE_STATUS_RETURN("renderSequenceParams");
}
- ret = renderPictureParams(task);
+ ret = renderPictureParams();
CHECK_ENCODE_STATUS_RETURN("renderPictureParams");
- ret = renderSliceParams(task);
+ ret = renderSliceParams();
CHECK_ENCODE_STATUS_RETURN("renderPictureParams");
LOG_V( "End\n");
diff --git a/videoencoder/VideoEncoderMP4.h b/videoencoder/VideoEncoderMP4.h
index 7e579c0..b453023 100644
--- a/videoencoder/VideoEncoderMP4.h
+++ b/videoencoder/VideoEncoderMP4.h
@@ -19,10 +19,11 @@
VideoEncoderMP4();
virtual ~VideoEncoderMP4() {};
-// Encode_Status getOutput(VideoEncOutputBuffer *outBuffer);
+ Encode_Status getOutput(VideoEncOutputBuffer *outBuffer);
protected:
- virtual Encode_Status sendEncodeCommand(EncodeTask *task);
+ virtual Encode_Status sendEncodeCommand(void);
+
virtual Encode_Status derivedSetParams(VideoParamConfigSet *videoEncParams) {
return ENCODE_SUCCESS;
}
@@ -35,16 +36,13 @@
virtual Encode_Status derivedSetConfig(VideoParamConfigSet *videoEncConfig) {
return ENCODE_SUCCESS;
}
- virtual Encode_Status getExtFormatOutput(VideoEncOutputBuffer *outBuffer);
- //virtual Encode_Status updateFrameInfo(EncodeTask* task);
-
// Local Methods
private:
Encode_Status getHeaderPos(uint8_t *inBuffer, uint32_t bufSize, uint32_t *headerSize);
Encode_Status outputConfigData(VideoEncOutputBuffer *outBuffer);
- Encode_Status renderSequenceParams(EncodeTask *task);
- Encode_Status renderPictureParams(EncodeTask *task);
- Encode_Status renderSliceParams(EncodeTask *task);
+ Encode_Status renderSequenceParams();
+ Encode_Status renderPictureParams();
+ Encode_Status renderSliceParams();
unsigned char mProfileLevelIndication;
uint32_t mFixedVOPTimeIncrement;