[Libav-user] Nvenc_H264 very slow compared to Libx264

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

[Libav-user] Nvenc_H264 very slow compared to Libx264

Philippe Noël
Hi,

I was using libx264 to encode a video file using libav from a C file and switched to nvenc_h264 and now the encode is very slow. It appears nvenc_h264 does not have a "ultrafast" setting.

With nvenc_h264 I am using preset "llhq" and tune "zerolatency". Am I using the wrong settings?

Cheers,

Philippe

_______________________________________________
Libav-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".
Reply | Threaded
Open this post in threaded view
|

Re: Nvenc_H264 very slow compared to Libx264

Jodon Karlik


On Thu, Jan 16, 2020 at 5:28 PM Philippe Noël <[hidden email]> wrote:
Hi,

I was using libx264 to encode a video file using libav from a C file and switched to nvenc_h264 and now the encode is very slow. It appears nvenc_h264 does not have a "ultrafast" setting.

With nvenc_h264 I am using preset "llhq" and tune "zerolatency". Am I using the wrong settings?

Cheers,

Philippe
_______________________________________________
Libav-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".

In my experience, x264 is very fast and you may not be able to beat it at low quality.  That said, there are a lot of possibilities for why it may be slow.  Look at:  https://devblogs.nvidia.com/nvidia-ffmpeg-transcoding-guide/ which will give you some tips for minimizing PCIe transfers to keep it fast.

Cheers.

_______________________________________________
Libav-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".
Reply | Threaded
Open this post in threaded view
|

Re: Nvenc_H264 very slow compared to Libx264

Philippe Noël
In my experience, x264 is very fast and you may not be able to beat it at low quality.  That said, there are a lot of possibilities for why it may be slow.  Look at:  https://devblogs.nvidia.com/nvidia-ffmpeg-transcoding-guide/ which will give you some tips for minimizing PCIe transfers to keep it fast.
Cheers.

Thanks! I read through the nvidia docs. It seems that I need to pass in the "hwaccel: cuvid" option in order to keep the raw frame in GPU memory. Do you have any idea how to do this in Libav (C)? I tried following this Stackoverflow post, but av_hwaccel_next() kept returning NULL for a pixel format of AV_PIX_FMT_YUV420P and a codec of "h264_nvenc." I also see that av_hwaccel_next is deprecated. Do you have any suggestions?

Thanks!

Philippe

On Fri, Jan 17, 2020 at 12:07 AM Jodon Karlik <[hidden email]> wrote:


On Thu, Jan 16, 2020 at 5:28 PM Philippe Noël <[hidden email]> wrote:
Hi,

I was using libx264 to encode a video file using libav from a C file and switched to nvenc_h264 and now the encode is very slow. It appears nvenc_h264 does not have a "ultrafast" setting.

With nvenc_h264 I am using preset "llhq" and tune "zerolatency". Am I using the wrong settings?

Cheers,

Philippe
_______________________________________________
Libav-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".

In my experience, x264 is very fast and you may not be able to beat it at low quality.  That said, there are a lot of possibilities for why it may be slow.  Look at:  https://devblogs.nvidia.com/nvidia-ffmpeg-transcoding-guide/ which will give you some tips for minimizing PCIe transfers to keep it fast.

Cheers.
_______________________________________________
Libav-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".

_______________________________________________
Libav-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".
Reply | Threaded
Open this post in threaded view
|

Re: Nvenc_H264 very slow compared to Libx264

Strahinja Radman


>  Thanks! I read through the nvidia docs. It seems that I need to pass in the "hwaccel: cuvid" option in order to keep the raw frame in GPU memory. Do you have any idea how to do this in Libav (C)? I tried following this Stackoverflow post, but av_hwaccel_next() kept >   returning NULL for a pixel format of AV_PIX_FMT_YUV420P and a codec of "h264_nvenc." I also see that av_hwaccel_next is deprecated. Do you have any suggestions?  

