Commit a56d0497 authored by Timo Rothenpieler's avatar Timo Rothenpieler

avcodec/nvenc: migrate to new encode API

Signed-off-by: 's avatarTimo Rothenpieler <timo@rothenpieler.org>
parent cf42f316
......@@ -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;
......
......@@ -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);
......
......@@ -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),
......
......@@ -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),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment