Source code
Revision control
Copy as Markdown
Other Tools
diff --git a/media/ffvpx/libavcodec/avcodec.h b/media/ffvpx/libavcodec/avcodec.h
--- a/media/ffvpx/libavcodec/avcodec.h
+++ b/media/ffvpx/libavcodec/avcodec.h
@@ -2105,6 +2105,8 @@ typedef struct AVCodecContext {
*/
AVFrameSideData **decoded_side_data;
int nb_decoded_side_data;
+
+ void* moz_ndk_crypto;
} AVCodecContext;
/**
diff --git a/media/ffvpx/libavcodec/mediacodec_wrapper.c b/media/ffvpx/libavcodec/mediacodec_wrapper.c
--- a/media/ffvpx/libavcodec/mediacodec_wrapper.c
+++ b/media/ffvpx/libavcodec/mediacodec_wrapper.c
@@ -1537,6 +1537,11 @@ fail:
return ret;
}
+static int mediacodec_jni_queueSecureInputBuffer(FFAMediaCodec* ctx, size_t idx, off_t offset, void* cryptoInfo, uint64_t time, uint32_t flags)
+{
+ return AVERROR_PATCHWELCOME;
+}
+
static ssize_t mediacodec_jni_dequeueOutputBuffer(FFAMediaCodec* ctx, FFAMediaCodecBufferInfo *info, int64_t timeoutUs)
{
int ret = 0;
@@ -1811,6 +1816,7 @@ static const FFAMediaCodec media_codec_jni = {
.dequeueInputBuffer = mediacodec_jni_dequeueInputBuffer,
.queueInputBuffer = mediacodec_jni_queueInputBuffer,
+ .queueSecureInputBuffer = mediacodec_jni_queueSecureInputBuffer,
.dequeueOutputBuffer = mediacodec_jni_dequeueOutputBuffer,
.getOutputFormat = mediacodec_jni_getOutputFormat,
@@ -2209,7 +2215,7 @@ static int mediacodec_ndk_configure(FFAMediaCodec* ctx,
return AVERROR_EXTERNAL;
}
} else {
- status = AMediaCodec_configure(codec->impl, format->impl, native_window, NULL, flags);
+ status = AMediaCodec_configure(codec->impl, format->impl, native_window, (AMediaCrypto*)crypto, flags);
if (status != AMEDIA_OK) {
av_log(codec, AV_LOG_ERROR, "Decoder configure failed, %d\n", status);
return AVERROR_EXTERNAL;
@@ -2263,6 +2269,14 @@ static int mediacodec_ndk_queueInputBuffer(FFAMediaCodec *ctx, size_t idx,
return AMediaCodec_queueInputBuffer(codec->impl, idx, offset, size, time, flags);
}
+static int mediacodec_ndk_queueSecureInputBuffer(FFAMediaCodec *ctx, size_t idx,
+ off_t offset, void* cryptoInfo,
+ uint64_t time, uint32_t flags)
+{
+ FFAMediaCodecNdk *codec = (FFAMediaCodecNdk *)ctx;
+ return AMediaCodec_queueSecureInputBuffer(codec->impl, idx, offset, (AMediaCodecCryptoInfo*)cryptoInfo, time, flags);
+}
+
static ssize_t mediacodec_ndk_dequeueOutputBuffer(FFAMediaCodec* ctx, FFAMediaCodecBufferInfo *info, int64_t timeoutUs)
{
FFAMediaCodecNdk *codec = (FFAMediaCodecNdk *)ctx;
@@ -2507,6 +2521,7 @@ static const FFAMediaCodec media_codec_ndk = {
.dequeueInputBuffer = mediacodec_ndk_dequeueInputBuffer,
.queueInputBuffer = mediacodec_ndk_queueInputBuffer,
+ .queueSecureInputBuffer = mediacodec_ndk_queueSecureInputBuffer,
.dequeueOutputBuffer = mediacodec_ndk_dequeueOutputBuffer,
.getOutputFormat = mediacodec_ndk_getOutputFormat,
diff --git a/media/ffvpx/libavcodec/mediacodec_wrapper.h b/media/ffvpx/libavcodec/mediacodec_wrapper.h
--- a/media/ffvpx/libavcodec/mediacodec_wrapper.h
+++ b/media/ffvpx/libavcodec/mediacodec_wrapper.h
@@ -214,6 +214,7 @@ struct FFAMediaCodec {
ssize_t (*dequeueInputBuffer)(FFAMediaCodec* codec, int64_t timeoutUs);
int (*queueInputBuffer)(FFAMediaCodec* codec, size_t idx, off_t offset, size_t size, uint64_t time, uint32_t flags);
+ int (*queueSecureInputBuffer)(FFAMediaCodec* codec, size_t idx, off_t offset, void* cryptoInfo, uint64_t time, uint32_t flags);
ssize_t (*dequeueOutputBuffer)(FFAMediaCodec* codec, FFAMediaCodecBufferInfo *info, int64_t timeoutUs);
FFAMediaFormat* (*getOutputFormat)(FFAMediaCodec* codec);
@@ -299,6 +300,11 @@ static inline int ff_AMediaCodec_queueInputBuffer(FFAMediaCodec *codec, size_t i
return codec->queueInputBuffer(codec, idx, offset, size, time, flags);
}
+static inline int ff_AMediaCodec_queueSecureInputBuffer(FFAMediaCodec *codec, size_t idx, off_t offset, void* cryptoInfo, uint64_t time, uint32_t flags)
+{
+ return codec->queueSecureInputBuffer(codec, idx, offset, cryptoInfo, time, flags);
+}
+
static inline ssize_t ff_AMediaCodec_dequeueOutputBuffer(FFAMediaCodec* codec, FFAMediaCodecBufferInfo *info, int64_t timeoutUs)
{
return codec->dequeueOutputBuffer(codec, info, timeoutUs);
diff --git a/media/ffvpx/libavcodec/mediacodecdec_common.c b/media/ffvpx/libavcodec/mediacodecdec_common.c
--- a/media/ffvpx/libavcodec/mediacodecdec_common.c
+++ b/media/ffvpx/libavcodec/mediacodecdec_common.c
@@ -837,7 +837,7 @@ int ff_mediacodec_dec_init(AVCodecContext *avctx, MediaCodecDecContext *s,
if (ret < 0)
goto fail;
- status = ff_AMediaCodec_configure(s->codec, format, s->surface, NULL, 0);
+ status = ff_AMediaCodec_configure(s->codec, format, s->surface, avctx->moz_ndk_crypto, 0);
if (status < 0) {
char *desc = ff_AMediaFormat_toString(format);
av_log(avctx, AV_LOG_ERROR,
@@ -943,7 +943,11 @@ int ff_mediacodec_dec_send(AVCodecContext *avctx, MediaCodecDecContext *s,
av_log(avctx, AV_LOG_DEBUG, "Sending End Of Stream signal\n");
- status = ff_AMediaCodec_queueInputBuffer(codec, index, 0, 0, pts, flags);
+ if (pkt->moz_ndk_crypto_info) {
+ status = ff_AMediaCodec_queueSecureInputBuffer(codec, index, 0, pkt->moz_ndk_crypto_info, pts, flags);
+ } else {
+ status = ff_AMediaCodec_queueInputBuffer(codec, index, 0, 0, pts, flags);
+ }
if (status < 0) {
av_log(avctx, AV_LOG_ERROR, "Failed to queue input empty buffer (status = %d)\n", status);
return AVERROR_EXTERNAL;
@@ -960,7 +964,11 @@ int ff_mediacodec_dec_send(AVCodecContext *avctx, MediaCodecDecContext *s,
memcpy(data, pkt->data + offset, size);
offset += size;
- status = ff_AMediaCodec_queueInputBuffer(codec, index, 0, size, pts, 0);
+ if (pkt->moz_ndk_crypto_info) {
+ status = ff_AMediaCodec_queueSecureInputBuffer(codec, index, 0, pkt->moz_ndk_crypto_info, pts, 0);
+ } else {
+ status = ff_AMediaCodec_queueInputBuffer(codec, index, 0, size, pts, 0);
+ }
if (status < 0) {
av_log(avctx, AV_LOG_ERROR, "Failed to queue input buffer (status = %d)\n", status);
return AVERROR_EXTERNAL;
diff --git a/media/ffvpx/libavcodec/packet.c b/media/ffvpx/libavcodec/packet.c
--- a/media/ffvpx/libavcodec/packet.c
+++ b/media/ffvpx/libavcodec/packet.c
@@ -390,6 +390,32 @@ int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
return AVERROR(ENOENT);
}
+static void av_packet_free_moz_crypto_info(AVPacket *pkt) {
+ if (pkt->moz_crypto_info_release && pkt->moz_crypto_info) {
+ (*pkt->moz_crypto_info_release)(pkt->moz_crypto_info);
+ }
+ pkt->moz_ndk_crypto_info = NULL;
+ pkt->moz_crypto_info = NULL;
+ pkt->moz_crypto_info_addref = NULL;
+ pkt->moz_crypto_info_release = NULL;
+}
+
+static int av_packet_copy_moz_crypto_info(AVPacket *dst, const AVPacket *src) {
+ av_packet_free_moz_crypto_info(dst);
+ if (!src->moz_ndk_crypto_info) {
+ return 0;
+ }
+ if (!src->moz_crypto_info || !src->moz_crypto_info_addref || !src->moz_crypto_info_release) {
+ return AVERROR(EINVAL);
+ }
+ dst->moz_ndk_crypto_info = src->moz_ndk_crypto_info;
+ dst->moz_crypto_info = src->moz_crypto_info;
+ dst->moz_crypto_info_addref = src->moz_crypto_info_addref;
+ dst->moz_crypto_info_release = src->moz_crypto_info_release;
+ (*dst->moz_crypto_info_addref)(dst->moz_crypto_info);
+ return 0;
+}
+
int av_packet_copy_props(AVPacket *dst, const AVPacket *src)
{
int i, ret;
@@ -406,10 +432,16 @@ int av_packet_copy_props(AVPacket *dst, const AVPacket *src)
dst->side_data = NULL;
dst->side_data_elems = 0;
- ret = av_buffer_replace(&dst->opaque_ref, src->opaque_ref);
+ ret = av_packet_copy_moz_crypto_info(dst, src);
if (ret < 0)
return ret;
+ ret = av_buffer_replace(&dst->opaque_ref, src->opaque_ref);
+ if (ret < 0) {
+ av_packet_free_moz_crypto_info(dst);
+ return ret;
+ }
+
for (i = 0; i < src->side_data_elems; i++) {
enum AVPacketSideDataType type = src->side_data[i].type;
size_t size = src->side_data[i].size;
@@ -417,6 +449,7 @@ int av_packet_copy_props(AVPacket *dst, const AVPacket *src)
uint8_t *dst_data = av_packet_new_side_data(dst, type, size);
if (!dst_data) {
+ av_packet_free_moz_crypto_info(dst);
av_buffer_unref(&dst->opaque_ref);
av_packet_free_side_data(dst);
return AVERROR(ENOMEM);
@@ -429,6 +462,7 @@ int av_packet_copy_props(AVPacket *dst, const AVPacket *src)
void av_packet_unref(AVPacket *pkt)
{
+ av_packet_free_moz_crypto_info(pkt);
av_packet_free_side_data(pkt);
av_buffer_unref(&pkt->opaque_ref);
av_buffer_unref(&pkt->buf);
diff --git a/media/ffvpx/libavcodec/packet.h b/media/ffvpx/libavcodec/packet.h
--- a/media/ffvpx/libavcodec/packet.h
+++ b/media/ffvpx/libavcodec/packet.h
@@ -581,6 +581,15 @@ typedef struct AVPacket {
* or muxers.
*/
AVRational time_base;
+
+ /**
+ * Mozilla extensions to manage AMediaCryptoInfo for encrypted packets on
+ * Android. Must provide all parameters if any are given.
+ */
+ void* moz_ndk_crypto_info;
+ void* moz_crypto_info;
+ void (*moz_crypto_info_addref)(void*);
+ void (*moz_crypto_info_release)(void*);
} AVPacket;
#if FF_API_INIT_PACKET