summaryrefslogtreecommitdiff
path: root/libavcodec/nvenc_h264.c
diff options
context:
space:
mode:
authorPhilip Langdale <philipl@overt.org>2020-04-10 13:32:11 -0700
committerPhilip Langdale <philipl@overt.org>2020-04-15 14:54:42 -0700
commit22b25b3ea5cf5e241e8dde5ddd107a3b1e6eb7a0 (patch)
tree2b785523fa8901d1a4412a67637a131c18e9c6bc /libavcodec/nvenc_h264.c
parente6fb3aba42084cd6af3a417435c444ad872ce629 (diff)
downloadffmpeg-22b25b3ea5cf5e241e8dde5ddd107a3b1e6eb7a0.tar.gz
avcodec: Add explicit capability flag for encoder flushing
Previously, there was no way to flush an encoder such that after draining, the encoder could be used again. We generally suggested that clients teardown and replace the encoder instance in these situations. However, for at least some hardware encoders, the cost of this tear down/replace cycle is very high, which can get in the way of some use-cases - for example: segmented encoding with nvenc. To help address that use case, we added support for calling avcodec_flush_buffers() to nvenc and things worked in practice, although it was not clearly documented as to whether this should work or not. There was only one previous example of an encoder implementing the flush callback (audiotoolboxenc) and it's unclear if that was intentional or not. However, it was clear that calling avocdec_flush_buffers() on any other encoder would leave the encoder in an undefined state, and that's not great. As part of cleaning this up, this change introduces a formal capability flag for encoders that support flushing and ensures a flush call is a no-op for any other encoder. This allows client code to check if it is meaningful to call flush on an encoder before actually doing it. I have not attempted to separate the steps taken inside avcodec_flush_buffers() because it's not doing anything that's wrong for an encoder. But I did add a sanity check to reject attempts to flush a frame threaded encoder because I couldn't wrap my head around whether that code path was actually safe or not. As this combination doesn't exist today, we'll deal with it if it ever comes up.
Diffstat (limited to 'libavcodec/nvenc_h264.c')
-rw-r--r--libavcodec/nvenc_h264.c11
1 files changed, 8 insertions, 3 deletions
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",