diff options
| author | Ryan Saffores <ryan.d.saffores@intel.com> | 2013-12-03 15:20:23 -0800 |
|---|---|---|
| committer | Patrick Tjin <pattjin@google.com> | 2014-07-21 22:02:56 -0700 |
| commit | b6f41f9d03897dbc6e44887d2e3ad2d7a26ed203 (patch) | |
| tree | f4c8c9f2d404b6ecd62d9402c977a6b100e15e0b /videocodec/securevideo | |
| parent | d7335ebe601f03f24d166e992b8c998e750908f6 (diff) | |
| download | android_hardware_intel_common_omx-components-b6f41f9d03897dbc6e44887d2e3ad2d7a26ed203.tar.gz android_hardware_intel_common_omx-components-b6f41f9d03897dbc6e44887d2e3ad2d7a26ed203.tar.bz2 android_hardware_intel_common_omx-components-b6f41f9d03897dbc6e44887d2e3ad2d7a26ed203.zip | |
Adding secure video decoder for merrplus build target
BZ: 156327
Adding directory with secure video decoder for merrplus
build target to enable Anniedale PO
Change-Id: I39c083f633228894e186c8bff69d1dd73444728b
Signed-off-by: Ryan Saffores <ryan.d.saffores@intel.com>
Diffstat (limited to 'videocodec/securevideo')
| -rw-r--r-- | videocodec/securevideo/merrplus/OMXVideoDecoderAVCSecure.cpp | 465 | ||||
| -rw-r--r-- | videocodec/securevideo/merrplus/OMXVideoDecoderAVCSecure.h | 86 |
2 files changed, 551 insertions, 0 deletions
diff --git a/videocodec/securevideo/merrplus/OMXVideoDecoderAVCSecure.cpp b/videocodec/securevideo/merrplus/OMXVideoDecoderAVCSecure.cpp new file mode 100644 index 0000000..590c9ea --- /dev/null +++ b/videocodec/securevideo/merrplus/OMXVideoDecoderAVCSecure.cpp @@ -0,0 +1,465 @@ +/* +* Copyright (c) 2009-2012 Intel Corporation. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +//#define LOG_NDEBUG 0 +#define LOG_TAG "OMXVideoDecoder" +#include <utils/Log.h> +#include "OMXVideoDecoderAVCSecure.h" +#include <time.h> +#include <signal.h> +#include <pthread.h> + +extern "C" { +#include <sepdrm.h> +#include <fcntl.h> +#include <linux/psb_drm.h> +#include "xf86drm.h" +#include "xf86drmMode.h" +} + +// Be sure to have an equal string in VideoDecoderHost.cpp (libmix) +static const char* AVC_MIME_TYPE = "video/avc"; +static const char* AVC_SECURE_MIME_TYPE = "video/avc-secure"; + +#define IMR_INITIAL_OFFSET 0 //1024 +#define IMR_BUFFER_SIZE (8 * 1024 * 1024) +#define KEEP_ALIVE_INTERVAL 5 // seconds +#define DRM_KEEP_ALIVE_TIMER 1000000 +#define WV_SESSION_ID 0x00000011 +#define NALU_BUFFER_SIZE 8192 +#define FLUSH_WAIT_INTERVAL (30 * 1000) //30 ms + + +#pragma pack(push, 1) +struct IMRDataBuffer { + uint32_t offset; + uint32_t size; + uint8_t *data; + uint8_t clear; // 0 when IMR offset is valid, 1 when data is valid +}; +#pragma pack(pop) + +OMXVideoDecoderAVCSecure::OMXVideoDecoderAVCSecure() + : mKeepAliveTimer(0), + mSessionPaused(false), + mDrmDevFd(-1) { + LOGV("OMXVideoDecoderAVCSecure is constructed."); + mVideoDecoder = createVideoDecoder(AVC_SECURE_MIME_TYPE); + if (!mVideoDecoder) { + LOGE("createVideoDecoder failed for \"%s\"", AVC_SECURE_MIME_TYPE); + } + // Override default native buffer count defined in the base class + mNativeBufferCount = OUTPORT_NATIVE_BUFFER_COUNT; + + BuildHandlerList(); + + mDrmDevFd = open("/dev/card0", O_RDWR, 0); + if (mDrmDevFd < 0) { + LOGE("Failed to open drm device."); + } +} + +OMXVideoDecoderAVCSecure::~OMXVideoDecoderAVCSecure() { + LOGV("OMXVideoDecoderAVCSecure is destructed."); + + if (mDrmDevFd) { + close(mDrmDevFd); + mDrmDevFd = 0; + } +} + +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::InitInputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput) { + // OMX_PARAM_PORTDEFINITIONTYPE + paramPortDefinitionInput->nBufferCountActual = INPORT_ACTUAL_BUFFER_COUNT; + paramPortDefinitionInput->nBufferCountMin = INPORT_MIN_BUFFER_COUNT; + paramPortDefinitionInput->nBufferSize = INPORT_BUFFER_SIZE; + paramPortDefinitionInput->format.video.cMIMEType = (OMX_STRING)AVC_MIME_TYPE; + paramPortDefinitionInput->format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; + + // OMX_VIDEO_PARAM_AVCTYPE + memset(&mParamAvc, 0, sizeof(mParamAvc)); + SetTypeHeader(&mParamAvc, sizeof(mParamAvc)); + mParamAvc.nPortIndex = INPORT_INDEX; + // TODO: check eProfile/eLevel + mParamAvc.eProfile = OMX_VIDEO_AVCProfileHigh; //OMX_VIDEO_AVCProfileBaseline; + mParamAvc.eLevel = OMX_VIDEO_AVCLevel41; //OMX_VIDEO_AVCLevel1; + + this->ports[INPORT_INDEX]->SetMemAllocator(MemAllocIMR, MemFreeIMR, this); + + for (int i = 0; i < INPORT_ACTUAL_BUFFER_COUNT; i++) { + mIMRSlot[i].offset = IMR_INITIAL_OFFSET + i * INPORT_BUFFER_SIZE; + mIMRSlot[i].owner = NULL; + } + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::ProcessorInit(void) { + mSessionPaused = false; + return OMXVideoDecoderBase::ProcessorInit(); +} + +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::ProcessorDeinit(void) { + // Session should be torn down in ProcessorStop, delayed to ProcessorDeinit + // to allow remaining frames completely rendered. + LOGI("Calling Drm_DestroySession."); + uint32_t sepres = drm_destroy_session(WV_SESSION_ID); + if (sepres != 0) { + LOGW("Drm_DestroySession returns %#x", sepres); + } + EnableIEDSession(false); + + return OMXVideoDecoderBase::ProcessorDeinit(); +} + +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::ProcessorStart(void) { + uint32_t imrOffset = 0; + uint32_t imrBufferSize = IMR_BUFFER_SIZE; + uint32_t sessionID; + + EnableIEDSession(true); + uint32_t sepres = drm_wv_create_session( &sessionID); + if (sepres != 0) { + LOGW("Drm_WV_CreateSession failed. Result = %#x", sepres); + // Returning error will cause OMX client to crash. + //return OMX_ErrorHardware; + } + if (sessionID != WV_SESSION_ID) { + LOGE("Invalid session ID %#x created", sessionID); + //return OMX_ErrorHardware; + } + LOGI("drm_wv_create_session: sessionID = %#x", sessionID); + + //drmCommandNone(mDrmDevFd, DRM_PSB_HDCP_DISPLAY_IED_OFF); + + int ret; + struct sigevent sev; + memset(&sev, 0, sizeof(sev)); + sev.sigev_notify = SIGEV_THREAD; + sev.sigev_value.sival_ptr = this; + sev.sigev_notify_function = KeepAliveTimerCallback; + + ret = timer_create(CLOCK_REALTIME, &sev, &mKeepAliveTimer); + if (ret != 0) { + LOGE("Failed to create timer."); + } else { + struct itimerspec its; + its.it_value.tv_sec = -1; // never expire + its.it_value.tv_nsec = 0; + its.it_interval.tv_sec = KEEP_ALIVE_INTERVAL; + its.it_interval.tv_nsec = 0; + + ret = timer_settime(mKeepAliveTimer, TIMER_ABSTIME, &its, NULL); + if (ret != 0) { + LOGE("Failed to set timer."); + } + } + mSessionPaused = false; + return OMXVideoDecoderBase::ProcessorStart(); +} + +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::ProcessorStop(void) { + if (mKeepAliveTimer != 0) { + timer_delete(mKeepAliveTimer); + mKeepAliveTimer = 0; + } + + return OMXVideoDecoderBase::ProcessorStop(); +} + + +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::ProcessorFlush(OMX_U32 portIndex) { + return OMXVideoDecoderBase::ProcessorFlush(portIndex); +} + +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::ProcessorProcess( + OMX_BUFFERHEADERTYPE ***pBuffers, + buffer_retain_t *retains, + OMX_U32 numberBuffers) { + + OMX_BUFFERHEADERTYPE *pInput = *pBuffers[INPORT_INDEX]; + IMRDataBuffer *imrBuffer = (IMRDataBuffer *)pInput->pBuffer; + if (imrBuffer->size == 0) { + // error occurs during decryption. + LOGW("size of returned IMR buffer is 0, decryption fails."); + mVideoDecoder->flush(); + usleep(FLUSH_WAIT_INTERVAL); + OMX_BUFFERHEADERTYPE *pOutput = *pBuffers[OUTPORT_INDEX]; + pOutput->nFilledLen = 0; + // reset IMR buffer size + imrBuffer->size = INPORT_BUFFER_SIZE; + this->ports[INPORT_INDEX]->FlushPort(); + this->ports[OUTPORT_INDEX]->FlushPort(); + return OMX_ErrorNone; + } + + OMX_ERRORTYPE ret; + ret = OMXVideoDecoderBase::ProcessorProcess(pBuffers, retains, numberBuffers); + if (ret != OMX_ErrorNone) { + LOGE("OMXVideoDecoderBase::ProcessorProcess failed. Result: %#x", ret); + return ret; + } + + if (mSessionPaused && (retains[OUTPORT_INDEX] == BUFFER_RETAIN_GETAGAIN)) { + retains[OUTPORT_INDEX] = BUFFER_RETAIN_NOT_RETAIN; + OMX_BUFFERHEADERTYPE *pOutput = *pBuffers[OUTPORT_INDEX]; + pOutput->nFilledLen = 0; + this->ports[INPORT_INDEX]->FlushPort(); + this->ports[OUTPORT_INDEX]->FlushPort(); + } + + return ret; +} + +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::ProcessorPause(void) { +#if 0 + uint32_t sepres = Drm_Playback_Pause(WV_SESSION_ID); + if (sepres != 0) { + LOGE("Drm_Playback_Pause failed. Result = %#x", sepres); + } +#endif + return OMXVideoDecoderBase::ProcessorPause(); +} + +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::ProcessorResume(void) { +#if 0 + uint32_t sepres = Drm_Playback_Resume(WV_SESSION_ID); + if (sepres != 0) { + LOGE("Drm_Playback_Resume failed. Result = %#x", sepres); + } +#endif + return OMXVideoDecoderBase::ProcessorResume(); +} + +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::PrepareConfigBuffer(VideoConfigBuffer *p) { + OMX_ERRORTYPE ret; + ret = OMXVideoDecoderBase::PrepareConfigBuffer(p); + CHECK_RETURN_VALUE("OMXVideoDecoderBase::PrepareConfigBuffer"); + p->flag |= WANT_SURFACE_PROTECTION; + return ret; +} + +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::PrepareDecodeBuffer(OMX_BUFFERHEADERTYPE *buffer, buffer_retain_t *retain, VideoDecodeBuffer *p) { + OMX_ERRORTYPE ret; + ret = OMXVideoDecoderBase::PrepareDecodeBuffer(buffer, retain, p); + CHECK_RETURN_VALUE("OMXVideoDecoderBase::PrepareDecodeBuffer"); + + if (buffer->nFilledLen == 0) { + return OMX_ErrorNone; + } + // OMX_BUFFERFLAG_CODECCONFIG is an optional flag + // if flag is set, buffer will only contain codec data. + if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { + LOGV("Received AVC codec data."); + return ret; + } + p->flag |= HAS_COMPLETE_FRAME; + + if (buffer->nOffset != 0) { + LOGW("buffer offset %lu is not zero!!!", buffer->nOffset); + } + + IMRDataBuffer *imrBuffer = (IMRDataBuffer *)buffer->pBuffer; + if (imrBuffer->clear) { + p->data = imrBuffer->data + buffer->nOffset; + p->size = buffer->nFilledLen; + } else { + imrBuffer->size = NALU_BUFFER_SIZE; + struct drm_wv_nalu_headers nalu_headers; + nalu_headers.p_enc_ciphertext = imrBuffer->data; + + // TODO: NALU Buffer is supposed to be 4k but using 1k, fix it once chaabi fix is there + + nalu_headers.hdrs_buf_len = 1024; + nalu_headers.frame_size = buffer->nFilledLen; + // Make sure that NALU header frame size is 16 bytes aligned + nalu_headers.frame_size = (nalu_headers.frame_size + 0xF) & (~0xF); + // Use same video buffer to fill NALU headers returned by chaabi, + // Adding 4 because the first 4 bytes after databuffer will be used to store length of NALU headers + nalu_headers.p_hdrs_buf = (uint8_t *)(imrBuffer->data + nalu_headers.frame_size + 4); + nalu_headers.parse_size = buffer->nFilledLen; + + uint32_t res = drm_wv_return_naluheaders(WV_SESSION_ID, &nalu_headers); + if (res == DRM_FAIL_FW_SESSION || !nalu_headers.hdrs_buf_len) { + LOGW("Drm_WV_ReturnNALUHeaders failed. Session is disabled."); + mSessionPaused = true; + ret = OMX_ErrorNotReady; + } else if (res != 0) { + mSessionPaused = false; + LOGE("Drm_WV_ReturnNALUHeaders failed. Error = %#x, frame_size: %d, len = %lu", res, nalu_headers.frame_size, buffer->nFilledLen); + ret = OMX_ErrorHardware; + } else { + mSessionPaused = false; + // NALU headers are appended to encrypted video bitstream + // |...encrypted video bitstream (16 bytes aligned)...| 4 bytes of header size |...NALU headers..| + uint32_t *ptr = (uint32_t*)(imrBuffer->data + nalu_headers.frame_size); + *ptr = nalu_headers.hdrs_buf_len; + p->data = imrBuffer->data; + p->size = nalu_headers.frame_size; + p->flag |= IS_SECURE_DATA; + } + } + + // reset IMR size + imrBuffer->size = NALU_BUFFER_SIZE; + return ret; +} + +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::BuildHandlerList(void) { + OMXVideoDecoderBase::BuildHandlerList(); + AddHandler(OMX_IndexParamVideoAvc, GetParamVideoAvc, SetParamVideoAvc); + AddHandler(OMX_IndexParamVideoProfileLevelQuerySupported, GetParamVideoAVCProfileLevel, SetParamVideoAVCProfileLevel); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::GetParamVideoAvc(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_PARAM_AVCTYPE *p = (OMX_VIDEO_PARAM_AVCTYPE *)pStructure; + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, INPORT_INDEX); + + memcpy(p, &mParamAvc, sizeof(*p)); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::SetParamVideoAvc(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_PARAM_AVCTYPE *p = (OMX_VIDEO_PARAM_AVCTYPE *)pStructure; + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, INPORT_INDEX); + CHECK_SET_PARAM_STATE(); + + // TODO: do we need to check if port is enabled? + // TODO: see SetPortAvcParam implementation - Can we make simple copy???? + memcpy(&mParamAvc, p, sizeof(mParamAvc)); + return OMX_ErrorNone; +} + + +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::GetParamVideoAVCProfileLevel(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_PARAM_PROFILELEVELTYPE *p = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pStructure; + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, INPORT_INDEX); + CHECK_ENUMERATION_RANGE(p->nProfileIndex,1); + + p->eProfile = mParamAvc.eProfile; + p->eLevel = mParamAvc.eLevel; + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::SetParamVideoAVCProfileLevel(OMX_PTR pStructure) { + LOGW("SetParamVideoAVCProfileLevel is not supported."); + return OMX_ErrorUnsupportedSetting; +} + +OMX_U8* OMXVideoDecoderAVCSecure::MemAllocIMR(OMX_U32 nSizeBytes, OMX_PTR pUserData) { + OMXVideoDecoderAVCSecure* p = (OMXVideoDecoderAVCSecure *)pUserData; + if (p) { + return p->MemAllocIMR(nSizeBytes); + } + LOGE("NULL pUserData."); + return NULL; +} + +void OMXVideoDecoderAVCSecure::MemFreeIMR(OMX_U8 *pBuffer, OMX_PTR pUserData) { + OMXVideoDecoderAVCSecure* p = (OMXVideoDecoderAVCSecure *)pUserData; + if (p) { + p->MemFreeIMR(pBuffer); + return; + } + LOGE("NULL pUserData."); +} + +OMX_U8* OMXVideoDecoderAVCSecure::MemAllocIMR(OMX_U32 nSizeBytes) { + if (nSizeBytes > INPORT_BUFFER_SIZE) { + LOGE("Invalid size (%lu) of memory to allocate.", nSizeBytes); + return NULL; + } + LOGW_IF(nSizeBytes != INPORT_BUFFER_SIZE, "Size of memory to allocate is %lu", nSizeBytes); + for (int i = 0; i < INPORT_ACTUAL_BUFFER_COUNT; i++) { + if (mIMRSlot[i].owner == NULL) { + IMRDataBuffer *pBuffer = new IMRDataBuffer; + if (pBuffer == NULL) { + LOGE("Failed to allocate memory."); + return NULL; + } + + pBuffer->data = new uint8_t [INPORT_BUFFER_SIZE]; + if (pBuffer->data == NULL) { + delete pBuffer; + LOGE("Failed to allocate memory, size to allocate %d.", INPORT_BUFFER_SIZE); + return NULL; + } + + pBuffer->offset = mIMRSlot[i].offset; + pBuffer->size = INPORT_BUFFER_SIZE; + mIMRSlot[i].owner = (OMX_U8 *)pBuffer; + + LOGV("Allocating buffer = %#x, IMR offset = %#x, data = %#x", (uint32_t)pBuffer, mIMRSlot[i].offset, (uint32_t)pBuffer->data); + return (OMX_U8 *) pBuffer; + } + } + LOGE("IMR slot is not available."); + return NULL; +} + +void OMXVideoDecoderAVCSecure::MemFreeIMR(OMX_U8 *pBuffer) { + IMRDataBuffer *p = (IMRDataBuffer*) pBuffer; + if (p == NULL) { + return; + } + for (int i = 0; i < INPORT_ACTUAL_BUFFER_COUNT; i++) { + if (pBuffer == mIMRSlot[i].owner) { + LOGV("Freeing IMR offset = %d, data = %#x", mIMRSlot[i].offset, (uint32_t)p->data); + delete [] p->data; + delete p; + mIMRSlot[i].owner = NULL; + return; + } + } + LOGE("Invalid buffer %#x to de-allocate", (uint32_t)pBuffer); +} + +void OMXVideoDecoderAVCSecure::KeepAliveTimerCallback(sigval v) { + OMXVideoDecoderAVCSecure *p = (OMXVideoDecoderAVCSecure *)v.sival_ptr; + if (p) { + p->KeepAliveTimerCallback(); + } +} + +void OMXVideoDecoderAVCSecure::KeepAliveTimerCallback() { + uint32_t timeout = DRM_KEEP_ALIVE_TIMER; + uint32_t sepres = drm_keep_alive(WV_SESSION_ID, &timeout); + if (sepres != 0) { + LOGE("Drm_KeepAlive failed. Result = %#x", sepres); + } +} + + +bool OMXVideoDecoderAVCSecure::EnableIEDSession(bool enable) +{ + if (mDrmDevFd < 0) { + return false; + } + int request = enable ? DRM_PSB_ENABLE_IED_SESSION : DRM_PSB_DISABLE_IED_SESSION; + int ret = drmCommandNone(mDrmDevFd, request); + return ret == 0; +} + +DECLARE_OMX_COMPONENT("OMX.Intel.VideoDecoder.AVC.secure", "video_decoder.avc", OMXVideoDecoderAVCSecure); diff --git a/videocodec/securevideo/merrplus/OMXVideoDecoderAVCSecure.h b/videocodec/securevideo/merrplus/OMXVideoDecoderAVCSecure.h new file mode 100644 index 0000000..733f959 --- /dev/null +++ b/videocodec/securevideo/merrplus/OMXVideoDecoderAVCSecure.h @@ -0,0 +1,86 @@ +/* +* Copyright (c) 2009-2012 Intel Corporation. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef OMX_VIDEO_DECODER_AVC_SECURE_H_ +#define OMX_VIDEO_DECODER_AVC_SECURE_H_ + + +#include "OMXVideoDecoderBase.h" + +class OMXVideoDecoderAVCSecure : public OMXVideoDecoderBase { +public: + OMXVideoDecoderAVCSecure(); + virtual ~OMXVideoDecoderAVCSecure(); + +protected: + virtual OMX_ERRORTYPE InitInputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput); + virtual OMX_ERRORTYPE ProcessorInit(void); + virtual OMX_ERRORTYPE ProcessorDeinit(void); + virtual OMX_ERRORTYPE ProcessorStart(void); + virtual OMX_ERRORTYPE ProcessorStop(void); + virtual OMX_ERRORTYPE ProcessorPause(void); + virtual OMX_ERRORTYPE ProcessorResume(void); + virtual OMX_ERRORTYPE ProcessorFlush(OMX_U32 portIndex); + virtual OMX_ERRORTYPE ProcessorProcess( + OMX_BUFFERHEADERTYPE ***pBuffers, + buffer_retain_t *retains, + OMX_U32 numberBuffers); + + virtual OMX_ERRORTYPE PrepareConfigBuffer(VideoConfigBuffer *p); + virtual OMX_ERRORTYPE PrepareDecodeBuffer(OMX_BUFFERHEADERTYPE *buffer, buffer_retain_t *retain, VideoDecodeBuffer *p); + + virtual OMX_ERRORTYPE BuildHandlerList(void); + DECLARE_HANDLER(OMXVideoDecoderAVCSecure, ParamVideoAvc); + DECLARE_HANDLER(OMXVideoDecoderAVCSecure, ParamVideoAVCProfileLevel); + +private: + static OMX_U8* MemAllocIMR(OMX_U32 nSizeBytes, OMX_PTR pUserData); + static void MemFreeIMR(OMX_U8 *pBuffer, OMX_PTR pUserData); + OMX_U8* MemAllocIMR(OMX_U32 nSizeBytes); + void MemFreeIMR(OMX_U8 *pBuffer); + static void KeepAliveTimerCallback(sigval v); + void KeepAliveTimerCallback(); + bool EnableIEDSession(bool enable); + +private: + enum { + // OMX_PARAM_PORTDEFINITIONTYPE + INPORT_MIN_BUFFER_COUNT = 1, + INPORT_ACTUAL_BUFFER_COUNT = 5, + INPORT_BUFFER_SIZE = 1382400, + + // for OMX_VIDEO_PARAM_INTEL_AVC_DECODE_SETTINGS + // default number of reference frame + NUM_REFERENCE_FRAME = 4, + + // a typical value for 1080p clips + OUTPORT_NATIVE_BUFFER_COUNT = 17, + }; + + OMX_VIDEO_PARAM_AVCTYPE mParamAvc; + + struct IMRSlot { + uint32_t offset; + uint8_t *owner; // pointer to OMX buffer that owns this slot + } mIMRSlot[INPORT_ACTUAL_BUFFER_COUNT]; + + timer_t mKeepAliveTimer; + + bool mSessionPaused; + int mDrmDevFd; +}; + +#endif /* OMX_VIDEO_DECODER_AVC_SECURE_H_ */ |
