2
votes

Is it possible to decrypt and decode data using MediaCodec API? I want to decrypt and decode the data which is encrypted by widevine or other DRM mechanism. The basic thing I want to try is I configured the MediaCodec with Surface which is created from SurfaceTexure. MediaCodec->configure(..????., with mediacrypto instance, ...) I'm not sure if I can pass SurfaceTexture in this case? Or any secure configure I should do?

MediaCodec->start()
MediaCodec->queuesecureinputbuffer(...,with cryptoinfo,...)
MediaCodec->dequeoutputbuffer() to get the decoded data back....

The sample I could find is to directly render decrypted data onto a SurfaceView.

But I just want to get the decoded buffer or a SurfaceTexture which is rendered by the MediaCodec.

If I didn't set any secure configure such as MediaFormat->SetFeatureEnabled("secure-playback", true); use OMX.qcom.video.decoder.avc to create the decoder. I will get such error,

E/OMX-VDEC-1080P(23290): 
E/OMX-VDEC-1080P(23290): ERROR: Sending OMX_EventError to Client
E/        (23290): not in avi mode
E/ACodec  ( 1930): [OMX.qcom.video.decoder.avc] ERROR(0x80001009)
E/ACodec  ( 1930): signalError(omxError 0x80001009, internalError -2147483648)
E/MediaCodec( 1930): Codec reported err 0x80001009, actionCode 0, while in state 6
W/System.err( 1930): java.lang.IllegalStateException
W/System.err( 1930):  at android.media.MediaCodec.native_dequeueOutputBuffer(Native Method)
W/System.err( 1930):  at android.media.MediaCodec.dequeueOutputBuffer(MediaCodec.java:1033)

Once I set the secure config and use MediaCodec::CreateByCodecName(with ".secure" appended) I will get this kind of error...

E/ACodec: native window could not be authenticated
E/ACodec: Failed to allocate buffers after transitioning to IDLE state (error 0xffffffff)
E/ACodec: signalError(omxError 0x80001001, internalError -1)
1

1 Answers

4
votes

It depends to some extent on the device's hardware, but generally speaking, DRM-protected video can only be sent to a SurfaceView. Further, the SurfaceView's Surface must be on a hardware overlay.

DRM-protected video is decrypted by the video decoder hardware, and the decoded frames are written to memory that is inaccessible to software. Not even the Linux kernel can read from it. The frames are passed by handle to Hardware Composer, which tells the display hardware to show them on an overlay plane.

Because the memory is only accessible to the video decoder and the display, it can't be accessed by the GPU, which means the data can't be used as a GLES external texture. The frame cannot be composited with GLES, so if HWC isn't able to allocate an overlay the video will not appear. (For more about HWC and composition, see the graphics arch doc.)