From patchwork Sat Sep 2 19:27:03 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Timo Rothenpieler X-Patchwork-Id: 4953 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.2.15.201 with SMTP id 70csp1731073jao; Sat, 2 Sep 2017 12:27:23 -0700 (PDT) X-Google-Smtp-Source: ADKCNb5kOe5kT+O69vITSVnnlGau+CC5U6iqgUl7ph0Pu5DvT50oqT8+R88OSwo8BzDMEig9Zsjz X-Received: by 10.223.171.22 with SMTP id q22mr2148752wrc.23.1504380443879; Sat, 02 Sep 2017 12:27:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1504380443; cv=none; d=google.com; s=arc-20160816; b=p/DJO+u4BQv7LxAwzzEiS4ypH+GmhKT7GtzQ4jaacA1R7TNGOblf0rAWDSuMf+8+82 YlpkQIc92Lhrouw+2ss+yDObeMbksZvsPD0Zb1rY5KYvk5S3ysh1RJalrXpC9QIeHd7U WEebdWsEIfd8zrq/BgJZcRLWYvLlvOTgXukdtdw00gY1oRMGBlqlJ73K5nxdCdsdtQ6c 6yfEJZsVpWv5alaXqCeZ2MKbCwyqQe9Y4rY9EuYzt+sTrxebnAFrtdIU1CbRlS79UZnU t+KkbK+kpdNXJkCNMVoW++KGFz99M012cvhrMnH7BNo11+xGJoIoKPeOYlMlbAoO5nJ/ 6KdQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:message-id:date:to:from:dkim-signature :delivered-to:arc-authentication-results; bh=dAOwALF8rTsSbHjw0aZPiGBHkmGuif9EQMlNvNkuBZc=; b=lXmgHi/8LBeHrllz0Mm3H9+ifBcIJ4kN8eiN1dSVVG9i6g1xrICmYksQPErUKDnvfd H9I/cHxe1/6hD1bad9ipRot4yOo9o3riesKlnfohYQsqlWr5rDxbTvFamhuAE/MiS1w8 c1tLs3bCghFLMvteJE4uiaz2dIza9apz1vFxQGcRU+3W8+yz+nAGuvjaUoRXfYSBD8Ow 8hSE0Vj+RK0wCik4QXEEbt/wPyOywfwtcCBXGZ5LF0xH9nKsoMl0qzfwZajJZHk6J8TN F7XRiyfpeJpGRzHaCcHva76spn5TMe4CbCD9Zfnfgp53KtKRiLDF5wss1PQGSn3hkOUC ZgRA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@rothenpieler.org header.s=mail header.b=Id6DqWPh; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id 41si2536471wrw.331.2017.09.02.12.27.23; Sat, 02 Sep 2017 12:27:23 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@rothenpieler.org header.s=mail header.b=Id6DqWPh; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 8D913689E1C; Sat, 2 Sep 2017 22:27:18 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from btbn.de (btbn.de [5.9.118.179]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 05A09689D87 for ; Sat, 2 Sep 2017 22:27:12 +0300 (EEST) Received: from localhost.localdomain (unknown [IPv6:2a02:8109:43f:959c:ba97:5aff:fe10:ec69]) by btbn.de (Postfix) with ESMTPSA id 6FDE014A650; Sat, 2 Sep 2017 21:27:13 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=rothenpieler.org; s=mail; t=1504380433; bh=Z/HfSVLNjVMbbALXYtTkLUPrtvA9BgT2Ub4mulAt0gY=; h=From:To:Cc:Subject:Date; b=Id6DqWPhM+MV279nq7GtsMm7RZvXjySPGm0q4KxOMVu6xCDav1ZhOWSxgTHvVgRgF x2Ym7bHv9fICQf3pYMSyqgIDBZIEXmEDTSR6jmKy699TJ+QJzNZ3HAqNDvXRh7pN1S mWczUTPaAsSzqpY9xhPO6hhyT+FOoTUMQBs11YPk= From: Timo Rothenpieler To: ffmpeg-devel@ffmpeg.org Date: Sat, 2 Sep 2017 21:27:03 +0200 Message-Id: <20170902192703.13955-1-timo@rothenpieler.org> X-Mailer: git-send-email 2.14.1 Subject: [FFmpeg-devel] [PATCH] avcodec/nvenc: migrate to new 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 Cc: Timo Rothenpieler MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Signed-off-by: Timo Rothenpieler --- libavcodec/nvenc.c | 65 ++++++++++++++++++++++++++++++++++++++++--------- libavcodec/nvenc.h | 6 +++++ libavcodec/nvenc_h264.c | 6 +++++ libavcodec/nvenc_hevc.c | 4 +++ 4 files changed, 70 insertions(+), 11 deletions(-) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index 744e5e0e01..b54cb1275b 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -1807,8 +1807,7 @@ static int output_ready(AVCodecContext *avctx, int flush) return (nb_ready > 0) && (nb_ready + nb_pending >= ctx->async_depth); } -int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, - const AVFrame *frame, int *got_packet) +int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) { NVENCSTATUS nv_status; CUresult cu_res; @@ -1823,12 +1822,16 @@ int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, NV_ENC_PIC_PARAMS pic_params = { 0 }; pic_params.version = NV_ENC_PIC_PARAMS_VER; + if (!ctx->cu_context || !ctx->nvencoder) + return AVERROR(EINVAL); + + if (ctx->encoder_flushing) + return AVERROR_EOF; + if (frame) { inSurf = get_free_frame(ctx); - if (!inSurf) { - av_log(avctx, AV_LOG_ERROR, "No free surfaces\n"); - return AVERROR_BUG; - } + if (!inSurf) + return AVERROR(EAGAIN); cu_res = dl_fn->cuda_dl->cuCtxPushCurrent(ctx->cu_context); if (cu_res != CUDA_SUCCESS) { @@ -1876,6 +1878,7 @@ int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, nvenc_codec_specific_pic_params(avctx, &pic_params); } else { pic_params.encodePicFlags = NV_ENC_PIC_FLAG_EOS; + ctx->encoder_flushing = 1; } cu_res = dl_fn->cuda_dl->cuCtxPushCurrent(ctx->cu_context); @@ -1914,7 +1917,23 @@ int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, } } - if (output_ready(avctx, !frame)) { + return 0; +} + +int ff_nvenc_receive_packet(AVCodecContext *avctx, AVPacket *pkt) +{ + CUresult cu_res; + CUcontext dummy; + NvencSurface *tmpoutsurf; + int res; + + NvencContext *ctx = avctx->priv_data; + NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs; + + if (!ctx->cu_context || !ctx->nvencoder) + return AVERROR(EINVAL); + + if (output_ready(avctx, ctx->encoder_flushing)) { av_fifo_generic_read(ctx->output_surface_ready_queue, &tmpoutsurf, sizeof(tmpoutsurf), NULL); cu_res = dl_fn->cuda_dl->cuCtxPushCurrent(ctx->cu_context); @@ -1935,10 +1954,34 @@ int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, return res; av_fifo_generic_write(ctx->unused_surface_queue, &tmpoutsurf, sizeof(tmpoutsurf), NULL); - - *got_packet = 1; + } else if (ctx->encoder_flushing) { + return AVERROR_EOF; } else { + return AVERROR(EAGAIN); + } + + 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; diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h index 2c682275da..afb93cc22c 100644 --- a/libavcodec/nvenc.h +++ b/libavcodec/nvenc.h @@ -116,6 +116,8 @@ typedef struct NvencContext AVFifoBuffer *output_surface_ready_queue; AVFifoBuffer *timestamp_list; + int encoder_flushing; + struct { CUdeviceptr ptr; NV_ENC_REGISTERED_PTR regptr; @@ -169,6 +171,10 @@ int ff_nvenc_encode_init(AVCodecContext *avctx); int ff_nvenc_encode_close(AVCodecContext *avctx); +int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame); + +int ff_nvenc_receive_packet(AVCodecContext *avctx, AVPacket *pkt); + int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet); diff --git a/libavcodec/nvenc_h264.c b/libavcodec/nvenc_h264.c index 9adbe9f909..c3b4bac749 100644 --- a/libavcodec/nvenc_h264.c +++ b/libavcodec/nvenc_h264.c @@ -164,6 +164,8 @@ 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), @@ -190,6 +192,8 @@ 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), @@ -216,6 +220,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, .priv_data_size = sizeof(NvencContext), diff --git a/libavcodec/nvenc_hevc.c b/libavcodec/nvenc_hevc.c index 81da9d222d..89e8c3e53a 100644 --- a/libavcodec/nvenc_hevc.c +++ b/libavcodec/nvenc_hevc.c @@ -153,6 +153,8 @@ 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), @@ -178,6 +180,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, .priv_data_size = sizeof(NvencContext),