aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorywan171 <yi.a.wang@intel.com>2014-11-14 14:13:50 +0800
committerEd Tam <etam@google.com>2014-11-20 10:48:50 -0800
commitc51d5398ac792d8ddd35d72322038305281b80ed (patch)
tree4b2c56974fa4a9adb3c386401d6c47578c59d3de
parent9cfd42b1c84f88bac7dd539e18fa8a99a91c984c (diff)
downloadandroid_hardware_intel_common_omx-components-c51d5398ac792d8ddd35d72322038305281b80ed.tar.gz
android_hardware_intel_common_omx-components-c51d5398ac792d8ddd35d72322038305281b80ed.tar.bz2
android_hardware_intel_common_omx-components-c51d5398ac792d8ddd35d72322038305281b80ed.zip
DecoderVP9Hybrid: add adaptive playback support
1. if the output buffer is big enough, drain the frame before dealing with new resolution frame 2. if the output buffer is not big enough, the output buffer should be reallocated Bug: 17729532 BZ: 225243 Change-Id: Id252bea17a9f474bbb8dcb97da29cb2b98db5e37 Signed-off-by: ywan171 <yi.a.wang@intel.com>
-rw-r--r--videocodec/OMXVideoDecoderVP9Hybrid.cpp79
-rw-r--r--videocodec/OMXVideoDecoderVP9Hybrid.h8
2 files changed, 82 insertions, 5 deletions
diff --git a/videocodec/OMXVideoDecoderVP9Hybrid.cpp b/videocodec/OMXVideoDecoderVP9Hybrid.cpp
index 59370e3..8726e56 100644
--- a/videocodec/OMXVideoDecoderVP9Hybrid.cpp
+++ b/videocodec/OMXVideoDecoderVP9Hybrid.cpp
@@ -40,6 +40,8 @@ OMXVideoDecoderVP9Hybrid::OMXVideoDecoderVP9Hybrid() {
mCheckBufferAvailable = NULL;
mGetOutput = NULL;
mGetRawDataOutput = NULL;
+ mGetFrameResolution = NULL;
+ mDeinitDecoder = NULL;
mLastTimeStamp = 0;
mWorkingMode = RAWDATA_MODE;
mDecodedImageWidth = 0;
@@ -101,10 +103,13 @@ OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::ProcessorInit(void) {
mCheckBufferAvailable = (IsBufferAvailableFunc)dlsym(mLibHandle, "Decoder_IsBufferAvailable");
mGetOutput = (GetOutputFunc)dlsym(mLibHandle, "Decoder_GetOutput");
mGetRawDataOutput = (GetRawDataOutputFunc)dlsym(mLibHandle, "Decoder_GetRawDataOutput");
+ mGetFrameResolution = (GetFrameResolutionFunc)dlsym(mLibHandle, "Decoder_GetFrameResolution");
+ mDeinitDecoder = (DeinitFunc)dlsym(mLibHandle, "Decoder_Deinit");
if (mOpenDecoder == NULL || mCloseDecoder == NULL
|| mInitDecoder == NULL || mSingalRenderDone == NULL
|| mDecoderDecode == NULL || mCheckBufferAvailable == NULL
- || mGetOutput == NULL || mGetRawDataOutput == NULL) {
+ || mGetOutput == NULL || mGetRawDataOutput == NULL
+ || mGetFrameResolution == NULL || mDeinitDecoder == NULL) {
return OMX_ErrorBadParameter;
}
@@ -117,6 +122,54 @@ OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::ProcessorInit(void) {
return OMX_ErrorNone;
}
+OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::ProcessorReset(void)
+{
+ uint32_t buff[MAX_GRAPHIC_BUFFER_NUM];
+ uint32_t i, bufferCount;
+ bool gralloc_mode = (mWorkingMode == GRAPHICBUFFER_MODE);
+ uint32_t bufferSize, bufferStride, bufferHeight;
+ if (!gralloc_mode) {
+ bufferSize = mDecodedImageWidth * mDecodedImageHeight * 1.5;
+ bufferStride = mDecodedImageWidth;
+ bufferHeight = mDecodedImageHeight;
+ bufferCount = 12;
+ } else {
+ bufferSize = mGraphicBufferParam.graphicBufferStride *
+ mGraphicBufferParam.graphicBufferHeight * 1.5;
+ bufferStride = mGraphicBufferParam.graphicBufferStride;
+ bufferCount = mOMXBufferHeaderTypePtrNum;
+ bufferHeight = mGraphicBufferParam.graphicBufferHeight;
+
+ for (i = 0; i < bufferCount; i++ ) {
+ OMX_BUFFERHEADERTYPE *buf_hdr = mOMXBufferHeaderTypePtrArray[i];
+ buff[i] = (uint32_t)(buf_hdr->pBuffer);
+ }
+ }
+ mInitDecoder(mHybridCtx,bufferSize,bufferStride,bufferHeight,bufferCount,gralloc_mode, buff);
+
+ return OMX_ErrorNone;
+}
+
+bool OMXVideoDecoderVP9Hybrid::isReallocateNeeded(const uint8_t * data,uint32_t data_sz)
+{
+ bool gralloc_mode = (mWorkingMode == GRAPHICBUFFER_MODE);
+ uint32_t width, height;
+ bool ret = true;
+ if (gralloc_mode) {
+ ret = mGetFrameResolution(data,data_sz, &width, &height);
+ if (ret) {
+ ret = width > mGraphicBufferParam.graphicBufferWidth
+ || height > mGraphicBufferParam.graphicBufferHeight;
+ if (ret) {
+ mDecodedImageNewWidth = width;
+ mDecodedImageNewHeight = height;
+ return true;
+ }
+ }
+ }
+ return ret;
+}
+
OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::ProcessorDeinit(void) {
mCloseDecoder(mCtx,mHybridCtx);
mOMXBufferHeaderTypePtrNum = 0;
@@ -181,9 +234,21 @@ OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::ProcessorProcess(
int32_t time_ms;
gettimeofday(&tv_start,NULL);
#endif
- if (mDecoderDecode(mCtx,mHybridCtx,inBuffer->pBuffer + inBuffer->nOffset,inBuffer->nFilledLen, eos) == false) {
- LOGE("on2 decoder failed to decode frame.");
- return OMX_ErrorBadParameter;
+ int res = mDecoderDecode(mCtx,mHybridCtx,inBuffer->pBuffer + inBuffer->nOffset,inBuffer->nFilledLen, eos);
+ if (res != 0) {
+ if (res == -2) {
+ if (isReallocateNeeded(inBuffer->pBuffer + inBuffer->nOffset,inBuffer->nFilledLen)) {
+ retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
+ HandleFormatChange();
+ return OMX_ErrorNone;
+ }
+ // drain the last frame, keep the current input buffer
+ res = mDecoderDecode(mCtx,mHybridCtx,NULL,0,true);
+ retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
+ } else {
+ LOGE("on2 decoder failed to decode frame.");
+ return OMX_ErrorBadParameter;
+ }
}
#if LOG_TIME == 1
@@ -268,6 +333,7 @@ OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::FillRenderBuffer(OMX_BUFFERHEADERTYPE **
if (mDecodedImageHeight == 0 && mDecodedImageWidth == 0) {
mDecodedImageWidth = mDecodedImageNewWidth;
mDecodedImageHeight = mDecodedImageNewHeight;
+ *isResolutionChange = OMX_TRUE;
}
if ((mDecodedImageNewWidth != mDecodedImageWidth)
|| (mDecodedImageNewHeight!= mDecodedImageHeight)) {
@@ -316,6 +382,8 @@ OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::SetParamVideoVp9(OMX_PTR) {
OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::HandleFormatChange(void)
{
+ ALOGI("handle format change from %dx%d to %dx%d",
+ mDecodedImageWidth,mDecodedImageHeight,mDecodedImageNewWidth,mDecodedImageNewHeight);
mDecodedImageWidth = mDecodedImageNewWidth;
mDecodedImageHeight = mDecodedImageNewHeight;
// Sync port definition as it may change.
@@ -384,6 +452,7 @@ OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::HandleFormatChange(void)
paramPortDefinitionOutput.bEnabled = (OMX_BOOL)false;
mOMXBufferHeaderTypePtrNum = 0;
memset(&mGraphicBufferParam, 0, sizeof(mGraphicBufferParam));
+ mDeinitDecoder(mHybridCtx);
this->ports[INPORT_INDEX]->SetPortDefinition(&paramPortDefinitionInput, true);
this->ports[OUTPORT_INDEX]->SetPortDefinition(&paramPortDefinitionOutput, true);
@@ -456,6 +525,8 @@ OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::SetNativeBufferModeSpecific(OMX_PTR pStr
port_def.format.video.cMIMEType = (OMX_STRING)VA_VED_RAW_MIME_TYPE;
// add borders for libvpx decode need.
port_def.format.video.nFrameWidth += VPX_DECODE_BORDER * 2;
+ mDecodedImageWidth = port_def.format.video.nFrameWidth;
+ mDecodedImageHeight = port_def.format.video.nFrameHeight;
// make heigth 32bit align
port_def.format.video.nFrameHeight = (port_def.format.video.nFrameHeight + 0x1f) & ~0x1f;
port_def.format.video.eColorFormat = GetOutputColorFormat(port_def.format.video.nFrameWidth);
diff --git a/videocodec/OMXVideoDecoderVP9Hybrid.h b/videocodec/OMXVideoDecoderVP9Hybrid.h
index 5775620..f0fc2f1 100644
--- a/videocodec/OMXVideoDecoderVP9Hybrid.h
+++ b/videocodec/OMXVideoDecoderVP9Hybrid.h
@@ -38,6 +38,7 @@ protected:
OMX_BUFFERHEADERTYPE ***pBuffers,
buffer_retain_t *retains,
OMX_U32 numberBuffers);
+ virtual OMX_ERRORTYPE ProcessorReset(void);
virtual OMX_ERRORTYPE ProcessorPreFillBuffer(OMX_BUFFERHEADERTYPE* buffer);
virtual bool IsAllBufferAvailable(void);
@@ -57,6 +58,7 @@ protected:
DECLARE_HANDLER(OMXVideoDecoderVP9Hybrid, ParamVideoVp9);
private:
+ bool isReallocateNeeded(const uint8_t *data, uint32_t data_sz);
void *mCtx;
void *mHybridCtx;
void *mLibHandle;
@@ -69,10 +71,12 @@ private:
typedef bool (*InitFunc)(void *,uint32_t, uint32_t, uint32_t, uint32_t, bool, uint32_t *);
typedef bool (*CloseFunc)(void *, void *);
typedef bool (*SingalRenderDoneFunc)(void *, unsigned int);
- typedef bool (*DecodeFunc)(void *, void *, unsigned char *, unsigned int, bool);
+ typedef int (*DecodeFunc)(void *, void *, unsigned char *, unsigned int, bool);
typedef bool (*IsBufferAvailableFunc)(void *);
typedef int (*GetOutputFunc)(void*, void *, unsigned int *, unsigned int *);
typedef int (*GetRawDataOutputFunc)(void*, void *, unsigned char *, int, int);
+ typedef void (*DeinitFunc)(void *);
+ typedef bool (*GetFrameResolutionFunc)(const uint8_t *, uint32_t , uint32_t *, uint32_t *);
OpenFunc mOpenDecoder;
InitFunc mInitDecoder;
CloseFunc mCloseDecoder;
@@ -81,6 +85,8 @@ private:
IsBufferAvailableFunc mCheckBufferAvailable;
GetOutputFunc mGetOutput;
GetRawDataOutputFunc mGetRawDataOutput;
+ GetFrameResolutionFunc mGetFrameResolution;
+ DeinitFunc mDeinitDecoder;
int64_t mLastTimeStamp;
enum {
// OMX_PARAM_PORTDEFINITIONTYPE