From patchwork Wed Apr 8 17:58:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Almer X-Patchwork-Id: 18783 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id B9D1744BAC2 for ; Wed, 8 Apr 2020 20:59:55 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 89EF568B7E0; Wed, 8 Apr 2020 20:59:55 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-qt1-f194.google.com (mail-qt1-f194.google.com [209.85.160.194]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id E509C68B7D0 for ; Wed, 8 Apr 2020 20:59:48 +0300 (EEST) Received: by mail-qt1-f194.google.com with SMTP id g7so557501qtj.13 for ; Wed, 08 Apr 2020 10:59:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=JV9uYom1i2TGztfRmT2aU8E8aakHzdBOq01DYokvrJE=; b=nMMLaWigoXHVH/0VTBG+wQ3+J7yGy40TCzX0Z8uNaqNYV97jB5qxDyZvcgoZoe/gp8 xkfzLRk5daN7teUbgxO4rjtvXtZkLTIyzSx8fVCT6mVLbCEp47teBowSf0xk0YdEw3aC YnO+qomAHlafpKKqkS+6lmy02/4HpK/YFRoV3nvmfmwxCfRukJ3fMJqfWoPYY1u92V8G Sxhpzkevqo1zkxjFyzvQYL6fftDI4P3Z6kteMTu1MhsUGfQtFMy/a5VpozQ/WwPBOj2/ HmK1wR8E26IYOm2HFtTwGQ5zdaMDXJZFQTPC4hudqWWVVj44zDS+f9D0VjivTfeUCO+M 7JNA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=JV9uYom1i2TGztfRmT2aU8E8aakHzdBOq01DYokvrJE=; b=g2g5bbvxv7TFcZZIeENBwwqhYKGvXctXDrnakrg+A2ka/XM0kPLhBfWMq2XbDz/SgZ TXkT0LHoKLrZ3oB3vffVZNL4TRhThs0rGFb1wLCzgcybIMfpkIjGhhcAlifT1XDaPiZt mOFHpuiymTDvkhMOS02ur2qL2dy+Q964JFuLRkzWi6tk959l2qgLhnKE6V71YtoICV/G ybD1qND02Cc+EkJk1t6CPSuMJ3SR5BfOSAPrRrC4F+JnPP4gueGeI1LgPT0rltOZyO5Q +C4OH3L7TdWZ0m5jf2VjJNiVlUSMCPi+D5Qd8T2fqQivxCIUE3zQoNtX/aY5ukYNZsnF nv1Q== X-Gm-Message-State: AGi0PuZu4Q7YjNqcLRlSitrmk/bB7rVF7CvBjamRo+pGtaVAgIg5idPH adI4jXK33YjDDuebywEeADSxvyPrP0Y= X-Google-Smtp-Source: APiQypKJBrqh9oIBttDMkg0Cm9FQar9RtkAgjPtIjlNMWfw2qWg58qENshbvxev1G42yl4gpOEnHBQ== X-Received: by 2002:ac8:4e0e:: with SMTP id c14mr7967965qtw.312.1586368787075; Wed, 08 Apr 2020 10:59:47 -0700 (PDT) Received: from localhost.localdomain ([191.83.218.14]) by smtp.gmail.com with ESMTPSA id g27sm17447510qkk.55.2020.04.08.10.59.46 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 08 Apr 2020 10:59:46 -0700 (PDT) From: James Almer To: ffmpeg-devel@ffmpeg.org Date: Wed, 8 Apr 2020 14:58:36 -0300 Message-Id: <20200408175836.8231-1-jamrial@gmail.com> X-Mailer: git-send-email 2.26.0 In-Reply-To: <20200326195857.5838-1-jamrial@gmail.com> References: <20200326195857.5838-1-jamrial@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH] avcodec/nvenc: adapt to the new internal encode API X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Signed-off-by: James Almer --- This removes the encode2() implementation as it'll never be used if a receive_packet() one exists, and the flush() implementation since according to Anton Khirnov avcodec_flush_buffers() is not meant to be used with encoders, where its behavior is undefined. libavcodec/nvenc.c | 84 +++++++++++------------------------------ libavcodec/nvenc.h | 4 +- libavcodec/nvenc_h264.c | 7 ---- libavcodec/nvenc_hevc.c | 5 --- 4 files changed, 25 insertions(+), 75 deletions(-) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index 9a96bf2bba..6c0baf4d86 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -30,6 +30,7 @@ #include "libavutil/avassert.h" #include "libavutil/mem.h" #include "libavutil/pixdesc.h" +#include "encode.h" #include "internal.h" #define CHECK_CU(x) FF_CUDA_CHECK_DL(avctx, dl_fn->cuda_dl, x) @@ -1491,6 +1492,8 @@ av_cold int ff_nvenc_encode_close(AVCodecContext *avctx) av_freep(&ctx->surfaces); ctx->nb_surfaces = 0; + av_frame_free(&ctx->frame); + if (ctx->nvencoder) { p_nvenc->nvEncDestroyEncoder(ctx->nvencoder); @@ -1544,6 +1547,10 @@ av_cold int ff_nvenc_encode_init(AVCodecContext *avctx) ctx->data_pix_fmt = avctx->pix_fmt; } + ctx->frame = av_frame_alloc(); + if (!ctx->frame) + return AVERROR(ENOMEM); + if ((ret = nvenc_load_libraries(avctx)) < 0) return ret; @@ -1881,9 +1888,7 @@ static int process_output_surface(AVCodecContext *avctx, AVPacket *pkt, NvencSur goto error; } - res = pkt->data ? - ff_alloc_packet2(avctx, pkt, lock_params.bitstreamSizeInBytes, lock_params.bitstreamSizeInBytes) : - av_new_packet(pkt, lock_params.bitstreamSizeInBytes); + res = av_new_packet(pkt, lock_params.bitstreamSizeInBytes); if (res < 0) { p_nvenc->nvEncUnlockBitstream(ctx->nvencoder, tmpoutsurf->output_surface); @@ -2075,7 +2080,7 @@ static void reconfig_encoder(AVCodecContext *avctx, const AVFrame *frame) } } -int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) +int ff_nvenc_receive_packet(AVCodecContext *avctx, AVPacket *pkt) { NVENCSTATUS nv_status; NvencSurface *tmp_out_surf, *in_surf; @@ -2087,27 +2092,24 @@ int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs; NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs; + AVFrame *frame = ctx->frame; + NV_ENC_PIC_PARAMS pic_params = { 0 }; pic_params.version = NV_ENC_PIC_PARAMS_VER; if ((!ctx->cu_context && !ctx->d3d11_device) || !ctx->nvencoder) return AVERROR(EINVAL); - if (ctx->encoder_flushing) { - if (avctx->internal->draining) - return AVERROR_EOF; - - ctx->encoder_flushing = 0; - ctx->first_packet_output = 0; - ctx->initial_pts[0] = AV_NOPTS_VALUE; - ctx->initial_pts[1] = AV_NOPTS_VALUE; - av_fifo_reset(ctx->timestamp_list); + if (!frame->buf[0]) { + res = ff_encode_get_frame(avctx, frame); + if (res < 0 && res != AVERROR_EOF) + return res; } - if (frame) { + if (frame->buf[0]) { in_surf = get_free_frame(ctx); if (!in_surf) - return AVERROR(EAGAIN); + goto output; res = nvenc_push_context(avctx); if (res < 0) @@ -2164,7 +2166,6 @@ int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) nvenc_codec_specific_pic_params(avctx, &pic_params, sei_data); } else { pic_params.encodePicFlags = NV_ENC_PIC_FLAG_EOS; - ctx->encoder_flushing = 1; } res = nvenc_push_context(avctx); @@ -2182,7 +2183,7 @@ int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) nv_status != NV_ENC_ERR_NEED_MORE_INPUT) return nvenc_print_error(avctx, nv_status, "EncodePicture failed!"); - if (frame) { + if (frame->buf[0]) { av_fifo_generic_write(ctx->output_surface_queue, &in_surf, sizeof(in_surf), NULL); timestamp_queue_enqueue(ctx->timestamp_list, frame->pts); @@ -2190,6 +2191,8 @@ int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) ctx->initial_pts[0] = frame->pts; else if (ctx->initial_pts[1] == AV_NOPTS_VALUE) ctx->initial_pts[1] = frame->pts; + + av_frame_unref(frame); } /* all the pending buffers are now ready for output */ @@ -2200,20 +2203,8 @@ int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) } } - return 0; -} - -int ff_nvenc_receive_packet(AVCodecContext *avctx, AVPacket *pkt) -{ - NvencSurface *tmp_out_surf; - int res, res2; - - NvencContext *ctx = avctx->priv_data; - - if ((!ctx->cu_context && !ctx->d3d11_device) || !ctx->nvencoder) - return AVERROR(EINVAL); - - if (output_ready(avctx, ctx->encoder_flushing)) { +output: + if (output_ready(avctx, avctx->internal->draining)) { av_fifo_generic_read(ctx->output_surface_ready_queue, &tmp_out_surf, sizeof(tmp_out_surf), NULL); res = nvenc_push_context(avctx); @@ -2230,7 +2221,7 @@ int ff_nvenc_receive_packet(AVCodecContext *avctx, AVPacket *pkt) return res; av_fifo_generic_write(ctx->unused_surface_queue, &tmp_out_surf, sizeof(tmp_out_surf), NULL); - } else if (ctx->encoder_flushing) { + } else if (avctx->internal->draining) { return AVERROR_EOF; } else { return AVERROR(EAGAIN); @@ -2238,32 +2229,3 @@ int ff_nvenc_receive_packet(AVCodecContext *avctx, AVPacket *pkt) return 0; } - -int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, - const AVFrame *frame, int *got_packet) -{ - NvencContext *ctx = avctx->priv_data; - int res; - - if (!ctx->encoder_flushing) { - res = ff_nvenc_send_frame(avctx, frame); - if (res < 0) - return res; - } - - res = ff_nvenc_receive_packet(avctx, pkt); - if (res == AVERROR(EAGAIN) || res == AVERROR_EOF) { - *got_packet = 0; - } else if (res < 0) { - return res; - } else { - *got_packet = 1; - } - - return 0; -} - -av_cold void ff_nvenc_encode_flush(AVCodecContext *avctx) -{ - ff_nvenc_send_frame(avctx, NULL); -} diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h index c44c81e675..6e0d418365 100644 --- a/libavcodec/nvenc.h +++ b/libavcodec/nvenc.h @@ -137,6 +137,8 @@ typedef struct NvencContext CUstream cu_stream; ID3D11Device *d3d11_device; + AVFrame *frame; + int nb_surfaces; NvencSurface *surfaces; @@ -145,8 +147,6 @@ typedef struct NvencContext AVFifoBuffer *output_surface_ready_queue; AVFifoBuffer *timestamp_list; - int encoder_flushing; - struct { void *ptr; int ptr_index; diff --git a/libavcodec/nvenc_h264.c b/libavcodec/nvenc_h264.c index 479155fe15..43ec48f89d 100644 --- a/libavcodec/nvenc_h264.c +++ b/libavcodec/nvenc_h264.c @@ -178,9 +178,7 @@ AVCodec ff_nvenc_encoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H264, .init = nvenc_old_init, - .send_frame = ff_nvenc_send_frame, .receive_packet = ff_nvenc_receive_packet, - .encode2 = ff_nvenc_encode_frame, .close = ff_nvenc_encode_close, .priv_data_size = sizeof(NvencContext), .priv_class = &nvenc_class, @@ -207,9 +205,7 @@ AVCodec ff_nvenc_h264_encoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H264, .init = nvenc_old_init, - .send_frame = ff_nvenc_send_frame, .receive_packet = ff_nvenc_receive_packet, - .encode2 = ff_nvenc_encode_frame, .close = ff_nvenc_encode_close, .priv_data_size = sizeof(NvencContext), .priv_class = &nvenc_h264_class, @@ -236,11 +232,8 @@ AVCodec ff_h264_nvenc_encoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H264, .init = ff_nvenc_encode_init, - .send_frame = ff_nvenc_send_frame, .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 = &h264_nvenc_class, .defaults = defaults, diff --git a/libavcodec/nvenc_hevc.c b/libavcodec/nvenc_hevc.c index 7c9b3848f1..a575d64092 100644 --- a/libavcodec/nvenc_hevc.c +++ b/libavcodec/nvenc_hevc.c @@ -166,9 +166,7 @@ AVCodec ff_nvenc_hevc_encoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_HEVC, .init = nvenc_old_init, - .send_frame = ff_nvenc_send_frame, .receive_packet = ff_nvenc_receive_packet, - .encode2 = ff_nvenc_encode_frame, .close = ff_nvenc_encode_close, .priv_data_size = sizeof(NvencContext), .priv_class = &nvenc_hevc_class, @@ -194,11 +192,8 @@ AVCodec ff_hevc_nvenc_encoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_HEVC, .init = ff_nvenc_encode_init, - .send_frame = ff_nvenc_send_frame, .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 = &hevc_nvenc_class, .defaults = defaults,