static int nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt,

    const AVFrame *frame, int *got_packet)

{

    NVENCSTATUS nv_status;

    NvencOutputSurface *tmpoutsurf;

    int res, i = 0;



    NvencContext *ctx = avctx->priv_data;

    NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;

    NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;



    NV_ENC_PIC_PARAMS pic_params = { 0 };

    pic_params.version = NV_ENC_PIC_PARAMS_VER;



    if (frame) {

        NV_ENC_LOCK_INPUT_BUFFER lockBufferParams = { 0 };

        NvencInputSurface *inSurf = NULL;



        for (i = 0; i < ctx->max_surface_count; ++i) {

            if (!ctx->input_surfaces[i].lockCount) {

                inSurf = &ctx->input_surfaces[i];

                break;

            }

        }



        av_assert0(inSurf);



        inSurf->lockCount = 1;



        lockBufferParams.version = NV_ENC_LOCK_INPUT_BUFFER_VER;

        lockBufferParams.inputBuffer = inSurf->input_surface;



        nv_status = p_nvenc->nvEncLockInputBuffer(ctx->nvencoder, &lockBufferParams);

        if (nv_status != NV_ENC_SUCCESS) {

            av_log(avctx, AV_LOG_ERROR, "Failed locking nvenc input buffer\n");

            return 0;

        }



        if (avctx->pix_fmt == AV_PIX_FMT_YUV420P) {

            uint8_t *buf = lockBufferParams.bufferDataPtr;



            av_image_copy_plane(buf, lockBufferParams.pitch,

                frame->data[0], frame->linesize[0],

                avctx->width, avctx->height);



            buf += inSurf->height * lockBufferParams.pitch;



            av_image_copy_plane(buf, lockBufferParams.pitch >> 1,

                frame->data[2], frame->linesize[2],

                avctx->width >> 1, avctx->height >> 1);



            buf += (inSurf->height * lockBufferParams.pitch) >> 2;



            av_image_copy_plane(buf, lockBufferParams.pitch >> 1,

                frame->data[1], frame->linesize[1],

                avctx->width >> 1, avctx->height >> 1);

        } else if (avctx->pix_fmt == AV_PIX_FMT_NV12) {

            uint8_t *buf = lockBufferParams.bufferDataPtr;



            av_image_copy_plane(buf, lockBufferParams.pitch,

                frame->data[0], frame->linesize[0],

                avctx->width, avctx->height);



            buf += inSurf->height * lockBufferParams.pitch;



            av_image_copy_plane(buf, lockBufferParams.pitch,

                frame->data[1], frame->linesize[1],

                avctx->width, avctx->height >> 1);

        } else if (avctx->pix_fmt == AV_PIX_FMT_YUV444P) {

            uint8_t *buf = lockBufferParams.bufferDataPtr;



            av_image_copy_plane(buf, lockBufferParams.pitch,

                frame->data[0], frame->linesize[0],

                avctx->width, avctx->height);



            buf += inSurf->height * lockBufferParams.pitch;



            av_image_copy_plane(buf, lockBufferParams.pitch,

                frame->data[1], frame->linesize[1],

                avctx->width, avctx->height);



            buf += inSurf->height * lockBufferParams.pitch;



            av_image_copy_plane(buf, lockBufferParams.pitch,

                frame->data[2], frame->linesize[2],

                avctx->width, avctx->height);

        } else {

            av_log(avctx, AV_LOG_FATAL, "Invalid pixel format!\n");

            return AVERROR(EINVAL);

        }



        nv_status = p_nvenc->nvEncUnlockInputBuffer(ctx->nvencoder, inSurf->input_surface);

        if (nv_status != NV_ENC_SUCCESS) {

            av_log(avctx, AV_LOG_FATAL, "Failed unlocking input buffer!\n");

            return AVERROR_EXTERNAL;

        }



        for (i = 0; i < ctx->max_surface_count; ++i)

            if (!ctx->output_surfaces[i].busy)

                break;



        if (i == ctx->max_surface_count) {

            inSurf->lockCount = 0;

            av_log(avctx, AV_LOG_FATAL, "No free output surface found!\n");

            return AVERROR_EXTERNAL;

        }



        ctx->output_surfaces[i].input_surface = inSurf;



        pic_params.inputBuffer = inSurf->input_surface;

        pic_params.bufferFmt = inSurf->format;

        pic_params.inputWidth = avctx->width;

        pic_params.inputHeight = avctx->height;

        pic_params.outputBitstream = ctx->output_surfaces[i].output_surface;

        pic_params.completionEvent = 0;



        if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT) {

            if (frame->top_field_first) {

                pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FIELD_TOP_BOTTOM;

            } else {

                pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FIELD_BOTTOM_TOP;

            }

        } else {

            pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FRAME;

        }



        pic_params.encodePicFlags = 0;

        pic_params.inputTimeStamp = frame->pts;

        pic_params.inputDuration = 0;

        switch (avctx->codec->id) {

        case AV_CODEC_ID_H264:

          pic_params.codecPicParams.h264PicParams.sliceMode = ctx->encode_config.encodeCodecConfig.h264Config.sliceMode;

          pic_params.codecPicParams.h264PicParams.sliceModeData = ctx->encode_config.encodeCodecConfig.h264Config.sliceModeData;

          break;

        case AV_CODEC_ID_H265:

          pic_params.codecPicParams.hevcPicParams.sliceMode = ctx->encode_config.encodeCodecConfig.hevcConfig.sliceMode;

          pic_params.codecPicParams.hevcPicParams.sliceModeData = ctx->encode_config.encodeCodecConfig.hevcConfig.sliceModeData;

          break;

        default:

          av_log(avctx, AV_LOG_ERROR, "Unknown codec name\n");

          return AVERROR(EINVAL);

        }



        res = timestamp_queue_enqueue(&ctx->timestamp_list, frame->pts);



        if (res)

            return res;

    } else {

        pic_params.encodePicFlags = NV_ENC_PIC_FLAG_EOS;

    }



    nv_status = p_nvenc->nvEncEncodePicture(ctx->nvencoder, &pic_params);



    if (frame && nv_status == NV_ENC_ERR_NEED_MORE_INPUT) {

        res = out_surf_queue_enqueue(&ctx->output_surface_queue, &ctx->output_surfaces[i]);



        if (res)

            return res;



        ctx->output_surfaces[i].busy = 1;

    }



    if (nv_status != NV_ENC_SUCCESS && nv_status != NV_ENC_ERR_NEED_MORE_INPUT) {

        av_log(avctx, AV_LOG_ERROR, "EncodePicture failed!\n");

        return AVERROR_EXTERNAL;

    }



    if (nv_status != NV_ENC_ERR_NEED_MORE_INPUT) {

        while (ctx->output_surface_queue.count) {

            tmpoutsurf = out_surf_queue_dequeue(&ctx->output_surface_queue);

            res = out_surf_queue_enqueue(&ctx->output_surface_ready_queue, tmpoutsurf);



            if (res)

                return res;

        }



        if (frame) {

            res = out_surf_queue_enqueue(&ctx->output_surface_ready_queue, &ctx->output_surfaces[i]);



            if (res)

                return res;



            ctx->output_surfaces[i].busy = 1;

        }

    }



    if (ctx->output_surface_ready_queue.count && (!frame || ctx->output_surface_ready_queue.count + ctx->output_surface_queue.count >= ctx->buffer_delay)) {

        tmpoutsurf = out_surf_queue_dequeue(&ctx->output_surface_ready_queue);



        res = process_output_surface(avctx, pkt, tmpoutsurf);



        if (res)

            return res;



        tmpoutsurf->busy = 0;

        av_assert0(tmpoutsurf->input_surface->lockCount);

        tmpoutsurf->input_surface->lockCount--;



        *got_packet = 1;

    } else {

        *got_packet = 0;

    }



    return 0;

}

