mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
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 3553809703
.
This commit is contained in:
parent
73a2252f1d
commit
6c418ae25e
@ -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, ¶ms);
|
||||
}
|
||||
|
||||
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, ×tamp, 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;
|
||||
av_fifo_read(queue, ×tamp, 1);
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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",
|
||||
|
@ -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,
|
||||
|
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user