---
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
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel