diff options
author | Timo Rothenpieler <timo@rothenpieler.org> | 2017-09-02 20:30:21 +0300 |
---|---|---|
committer | Timo Rothenpieler <timo@rothenpieler.org> | 2017-09-07 13:08:32 +0300 |
commit | a56d0497cbab6f9abf68f77f1b4fe16c4a53f101 (patch) | |
tree | db6733138807721e57b31352ceacd735dd270dd8 /libavcodec/nvenc.c | |
parent | cf42f316c525a76680b8b2d3e68c61db71eaa50d (diff) |
avcodec/nvenc: migrate to new encode API
Signed-off-by: Timo Rothenpieler <timo@rothenpieler.org>
Diffstat (limited to 'libavcodec/nvenc.c')
-rw-r--r-- | libavcodec/nvenc.c | 65 |
1 files changed, 54 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) { @@ -1844,9 +1847,8 @@ int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, return AVERROR_EXTERNAL; } - if (res) { + if (res) return res; - } pic_params.inputBuffer = inSurf->input_surface; pic_params.bufferFmt = inSurf->format; @@ -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; |