]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/nvenc.c
omx: Use the EOS flag to handle flushing at the end
[ffmpeg] / libavcodec / nvenc.c
index 14651d41c7c83a63e0925d2c9509f5ad2d785c2b..fe7b7f40f0d783e28523e39c3a51d4049aa157d9 100644 (file)
@@ -178,6 +178,7 @@ static av_cold int nvenc_load_libraries(AVCodecContext *avctx)
     nvel->cu_device_compute_capability = cuDeviceComputeCapability;
     nvel->cu_ctx_create                = cuCtxCreate_v2;
     nvel->cu_ctx_pop_current           = cuCtxPopCurrent_v2;
+    nvel->cu_ctx_push_current          = cuCtxPushCurrent_v2;
     nvel->cu_ctx_destroy               = cuCtxDestroy_v2;
 #else
     LOAD_LIBRARY(nvel->cuda, CUDA_LIBNAME);
@@ -190,6 +191,7 @@ static av_cold int nvenc_load_libraries(AVCodecContext *avctx)
                 "cuDeviceComputeCapability");
     LOAD_SYMBOL(nvel->cu_ctx_create, nvel->cuda, "cuCtxCreate_v2");
     LOAD_SYMBOL(nvel->cu_ctx_pop_current, nvel->cuda, "cuCtxPopCurrent_v2");
+    LOAD_SYMBOL(nvel->cu_ctx_push_current, nvel->cuda, "cuCtxPushCurrent_v2");
     LOAD_SYMBOL(nvel->cu_ctx_destroy, nvel->cuda, "cuCtxDestroy_v2");
 #endif
 
@@ -610,6 +612,53 @@ static void nvenc_setup_rate_control(AVCodecContext *avctx)
 
     if (rc->averageBitRate > 0)
         avctx->bit_rate = rc->averageBitRate;
+
+#if NVENCAPI_MAJOR_VERSION >= 7
+    if (ctx->aq) {
+        ctx->config.rcParams.enableAQ   = 1;
+        ctx->config.rcParams.aqStrength = ctx->aq_strength;
+        av_log(avctx, AV_LOG_VERBOSE, "AQ enabled.\n");
+    }
+
+    if (ctx->temporal_aq) {
+        ctx->config.rcParams.enableTemporalAQ = 1;
+        av_log(avctx, AV_LOG_VERBOSE, "Temporal AQ enabled.\n");
+    }
+
+    if (ctx->rc_lookahead > 0) {
+        int lkd_bound = FFMIN(ctx->nb_surfaces, ctx->async_depth) -
+                        ctx->config.frameIntervalP - 4;
+
+        if (lkd_bound < 0) {
+            av_log(avctx, AV_LOG_WARNING,
+                   "Lookahead not enabled. Increase buffer delay (-delay).\n");
+        } else {
+            ctx->config.rcParams.enableLookahead = 1;
+            ctx->config.rcParams.lookaheadDepth  = av_clip(ctx->rc_lookahead, 0, lkd_bound);
+            ctx->config.rcParams.disableIadapt   = ctx->no_scenecut;
+            ctx->config.rcParams.disableBadapt   = !ctx->b_adapt;
+            av_log(avctx, AV_LOG_VERBOSE,
+                   "Lookahead enabled: depth %d, scenecut %s, B-adapt %s.\n",
+                   ctx->config.rcParams.lookaheadDepth,
+                   ctx->config.rcParams.disableIadapt ? "disabled" : "enabled",
+                   ctx->config.rcParams.disableBadapt ? "disabled" : "enabled");
+        }
+    }
+
+    if (ctx->strict_gop) {
+        ctx->config.rcParams.strictGOPTarget = 1;
+        av_log(avctx, AV_LOG_VERBOSE, "Strict GOP target enabled.\n");
+    }
+
+    if (ctx->nonref_p)
+        ctx->config.rcParams.enableNonRefP = 1;
+
+    if (ctx->zerolatency)
+        ctx->config.rcParams.zeroReorderDelay = 1;
+
+    if (ctx->quality)
+        ctx->config.rcParams.targetQuality = ctx->quality;
+#endif /* NVENCAPI_MAJOR_VERSION >= 7 */
 }
 
 static int nvenc_setup_h264_config(AVCodecContext *avctx)
@@ -676,6 +725,11 @@ static int nvenc_setup_h264_config(AVCodecContext *avctx)
         break;
     }
 
+    if (ctx->data_pix_fmt == AV_PIX_FMT_YUV444P) {
+        cc->profileGUID = NV_ENC_H264_PROFILE_HIGH_444_GUID;
+        avctx->profile = FF_PROFILE_H264_HIGH_444_PREDICTIVE;
+    }
+
     h264->level = ctx->level;
 
     return 0;
@@ -876,7 +930,7 @@ static int nvenc_setup_encoder(AVCodecContext *avctx)
 
     ret = nv->nvEncInitializeEncoder(ctx->nvenc_ctx, &ctx->params);
     if (ret != NV_ENC_SUCCESS)
-        return nvenc_print_error(avctx, ret, "Cannot initialize the decoder");
+        return nvenc_print_error(avctx, ret, "InitializeEncoder failed");
 
     cpb_props = ff_add_cpb_side_data(avctx);
     if (!cpb_props)
@@ -1470,9 +1524,11 @@ int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                           const AVFrame *frame, int *got_packet)
 {
     NVENCContext *ctx               = avctx->priv_data;
+    NVENCLibraryContext *nvel       = &ctx->nvel;
     NV_ENCODE_API_FUNCTION_LIST *nv = &ctx->nvel.nvenc_funcs;
     NV_ENC_PIC_PARAMS params        = { 0 };
     NVENCFrame         *nvenc_frame = NULL;
+    CUcontext dummy;
     int enc_ret, ret;
 
     params.version = NV_ENC_PIC_PARAMS_VER;
@@ -1518,7 +1574,10 @@ int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
         params.encodePicFlags = NV_ENC_PIC_FLAG_EOS;
     }
 
+    nvel->cu_ctx_push_current(ctx->cu_context);
     enc_ret = nv->nvEncEncodePicture(ctx->nvenc_ctx, &params);
+    nvel->cu_ctx_pop_current(&dummy);
+
     if (enc_ret != NV_ENC_SUCCESS &&
         enc_ret != NV_ENC_ERR_NEED_MORE_INPUT)
         return nvenc_print_error(avctx, enc_ret, "Error encoding the frame");