From c8dea81921504c5e25a705dec4438dc95463f49b Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sat, 2 Sep 2017 20:32:27 +0100 Subject: [PATCH] lavc: Add wrapped_avframe decoder Intended for use with hardware frames for which rawvideo is not sufficient. Requires the trusted packet flag to be set - decoding fails if not to avoid security issues (the wrapped AVFrame can contain pointers to arbitrary data). --- libavcodec/Makefile | 1 + libavcodec/allcodecs.c | 2 +- libavcodec/version.h | 2 +- libavcodec/wrapped_avframe.c | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 999632cf9e..943e5db511 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -653,6 +653,7 @@ OBJS-$(CONFIG_WMV2_DECODER) += wmv2dec.o wmv2.o wmv2data.o \ OBJS-$(CONFIG_WMV2_ENCODER) += wmv2enc.o wmv2.o wmv2data.o \ msmpeg4.o msmpeg4enc.o msmpeg4data.o OBJS-$(CONFIG_WNV1_DECODER) += wnv1.o +OBJS-$(CONFIG_WRAPPED_AVFRAME_DECODER) += wrapped_avframe.o OBJS-$(CONFIG_WRAPPED_AVFRAME_ENCODER) += wrapped_avframe.o OBJS-$(CONFIG_WS_SND1_DECODER) += ws-snd1.o OBJS-$(CONFIG_XAN_DPCM_DECODER) += dpcm.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index ce0bc7ecf3..625720578f 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -377,7 +377,7 @@ static void register_all(void) REGISTER_DECODER(VQA, vqa); REGISTER_DECODER(BITPACKED, bitpacked); REGISTER_DECODER(WEBP, webp); - REGISTER_ENCODER(WRAPPED_AVFRAME, wrapped_avframe); + REGISTER_ENCDEC (WRAPPED_AVFRAME, wrapped_avframe); REGISTER_ENCDEC (WMV1, wmv1); REGISTER_ENCDEC (WMV2, wmv2); REGISTER_DECODER(WMV3, wmv3); diff --git a/libavcodec/version.h b/libavcodec/version.h index 2aff092cf4..e1224752bd 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #define LIBAVCODEC_VERSION_MAJOR 57 #define LIBAVCODEC_VERSION_MINOR 106 -#define LIBAVCODEC_VERSION_MICRO 100 +#define LIBAVCODEC_VERSION_MICRO 101 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ diff --git a/libavcodec/wrapped_avframe.c b/libavcodec/wrapped_avframe.c index 14360320ff..5f88a668b9 100644 --- a/libavcodec/wrapped_avframe.c +++ b/libavcodec/wrapped_avframe.c @@ -75,6 +75,33 @@ static int wrapped_avframe_encode(AVCodecContext *avctx, AVPacket *pkt, return 0; } +static int wrapped_avframe_decode(AVCodecContext *avctx, void *data, + int *got_frame, AVPacket *pkt) +{ + AVFrame *in, *out; + int err; + + if (!(pkt->flags & AV_PKT_FLAG_TRUSTED)) { + // This decoder is not usable with untrusted input. + return AVERROR(EPERM); + } + + if (pkt->size < sizeof(AVFrame)) + return AVERROR(EINVAL); + + in = (AVFrame*)pkt->data; + out = data; + + err = ff_decode_frame_props(avctx, out); + if (err < 0) + return err; + + av_frame_move_ref(out, in); + + *got_frame = 1; + return 0; +} + AVCodec ff_wrapped_avframe_encoder = { .name = "wrapped_avframe", .long_name = NULL_IF_CONFIG_SMALL("AVFrame to AVPacket passthrough"), @@ -83,3 +110,12 @@ AVCodec ff_wrapped_avframe_encoder = { .encode2 = wrapped_avframe_encode, .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; + +AVCodec ff_wrapped_avframe_decoder = { + .name = "wrapped_avframe", + .long_name = NULL_IF_CONFIG_SMALL("AVPacket to AVFrame passthrough"), + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_WRAPPED_AVFRAME, + .decode = wrapped_avframe_decode, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, +};