aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Qiu <junhai.qiu@intel.com>2012-05-15 17:21:57 -0700
committerPatrick Tjin <pattjin@google.com>2014-07-21 22:02:47 -0700
commitbc7b7fbfa1007b823a7e09c43d71bbee57f1f1ae (patch)
tree7a56d0c7722db7bd307ed0b531ce33cf453bf62d
parent6540b054b9f0beae74d92e2e006822cf67962b50 (diff)
downloadandroid_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.cpp122
-rw-r--r--videocodec/OMXVideoDecoderAVCSecure.h2
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_ */