aboutsummaryrefslogtreecommitdiffstats
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:43:32 +0200
commitd341895a087b32efd4472fbbf6eb342eaf220bd2 (patch)
treecbb7b7ee89864a43fbccd5d87b19c371b3034a84
parentcb3453eb25e249b7c428badd24d8dbcfc74ec3e7 (diff)
downloadffmpeg-d341895a087b32efd4472fbbf6eb342eaf220bd2.tar.gz
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.c117
-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, 24 insertions, 104 deletions
diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
index 9acf3e8697..aa9cd81485 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"
@@ -163,27 +162,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;
@@ -1772,8 +1750,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);
@@ -1857,11 +1835,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);
@@ -2205,53 +2179,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,
@@ -2259,14 +2198,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) {
- pkt->dts = dts - FFMAX(ctx->encode_config.frameIntervalP - 1, 0) * FFMAX(avctx->ticks_per_frame, 1);
+ pkt->dts = timestamp_queue_dequeue(ctx->timestamp_list) -
+ FFMAX(ctx->encode_config.frameIntervalP - 1, 0) * FFMAX(avctx->ticks_per_frame, 1);
} else {
pkt->dts = pkt->pts;
}
@@ -2363,7 +2300,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;
@@ -2593,8 +2530,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;
@@ -2662,17 +2597,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);
@@ -2681,17 +2608,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 */
@@ -2701,10 +2628,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)
@@ -2763,5 +2686,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 411c83aa94..05a7ac48b1 100644
--- a/libavcodec/nvenc.h
+++ b/libavcodec/nvenc.h
@@ -171,7 +171,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 5dc2961c3b..a69358b03b 100644
--- a/libavcodec/nvenc_h264.c
+++ b/libavcodec/nvenc_h264.c
@@ -232,8 +232,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 1362a927c8..5ad423444a 100644
--- a/libavcodec/nvenc_hevc.c
+++ b/libavcodec/nvenc_hevc.c
@@ -214,8 +214,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",