diff options
author | Anton Khirnov <anton@khirnov.net> | 2016-10-26 13:41:12 +0200 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2016-12-14 09:06:44 +0100 |
commit | 549d0bdca53af7a6e0c612ab4b03baecf3a5878f (patch) | |
tree | c9b90d376f74d82b8b5bc95e7c06423b14b915e0 /libavcodec/decode.c | |
parent | 47e547b321338c73c21fa623789f1efbd80a297a (diff) | |
download | ffmpeg-streaming-549d0bdca53af7a6e0c612ab4b03baecf3a5878f.zip ffmpeg-streaming-549d0bdca53af7a6e0c612ab4b03baecf3a5878f.tar.gz |
decode: be more explicit about storing the last packet properties
The current code stores a pointer to the packet passed to the decoder,
which is then used during get_buffer() for timestamps and side data
passthrough. However, since this is a pointer to user data which we do
not own, storing it is potentially dangerous. It is also ill defined for
the new decoding API with split input/output.
Fix this problem by making an explicit internally owned copy of the
packet properties.
Diffstat (limited to 'libavcodec/decode.c')
-rw-r--r-- | libavcodec/decode.c | 33 |
1 files changed, 20 insertions, 13 deletions
diff --git a/libavcodec/decode.c b/libavcodec/decode.c index 00085c3..b02278d 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -99,6 +99,14 @@ fail2: return 0; } +static int extract_packet_props(AVCodecInternal *avci, const AVPacket *pkt) +{ + av_packet_unref(avci->last_pkt_props); + if (pkt) + return av_packet_copy_props(avci->last_pkt_props, pkt); + return 0; +} + static int unrefcount_frame(AVCodecInternal *avci, AVFrame *frame) { int ret; @@ -304,7 +312,10 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi return AVERROR(ENOSYS); } - avctx->internal->pkt = avpkt; + ret = extract_packet_props(avci, avpkt); + if (ret < 0) + return ret; + ret = apply_param_change(avctx, avpkt); if (ret < 0) return ret; @@ -368,7 +379,9 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, return AVERROR(ENOSYS); } - avctx->internal->pkt = avpkt; + ret = extract_packet_props(avci, avpkt); + if (ret < 0) + return ret; if (!avpkt->data && avpkt->size) { av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n"); @@ -408,7 +421,10 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, { int ret; - avctx->internal->pkt = avpkt; + ret = extract_packet_props(avctx->internal, avpkt); + if (ret < 0) + return ret; + *got_sub_ptr = 0; ret = avctx->codec->decode(avctx, sub, got_sub_ptr, avpkt); if (*got_sub_ptr) @@ -739,7 +755,7 @@ int avcodec_default_get_buffer2(AVCodecContext *avctx, AVFrame *frame, int flags int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame) { - AVPacket *pkt = avctx->internal->pkt; + AVPacket *pkt = avctx->internal->last_pkt_props; int i; struct { enum AVPacketSideDataType packet; @@ -759,15 +775,6 @@ int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame) frame->chroma_location = avctx->chroma_sample_location; frame->reordered_opaque = avctx->reordered_opaque; - if (!pkt) { -#if FF_API_PKT_PTS -FF_DISABLE_DEPRECATION_WARNINGS - frame->pkt_pts = AV_NOPTS_VALUE; -FF_ENABLE_DEPRECATION_WARNINGS -#endif - frame->pts = AV_NOPTS_VALUE; - return 0; - } #if FF_API_PKT_PTS FF_DISABLE_DEPRECATION_WARNINGS |