summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimo Rothenpieler <timo@rothenpieler.org>2023-06-16 20:23:26 +0200
committerTimo Rothenpieler <timo@rothenpieler.org>2023-06-16 22:10:42 +0200
commit6c418ae25ede55fa1f896a7449ebaffd18886002 (patch)
tree0545cce47537221903eaa045557085d37d8c9239
parent73a2252f1d9062fa877ef153532bc35351dafab6 (diff)
Revert "lavc/nvenc: handle frame durations and AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE"
The implementation is flawed in that the frame opaque data is not in fact correctly reordered along with the packets, but is being output in packet input order, just like the dts are. This reverts commit 35538097038fd1e36577306d3165f38c8fa02466.
-rw-r--r--libavcodec/nvenc.c116
-rw-r--r--libavcodec/nvenc.h2
-rw-r--r--libavcodec/nvenc_av1.c3
-rw-r--r--libavcodec/nvenc_h264.c3
-rw-r--r--libavcodec/nvenc_hevc.c3
5 files changed, 23 insertions, 104 deletions
diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
index 7874cb887b..177e23d7e4 100644
--- a/libavcodec/nvenc.c
+++ b/libavcodec/nvenc.c
@@ -28,7 +28,6 @@
#include "av1.h"
#endif
-#include "libavutil/buffer.h"
#include "libavutil/hwcontext_cuda.h"
#include "libavutil/hwcontext.h"
#include "libavutil/cuda_check.h"
@@ -168,27 +167,6 @@ static int nvenc_print_error(AVCodecContext *avctx, NVENCSTATUS err,
return ret;
}
-typedef struct FrameData {
- int64_t pts;
- int64_t duration;
-#if FF_API_REORDERED_OPAQUE
- int64_t reordered_opaque;
-#endif
-
- void *frame_opaque;
- AVBufferRef *frame_opaque_ref;
-} FrameData;
-
-static void reorder_queue_flush(AVFifo *queue)
-{
- FrameData fd;
-
- av_assert0(queue);
-
- while (av_fifo_read(queue, &fd, 1) >= 0)
- av_buffer_unref(&fd.frame_opaque_ref);
-}
-
typedef struct GUIDTuple {
const GUID guid;
int flags;
@@ -1789,8 +1767,8 @@ static av_cold int nvenc_setup_surfaces(AVCodecContext *avctx)
if (!ctx->surfaces)
return AVERROR(ENOMEM);
- ctx->reorder_queue = av_fifo_alloc2(ctx->nb_surfaces, sizeof(FrameData), 0);
- if (!ctx->reorder_queue)
+ ctx->timestamp_list = av_fifo_alloc2(ctx->nb_surfaces, sizeof(int64_t), 0);
+ if (!ctx->timestamp_list)
return AVERROR(ENOMEM);
ctx->unused_surface_queue = av_fifo_alloc2(ctx->nb_surfaces, sizeof(NvencSurface*), 0);
@@ -1874,11 +1852,7 @@ av_cold int ff_nvenc_encode_close(AVCodecContext *avctx)
p_nvenc->nvEncEncodePicture(ctx->nvencoder, &params);
}
- if (ctx->reorder_queue) {
- reorder_queue_flush(ctx->reorder_queue);
- av_fifo_freep2(&ctx->reorder_queue);
- }
-
+ av_fifo_freep2(&ctx->timestamp_list);
av_fifo_freep2(&ctx->output_surface_ready_queue);
av_fifo_freep2(&ctx->output_surface_queue);
av_fifo_freep2(&ctx->unused_surface_queue);
@@ -2222,53 +2196,18 @@ static void nvenc_codec_specific_pic_params(AVCodecContext *avctx,
}
}
-static void reorder_queue_enqueue(AVFifo *queue, const AVCodecContext *avctx,
- const AVFrame *frame, AVBufferRef **opaque_ref)
+static inline void timestamp_queue_enqueue(AVFifo *queue, int64_t timestamp)
{
- FrameData fd;
-
- fd.pts = frame->pts;
- fd.duration = frame->duration;
-#if FF_API_REORDERED_OPAQUE
-FF_DISABLE_DEPRECATION_WARNINGS
- fd.reordered_opaque = frame->reordered_opaque;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
- fd.frame_opaque = frame->opaque;
- fd.frame_opaque_ref = *opaque_ref;
-
- *opaque_ref = NULL;
-
- av_fifo_write(queue, &fd, 1);
+ av_fifo_write(queue, &timestamp, 1);
}
-static int64_t reorder_queue_dequeue(AVFifo *queue, AVCodecContext *avctx,
- AVPacket *pkt)
+static inline int64_t timestamp_queue_dequeue(AVFifo *queue)
{
- FrameData fd;
-
+ int64_t timestamp = AV_NOPTS_VALUE;
// The following call might fail if the queue is empty.
- if (av_fifo_read(queue, &fd, 1) < 0)
- return AV_NOPTS_VALUE;
-
- if (pkt) {
-#if FF_API_REORDERED_OPAQUE
-FF_DISABLE_DEPRECATION_WARNINGS
- avctx->reordered_opaque = fd.reordered_opaque;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
- pkt->duration = fd.duration;
+ av_fifo_read(queue, &timestamp, 1);
- if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
- pkt->opaque = fd.frame_opaque;
- pkt->opaque_ref = fd.frame_opaque_ref;
- fd.frame_opaque_ref = NULL;
- }
- }
-
- av_buffer_unref(&fd.frame_opaque_ref);
-
- return fd.pts;
+ return timestamp;
}
static int nvenc_set_timestamp(AVCodecContext *avctx,
@@ -2276,15 +2215,12 @@ static int nvenc_set_timestamp(AVCodecContext *avctx,
AVPacket *pkt)
{
NvencContext *ctx = avctx->priv_data;
- int64_t dts;
pkt->pts = params->outputTimeStamp;
- dts = reorder_queue_dequeue(ctx->reorder_queue, avctx, pkt);
-
if (avctx->codec_descriptor->props & AV_CODEC_PROP_REORDER) {
FF_DISABLE_DEPRECATION_WARNINGS
- pkt->dts = dts -
+ pkt->dts = timestamp_queue_dequeue(ctx->timestamp_list) -
#if FF_API_TICKS_PER_FRAME
FFMAX(avctx->ticks_per_frame, 1) *
#endif
@@ -2386,7 +2322,7 @@ static int process_output_surface(AVCodecContext *avctx, AVPacket *pkt, NvencSur
return 0;
error:
- reorder_queue_dequeue(ctx->reorder_queue, avctx, NULL);
+ timestamp_queue_dequeue(ctx->timestamp_list);
error2:
return res;
@@ -2616,8 +2552,6 @@ static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
int sei_count = 0;
int i;
- AVBufferRef *opaque_ref = NULL;
-
NvencContext *ctx = avctx->priv_data;
NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;
@@ -2685,17 +2619,9 @@ static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
pic_params.encodePicFlags = NV_ENC_PIC_FLAG_EOS;
}
- // make a reference for enqueing in the reorder queue here,
- // so that reorder_queue_enqueue() cannot fail
- if (frame && frame->opaque_ref && avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
- opaque_ref = av_buffer_ref(frame->opaque_ref);
- if (!opaque_ref)
- return AVERROR(ENOMEM);
- }
-
res = nvenc_push_context(avctx);
if (res < 0)
- goto opaque_ref_fail;
+ return res;
nv_status = p_nvenc->nvEncEncodePicture(ctx->nvencoder, &pic_params);
@@ -2704,17 +2630,17 @@ static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
res = nvenc_pop_context(avctx);
if (res < 0)
- goto opaque_ref_fail;
+ return res;
if (nv_status != NV_ENC_SUCCESS &&
- nv_status != NV_ENC_ERR_NEED_MORE_INPUT) {
- res = nvenc_print_error(avctx, nv_status, "EncodePicture failed!");
- goto opaque_ref_fail;
- }
+ nv_status != NV_ENC_ERR_NEED_MORE_INPUT)
+ return nvenc_print_error(avctx, nv_status, "EncodePicture failed!");
if (frame && frame->buf[0]) {
av_fifo_write(ctx->output_surface_queue, &in_surf, 1);
- reorder_queue_enqueue(ctx->reorder_queue, avctx, frame, &opaque_ref);
+
+ if (avctx->codec_descriptor->props & AV_CODEC_PROP_REORDER)
+ timestamp_queue_enqueue(ctx->timestamp_list, frame->pts);
}
/* all the pending buffers are now ready for output */
@@ -2724,10 +2650,6 @@ static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
}
return 0;
-
-opaque_ref_fail:
- av_buffer_unref(&opaque_ref);
- return res;
}
int ff_nvenc_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
@@ -2786,5 +2708,5 @@ av_cold void ff_nvenc_encode_flush(AVCodecContext *avctx)
NvencContext *ctx = avctx->priv_data;
nvenc_send_frame(avctx, NULL);
- reorder_queue_flush(ctx->reorder_queue);
+ av_fifo_reset2(ctx->timestamp_list);
}
diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h
index 97aad80cd0..55ec199211 100644
--- a/libavcodec/nvenc.h
+++ b/libavcodec/nvenc.h
@@ -176,7 +176,7 @@ typedef struct NvencContext
AVFifo *unused_surface_queue;
AVFifo *output_surface_queue;
AVFifo *output_surface_ready_queue;
- AVFifo *reorder_queue;
+ AVFifo *timestamp_list;
NV_ENC_SEI_PAYLOAD *sei_data;
int sei_data_size;
diff --git a/libavcodec/nvenc_av1.c b/libavcodec/nvenc_av1.c
index 2b349c7b61..2ed99d948b 100644
--- a/libavcodec/nvenc_av1.c
+++ b/libavcodec/nvenc_av1.c
@@ -181,8 +181,7 @@ const FFCodec ff_av1_nvenc_encoder = {
.defaults = defaults,
.p.pix_fmts = ff_nvenc_pix_fmts,
.p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |
- AV_CODEC_CAP_ENCODER_FLUSH | AV_CODEC_CAP_DR1 |
- AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
+ AV_CODEC_CAP_ENCODER_FLUSH | AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
FF_CODEC_CAP_INIT_CLEANUP,
.p.wrapper_name = "nvenc",
diff --git a/libavcodec/nvenc_h264.c b/libavcodec/nvenc_h264.c
index 698615855b..dfa8cce72e 100644
--- a/libavcodec/nvenc_h264.c
+++ b/libavcodec/nvenc_h264.c
@@ -244,8 +244,7 @@ const FFCodec ff_h264_nvenc_encoder = {
.p.priv_class = &h264_nvenc_class,
.defaults = defaults,
.p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |
- AV_CODEC_CAP_ENCODER_FLUSH | AV_CODEC_CAP_DR1 |
- AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
+ AV_CODEC_CAP_ENCODER_FLUSH | AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
FF_CODEC_CAP_INIT_CLEANUP,
.p.pix_fmts = ff_nvenc_pix_fmts,
diff --git a/libavcodec/nvenc_hevc.c b/libavcodec/nvenc_hevc.c
index d99077f170..ca58a84f22 100644
--- a/libavcodec/nvenc_hevc.c
+++ b/libavcodec/nvenc_hevc.c
@@ -226,8 +226,7 @@ const FFCodec ff_hevc_nvenc_encoder = {
.defaults = defaults,
.p.pix_fmts = ff_nvenc_pix_fmts,
.p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |
- AV_CODEC_CAP_ENCODER_FLUSH | AV_CODEC_CAP_DR1 |
- AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
+ AV_CODEC_CAP_ENCODER_FLUSH | AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
FF_CODEC_CAP_INIT_CLEANUP,
.p.wrapper_name = "nvenc",