2

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)
fadden
  • 51,356
  • 5
  • 116
  • 166
user588477
  • 165
  • 11

1 Answers1

4

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.)

fadden
  • 51,356
  • 5
  • 116
  • 166
  • Could it possible to transform from SurfaceView to SurfaceTexture? – user588477 May 18 '16 at 06:46
  • Or is it possible to use MediaCodec->Configure( without a surface?) – user588477 May 18 '16 at 07:00
  • Even if you succeed in configuring MediaCodec, the "trusted path" mechanism will prevent you from gaining access to the pixel data. For example, try rotating a device while playing a DRM-protected movie from the Play Store. Normally the framework captures the screen and uses it to animate the rotation, but the video player just goes black... not even SurfaceFlinger can read the pixels. The app can set the position, size, and orientation of the SurfaceView, but that's about it. – fadden May 18 '16 at 15:31
  • I try using surfaceview for our code. I played clearkey test sample and also got the error when dequeueoutputbuffer. The queuesecureinputbuffer returns success, I don't know why deuqueoutputbuffer will get such error. – user588477 May 26 '16 at 09:53
  • The error is E/OMX-VDEC-1080P( 187): ERROR: Sending OMX_EventError to Client E/ ( 187): not in avi mode E/ACodec (21747): [OMX.qcom.video.decoder.avc] ERROR(0x80001009) E/ACodec (21747): signalError(omxError 0x80001009, internalError -2147483648) E/MediaCodec(21747): Codec reported err 0x80001009, actionCode 0, while in state 6 W/System.err(21747): java.lang.IllegalStateException W/System.err(21747): at android.media.MediaCodec.native_dequeueOutputBuffer(Native Method) W/System.err(21747): at android.media.MediaCodec.dequeueOutputBuffer(MediaCodec.java:1033) – user588477 May 26 '16 at 09:56