static int nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt,

    const AVFrame *frame, int *got_packet)

{

    NVENCSTATUS nv_status;

    NvencOutputSurface *tmpoutsurf;

    int res, i = 0;



    NvencContext *ctx = avctx->priv_data;

    NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;

    NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;



    NV_ENC_PIC_PARAMS pic_params = { 0 };

    pic_params.version = NV_ENC_PIC_PARAMS_VER;



    if (frame) {

        NV_ENC_LOCK_INPUT_BUFFER lockBufferParams = { 0 };

        NvencInputSurface *inSurf = NULL;



        for (i = 0; i < ctx->max_surface_count; ++i) {

            if (!ctx->input_surfaces[i].lockCount) {

                inSurf = &ctx->input_surfaces[i];

                break;

            }

        }



        av_assert0(inSurf);



        inSurf->lockCount = 1;



        lockBufferParams.version = NV_ENC_LOCK_INPUT_BUFFER_VER;

        lockBufferParams.inputBuffer = inSurf->input_surface;



        nv_status = p_nvenc->nvEncLockInputBuffer(ctx->nvencoder, &lockBufferParams);

        if (nv_status != NV_ENC_SUCCESS) {

            av_log(avctx, AV_LOG_ERROR, "Failed locking nvenc input buffer\n");

            return 0;

        }



        if (avctx->pix_fmt == AV_PIX_FMT_YUV420P) {

            uint8_t *buf = lockBufferParams.bufferDataPtr;



            av_image_copy_plane(buf, lockBufferParams.pitch,

                frame->data[0], frame->linesize[0],

                avctx->width, avctx->height);



            buf += inSurf->height * lockBufferParams.pitch;



            av_image_copy_plane(buf, lockBufferParams.pitch >> 1,

                frame->data[2], frame->linesize[2],

                avctx->width >> 1, avctx->height >> 1);



            buf += (inSurf->height * lockBufferParams.pitch) >> 2;



            av_image_copy_plane(buf, lockBufferParams.pitch >> 1,

                frame->data[1], frame->linesize[1],

                avctx->width >> 1, avctx->height >> 1);

        } else if (avctx->pix_fmt == AV_PIX_FMT_NV12) {

            uint8_t *buf = lockBufferParams.bufferDataPtr;



            av_image_copy_plane(buf, lockBufferParams.pitch,

                frame->data[0], frame->linesize[0],

                avctx->width, avctx->height);



            buf += inSurf->height * lockBufferParams.pitch;



            av_image_copy_plane(buf, lockBufferParams.pitch,

                frame->data[1], frame->linesize[1],

                avctx->width, avctx->height >> 1);

        } else if (avctx->pix_fmt == AV_PIX_FMT_YUV444P) {

            uint8_t *buf = lockBufferParams.bufferDataPtr;



            av_image_copy_plane(buf, lockBufferParams.pitch,

                frame->data[0], frame->linesize[0],

                avctx->width, avctx->height);



            buf += inSurf->height * lockBufferParams.pitch;



            av_image_copy_plane(buf, lockBufferParams.pitch,

                frame->data[1], frame->linesize[1],

                avctx->width, avctx->height);



            buf += inSurf->height * lockBufferParams.pitch;



            av_image_copy_plane(buf, lockBufferParams.pitch,

                frame->data[2], frame->linesize[2],

                avctx->width, avctx->height);

        } else {

            av_log(avctx, AV_LOG_FATAL, "Invalid pixel format!\n");

            return AVERROR(EINVAL);

        }



        nv_status = p_nvenc->nvEncUnlockInputBuffer(ctx->nvencoder, inSurf->input_surface);

        if (nv_status != NV_ENC_SUCCESS) {

            av_log(avctx, AV_LOG_FATAL, "Failed unlocking input buffer!\n");

            return AVERROR_EXTERNAL;

        }



        for (i = 0; i < ctx->max_surface_count; ++i)

            if (!ctx->output_surfaces[i].busy)

                break;



        if (i == ctx->max_surface_count) {

            inSurf->lockCount = 0;

            av_log(avctx, AV_LOG_FATAL, "No free output surface found!\n");

            return AVERROR_EXTERNAL;

        }



        ctx->output_surfaces[i].input_surface = inSurf;



        pic_params.inputBuffer = inSurf->input_surface;

        pic_params.bufferFmt = inSurf->format;

        pic_params.inputWidth = avctx->width;

        pic_params.inputHeight = avctx->height;

        pic_params.outputBitstream = ctx->output_surfaces[i].output_surface;

        pic_params.completionEvent = 0;



        if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT) {

            if (frame->top_field_first) {

                pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FIELD_TOP_BOTTOM;

            } else {

                pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FIELD_BOTTOM_TOP;

            }

        } else {

            pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FRAME;

        }



        pic_params.encodePicFlags = 0;

        pic_params.inputTimeStamp = frame->pts;

        pic_params.inputDuration = 0;

        switch (avctx->codec->id) {

        case AV_CODEC_ID_H264:

          pic_params.codecPicParams.h264PicParams.sliceMode = ctx->encode_config.encodeCodecConfig.h264Config.sliceMode;

          pic_params.codecPicParams.h264PicParams.sliceModeData = ctx->encode_config.encodeCodecConfig.h264Config.sliceModeData;

          break;

        case AV_CODEC_ID_H265:

          pic_params.codecPicParams.hevcPicParams.sliceMode = ctx->encode_config.encodeCodecConfig.hevcConfig.sliceMode;

          pic_params.codecPicParams.hevcPicParams.sliceModeData = ctx->encode_config.encodeCodecConfig.hevcConfig.sliceModeData;

          break;

        default:

          av_log(avctx, AV_LOG_ERROR, "Unknown codec name\n");

          return AVERROR(EINVAL);

        }



        res = timestamp_queue_enqueue(&ctx->timestamp_list, frame->pts);



        if (res)

            return res;

    } else {

        pic_params.encodePicFlags = NV_ENC_PIC_FLAG_EOS;

    }



    nv_status = p_nvenc->nvEncEncodePicture(ctx->nvencoder, &pic_params);



    if (frame && nv_status == NV_ENC_ERR_NEED_MORE_INPUT) {

        res = out_surf_queue_enqueue(&ctx->output_surface_queue, &ctx->output_surfaces[i]);



        if (res)

            return res;



        ctx->output_surfaces[i].busy = 1;

    }



    if (nv_status != NV_ENC_SUCCESS && nv_status != NV_ENC_ERR_NEED_MORE_INPUT) {

        av_log(avctx, AV_LOG_ERROR, "EncodePicture failed!\n");

        return AVERROR_EXTERNAL;

    }



    if (nv_status != NV_ENC_ERR_NEED_MORE_INPUT) {

        while (ctx->output_surface_queue.count) {

            tmpoutsurf = out_surf_queue_dequeue(&ctx->output_surface_queue);

            res = out_surf_queue_enqueue(&ctx->output_surface_ready_queue, tmpoutsurf);



            if (res)

                return res;

        }



        if (frame) {

            res = out_surf_queue_enqueue(&ctx->output_surface_ready_queue, &ctx->output_surfaces[i]);



            if (res)

                return res;



            ctx->output_surfaces[i].busy = 1;

        }

    }



    if (ctx->output_surface_ready_queue.count && (!frame || ctx->output_surface_ready_queue.count + ctx->output_surface_queue.count >= ctx->buffer_delay)) {

        tmpoutsurf = out_surf_queue_dequeue(&ctx->output_surface_ready_queue);



        res = process_output_surface(avctx, pkt, tmpoutsurf);



        if (res)

            return res;



        tmpoutsurf->busy = 0;

        av_assert0(tmpoutsurf->input_surface->lockCount);

        tmpoutsurf->input_surface->lockCount--;



        *got_packet = 1;

    } else {

        *got_packet = 0;

    }



    return 0;

}

    NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;         return AVERROR_EXTERNAL;         switch (avctx->codec->id) {         case AV_CODEC_ID_H264:         case AV_CODEC_ID_H265:         } else {     } else {             } else {         } else {             } else {         } else {                 break;                 break;                 break;                 break;                 break;             } else {         } else {         } else {             } else {         default:         if (nv_status != NV_ENC_SUCCESS) {         if (nv_status != NV_ENC_SUCCESS) {         if (nv_status != NV_ENC_SUCCESS) {         NV_ENC_LOCK_INPUT_BUFFER lockBufferParams = { 0 };         NvencInputSurface *inSurf = NULL;         for (i = 0; i < ctx->max_surface_count; ++i) {             if (!ctx->input_surfaces[i].lockCount) {                 inSurf = &ctx->input_surfaces[i];                 break;         inSurf->lockCount = 1;         lockBufferParams.version = NV_ENC_LOCK_INPUT_BUFFER_VER;         lockBufferParams.inputBuffer = inSurf->input_surface;         nv_status = p_nvenc->nvEncLockInputBuffer(ctx->nvencoder, &lockBufferParams);         if (nv_status != NV_ENC_SUCCESS) {             av_log(avctx, AV_LOG_ERROR, "Failed locking nvenc input buffer\n");             return 0;         if (avctx->pix_fmt == AV_PIX_FMT_YUV420P) {             uint8_t *buf = lockBufferParams.bufferDataPtr;             av_image_copy_plane(buf, lockBufferParams.pitch,                 frame->data[0], frame->linesize[0],                 avctx->width, avctx->height);             buf += inSurf->height * lockBufferParams.pitch;             av_image_copy_plane(buf, lockBufferParams.pitch >> 1,                 frame->data[2], frame->linesize[2],                 avctx->width >> 1, avctx->height >> 1);             buf += (inSurf->height * lockBufferParams.pitch) >> 2;             av_image_copy_plane(buf, lockBufferParams.pitch >> 1,                 frame->data[1], frame->linesize[1],                 avctx->width >> 1, avctx->height >> 1);         } else if (avctx->pix_fmt == AV_PIX_FMT_NV12) {             uint8_t *buf = lockBufferParams.bufferDataPtr;             av_image_copy_plane(buf, lockBufferParams.pitch,                 frame->data[0], frame->linesize[0],                 avctx->width, avctx->height);             buf += inSurf->height * lockBufferParams.pitch;             av_image_copy_plane(buf, lockBufferParams.pitch,                 frame->data[1], frame->linesize[1],                 avctx->width, avctx->height >> 1);         } else if (avctx->pix_fmt == AV_PIX_FMT_YUV444P) {             uint8_t *buf = lockBufferParams.bufferDataPtr;             av_image_copy_plane(buf, lockBufferParams.pitch,                 frame->data[0], frame->linesize[0],                 avctx->width, avctx->height);             buf += inSurf->height * lockBufferParams.pitch;             av_image_copy_plane(buf, lockBufferParams.pitch,                 frame->data[1], frame->linesize[1],                 avctx->width, avctx->height);             buf += inSurf->height * lockBufferParams.pitch;             av_image_copy_plane(buf, lockBufferParams.pitch,                 frame->data[2], frame->linesize[2],                 avctx->width, avctx->height);         } else {             av_log(avctx, AV_LOG_FATAL, "Invalid pixel format!\n");             return AVERROR(EINVAL);         nv_status = p_nvenc->nvEncUnlockInputBuffer(ctx->nvencoder, inSurf->input_surface);         if (nv_status != NV_ENC_SUCCESS) {             av_log(avctx, AV_LOG_FATAL, "Failed unlocking input buffer!\n");             return AVERROR_EXTERNAL;         switch (avctx->codec->id) {         case AV_CODEC_ID_H264:           pic_params.codecPicParams.h264PicParams.sliceMode = ctx->encode_config.encodeCodecConfig.h264Config.sliceMode;           pic_params.codecPicParams.h264PicParams.sliceModeData = ctx->encode_config.encodeCodecConfig.h264Config.sliceModeData;           break;         case AV_CODEC_ID_H265:           pic_params.codecPicParams.hevcPicParams.sliceMode = ctx->encode_config.encodeCodecConfig.hevcConfig.sliceMode;           pic_params.codecPicParams.hevcPicParams.sliceModeData = ctx->encode_config.encodeCodecConfig.hevcConfig.sliceModeData;           break;         default:           av_log(avctx, AV_LOG_ERROR, "Unknown codec name\n");           return AVERROR(EINVAL);         if (res)
static int FUNC_0(AVCodecContext *VAR_0, AVPacket *VAR_1,

    const AVFrame *VAR_2, int *VAR_3)

{

    NVENCSTATUS nv_status;

    NvencOutputSurface *tmpoutsurf;

    int VAR_4, VAR_5 = 0;



    NvencContext *ctx = VAR_0->priv_data;

    NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;

    NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;



    NV_ENC_PIC_PARAMS pic_params = { 0 };

    pic_params.version = NV_ENC_PIC_PARAMS_VER;



    if (VAR_2) {

        NV_ENC_LOCK_INPUT_BUFFER lockBufferParams = { 0 };

        NvencInputSurface *inSurf = NULL;



        for (VAR_5 = 0; VAR_5 < ctx->max_surface_count; ++VAR_5) {

            if (!ctx->input_surfaces[VAR_5].lockCount) {

                inSurf = &ctx->input_surfaces[VAR_5];

                break;

            }

        }



        av_assert0(inSurf);



        inSurf->lockCount = 1;



        lockBufferParams.version = NV_ENC_LOCK_INPUT_BUFFER_VER;

        lockBufferParams.inputBuffer = inSurf->input_surface;



        nv_status = p_nvenc->nvEncLockInputBuffer(ctx->nvencoder, &lockBufferParams);

        if (nv_status != NV_ENC_SUCCESS) {

            av_log(VAR_0, AV_LOG_ERROR, "Failed locking nvenc input buffer\n");

            return 0;

        }



        if (VAR_0->pix_fmt == AV_PIX_FMT_YUV420P) {

            uint8_t *buf = lockBufferParams.bufferDataPtr;



            av_image_copy_plane(buf, lockBufferParams.pitch,

                VAR_2->data[0], VAR_2->linesize[0],

                VAR_0->width, VAR_0->height);



            buf += inSurf->height * lockBufferParams.pitch;



            av_image_copy_plane(buf, lockBufferParams.pitch >> 1,

                VAR_2->data[2], VAR_2->linesize[2],

                VAR_0->width >> 1, VAR_0->height >> 1);



            buf += (inSurf->height * lockBufferParams.pitch) >> 2;



            av_image_copy_plane(buf, lockBufferParams.pitch >> 1,

                VAR_2->data[1], VAR_2->linesize[1],

                VAR_0->width >> 1, VAR_0->height >> 1);

        } else if (VAR_0->pix_fmt == AV_PIX_FMT_NV12) {

            uint8_t *buf = lockBufferParams.bufferDataPtr;



            av_image_copy_plane(buf, lockBufferParams.pitch,

                VAR_2->data[0], VAR_2->linesize[0],

                VAR_0->width, VAR_0->height);



            buf += inSurf->height * lockBufferParams.pitch;



            av_image_copy_plane(buf, lockBufferParams.pitch,

                VAR_2->data[1], VAR_2->linesize[1],

                VAR_0->width, VAR_0->height >> 1);

        } else if (VAR_0->pix_fmt == AV_PIX_FMT_YUV444P) {

            uint8_t *buf = lockBufferParams.bufferDataPtr;



            av_image_copy_plane(buf, lockBufferParams.pitch,

                VAR_2->data[0], VAR_2->linesize[0],

                VAR_0->width, VAR_0->height);



            buf += inSurf->height * lockBufferParams.pitch;



            av_image_copy_plane(buf, lockBufferParams.pitch,

                VAR_2->data[1], VAR_2->linesize[1],

                VAR_0->width, VAR_0->height);



            buf += inSurf->height * lockBufferParams.pitch;



            av_image_copy_plane(buf, lockBufferParams.pitch,

                VAR_2->data[2], VAR_2->linesize[2],

                VAR_0->width, VAR_0->height);

        } else {

            av_log(VAR_0, AV_LOG_FATAL, "Invalid pixel format!\n");

            return AVERROR(EINVAL);

        }



        nv_status = p_nvenc->nvEncUnlockInputBuffer(ctx->nvencoder, inSurf->input_surface);

        if (nv_status != NV_ENC_SUCCESS) {

            av_log(VAR_0, AV_LOG_FATAL, "Failed unlocking input buffer!\n");

            return AVERROR_EXTERNAL;

        }



        for (VAR_5 = 0; VAR_5 < ctx->max_surface_count; ++VAR_5)

            if (!ctx->output_surfaces[VAR_5].busy)

                break;



        if (VAR_5 == ctx->max_surface_count) {

            inSurf->lockCount = 0;

            av_log(VAR_0, AV_LOG_FATAL, "No free output surface found!\n");

            return AVERROR_EXTERNAL;

        }



        ctx->output_surfaces[VAR_5].input_surface = inSurf;



        pic_params.inputBuffer = inSurf->input_surface;

        pic_params.bufferFmt = inSurf->format;

        pic_params.inputWidth = VAR_0->width;

        pic_params.inputHeight = VAR_0->height;

        pic_params.outputBitstream = ctx->output_surfaces[VAR_5].output_surface;

        pic_params.completionEvent = 0;



        if (VAR_0->flags & AV_CODEC_FLAG_INTERLACED_DCT) {

            if (VAR_2->top_field_first) {

                pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FIELD_TOP_BOTTOM;

            } else {

                pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FIELD_BOTTOM_TOP;

            }

        } else {

            pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FRAME;

        }



        pic_params.encodePicFlags = 0;

        pic_params.inputTimeStamp = VAR_2->pts;

        pic_params.inputDuration = 0;

        switch (VAR_0->codec->id) {

        case AV_CODEC_ID_H264:

          pic_params.codecPicParams.h264PicParams.sliceMode = ctx->encode_config.encodeCodecConfig.h264Config.sliceMode;

          pic_params.codecPicParams.h264PicParams.sliceModeData = ctx->encode_config.encodeCodecConfig.h264Config.sliceModeData;

          break;

        case AV_CODEC_ID_H265:

          pic_params.codecPicParams.hevcPicParams.sliceMode = ctx->encode_config.encodeCodecConfig.hevcConfig.sliceMode;

          pic_params.codecPicParams.hevcPicParams.sliceModeData = ctx->encode_config.encodeCodecConfig.hevcConfig.sliceModeData;

          break;

        default:

          av_log(VAR_0, AV_LOG_ERROR, "Unknown codec name\n");

          return AVERROR(EINVAL);

        }



        VAR_4 = timestamp_queue_enqueue(&ctx->timestamp_list, VAR_2->pts);



        if (VAR_4)

            return VAR_4;

    } else {

        pic_params.encodePicFlags = NV_ENC_PIC_FLAG_EOS;

    }



    nv_status = p_nvenc->nvEncEncodePicture(ctx->nvencoder, &pic_params);



    if (VAR_2 && nv_status == NV_ENC_ERR_NEED_MORE_INPUT) {

        VAR_4 = out_surf_queue_enqueue(&ctx->output_surface_queue, &ctx->output_surfaces[VAR_5]);



        if (VAR_4)

            return VAR_4;



        ctx->output_surfaces[VAR_5].busy = 1;

    }



    if (nv_status != NV_ENC_SUCCESS && nv_status != NV_ENC_ERR_NEED_MORE_INPUT) {

        av_log(VAR_0, AV_LOG_ERROR, "EncodePicture failed!\n");

        return AVERROR_EXTERNAL;

    }



    if (nv_status != NV_ENC_ERR_NEED_MORE_INPUT) {

        while (ctx->output_surface_queue.count) {

            tmpoutsurf = out_surf_queue_dequeue(&ctx->output_surface_queue);

            VAR_4 = out_surf_queue_enqueue(&ctx->output_surface_ready_queue, tmpoutsurf);



            if (VAR_4)

                return VAR_4;

        }



        if (VAR_2) {

            VAR_4 = out_surf_queue_enqueue(&ctx->output_surface_ready_queue, &ctx->output_surfaces[VAR_5]);



            if (VAR_4)

                return VAR_4;



            ctx->output_surfaces[VAR_5].busy = 1;

        }

    }



    if (ctx->output_surface_ready_queue.count && (!VAR_2 || ctx->output_surface_ready_queue.count + ctx->output_surface_queue.count >= ctx->buffer_delay)) {

        tmpoutsurf = out_surf_queue_dequeue(&ctx->output_surface_ready_queue);



        VAR_4 = process_output_surface(VAR_0, VAR_1, tmpoutsurf);



        if (VAR_4)

            return VAR_4;



        tmpoutsurf->busy = 0;

        av_assert0(tmpoutsurf->input_surface->lockCount);

        tmpoutsurf->input_surface->lockCount--;



        *VAR_3 = 1;

    } else {

        *VAR_3 = 0;

    }



    return 0;

}

static int FUNC_0(AVCodecContext *VAR_0, AVPacket *VAR_1,
const AVFrame *VAR_2, int *VAR_3)
{ NVENCSTATUS nv_status; NvencOutputSurface *tmpoutsurf; int VAR_4, VAR_5 = 0; NvencContext *ctx = VAR_0->priv_data; NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs; NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs; NV_ENC_PIC_PARAMS pic_params = { 0 }; pic_params.version = NV_ENC_PIC_PARAMS_VER; if (VAR_2) { NV_ENC_LOCK_INPUT_BUFFER lockBufferParams = { 0 }; NvencInputSurface *inSurf = NULL; for (VAR_5 = 0; VAR_5 < ctx->max_surface_count; ++VAR_5) { if (!ctx->input_surfaces[VAR_5].lockCount) { inSurf = &ctx->input_surfaces[VAR_5]; break; } } av_assert0(inSurf); inSurf->lockCount = 1; lockBufferParams.version = NV_ENC_LOCK_INPUT_BUFFER_VER; lockBufferParams.inputBuffer = inSurf->input_surface; nv_status = p_nvenc->nvEncLockInputBuffer(ctx->nvencoder, &lockBufferParams); if (nv_status != NV_ENC_SUCCESS) { av_log(VAR_0, AV_LOG_ERROR, "Failed locking nvenc input buffer\n"); return 0; } if (VAR_0->pix_fmt == AV_PIX_FMT_YUV420P) { uint8_t *buf = lockBufferParams.bufferDataPtr; av_image_copy_plane(buf, lockBufferParams.pitch,
VAR_2->data[0], VAR_2->linesize[0],
VAR_0->width, VAR_0->height); buf += inSurf->height * lockBufferParams.pitch; av_image_copy_plane(buf, lockBufferParams.pitch >> 1,
VAR_2->data[2], VAR_2->linesize[2],
VAR_0->width >> 1, VAR_0->height >> 1); buf += (inSurf->height * lockBufferParams.pitch) >> 2; av_image_copy_plane(buf, lockBufferParams.pitch >> 1,
VAR_2->data[1], VAR_2->linesize[1],
VAR_0->width >> 1, VAR_0->height >> 1); } else if (VAR_0->pix_fmt == AV_PIX_FMT_NV12) { uint8_t *buf = lockBufferParams.bufferDataPtr; av_image_copy_plane(buf, lockBufferParams.pitch,
VAR_2->data[0], VAR_2->linesize[0],
VAR_0->width, VAR_0->height); buf += inSurf->height * lockBufferParams.pitch; av_image_copy_plane(buf, lockBufferParams.pitch,
VAR_2->data[1], VAR_2->linesize[1],
VAR_0->width, VAR_0->height >> 1); } else if (VAR_0->pix_fmt == AV_PIX_FMT_YUV444P) { uint8_t *buf = lockBufferParams.bufferDataPtr; av_image_copy_plane(buf, lockBufferParams.pitch,
VAR_2->data[0], VAR_2->linesize[0],
VAR_0->width, VAR_0->height); buf += inSurf->height * lockBufferParams.pitch; av_image_copy_plane(buf, lockBufferParams.pitch,
VAR_2->data[1], VAR_2->linesize[1],
VAR_0->width, VAR_0->height); buf += inSurf->height * lockBufferParams.pitch; av_image_copy_plane(buf, lockBufferParams.pitch,
VAR_2->data[2], VAR_2->linesize[2],
VAR_0->width, VAR_0->height); } else { av_log(VAR_0, AV_LOG_FATAL, "Invalid pixel format!\n"); return AVERROR(EINVAL); } nv_status = p_nvenc->nvEncUnlockInputBuffer(ctx->nvencoder, inSurf->input_surface); if (nv_status != NV_ENC_SUCCESS) { av_log(VAR_0, AV_LOG_FATAL, "Failed unlocking input buffer!\n"); return AVERROR_EXTERNAL; } for (VAR_5 = 0; VAR_5 < ctx->max_surface_count; ++VAR_5) if (!ctx->output_surfaces[VAR_5].busy)
break; if (VAR_5 == ctx->max_surface_count) { inSurf->lockCount = 0; av_log(VAR_0, AV_LOG_FATAL, "No free output surface found!\n"); return AVERROR_EXTERNAL; } ctx->output_surfaces[VAR_5].input_surface = inSurf; pic_params.inputBuffer = inSurf->input_surface; pic_params.bufferFmt = inSurf->format; pic_params.inputWidth = VAR_0->width; pic_params.inputHeight = VAR_0->height; pic_params.outputBitstream = ctx->output_surfaces[VAR_5].output_surface; pic_params.completionEvent = 0; if (VAR_0->flags & AV_CODEC_FLAG_INTERLACED_DCT) { if (VAR_2->top_field_first) { pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FIELD_TOP_BOTTOM; } else { pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FIELD_BOTTOM_TOP; } } else { pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FRAME; } pic_params.encodePicFlags = 0; pic_params.inputTimeStamp = VAR_2->pts; pic_params.inputDuration = 0; switch (VAR_0->codec->id) { case AV_CODEC_ID_H264:
pic_params.codecPicParams.h264PicParams.sliceMode = ctx->encode_config.encodeCodecConfig.h264Config.sliceMode; pic_params.codecPicParams.h264PicParams.sliceModeData = ctx->encode_config.encodeCodecConfig.h264Config.sliceModeData; break; case AV_CODEC_ID_H265:
pic_params.codecPicParams.hevcPicParams.sliceMode = ctx->encode_config.encodeCodecConfig.hevcConfig.sliceMode; pic_params.codecPicParams.hevcPicParams.sliceModeData = ctx->encode_config.encodeCodecConfig.hevcConfig.sliceModeData; break; default:
av_log(VAR_0, AV_LOG_ERROR, "Unknown codec name\n"); return AVERROR(EINVAL); } VAR_4 = timestamp_queue_enqueue(&ctx->timestamp_list, VAR_2->pts); if (VAR_4)
return VAR_4; } else { pic_params.encodePicFlags = NV_ENC_PIC_FLAG_EOS; } nv_status = p_nvenc->nvEncEncodePicture(ctx->nvencoder, &pic_params); if (VAR_2 && nv_status == NV_ENC_ERR_NEED_MORE_INPUT) { VAR_4 = out_surf_queue_enqueue(&ctx->output_surface_queue, &ctx->output_surfaces[VAR_5]); if (VAR_4)
return VAR_4; ctx->output_surfaces[VAR_5].busy = 1; } if (nv_status != NV_ENC_SUCCESS && nv_status != NV_ENC_ERR_NEED_MORE_INPUT) { av_log(VAR_0, AV_LOG_ERROR, "EncodePicture failed!\n"); return AVERROR_EXTERNAL; } if (nv_status != NV_ENC_ERR_NEED_MORE_INPUT) { while (ctx->output_surface_queue.count) { tmpoutsurf = out_surf_queue_dequeue(&ctx->output_surface_queue); VAR_4 = out_surf_queue_enqueue(&ctx->output_surface_ready_queue, tmpoutsurf); if (VAR_4)
return VAR_4; } if (VAR_2) { VAR_4 = out_surf_queue_enqueue(&ctx->output_surface_ready_queue, &ctx->output_surfaces[VAR_5]); if (VAR_4)
return VAR_4; ctx->output_surfaces[VAR_5].busy = 1; } } if (ctx->output_surface_ready_queue.count && (!VAR_2 || ctx->output_surface_ready_queue.count + ctx->output_surface_queue.count >= ctx->buffer_delay)) { tmpoutsurf = out_surf_queue_dequeue(&ctx->output_surface_ready_queue); VAR_4 = process_output_surface(VAR_0, VAR_1, tmpoutsurf); if (VAR_4)
return VAR_4; tmpoutsurf->busy = 0; av_assert0(tmpoutsurf->input_surface->lockCount); tmpoutsurf->input_surface->lockCount--; *VAR_3 = 1; } else { *VAR_3 = 0; } return 0; }