mediacodec_drm.patch (9722B)
1 diff --git a/media/ffvpx/libavcodec/avcodec.h b/media/ffvpx/libavcodec/avcodec.h 2 --- a/media/ffvpx/libavcodec/avcodec.h 3 +++ b/media/ffvpx/libavcodec/avcodec.h 4 @@ -2105,6 +2105,8 @@ typedef struct AVCodecContext { 5 */ 6 AVFrameSideData **decoded_side_data; 7 int nb_decoded_side_data; 8 + 9 + void* moz_ndk_crypto; 10 } AVCodecContext; 11 12 /** 13 diff --git a/media/ffvpx/libavcodec/mediacodec_wrapper.c b/media/ffvpx/libavcodec/mediacodec_wrapper.c 14 --- a/media/ffvpx/libavcodec/mediacodec_wrapper.c 15 +++ b/media/ffvpx/libavcodec/mediacodec_wrapper.c 16 @@ -1537,6 +1537,11 @@ fail: 17 return ret; 18 } 19 20 +static int mediacodec_jni_queueSecureInputBuffer(FFAMediaCodec* ctx, size_t idx, off_t offset, void* cryptoInfo, uint64_t time, uint32_t flags) 21 +{ 22 + return AVERROR_PATCHWELCOME; 23 +} 24 + 25 static ssize_t mediacodec_jni_dequeueOutputBuffer(FFAMediaCodec* ctx, FFAMediaCodecBufferInfo *info, int64_t timeoutUs) 26 { 27 int ret = 0; 28 @@ -1811,6 +1816,7 @@ static const FFAMediaCodec media_codec_jni = { 29 30 .dequeueInputBuffer = mediacodec_jni_dequeueInputBuffer, 31 .queueInputBuffer = mediacodec_jni_queueInputBuffer, 32 + .queueSecureInputBuffer = mediacodec_jni_queueSecureInputBuffer, 33 34 .dequeueOutputBuffer = mediacodec_jni_dequeueOutputBuffer, 35 .getOutputFormat = mediacodec_jni_getOutputFormat, 36 @@ -2209,7 +2215,7 @@ static int mediacodec_ndk_configure(FFAMediaCodec* ctx, 37 return AVERROR_EXTERNAL; 38 } 39 } else { 40 - status = AMediaCodec_configure(codec->impl, format->impl, native_window, NULL, flags); 41 + status = AMediaCodec_configure(codec->impl, format->impl, native_window, (AMediaCrypto*)crypto, flags); 42 if (status != AMEDIA_OK) { 43 av_log(codec, AV_LOG_ERROR, "Decoder configure failed, %d\n", status); 44 return AVERROR_EXTERNAL; 45 @@ -2263,6 +2269,14 @@ static int mediacodec_ndk_queueInputBuffer(FFAMediaCodec *ctx, size_t idx, 46 return AMediaCodec_queueInputBuffer(codec->impl, idx, offset, size, time, flags); 47 } 48 49 +static int mediacodec_ndk_queueSecureInputBuffer(FFAMediaCodec *ctx, size_t idx, 50 + off_t offset, void* cryptoInfo, 51 + uint64_t time, uint32_t flags) 52 +{ 53 + FFAMediaCodecNdk *codec = (FFAMediaCodecNdk *)ctx; 54 + return AMediaCodec_queueSecureInputBuffer(codec->impl, idx, offset, (AMediaCodecCryptoInfo*)cryptoInfo, time, flags); 55 +} 56 + 57 static ssize_t mediacodec_ndk_dequeueOutputBuffer(FFAMediaCodec* ctx, FFAMediaCodecBufferInfo *info, int64_t timeoutUs) 58 { 59 FFAMediaCodecNdk *codec = (FFAMediaCodecNdk *)ctx; 60 @@ -2507,6 +2521,7 @@ static const FFAMediaCodec media_codec_ndk = { 61 62 .dequeueInputBuffer = mediacodec_ndk_dequeueInputBuffer, 63 .queueInputBuffer = mediacodec_ndk_queueInputBuffer, 64 + .queueSecureInputBuffer = mediacodec_ndk_queueSecureInputBuffer, 65 66 .dequeueOutputBuffer = mediacodec_ndk_dequeueOutputBuffer, 67 .getOutputFormat = mediacodec_ndk_getOutputFormat, 68 diff --git a/media/ffvpx/libavcodec/mediacodec_wrapper.h b/media/ffvpx/libavcodec/mediacodec_wrapper.h 69 --- a/media/ffvpx/libavcodec/mediacodec_wrapper.h 70 +++ b/media/ffvpx/libavcodec/mediacodec_wrapper.h 71 @@ -214,6 +214,7 @@ struct FFAMediaCodec { 72 73 ssize_t (*dequeueInputBuffer)(FFAMediaCodec* codec, int64_t timeoutUs); 74 int (*queueInputBuffer)(FFAMediaCodec* codec, size_t idx, off_t offset, size_t size, uint64_t time, uint32_t flags); 75 + int (*queueSecureInputBuffer)(FFAMediaCodec* codec, size_t idx, off_t offset, void* cryptoInfo, uint64_t time, uint32_t flags); 76 77 ssize_t (*dequeueOutputBuffer)(FFAMediaCodec* codec, FFAMediaCodecBufferInfo *info, int64_t timeoutUs); 78 FFAMediaFormat* (*getOutputFormat)(FFAMediaCodec* codec); 79 @@ -299,6 +300,11 @@ static inline int ff_AMediaCodec_queueInputBuffer(FFAMediaCodec *codec, size_t i 80 return codec->queueInputBuffer(codec, idx, offset, size, time, flags); 81 } 82 83 +static inline int ff_AMediaCodec_queueSecureInputBuffer(FFAMediaCodec *codec, size_t idx, off_t offset, void* cryptoInfo, uint64_t time, uint32_t flags) 84 +{ 85 + return codec->queueSecureInputBuffer(codec, idx, offset, cryptoInfo, time, flags); 86 +} 87 + 88 static inline ssize_t ff_AMediaCodec_dequeueOutputBuffer(FFAMediaCodec* codec, FFAMediaCodecBufferInfo *info, int64_t timeoutUs) 89 { 90 return codec->dequeueOutputBuffer(codec, info, timeoutUs); 91 diff --git a/media/ffvpx/libavcodec/mediacodecdec_common.c b/media/ffvpx/libavcodec/mediacodecdec_common.c 92 --- a/media/ffvpx/libavcodec/mediacodecdec_common.c 93 +++ b/media/ffvpx/libavcodec/mediacodecdec_common.c 94 @@ -837,7 +837,7 @@ int ff_mediacodec_dec_init(AVCodecContext *avctx, MediaCodecDecContext *s, 95 if (ret < 0) 96 goto fail; 97 98 - status = ff_AMediaCodec_configure(s->codec, format, s->surface, NULL, 0); 99 + status = ff_AMediaCodec_configure(s->codec, format, s->surface, avctx->moz_ndk_crypto, 0); 100 if (status < 0) { 101 char *desc = ff_AMediaFormat_toString(format); 102 av_log(avctx, AV_LOG_ERROR, 103 @@ -943,7 +943,11 @@ int ff_mediacodec_dec_send(AVCodecContext *avctx, MediaCodecDecContext *s, 104 105 av_log(avctx, AV_LOG_DEBUG, "Sending End Of Stream signal\n"); 106 107 - status = ff_AMediaCodec_queueInputBuffer(codec, index, 0, 0, pts, flags); 108 + if (pkt->moz_ndk_crypto_info) { 109 + status = ff_AMediaCodec_queueSecureInputBuffer(codec, index, 0, pkt->moz_ndk_crypto_info, pts, flags); 110 + } else { 111 + status = ff_AMediaCodec_queueInputBuffer(codec, index, 0, 0, pts, flags); 112 + } 113 if (status < 0) { 114 av_log(avctx, AV_LOG_ERROR, "Failed to queue input empty buffer (status = %d)\n", status); 115 return AVERROR_EXTERNAL; 116 @@ -960,7 +964,11 @@ int ff_mediacodec_dec_send(AVCodecContext *avctx, MediaCodecDecContext *s, 117 memcpy(data, pkt->data + offset, size); 118 offset += size; 119 120 - status = ff_AMediaCodec_queueInputBuffer(codec, index, 0, size, pts, 0); 121 + if (pkt->moz_ndk_crypto_info) { 122 + status = ff_AMediaCodec_queueSecureInputBuffer(codec, index, 0, pkt->moz_ndk_crypto_info, pts, 0); 123 + } else { 124 + status = ff_AMediaCodec_queueInputBuffer(codec, index, 0, size, pts, 0); 125 + } 126 if (status < 0) { 127 av_log(avctx, AV_LOG_ERROR, "Failed to queue input buffer (status = %d)\n", status); 128 return AVERROR_EXTERNAL; 129 diff --git a/media/ffvpx/libavcodec/packet.c b/media/ffvpx/libavcodec/packet.c 130 --- a/media/ffvpx/libavcodec/packet.c 131 +++ b/media/ffvpx/libavcodec/packet.c 132 @@ -390,6 +390,32 @@ int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type, 133 return AVERROR(ENOENT); 134 } 135 136 +static void av_packet_free_moz_crypto_info(AVPacket *pkt) { 137 + if (pkt->moz_crypto_info_release && pkt->moz_crypto_info) { 138 + (*pkt->moz_crypto_info_release)(pkt->moz_crypto_info); 139 + } 140 + pkt->moz_ndk_crypto_info = NULL; 141 + pkt->moz_crypto_info = NULL; 142 + pkt->moz_crypto_info_addref = NULL; 143 + pkt->moz_crypto_info_release = NULL; 144 +} 145 + 146 +static int av_packet_copy_moz_crypto_info(AVPacket *dst, const AVPacket *src) { 147 + av_packet_free_moz_crypto_info(dst); 148 + if (!src->moz_ndk_crypto_info) { 149 + return 0; 150 + } 151 + if (!src->moz_crypto_info || !src->moz_crypto_info_addref || !src->moz_crypto_info_release) { 152 + return AVERROR(EINVAL); 153 + } 154 + dst->moz_ndk_crypto_info = src->moz_ndk_crypto_info; 155 + dst->moz_crypto_info = src->moz_crypto_info; 156 + dst->moz_crypto_info_addref = src->moz_crypto_info_addref; 157 + dst->moz_crypto_info_release = src->moz_crypto_info_release; 158 + (*dst->moz_crypto_info_addref)(dst->moz_crypto_info); 159 + return 0; 160 +} 161 + 162 int av_packet_copy_props(AVPacket *dst, const AVPacket *src) 163 { 164 int i, ret; 165 @@ -406,10 +432,16 @@ int av_packet_copy_props(AVPacket *dst, const AVPacket *src) 166 dst->side_data = NULL; 167 dst->side_data_elems = 0; 168 169 - ret = av_buffer_replace(&dst->opaque_ref, src->opaque_ref); 170 + ret = av_packet_copy_moz_crypto_info(dst, src); 171 if (ret < 0) 172 return ret; 173 174 + ret = av_buffer_replace(&dst->opaque_ref, src->opaque_ref); 175 + if (ret < 0) { 176 + av_packet_free_moz_crypto_info(dst); 177 + return ret; 178 + } 179 + 180 for (i = 0; i < src->side_data_elems; i++) { 181 enum AVPacketSideDataType type = src->side_data[i].type; 182 size_t size = src->side_data[i].size; 183 @@ -417,6 +449,7 @@ int av_packet_copy_props(AVPacket *dst, const AVPacket *src) 184 uint8_t *dst_data = av_packet_new_side_data(dst, type, size); 185 186 if (!dst_data) { 187 + av_packet_free_moz_crypto_info(dst); 188 av_buffer_unref(&dst->opaque_ref); 189 av_packet_free_side_data(dst); 190 return AVERROR(ENOMEM); 191 @@ -429,6 +462,7 @@ int av_packet_copy_props(AVPacket *dst, const AVPacket *src) 192 193 void av_packet_unref(AVPacket *pkt) 194 { 195 + av_packet_free_moz_crypto_info(pkt); 196 av_packet_free_side_data(pkt); 197 av_buffer_unref(&pkt->opaque_ref); 198 av_buffer_unref(&pkt->buf); 199 diff --git a/media/ffvpx/libavcodec/packet.h b/media/ffvpx/libavcodec/packet.h 200 --- a/media/ffvpx/libavcodec/packet.h 201 +++ b/media/ffvpx/libavcodec/packet.h 202 @@ -581,6 +581,15 @@ typedef struct AVPacket { 203 * or muxers. 204 */ 205 AVRational time_base; 206 + 207 + /** 208 + * Mozilla extensions to manage AMediaCryptoInfo for encrypted packets on 209 + * Android. Must provide all parameters if any are given. 210 + */ 211 + void* moz_ndk_crypto_info; 212 + void* moz_crypto_info; 213 + void (*moz_crypto_info_addref)(void*); 214 + void (*moz_crypto_info_release)(void*); 215 } AVPacket; 216 217 #if FF_API_INIT_PACKET