--- I'm quite suspicious of this. It passes tests w/ and w/o a lavc version bump, but I'm sure it's not completely correct and/or may need further changes in other parts of the codebase. The documentation bits probably need changes as well.
avtools/avconv.c | 2 ++ avtools/avplay.c | 2 ++ doc/examples/qsvdec.c | 2 ++ libavcodec/avcodec.h | 10 ++++++++++ libavcodec/decode.c | 13 +++++++++++++ libavcodec/encode.c | 2 ++ libavcodec/options_table.h | 2 ++ libavcodec/qsv_internal.h | 6 ++++-- libavcodec/version.h | 3 +++ libavfilter/buffersrc.c | 20 +++++++++++++++++++- libavfilter/vsrc_movie.c | 5 +++++ libavutil/frame.c | 6 ++++++ libavutil/frame.h | 6 ++++++ 13 files changed, 76 insertions(+), 3 deletions(-) diff --git a/avtools/avconv.c b/avtools/avconv.c index 4e3ffecdef..372290bb89 100644 --- a/avtools/avconv.c +++ b/avtools/avconv.c @@ -1713,7 +1713,9 @@ static int init_input_stream(int ist_index, char *error, int error_len) ist->dec_ctx->get_buffer2 = get_buffer; ist->dec_ctx->thread_safe_callbacks = 1; +#if FF_API_REFCOUNTED_FRAMES av_opt_set_int(ist->dec_ctx, "refcounted_frames", 1, 0); +#endif /* FF_API_REFCOUNTED_FRAMES */ if (!av_dict_get(ist->decoder_opts, "threads", NULL, 0)) av_dict_set(&ist->decoder_opts, "threads", "auto", 0); diff --git a/avtools/avplay.c b/avtools/avplay.c index b6dbc52cf7..5b1114d454 100644 --- a/avtools/avplay.c +++ b/avtools/avplay.c @@ -2069,8 +2069,10 @@ static int stream_component_open(PlayerState *is, int stream_index) if (!av_dict_get(opts, "threads", NULL, 0)) av_dict_set(&opts, "threads", "auto", 0); +#if FF_API_REFCOUNTED_FRAMES if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) av_dict_set(&opts, "refcounted_frames", "1", 0); +#endif /* FF_API_REFCOUNTED_FRAMES */ if (!codec || (ret = avcodec_open2(avctx, codec, &opts)) < 0) { goto fail; diff --git a/doc/examples/qsvdec.c b/doc/examples/qsvdec.c index 46e6ddcb0d..d77190595e 100644 --- a/doc/examples/qsvdec.c +++ b/doc/examples/qsvdec.c @@ -210,7 +210,9 @@ int main(int argc, char **argv) video_st->codecpar->extradata_size); decoder_ctx->extradata_size = video_st->codecpar->extradata_size; } +#if FF_API_REFCOUNTED_FRAMES decoder_ctx->refcounted_frames = 1; +#endif /* FF_API_REFCOUNTED_FRAMES */ decoder_ctx->opaque = &decode; decoder_ctx->get_format = get_format; diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 5624835023..e76753cfed 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -1982,6 +1982,7 @@ typedef struct AVCodecContext { */ int (*get_buffer2)(struct AVCodecContext *s, AVFrame *frame, int flags); +#if FF_API_REFCOUNTED_FRAMES /** * If non-zero, the decoded audio and video frames returned from * avcodec_decode_video2() and avcodec_decode_audio4() are reference-counted @@ -1996,6 +1997,7 @@ typedef struct AVCodecContext { * - decoding: set by the caller before avcodec_open2(). */ attribute_deprecated int refcounted_frames; +#endif /* FF_API_REFCOUNTED_FRAMES */ /* - encoding parameters */ float qcompress; ///< amount of qscale change between easy & hard scenes (0.0-1.0) @@ -3767,6 +3769,7 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, * @param avctx the codec context * @param[out] frame The AVFrame in which to store decoded audio samples. * The decoder will allocate a buffer for the decoded frame by +#if FF_API_REFCOUNTED_FRAMES * calling the AVCodecContext.get_buffer2() callback. * When AVCodecContext.refcounted_frames is set to 1, the frame is * reference counted and the returned reference belongs to the @@ -3777,6 +3780,13 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, * reference belongs to the decoder and is valid only until the * next call to this function or until closing or flushing the * decoder. The caller may not write to it. +#else + * calling the AVCodecContext.get_buffer2() callback. The + * returned reference belongs to the caller. The caller must + * release the frame using av_frame_unref() when the frame is + * no longer needed. The caller may safely write to the frame + * if av_frame_is_writable() returns 1. +#endif * @param[out] got_frame_ptr Zero if no frame could be decoded, otherwise it is * non-zero. Note that this field being set to zero * does not mean that an error has occurred. For diff --git a/libavcodec/decode.c b/libavcodec/decode.c index 27f75d73e3..110cc6529b 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -36,6 +36,7 @@ #include "decode.h" #include "internal.h" #include "thread.h" +#include "version.h" static int apply_param_change(AVCodecContext *avctx, AVPacket *avpkt) { @@ -110,6 +111,7 @@ static int extract_packet_props(AVCodecInternal *avci, const AVPacket *pkt) return 0; } +#if FF_API_REFCOUNTED_FRAMES static int unrefcount_frame(AVCodecInternal *avci, AVFrame *frame) { int ret; @@ -154,6 +156,7 @@ static int unrefcount_frame(AVCodecInternal *avci, AVFrame *frame) return 0; } +#endif static int bsfs_init(AVCodecContext *avctx) { @@ -576,11 +579,15 @@ static int compat_decode(AVCodecContext *avctx, AVFrame *frame, } if (frame != avci->compat_decode_frame) { +#if FF_API_REFCOUNTED_FRAMES +FF_DISABLE_DEPRECATION_WARNINGS if (!avctx->refcounted_frames) { ret = unrefcount_frame(avci, frame); if (ret < 0) goto finish; } +FF_ENABLE_DEPRECATION_WARNINGS +#endif *got_frame = 1; frame = avci->compat_decode_frame; @@ -1275,8 +1282,14 @@ void avcodec_flush_buffers(AVCodecContext *avctx) ff_decode_bsfs_uninit(avctx); +#if FF_API_REFCOUNTED_FRAMES +FF_DISABLE_DEPRECATION_WARNINGS if (!avctx->refcounted_frames) av_frame_unref(avctx->internal->to_free); +FF_ENABLE_DEPRECATION_WARNINGS +#else + av_frame_unref(avctx->internal->to_free); +#endif } void ff_decode_bsfs_uninit(AVCodecContext *avctx) diff --git a/libavcodec/encode.c b/libavcodec/encode.c index 9bb7ae5bde..641a91fc32 100644 --- a/libavcodec/encode.c +++ b/libavcodec/encode.c @@ -311,6 +311,7 @@ int attribute_align_arg avcodec_send_frame(AVCodecContext *avctx, const AVFrame if (avctx->codec->send_frame) return avctx->codec->send_frame(avctx, frame); +#if FF_API_REFCOUNTED_FRAMES // Emulation via old API. Do it here instead of avcodec_receive_packet, because: // 1. if the AVFrame is not refcounted, the copying will be much more // expensive than copying the packet data @@ -319,6 +320,7 @@ int attribute_align_arg avcodec_send_frame(AVCodecContext *avctx, const AVFrame if (avctx->internal->buffer_pkt_valid) return AVERROR(EAGAIN); +#endif /* FF_API_REFCOUNTED_FRAMES */ return do_encode(avctx, frame, &(int){0}); } diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h index 925ef376f3..f200fa64d8 100644 --- a/libavcodec/options_table.h +++ b/libavcodec/options_table.h @@ -414,7 +414,9 @@ static const AVOption avcodec_options[] = { {"s32p", "32-bit signed integer planar", 0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_S32P }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"}, {"fltp", "32-bit float planar", 0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_FLTP }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"}, {"dblp", "64-bit double planar", 0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_DBLP }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"}, +#if FF_API_REFCOUNTED_FRAMES {"refcounted_frames", NULL, OFFSET(refcounted_frames), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, A|V|D }, +#endif #if FF_API_SIDEDATA_ONLY_PKT {"side_data_only_packets", NULL, OFFSET(side_data_only_packets), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, A|V|E }, #endif diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h index 975c8de441..8ab8e5c5f3 100644 --- a/libavcodec/qsv_internal.h +++ b/libavcodec/qsv_internal.h @@ -59,10 +59,12 @@ typedef struct QSVFramesContext { AVBufferRef *hw_frames_ctx; void *logctx; - /* The memory ids for the external frames. - * Refcounted, since we need one reference owned by the QSVFramesContext + /* The memory ids for the external frames. */ +#if FF_API_REFCOUNTED_FRAMES + /* Refcounted, since we need one reference owned by the QSVFramesContext * (i.e. by the encoder/decoder) and another one given to the MFX session * from the frame allocator. */ +#endif /* FF_API_REFCOUNTED_FRAMES */ AVBufferRef *mids_buf; QSVMid *mids; int nb_mids; diff --git a/libavcodec/version.h b/libavcodec/version.h index aa6cdcd6bc..f0cba4cc6b 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -95,5 +95,8 @@ #ifndef FF_API_VAAPI_CONTEXT #define FF_API_VAAPI_CONTEXT (LIBAVCODEC_VERSION_MAJOR < 59) #endif +#ifndef FF_API_REFCOUNTED_FRAMES +#define FF_API_REFCOUNTED_FRAMES (LIBAVCODEC_VERSION_MAJOR < 59) +#endif #endif /* AVCODEC_VERSION_H */ diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c index df00971514..3e241058c1 100644 --- a/libavfilter/buffersrc.c +++ b/libavfilter/buffersrc.c @@ -33,6 +33,9 @@ #include "libavutil/internal.h" #include "libavutil/opt.h" #include "libavutil/samplefmt.h" + +#include "libavcodec/version.h" + #include "audio.h" #include "avfilter.h" #include "buffersrc.h" @@ -154,7 +157,10 @@ int attribute_align_arg av_buffersrc_add_frame(AVFilterContext *ctx, { BufferSourceContext *s = ctx->priv; AVFrame *copy; - int refcounted, ret; + int ret; +#if FF_API_REFCOUNTED_FRAMES + int refcounted; +#endif /* FF_API_REFCOUNTED_FRAMES */ if (!frame) { s->eof = 1; @@ -162,7 +168,9 @@ int attribute_align_arg av_buffersrc_add_frame(AVFilterContext *ctx, } else if (s->eof) return AVERROR(EINVAL); +#if FF_API_REFCOUNTED_FRAMES refcounted = !!frame->buf[0]; +#endif /* FF_API_REFCOUNTED_FRAMES */ switch (ctx->outputs[0]->type) { case AVMEDIA_TYPE_VIDEO: @@ -185,6 +193,7 @@ int attribute_align_arg av_buffersrc_add_frame(AVFilterContext *ctx, if (!(copy = av_frame_alloc())) return AVERROR(ENOMEM); +#if FF_API_REFCOUNTED_FRAMES if (refcounted) { av_frame_move_ref(copy, frame); } else { @@ -194,10 +203,19 @@ int attribute_align_arg av_buffersrc_add_frame(AVFilterContext *ctx, return ret; } } +#else + ret = av_frame_ref(copy, frame); + if (ret < 0) { + av_frame_free(©); + return ret; + } +#endif /* FF_API_REFCOUNTED_FRAMES */ if ((ret = av_fifo_generic_write(s->fifo, ©, sizeof(copy), NULL)) < 0) { +#if FF_API_REFCOUNTED_FRAMES if (refcounted) av_frame_move_ref(frame, copy); +#endif /* FF_API_REFCOUNTED_FRAMES */ av_frame_free(©); return ret; } diff --git a/libavfilter/vsrc_movie.c b/libavfilter/vsrc_movie.c index aff6e620ff..0bacb672fd 100644 --- a/libavfilter/vsrc_movie.c +++ b/libavfilter/vsrc_movie.c @@ -37,6 +37,7 @@ #include "libavutil/imgutils.h" #include "libavcodec/avcodec.h" +#include "libavcodec/version.h" #include "libavformat/avformat.h" @@ -157,7 +158,11 @@ static av_cold int movie_init(AVFilterContext *ctx) if (ret < 0) return ret; +#if FF_API_REFCOUNTED_FRAMES +FF_DISABLE_DEPRECATION_WARNINGS movie->codec_ctx->refcounted_frames = 1; +FF_ENABLE_DEPRECATION_WARNINGS +#endif if ((ret = avcodec_open2(movie->codec_ctx, codec, NULL)) < 0) { av_log(ctx, AV_LOG_ERROR, "Failed to open codec\n"); diff --git a/libavutil/frame.c b/libavutil/frame.c index db3897c299..2c29dc5ed3 100644 --- a/libavutil/frame.c +++ b/libavutil/frame.c @@ -16,6 +16,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavcodec/version.h" + #include "channel_layout.h" #include "buffer.h" #include "common.h" @@ -214,6 +216,7 @@ int av_frame_ref(AVFrame *dst, const AVFrame *src) if (ret < 0) return ret; +#if FF_API_REFCOUNTED_FRAMES /* duplicate the frame data if it's not refcounted */ if (!src->buf[0]) { ret = av_frame_get_buffer(dst, 32); @@ -226,6 +229,7 @@ int av_frame_ref(AVFrame *dst, const AVFrame *src) return ret; } +#endif /* FF_API_REFCOUNTED_FRAMES */ /* ref the buffers */ for (i = 0; i < FF_ARRAY_ELEMS(src->buf) && src->buf[i]; i++) { @@ -335,9 +339,11 @@ int av_frame_is_writable(AVFrame *frame) { int i, ret = 1; +#if FF_API_REFCOUNTED_FRAMES /* assume non-refcounted frames are not writable */ if (!frame->buf[0]) return 0; +#endif /* FF_API_REFCOUNTED_FRAMES */ for (i = 0; i < FF_ARRAY_ELEMS(frame->buf) && frame->buf[i]; i++) ret &= !!av_buffer_is_writable(frame->buf[i]); diff --git a/libavutil/frame.h b/libavutil/frame.h index ff3fe46dd6..1a784cddfe 100644 --- a/libavutil/frame.h +++ b/libavutil/frame.h @@ -310,10 +310,16 @@ typedef struct AVFrame { uint64_t channel_layout; /** +#if FF_API_REFCOUNTED_FRAMES * AVBuffer references backing the data for this frame. If all elements of * this array are NULL, then this frame is not reference counted. This array * must be filled contiguously -- if buf[i] is non-NULL then buf[j] must * also be non-NULL for all j < i. +#else + * AVBuffer references backing the data for this frame. This array must + * be filled contiguously -- if buf[i] is non-NULL then buf[j] must also + * be non-NULL for all j < i. +#endif * * There may be at most one AVBuffer per data plane, so for video this array * always contains all the references. For planar audio with more than -- 2.11.0 _______________________________________________ libav-devel mailing list libav-devel@libav.org https://lists.libav.org/mailman/listinfo/libav-devel