aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChang Ying <ying.chang@intel.com>2012-12-27 14:51:56 +0800
committerPatrick Tjin <pattjin@google.com>2014-07-21 22:02:50 -0700
commit62b0bf25eda4d2f48a228d7f3483e773e08292e2 (patch)
tree403547f74a4da241915031b46344bb3eea9ef3a8
parent115237a07f429df83c4d7cb34af86a1f636fc76b (diff)
downloadandroid_hardware_intel_common_omx-components-62b0bf25eda4d2f48a228d7f3483e773e08292e2.tar.gz
android_hardware_intel_common_omx-components-62b0bf25eda4d2f48a228d7f3483e773e08292e2.tar.bz2
android_hardware_intel_common_omx-components-62b0bf25eda4d2f48a228d7f3483e773e08292e2.zip
VE: Add VP8 HW encoder support
BZ: 77123 Add OMX.Intel.VideoEncoder.VP8 component to support HW VP8 encoder on MRFD. Change-Id: Id4dd4e76873f3a7793005077eba6bb2b57b90c39 Signed-off-by: Chang Ying <ying.chang@intel.com> Reviewed-on: http://android.intel.com:8080/83984 Reviewed-by: Yuan, Shengquan <shengquan.yuan@intel.com> Reviewed-by: Zhang, Zhangfei <zhangfei.zhang@intel.com> Reviewed-by: Shi, PingX <pingx.shi@intel.com> Tested-by: Shi, PingX <pingx.shi@intel.com> Reviewed-by: buildbot <buildbot@intel.com> Tested-by: buildbot <buildbot@intel.com>
-rw-r--r--videocodec/Android.mk35
-rw-r--r--videocodec/OMXVideoEncoderVP8.cpp233
-rw-r--r--videocodec/OMXVideoEncoderVP8.h32
3 files changed, 300 insertions, 0 deletions
diff --git a/videocodec/Android.mk b/videocodec/Android.mk
index d5e556d..b93dd1b 100644
--- a/videocodec/Android.mk
+++ b/videocodec/Android.mk
@@ -291,6 +291,41 @@ LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := libOMXVideoDecoderPAVC
include $(BUILD_SHARED_LIBRARY)
+include $(CLEAR_VARS)
+
+LOCAL_CPPFLAGS :=
+LOCAL_LDFLAGS :=
+
+LOCAL_SHARED_LIBRARIES := \
+ libwrs_omxil_common \
+ liblog \
+ libva_videoencoder \
+ libva \
+ libva-android \
+ libva-tpi \
+ libutils \
+ libhardware \
+ libintelmetadatabuffer
+
+LOCAL_C_INCLUDES := \
+ $(TARGET_OUT_HEADERS)/wrs_omxil_core \
+ $(TARGET_OUT_HEADERS)/khronos/openmax \
+ $(TARGET_OUT_HEADERS)/libmix_videoencoder \
+ $(TARGET_OUT_HEADERS)/libva \
+ $(TARGET_OUT_HEADERS)/libsharedbuffer \
+ $(TOP)/hardware/libhardware/include \
+ $(TOP)/frameworks/native/include/media/hardware \
+ $(TOP)/frameworks/native/include/media/openmax \
+ $(TARGET_OUT_HEADERS)/pvr
+
+LOCAL_SRC_FILES := \
+ OMXComponentCodecBase.cpp \
+ OMXVideoEncoderBase.cpp \
+ OMXVideoEncoderVP8.cpp
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := libOMXVideoEncoderVP8
+include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
diff --git a/videocodec/OMXVideoEncoderVP8.cpp b/videocodec/OMXVideoEncoderVP8.cpp
new file mode 100644
index 0000000..4ff3110
--- /dev/null
+++ b/videocodec/OMXVideoEncoderVP8.cpp
@@ -0,0 +1,233 @@
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "OMXVideoEncoderVP8"
+#include <utils/Log.h>
+#include "OMXVideoEncoderVP8.h"
+
+static const char *VP8_MIME_TYPE = "video/x-webm";
+
+OMXVideoEncoderVP8::OMXVideoEncoderVP8() {
+ LOGV("OMXVideoEncoderVP8 is constructed.");
+ BuildHandlerList();
+ mVideoEncoder = createVideoEncoder(VP8_MIME_TYPE);
+ if(!mVideoEncoder) LOGE("OMX_ErrorInsufficientResources");
+}
+
+OMXVideoEncoderVP8::~OMXVideoEncoderVP8() {
+ LOGV("OMXVideoEncoderVP8 is destructed.");
+}
+
+OMX_ERRORTYPE OMXVideoEncoderVP8::InitOutputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionOutput) {
+
+ memset(&mParamVp8, 0, sizeof(mParamVp8));
+ SetTypeHeader(&mParamVp8, sizeof(mParamVp8));
+ mParamVp8.nPortIndex = OUTPORT_INDEX;
+ mParamVp8.eProfile = OMX_VIDEO_VP8ProfileMain;
+ mParamVp8.eLevel = OMX_VIDEO_VP8Level_Version3;
+
+ paramPortDefinitionOutput->nBufferCountActual = OUTPORT_ACTUAL_BUFFER_COUNT;
+ paramPortDefinitionOutput->nBufferCountMin = OUTPORT_MIN_BUFFER_COUNT;
+ paramPortDefinitionOutput->nBufferSize = OUTPORT_BUFFER_SIZE;
+ paramPortDefinitionOutput->format.video.cMIMEType = (OMX_STRING)VP8_MIME_TYPE;
+ paramPortDefinitionOutput->format.video.eCompressionFormat = OMX_VIDEO_CodingVPX;
+
+ mParamProfileLevel.eProfile = OMX_VIDEO_VP8ProfileMain;
+ mParamProfileLevel.eLevel = OMX_VIDEO_VP8Level_Version3;
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE OMXVideoEncoderVP8::SetVideoEncoderParam() {
+
+ if (!mEncoderParams) {
+ LOGE("NULL pointer: mEncoderParams");
+ return OMX_ErrorBadParameter;
+ }
+
+ mVideoEncoder->getParameters(mEncoderParams);
+ mEncoderParams->profile = (VAProfile)PROFILE_VP8;
+ return OMXVideoEncoderBase::SetVideoEncoderParam();
+}
+
+OMX_ERRORTYPE OMXVideoEncoderVP8::ProcessorInit(void) {
+ return OMXVideoEncoderBase::ProcessorInit();
+}
+
+OMX_ERRORTYPE OMXVideoEncoderVP8::ProcessorDeinit(void) {
+ return OMXVideoEncoderBase::ProcessorDeinit();
+}
+
+OMX_ERRORTYPE OMXVideoEncoderVP8::ProcessorProcess(OMX_BUFFERHEADERTYPE **buffers,
+ buffer_retain_t *retains,
+ OMX_U32 numberBuffers) {
+
+ VideoEncOutputBuffer outBuf;
+ VideoEncRawBuffer inBuf;
+ Encode_Status ret = ENCODE_SUCCESS;
+
+ OMX_U32 outfilledlen = 0;
+ OMX_S64 outtimestamp = 0;
+ OMX_U32 outflags = 0;
+ OMX_ERRORTYPE oret = OMX_ErrorNone;
+
+ LOGV_IF(buffers[INPORT_INDEX]->nFlags & OMX_BUFFERFLAG_EOS,
+ "%s(),%d: got OMX_BUFFERFLAG_EOS\n", __func__, __LINE__);
+
+ if (!buffers[INPORT_INDEX]->nFilledLen) {
+ LOGV("%s(),%d: input buffer's nFilledLen is zero\n", __func__, __LINE__);
+ goto out;
+ }
+
+ inBuf.data = buffers[INPORT_INDEX]->pBuffer + buffers[INPORT_INDEX]->nOffset;
+ inBuf.size = buffers[INPORT_INDEX]->nFilledLen;
+
+ outBuf.data =
+ buffers[OUTPORT_INDEX]->pBuffer + buffers[OUTPORT_INDEX]->nOffset;
+ outBuf.dataSize = 0;
+ outBuf.bufferSize = buffers[OUTPORT_INDEX]->nAllocLen - buffers[OUTPORT_INDEX]->nOffset;
+
+ if (mFrameRetrieved) {
+ // encode and setConfig need to be thread safe
+ pthread_mutex_unlock(&mSerializationLock);
+ ret = mVideoEncoder->encode(&inBuf);
+ pthread_mutex_unlock(&mSerializationLock);
+
+ CHECK_ENCODE_STATUS("encode");
+ mFrameRetrieved = OMX_FALSE;
+
+ // This is for buffer contention, we won't release current buffer
+ // but the last input buffer
+ ports[INPORT_INDEX]->ReturnAllRetainedBuffers();
+ }
+
+ {
+ outBuf.format = OUTPUT_EVERYTHING;
+ mVideoEncoder->getOutput(&outBuf);
+ CHECK_ENCODE_STATUS("getOutput");
+
+ LOGV("output data size = %d", outBuf.dataSize);
+
+
+ outfilledlen = outBuf.dataSize;
+ outtimestamp = buffers[INPORT_INDEX]->nTimeStamp;
+
+ if (outBuf.flag & ENCODE_BUFFERFLAG_SYNCFRAME) {
+ outflags |= OMX_BUFFERFLAG_SYNCFRAME;
+ }
+
+ if (outBuf.flag & ENCODE_BUFFERFLAG_ENDOFFRAME) {
+ LOGV("Get buffer done\n");
+ outflags |= OMX_BUFFERFLAG_ENDOFFRAME;
+ mFrameRetrieved = OMX_TRUE;
+ retains[INPORT_INDEX] = BUFFER_RETAIN_ACCUMULATE;
+
+ } else {
+ retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; //get again
+
+ }
+
+ }
+
+
+ if (outfilledlen > 0) {
+ retains[OUTPORT_INDEX] = BUFFER_RETAIN_NOT_RETAIN;
+ } else {
+ retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
+ }
+
+
+
+#if SHOW_FPS
+ {
+ struct timeval t;
+ OMX_TICKS current_ts, interval_ts;
+ float current_fps, average_fps;
+
+ t.tv_sec = t.tv_usec = 0;
+ gettimeofday(&t, NULL);
+
+ current_ts =
+ (nsecs_t)t.tv_sec * 1000000000 + (nsecs_t)t.tv_usec * 1000;
+ interval_ts = current_ts - lastTs;
+ lastTs = current_ts;
+
+ current_fps = (float)1000000000 / (float)interval_ts;
+ average_fps = (current_fps + lastFps) / 2;
+ lastFps = current_fps;
+
+ LOGV("FPS = %2.1f\n", average_fps);
+ }
+#endif
+
+out:
+
+ if (retains[OUTPORT_INDEX] != BUFFER_RETAIN_GETAGAIN) {
+ buffers[OUTPORT_INDEX]->nFilledLen = outfilledlen;
+ buffers[OUTPORT_INDEX]->nTimeStamp = outtimestamp;
+ buffers[OUTPORT_INDEX]->nFlags = outflags;
+ }
+
+ if (retains[INPORT_INDEX] == BUFFER_RETAIN_NOT_RETAIN ||
+ retains[INPORT_INDEX] == BUFFER_RETAIN_ACCUMULATE ) {
+ mFrameInputCount ++;
+ }
+
+ if (retains[OUTPORT_INDEX] == BUFFER_RETAIN_NOT_RETAIN)
+ mFrameOutputCount ++;
+
+ return oret;
+}
+
+OMX_ERRORTYPE OMXVideoEncoderVP8::BuildHandlerList(void) {
+ OMXVideoEncoderBase::BuildHandlerList();
+ AddHandler((OMX_INDEXTYPE)OMX_IndexParamVideoVp8, GetParamVideoVp8, SetParamVideoVp8);
+ AddHandler((OMX_INDEXTYPE)OMX_IndexConfigVideoVp8ReferenceFrame, GetConfigVideoVp8ReferenceFrame, SetConfigVideoVp8ReferenceFrame);
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE OMXVideoEncoderVP8::GetParamVideoVp8(OMX_PTR pStructure) {
+ OMX_ERRORTYPE ret;
+ OMX_VIDEO_PARAM_VP8TYPE *p = (OMX_VIDEO_PARAM_VP8TYPE*) pStructure;
+ CHECK_TYPE_HEADER(p);
+ CHECK_PORT_INDEX(p, OUTPORT_INDEX);
+
+ memcpy(p, &mParamVp8, sizeof(*p));
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE OMXVideoEncoderVP8::SetParamVideoVp8(OMX_PTR pStructure) {
+ OMX_ERRORTYPE ret;
+ OMX_VIDEO_PARAM_VP8TYPE *p = (OMX_VIDEO_PARAM_VP8TYPE*) pStructure;
+ CHECK_TYPE_HEADER(p);
+ CHECK_PORT_INDEX(p, OUTPORT_INDEX);
+ CHECK_SET_PARAM_STATE();
+
+ memcpy(&mParamVp8, p, sizeof(mParamVp8));
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE OMXVideoEncoderVP8::GetConfigVideoVp8ReferenceFrame(OMX_PTR pStructure) {
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE OMXVideoEncoderVP8::SetConfigVideoVp8ReferenceFrame(OMX_PTR pStructure) {
+ OMX_ERRORTYPE ret;
+ Encode_Status retStatus = ENCODE_SUCCESS;
+ OMX_VIDEO_VP8REFERENCEFRAMETYPE *p = (OMX_VIDEO_VP8REFERENCEFRAMETYPE*) pStructure;
+ CHECK_TYPE_HEADER(p);
+ CHECK_PORT_INDEX(p, OUTPORT_INDEX);
+
+ CHECK_SET_CONFIG_STATE();
+
+ VideoConfigVP8 configVP8;
+ configVP8.no_ref_last = p->bUsePreviousFrame;
+ configVP8.no_ref_gf = p->bUseGoldenFrame;
+ configVP8.no_ref_arf = p->bUseAlternateFrame;
+
+ retStatus = mVideoEncoder->setConfig(&configVP8);
+ if(retStatus != ENCODE_SUCCESS) {
+ LOGW("Failed to set refresh config");
+ }
+ return OMX_ErrorNone;
+}
+
+DECLARE_OMX_COMPONENT("OMX.Intel.VideoEncoder.VP8", "video_encoder.vp8", OMXVideoEncoderVP8);
diff --git a/videocodec/OMXVideoEncoderVP8.h b/videocodec/OMXVideoEncoderVP8.h
new file mode 100644
index 0000000..4de1cf6
--- /dev/null
+++ b/videocodec/OMXVideoEncoderVP8.h
@@ -0,0 +1,32 @@
+
+#ifndef OMX_VIDEO_ENCODER_VP8_H
+#define OMX_VIDEO_ENCODER_VP8_H
+
+#include "OMXVideoEncoderBase.h"
+
+class OMXVideoEncoderVP8 : public OMXVideoEncoderBase {
+ public:
+ OMXVideoEncoderVP8();
+ virtual ~OMXVideoEncoderVP8();
+ protected:
+ virtual OMX_ERRORTYPE InitOutputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *paramPortDeninitionOutput);
+ virtual OMX_ERRORTYPE ProcessorInit(void);
+ virtual OMX_ERRORTYPE ProcessorDeinit(void);
+ virtual OMX_ERRORTYPE ProcessorProcess(OMX_BUFFERHEADERTYPE **buffers, buffer_retain_t *retains, OMX_U32 numberBuffers);
+ virtual OMX_ERRORTYPE BuildHandlerList(void);
+ virtual OMX_ERRORTYPE SetVideoEncoderParam();
+ DECLARE_HANDLER(OMXVideoEncoderVP8, ParamVideoVp8);
+ DECLARE_HANDLER(OMXVideoEncoderVP8, ConfigVideoVp8ReferenceFrame);
+ private:
+ enum {
+ OUTPORT_MIN_BUFFER_COUNT = 1,
+ OUTPORT_ACTUAL_BUFFER_COUNT = 2,
+ OUTPORT_BUFFER_SIZE = 1382400,
+ };
+
+ OMX_VIDEO_PARAM_VP8TYPE mParamVp8;
+ OMX_VIDEO_VP8REFERENCEFRAMETYPE mConfigVideoVp8ReferenceFrame;
+ OMX_CONFIG_INTRAREFRESHVOPTYPE mConfigVideoIntraVOPRefresh;
+};
+
+#endif /* OMX_VIDEO_ENCODER_VP8_H */