diff options
| author | Andy Qiu <junhai.qiu@intel.com> | 2012-05-15 17:21:57 -0700 |
|---|---|---|
| committer | Patrick Tjin <pattjin@google.com> | 2014-07-21 22:02:47 -0700 |
| commit | bc7b7fbfa1007b823a7e09c43d71bbee57f1f1ae (patch) | |
| tree | 7a56d0c7722db7bd307ed0b531ce33cf453bf62d | |
| parent | 6540b054b9f0beae74d92e2e006822cf67962b50 (diff) | |
| download | android_hardware_intel_common_omx-components-bc7b7fbfa1007b823a7e09c43d71bbee57f1f1ae.tar.gz android_hardware_intel_common_omx-components-bc7b7fbfa1007b823a7e09c43d71bbee57f1f1ae.tar.bz2 android_hardware_intel_common_omx-components-bc7b7fbfa1007b823a7e09c43d71bbee57f1f1ae.zip | |
[PORT FROM R3] Enhance pipeline to support HDCP authentication when playing protected content to HDMI.
BZ: 35857
During HDCP authentication, IED is disabled and video decryption fails. Video decoder needs to flush the pipeline
since IED is disabled and video will become scrambled if rendered. Video decoder will also reset decoding status since
reference frame may be dropped.
Change-Id: I9ab52299bff273fbecc48997f3bbb3c89002cf2f
Signed-off-by: Andy Qiu <junhai.qiu@intel.com>
Reviewed-on: http://android.intel.com:8080/48869
Reviewed-by: Ding, Haitao <haitao.ding@intel.com>
Tested-by: Ding, Haitao <haitao.ding@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
Signed-off-by: Andy Qiu <junhai.qiu@intel.com>
Reviewed-on: http://android.intel.com:8080/50575
Reviewed-by: Poornachandran, Rajesh <rajesh.poornachandran@intel.com>
Reviewed-by: Saffores, Ryan D <ryan.d.saffores@intel.com>
| -rw-r--r-- | videocodec/OMXVideoDecoderAVCSecure.cpp | 122 | ||||
| -rw-r--r-- | videocodec/OMXVideoDecoderAVCSecure.h | 2 |
2 files changed, 85 insertions, 39 deletions
diff --git a/videocodec/OMXVideoDecoderAVCSecure.cpp b/videocodec/OMXVideoDecoderAVCSecure.cpp index e3e0c3e..4f23287 100644 --- a/videocodec/OMXVideoDecoderAVCSecure.cpp +++ b/videocodec/OMXVideoDecoderAVCSecure.cpp @@ -22,6 +22,7 @@ #include <time.h> #include <signal.h> #include <pthread.h> + extern "C" { #include <sepdrm.h> } @@ -35,6 +36,7 @@ static const char* AVC_SECURE_MIME_TYPE = "video/avc-secure"; #define IMR_BUFFER_SIZE (8 * 1024 * 1024) #define WV_SESSION_ID 0x00000011 #define NALU_BUFFER_SIZE 8192 +#define FLUSH_WAIT_INTERVAL (30 * 1000) //30 ms #pragma pack(push, 1) @@ -48,7 +50,8 @@ struct IMRDataBuffer { OMXVideoDecoderAVCSecure::OMXVideoDecoderAVCSecure() - : mKeepAliveTimer(0) { + : mKeepAliveTimer(0), + mSessionPaused(false) { LOGV("OMXVideoDecoderAVCSecure is constructed."); mVideoDecoder = createVideoDecoder(AVC_SECURE_MIME_TYPE); if (!mVideoDecoder) { @@ -56,6 +59,7 @@ OMXVideoDecoderAVCSecure::OMXVideoDecoderAVCSecure() } // Override default native buffer count defined in the base class mNativeBufferCount = OUTPORT_NATIVE_BUFFER_COUNT; + BuildHandlerList(); } @@ -90,43 +94,15 @@ OMX_ERRORTYPE OMXVideoDecoderAVCSecure::InitInputPortFormatSpecific(OMX_PARAM_PO } OMX_ERRORTYPE OMXVideoDecoderAVCSecure::ProcessorInit(void) { - 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."); - } - - 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."); - } - sec_result_t sepres = Drm_Library_Init(); if (sepres != 0) { LOGE("Drm_Library_Init returned %08X", (unsigned int)sepres); } - + mSessionPaused = false; return OMXVideoDecoderBase::ProcessorInit(); } OMX_ERRORTYPE OMXVideoDecoderAVCSecure::ProcessorDeinit(void) { - if (mKeepAliveTimer != 0) { - timer_delete(mKeepAliveTimer); - mKeepAliveTimer = 0; - } - // Session should be torn down in ProcessorStop, delayed to ProcessorDeinit // to allow remaining frames completely rendered. sec_result_t sepres = Drm_DestroySession(WV_SESSION_ID); @@ -143,20 +119,49 @@ OMX_ERRORTYPE OMXVideoDecoderAVCSecure::ProcessorStart(void) { uint32_t sessionID; sec_result_t sepres = Drm_WV_CreateSession(&imrOffset, &imrBufferSize, &sessionID); if (sepres != 0) { - LOGE("Drm_WV_CreateSession failed. Result = %#x", sepres); - // TODO: return OMX_ErrorHardware - // Ignored temporarily, as this component can be used to play protected video using SW implementation. + 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_CreateSession: IMR Offset = %d, IMR size = %#x", imrOffset, imrBufferSize); + 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."); + } + + 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(); } @@ -169,7 +174,38 @@ OMX_ERRORTYPE OMXVideoDecoderAVCSecure::ProcessorProcess( OMX_BUFFERHEADERTYPE ***pBuffers, buffer_retain_t *retains, OMX_U32 numberBuffers) { - return OMXVideoDecoderBase::ProcessorProcess(pBuffers, retains, 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 = IMR_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) { + 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) { @@ -223,13 +259,20 @@ OMX_ERRORTYPE OMXVideoDecoderAVCSecure::PrepareDecodeBuffer(OMX_BUFFERHEADERTYPE } else { imrBuffer->size = NALU_BUFFER_SIZE; sec_result_t res = Drm_WV_ReturnNALUHeaders(WV_SESSION_ID, imrBuffer->offset, buffer->nFilledLen, imrBuffer->data, (uint32_t *)&(imrBuffer->size)); - if (res != 0) { + if (res == DRM_FAIL_FW_SESSION) { + 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, IMR offset = %d, len = %d", res, imrBuffer->offset, buffer->nFilledLen); - return OMX_ErrorHardware; + ret = OMX_ErrorHardware; + } else { + mSessionPaused = false; + p->data = imrBuffer->data; + p->size = imrBuffer->size; + p->flag |= IS_SECURE_DATA; } - p->data = imrBuffer->data; - p->size = imrBuffer->size; - p->flag |= IS_SECURE_DATA; } //reset IMR size @@ -366,4 +409,5 @@ void OMXVideoDecoderAVCSecure::KeepAliveTimerCallback() { Drm_KeepAlive(WV_SESSION_ID, &timeout); } + DECLARE_OMX_COMPONENT("OMX.Intel.VideoDecoder.AVC.secure", "video_decoder.avc", OMXVideoDecoderAVCSecure); diff --git a/videocodec/OMXVideoDecoderAVCSecure.h b/videocodec/OMXVideoDecoderAVCSecure.h index 4fdfc10..7f9fc10 100644 --- a/videocodec/OMXVideoDecoderAVCSecure.h +++ b/videocodec/OMXVideoDecoderAVCSecure.h @@ -76,6 +76,8 @@ private: } mIMRSlot[INPORT_ACTUAL_BUFFER_COUNT]; timer_t mKeepAliveTimer; + + bool mSessionPaused; }; #endif /* OMX_VIDEO_DECODER_AVC_SECURE_H_ */ |
