summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Turkin <andrey.turkin@gmail.com>2016-05-29 15:50:06 +0300
committerTimo Rothenpieler <timo@rothenpieler.org>2016-05-31 16:47:07 +0200
commit2f53b5b74b658583be39d3c805024c4d93f67f6b (patch)
tree6f6f8513428325302880e5a33fe41565981649f0
parent214e63f8511330e8da8d69b5ea402ff0a4f17316 (diff)
avcodec/nvenc: refactor encode_frame a bit
Signed-off-by: Timo Rothenpieler <timo@rothenpieler.org>
-rw-r--r--libavcodec/nvenc.c83
1 files changed, 44 insertions, 39 deletions
diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
index b302b5ce22..a31c6e8b22 100644
--- a/libavcodec/nvenc.c
+++ b/libavcodec/nvenc.c
@@ -141,20 +141,6 @@ static int nvenc_print_error(void *log_ctx, NVENCSTATUS err,
return ret;
}
-static void timestamp_queue_enqueue(AVFifoBuffer* queue, int64_t timestamp)
-{
- av_fifo_generic_write(queue, &timestamp, sizeof(timestamp), NULL);
-}
-
-static int64_t timestamp_queue_dequeue(AVFifoBuffer* queue)
-{
- int64_t timestamp = AV_NOPTS_VALUE;
- if (av_fifo_size(queue) > 0)
- av_fifo_generic_read(queue, &timestamp, sizeof(timestamp), NULL);
-
- return timestamp;
-}
-
static av_cold int nvenc_load_libraries(AVCodecContext *avctx)
{
NvencContext *ctx = avctx->priv_data;
@@ -1389,22 +1375,40 @@ static int nvenc_upload_frame(AVCodecContext *avctx, const AVFrame *frame,
}
static void nvenc_codec_specific_pic_params(AVCodecContext *avctx,
- NV_ENC_PIC_PARAMS *params)
+ NV_ENC_PIC_PARAMS *params)
{
NvencContext *ctx = avctx->priv_data;
switch (avctx->codec->id) {
case AV_CODEC_ID_H264:
- params->codecPicParams.h264PicParams.sliceMode = ctx->encode_config.encodeCodecConfig.h264Config.sliceMode;
- params->codecPicParams.h264PicParams.sliceModeData = ctx->encode_config.encodeCodecConfig.h264Config.sliceModeData;
- break;
- case AV_CODEC_ID_H265:
- params->codecPicParams.hevcPicParams.sliceMode = ctx->encode_config.encodeCodecConfig.hevcConfig.sliceMode;
- params->codecPicParams.hevcPicParams.sliceModeData = ctx->encode_config.encodeCodecConfig.hevcConfig.sliceModeData;
+ params->codecPicParams.h264PicParams.sliceMode =
+ ctx->encode_config.encodeCodecConfig.h264Config.sliceMode;
+ params->codecPicParams.h264PicParams.sliceModeData =
+ ctx->encode_config.encodeCodecConfig.h264Config.sliceModeData;
break;
+ case AV_CODEC_ID_HEVC:
+ params->codecPicParams.hevcPicParams.sliceMode =
+ ctx->encode_config.encodeCodecConfig.hevcConfig.sliceMode;
+ params->codecPicParams.hevcPicParams.sliceModeData =
+ ctx->encode_config.encodeCodecConfig.hevcConfig.sliceModeData;
+ break;
}
}
+static inline void timestamp_queue_enqueue(AVFifoBuffer* queue, int64_t timestamp)
+{
+ av_fifo_generic_write(queue, &timestamp, sizeof(timestamp), NULL);
+}
+
+static inline int64_t timestamp_queue_dequeue(AVFifoBuffer* queue)
+{
+ int64_t timestamp = AV_NOPTS_VALUE;
+ if (av_fifo_size(queue) > 0)
+ av_fifo_generic_read(queue, &timestamp, sizeof(timestamp), NULL);
+
+ return timestamp;
+}
+
static int nvenc_set_timestamp(AVCodecContext *avctx,
NV_ENC_LOCK_BITSTREAM *params,
AVPacket *pkt)
@@ -1539,17 +1543,20 @@ error2:
return res;
}
-static int output_ready(NvencContext *ctx, int flush)
+static int output_ready(AVCodecContext *avctx, int flush)
{
+ NvencContext *ctx = avctx->priv_data;
int nb_ready, nb_pending;
nb_ready = av_fifo_size(ctx->output_surface_ready_queue) / sizeof(NvencSurface*);
nb_pending = av_fifo_size(ctx->output_surface_queue) / sizeof(NvencSurface*);
- return nb_ready > 0 && (flush || nb_ready + nb_pending >= ctx->async_depth);
+ if (flush)
+ return nb_ready > 0;
+ 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)
+ const AVFrame *frame, int *got_packet)
{
NVENCSTATUS nv_status;
NvencSurface *tmpoutsurf, *inSurf;
@@ -1564,7 +1571,10 @@ int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
if (frame) {
inSurf = get_free_frame(ctx);
- av_assert0(inSurf);
+ if (!inSurf) {
+ av_log(avctx, AV_LOG_ERROR, "No free surfaces\n");
+ return AVERROR_BUG;
+ }
res = nvenc_upload_frame(avctx, frame, inSurf);
if (res) {
@@ -1577,14 +1587,12 @@ int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
pic_params.inputWidth = avctx->width;
pic_params.inputHeight = avctx->height;
pic_params.outputBitstream = inSurf->output_surface;
- pic_params.completionEvent = 0;
if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT) {
- if (frame->top_field_first) {
+ if (frame->top_field_first)
pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FIELD_TOP_BOTTOM;
- } else {
+ else
pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FIELD_BOTTOM_TOP;
- }
} else {
pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FRAME;
}
@@ -1601,25 +1609,22 @@ int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
}
nv_status = p_nvenc->nvEncEncodePicture(ctx->nvencoder, &pic_params);
+ if (nv_status != NV_ENC_SUCCESS &&
+ nv_status != NV_ENC_ERR_NEED_MORE_INPUT)
+ return nvenc_print_error(avctx, nv_status, "EncodePicture failed!");
- if (frame && nv_status == NV_ENC_ERR_NEED_MORE_INPUT)
+ if (frame)
av_fifo_generic_write(ctx->output_surface_queue, &inSurf, sizeof(inSurf), NULL);
- if (nv_status != NV_ENC_SUCCESS && nv_status != NV_ENC_ERR_NEED_MORE_INPUT) {
- return nvenc_print_error(avctx, nv_status, "EncodePicture failed!");
- }
-
- if (nv_status != NV_ENC_ERR_NEED_MORE_INPUT) {
+ /* all the pending buffers are now ready for output */
+ if (nv_status == NV_ENC_SUCCESS) {
while (av_fifo_size(ctx->output_surface_queue) > 0) {
av_fifo_generic_read(ctx->output_surface_queue, &tmpoutsurf, sizeof(tmpoutsurf), NULL);
av_fifo_generic_write(ctx->output_surface_ready_queue, &tmpoutsurf, sizeof(tmpoutsurf), NULL);
}
-
- if (frame)
- av_fifo_generic_write(ctx->output_surface_ready_queue, &inSurf, sizeof(inSurf), NULL);
}
- if (output_ready(ctx, !frame)) {
+ if (output_ready(avctx, !frame)) {
av_fifo_generic_read(ctx->output_surface_ready_queue, &tmpoutsurf, sizeof(tmpoutsurf), NULL);
res = process_output_surface(avctx, pkt, tmpoutsurf);