You first need to create hardware device context, this example will get you started https://github.com/FFmpeg/FFmpeg/blob/master/doc/examples/hw_decode.c . After this you need to create hardware frames context which you will use to pass frames inside of the GPU. For decoder get_hw_format should look something like this

enum AVPixelFormat get_hw_format(AVCodecContext* ctx, const enum AVPixelFormat* pix_fmts)
{
    const enum AVPixelFormat* p;
    for (p = pix_fmts; *p != -1; p++) {
     if (*p == this->hw_pix_fmt)
             break;
    }

    ctx->hw_frames_ctx = av_buffer_ref(this->hw_frames_ctx);  //This is the important line
    if (!p) return AV_PIX_FMT_NONE;
     return *p;
}

While opening the encoder you simply reference the same hw_frames_ctx

     enc_ctx->hw_frames_ctx = av_buffer_ref(hw_frames_ctx);

And that should be it.
--

Regards
Strahinja Radman

_______________________________________________
Libav-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".
Reply | Threaded
Open this post in threaded view
|

Re: Nvenc_H264 very slow compared to Libx264

Philippe Noël
You first need to create hardware device context, this example will get you started https://github.com/FFmpeg/FFmpeg/blob/master/doc/examples/hw_decode.c . After this you need to create hardware frames context which you will use to pass frames inside of the GPU. For decoder get_hw_format should look something like this

Thank you! This was extremely helpful. I have two follow-up clarifications, if you wouldn't mind: 

1. Would you mind elaborating on how to create a hardware frames context? I found this example on how to do it with VAAPI. Should I just copy the set_hwframe_ctx() function? What should I change the pix_fmt to for nvenc? 2. 

I noticed in the example you sent me they call av_hwdevice_find_type_by_name(argv[1]). Do I need to do this as well/should I replace argv[1] by "cuda" since I want to do nvenc? 

Thank you very much!!

Philippe 

On Sat, Jan 18, 2020 at 5:30 AM Strahinja Radman <[hidden email]> wrote:


>  Thanks! I read through the nvidia docs. It seems that I need to pass in the "hwaccel: cuvid" option in order to keep the raw frame in GPU memory. Do you have any idea how to do this in Libav (C)? I tried following this Stackoverflow post, but av_hwaccel_next() kept >   returning NULL for a pixel format of AV_PIX_FMT_YUV420P and a codec of "h264_nvenc." I also see that av_hwaccel_next is deprecated. Do you have any suggestions?  

You first need to create hardware device context, this example will get you started https://github.com/FFmpeg/FFmpeg/blob/master/doc/examples/hw_decode.c . After this you need to create hardware frames context which you will use to pass frames inside of the GPU. For decoder get_hw_format should look something like this

enum AVPixelFormat get_hw_format(AVCodecContext* ctx, const enum AVPixelFormat* pix_fmts)
{
    const enum AVPixelFormat* p;
    for (p = pix_fmts; *p != -1; p++) {
     if (*p == this->hw_pix_fmt)
             break;
    }

    ctx->hw_frames_ctx = av_buffer_ref(this->hw_frames_ctx);  //This is the important line
    if (!p) return AV_PIX_FMT_NONE;
     return *p;
}

While opening the encoder you simply reference the same hw_frames_ctx

     enc_ctx->hw_frames_ctx = av_buffer_ref(hw_frames_ctx);

And that should be it.
--

Regards
Strahinja Radman
_______________________________________________
Libav-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".

_______________________________________________
Libav-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".
Reply | Threaded
Open this post in threaded view
|

Re: Nvenc_H264 very slow compared to Libx264

Strahinja Radman

> 1. Would you mind elaborating on how to create a hardware frames context? I found this example on how to do it with VAAPI. Should I just copy the set_hwframe_ctx() function? What should I change the pix_fmt to for nvenc? 2. 
> I noticed in the example you sent me they call av_hwdevice_find_type_by_name(argv[1]). Do I need to do this as well/should I replace argv[1] by "cuda" since I want to do nvenc? >

argv[1] should be replaced by "cuda", yes.

--

Regards
Strahinja Radman

_______________________________________________
Libav-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".