summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/APIchanges6
-rw-r--r--libavcodec/audiotoolboxenc.c3
-rw-r--r--libavcodec/avcodec.h25
-rw-r--r--libavcodec/decode.c15
-rw-r--r--libavcodec/nvenc_h264.c11
-rw-r--r--libavcodec/nvenc_hevc.c6
-rw-r--r--libavcodec/version.h4
7 files changed, 57 insertions, 13 deletions
diff --git a/doc/APIchanges b/doc/APIchanges
index 4cc2367e69..e30148dc90 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -15,6 +15,12 @@ libavutil: 2017-10-21
API changes, most recent first:
+2020-04-15 - xxxxxxxxxx - lavc 58.79.100 - avcodec.h
+ Add formal support for calling avcodec_flush_buffers() on encoders.
+ Encoders that set the cap AV_CODEC_CAP_ENCODER_FLUSH will be flushed.
+ For all other encoders, the call is now a no-op rather than undefined
+ behaviour.
+
2020-xx-xx - xxxxxxxxxx - lavc 58.78.100 - avcodec.h codec_desc.h codec_id.h packet.h
Move AVCodecDesc-related public API to new header codec_desc.h.
Move AVCodecID enum to new header codec_id.h.
diff --git a/libavcodec/audiotoolboxenc.c b/libavcodec/audiotoolboxenc.c
index 2c1891693e..27632decf5 100644
--- a/libavcodec/audiotoolboxenc.c
+++ b/libavcodec/audiotoolboxenc.c
@@ -627,7 +627,8 @@ static const AVOption options[] = {
.encode2 = ffat_encode, \
.flush = ffat_encode_flush, \
.priv_class = &ffat_##NAME##_enc_class, \
- .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY __VA_ARGS__, \
+ .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | \
+ AV_CODEC_CAP_ENCODER_FLUSH __VA_ARGS__, \
.sample_fmts = (const enum AVSampleFormat[]) { \
AV_SAMPLE_FMT_S16, \
AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_NONE \
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 55151a0b71..b79b025e53 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -513,6 +513,13 @@ typedef struct RcOverride{
*/
#define AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE (1 << 20)
+/**
+ * This encoder can be flushed using avcodec_flush_buffers(). If this flag is
+ * not set, the encoder must be closed and reopened to ensure that no frames
+ * remain pending.
+ */
+#define AV_CODEC_CAP_ENCODER_FLUSH (1 << 21)
+
/* Exported side data.
These flags can be passed in AVCodecContext.export_side_data before initialization.
*/
@@ -4473,13 +4480,21 @@ int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels,
int buf_size, int align);
/**
- * Reset the internal decoder state / flush internal buffers. Should be called
+ * Reset the internal codec state / flush internal buffers. Should be called
* e.g. when seeking or when switching to a different stream.
*
- * @note when refcounted frames are not used (i.e. avctx->refcounted_frames is 0),
- * this invalidates the frames previously returned from the decoder. When
- * refcounted frames are used, the decoder just releases any references it might
- * keep internally, but the caller's reference remains valid.
+ * @note for decoders, when refcounted frames are not used
+ * (i.e. avctx->refcounted_frames is 0), this invalidates the frames previously
+ * returned from the decoder. When refcounted frames are used, the decoder just
+ * releases any references it might keep internally, but the caller's reference
+ * remains valid.
+ *
+ * @note for encoders, this function will only do something if the encoder
+ * declares support for AV_CODEC_CAP_ENCODER_FLUSH. When called, the encoder
+ * will drain any remaining packets, and can then be re-used for a different
+ * stream (as opposed to sending a null frame which will leave the encoder
+ * in a permanent EOF state after draining). This can be desirable if the
+ * cost of tearing down and replacing the encoder instance is high.
*/
void avcodec_flush_buffers(AVCodecContext *avctx);
diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index b7ae1fbb84..d4bdb9b1c0 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -2084,6 +2084,21 @@ void avcodec_flush_buffers(AVCodecContext *avctx)
{
AVCodecInternal *avci = avctx->internal;
+ if (av_codec_is_encoder(avctx->codec)) {
+ int caps = avctx->codec->capabilities;
+
+ if (!(caps & AV_CODEC_CAP_ENCODER_FLUSH)) {
+ // Only encoders that explicitly declare support for it can be
+ // flushed. Otherwise, this is a no-op.
+ av_log(avctx, AV_LOG_WARNING, "Ignoring attempt to flush encoder "
+ "that doesn't support it\n");
+ return;
+ }
+
+ // We haven't implemented flushing for frame-threaded encoders.
+ av_assert0(!(caps & AV_CODEC_CAP_FRAME_THREADS));
+ }
+
avci->draining = 0;
avci->draining_done = 0;
avci->nb_draining_errors = 0;
diff --git a/libavcodec/nvenc_h264.c b/libavcodec/nvenc_h264.c
index 479155fe15..c39f90fe1b 100644
--- a/libavcodec/nvenc_h264.c
+++ b/libavcodec/nvenc_h264.c
@@ -182,10 +182,12 @@ AVCodec ff_nvenc_encoder = {
.receive_packet = ff_nvenc_receive_packet,
.encode2 = ff_nvenc_encode_frame,
.close = ff_nvenc_encode_close,
+ .flush = ff_nvenc_encode_flush,
.priv_data_size = sizeof(NvencContext),
.priv_class = &nvenc_class,
.defaults = defaults,
- .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE,
+ .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |
+ AV_CODEC_CAP_ENCODER_FLUSH,
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.pix_fmts = ff_nvenc_pix_fmts,
.wrapper_name = "nvenc",
@@ -211,10 +213,12 @@ AVCodec ff_nvenc_h264_encoder = {
.receive_packet = ff_nvenc_receive_packet,
.encode2 = ff_nvenc_encode_frame,
.close = ff_nvenc_encode_close,
+ .flush = ff_nvenc_encode_flush,
.priv_data_size = sizeof(NvencContext),
.priv_class = &nvenc_h264_class,
.defaults = defaults,
- .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE,
+ .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |
+ AV_CODEC_CAP_ENCODER_FLUSH,
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.pix_fmts = ff_nvenc_pix_fmts,
.wrapper_name = "nvenc",
@@ -244,7 +248,8 @@ AVCodec ff_h264_nvenc_encoder = {
.priv_data_size = sizeof(NvencContext),
.priv_class = &h264_nvenc_class,
.defaults = defaults,
- .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE,
+ .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |
+ AV_CODEC_CAP_ENCODER_FLUSH,
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.pix_fmts = ff_nvenc_pix_fmts,
.wrapper_name = "nvenc",
diff --git a/libavcodec/nvenc_hevc.c b/libavcodec/nvenc_hevc.c
index 7c9b3848f1..ea337a514f 100644
--- a/libavcodec/nvenc_hevc.c
+++ b/libavcodec/nvenc_hevc.c
@@ -174,7 +174,8 @@ AVCodec ff_nvenc_hevc_encoder = {
.priv_class = &nvenc_hevc_class,
.defaults = defaults,
.pix_fmts = ff_nvenc_pix_fmts,
- .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE,
+ .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |
+ AV_CODEC_CAP_ENCODER_FLUSH,
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.wrapper_name = "nvenc",
};
@@ -203,7 +204,8 @@ AVCodec ff_hevc_nvenc_encoder = {
.priv_class = &hevc_nvenc_class,
.defaults = defaults,
.pix_fmts = ff_nvenc_pix_fmts,
- .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE,
+ .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |
+ AV_CODEC_CAP_ENCODER_FLUSH,
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.wrapper_name = "nvenc",
};
diff --git a/libavcodec/version.h b/libavcodec/version.h
index b348a6ca7a..a4eb83124c 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -28,8 +28,8 @@
#include "libavutil/version.h"
#define LIBAVCODEC_VERSION_MAJOR 58
-#define LIBAVCODEC_VERSION_MINOR 78
-#define LIBAVCODEC_VERSION_MICRO 102
+#define LIBAVCODEC_VERSION_MINOR 79
+#define LIBAVCODEC_VERSION_MICRO 100
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
LIBAVCODEC_VERSION_MINOR, \