Answers.Body: <p>Actually we can extract a video frame using only NVIDIA card via thumbnail_cuda filter. For it is necessary to configure FFmpeg with:</p>
  
  <pre><code>--enable-cuda-sdk --enable-filter=scale_cuda --enable-filter=thumbnail_cuda
  </code></pre>
  
  <p>We can resize frames at the decoding step then not necessary to use scale_npp filter. When we use the thumbnail_cuda filter we can set NV12 as the output format to prevent additional pixel format convertation. NV12 will be converted to yuvj420p without yuv420p in the middle.</p>
  
  <p>The FFmpeg command to perform it for a h264 stream looks as follow:</p>
  
  <pre><code>ffmpeg -hwaccel cuvid -c:v h264_cuvid -resize 120x70 -i video_source \
         -vf "thumbnail_cuda=2,hwdownload,format=nv12" \
         -vframes 1 frame.jpg
  </code></pre>
  
  <p>If we need to deocde mpeg2, hevc, vp8, etc then we should choose an appropriate decoder from the list:</p>
  
  <pre><code>ffmpeg -decoders | grep cuvid
  
   V..... h264_cuvid           Nvidia CUVID H264 decoder (codec h264)
   V..... hevc_cuvid           Nvidia CUVID HEVC decoder (codec hevc)
   V..... mjpeg_cuvid          Nvidia CUVID MJPEG decoder (codec mjpeg)
   V..... mpeg1_cuvid          Nvidia CUVID MPEG1VIDEO decoder (codec mpeg1video)
   V..... mpeg2_cuvid          Nvidia CUVID MPEG2VIDEO decoder (codec mpeg2video)
   V..... mpeg4_cuvid          Nvidia CUVID MPEG4 decoder (codec mpeg4)
   V..... vc1_cuvid            Nvidia CUVID VC1 decoder (codec vc1)
   V..... vp8_cuvid            Nvidia CUVID VP8 decoder (codec vp8)
   V..... vp9_cuvid            Nvidia CUVID VP9 decoder (codec vp9)
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-06-21T14:32:02.263Z
Answers.LastActivityDate: 2018-06-28T14:31:35.487Z
Answers.LastEditDate: 2018-06-28T14:31:35.487Z
Answers.UserDisplayName: Ivan Kolesnikov
Answers.Body: <p>Since the video bitstream is being decoded on the GPU, CUDA upload isn't required.</p>
  
  <p>Command with format conversion is</p>
  
  <pre><code>ffmpeg -hwaccel cuvid -c:v h264_cuvid -resize 1024x70 -i video_source \
         -vf "scale_npp=format=yuv420p,hwdownload,format=yuv420p" \
         -pix_fmt yuvj420p -color_range 2 -vframes 1 -y /tmp/frame.jpg
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-06-15T10:16:24.140Z
Answers.LastActivityDate: 2018-06-15T12:32:20.793Z
Answers.LastEditDate: 2018-06-15T12:32:20.793Z
Answers.UserDisplayName: Gyan
Body: <p>I want to extract a frame from the h264 video stream using NVIDIA card. <br>
  First of all we need to decode this stream via h264_cuvid decoder: <br></p>
  
  <blockquote>
    <p>ffmpeg -hwaccel cuvid -c:v h264_cuvid -i ...</p>
  </blockquote>
  
  <p><strong>As I understand currently we can't extract a video frame using only NVIDIA card in FFmpeg as this functional doesn't exist, like doesn't exist a codec like mjpeg_nvenc or something else. Please correct me if I wrong.</strong> <br></p>
  
  <p>I think we should be able to decode a video stream on the NVIDIA card then extract a frame via CPU codec, for example, mjpeg:</p>
  
  <blockquote>
    <p>ffmpeg -hwaccel cuvid -c:v h264_cuvid -i video_source -vcodec mjpeg
    -vframes 1 /tmp/frame.jpg</p>
  </blockquote>
  
  <p>In this case we will get the following error:</p>
  
  <blockquote>
    <p>Impossible to convert between the formats supported by the filter 'Parsed_null_0' and the filter 'auto_scaler_0' <br> 
    Error reinitializing
    filters! <br> Failed to inject frame into filter network: Function not
    implemented</p>
  </blockquote>
  
  <p>NVIDIA decode video to NV12(by default) or NV21 pixel format and it's not appropriate format for the mjpeg codec. Please also correct me if I wrong. <br>
  Let's try to change the output resolution and convert the pixel format via scale_npp to yuvj420p as mjpeg codes support it:</p>
  
  <blockquote>
    <p>ffmpeg -hwaccel cuvid -c:v h264_cuvid -i video_source -vcodec mjpeg
    -vf "hwupload_cuda,scale_npp=w=1024:h=70:format=nv12:interp_algo=lanczos,hwdownload,format=yuvj420p" -vframes 1 /tmp/frame.jpg</p>
  </blockquote>
  
  <p>I got the same error:</p>
  
  <blockquote>
    <p>Impossible to convert between the formats supported by the filter 'Parsed_null_0' and the filter 'auto_scaler_0' <br> 
    Error reinitializing
    filters! <br> Failed to inject frame into filter network: Function not
    implemented</p>
  </blockquote>
  
  <p>According the <a href="https://ffmpeg.org/ffmpeg-filters.html#scale_005fnpp" rel="nofollow noreferrer">FFmpeg documentation</a> format conversation isn't supported: "<em>Note that automatic format negotiation and conversion is not yet supported for hardware frames</em>"</p>
  
  <p>How to decode an input h264 stream via h264_cuvid decoder then convert the decoded video pixel format to yuvj420p and extract a frame via mjpeg codec? <br> Or please share your thoughts how to extract a frame from a video stream with decoding or decoding and encoding on NVIDIA card to any picture format.</p>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2018-06-14T14:37:30.833Z
Comments.Text: scale_npp supports yuv420p.
Comments.UserDisplayName: Gyan
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2018-06-15T06:53:24.077Z
Comments.Text: @Gyan Thank you for the comment! I tried the following command:
  ffmpeg -hwaccel cuvid -c:v h264_cuvid -i video_source -vcodec mjpeg -vf "hwupload_cuda,scale_npp=w=1024:h=70:format=nv12:interp_algo=lanczos,hwdownload,format=yuv420p" -vframes 1 /tmp/frame.jpg
  And received the same error: "Impossible to convert between the formats supported by the filter 'Parsed_null_0' and the filter 'auto_scaler_0' 
  Error reinitializing filters! 
  Failed to inject frame into filter network: Function not implemented"
Comments.UserDisplayName: Ivan Kolesnikov
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2018-06-15T06:57:47.037Z
Comments.Text: The format in scale_npp needs to be changed to yuv420p
Comments.UserDisplayName: Gyan
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2018-06-15T07:03:34.237Z
Comments.Text: @Gyan Thanks! I changed the formats to yuv420p in the command: 
   ffmpeg -hwaccel cuvid -c:v h264_cuvid -i video_source -vcodec mjpeg -vf "hwupload_cuda,scale_npp=w=1024:h=70:format=yuv420p:interp_algo=lanczos,hwdownload,format=yuv420p" -vframes 1 /tmp/frame.jpg
  Unfortunately, it didn't help and I got the same error.
Comments.UserDisplayName: Ivan Kolesnikov
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2018-06-15T07:23:58.983Z
Comments.Text: I don't have a compatible card to test with, but the decoded frames should already be on the GPU, so is hwupload required?
Comments.UserDisplayName: Gyan
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2018-06-15T09:02:12.540Z
Comments.Text: @Gyan Thanks a lot! The correct command with resizing at the decoding step is: ffmpeg -hwaccel cuvid -c:v h264_cuvid -resize 1024x70 -i video_source -vf "scale_npp=format=yuv420p,hwdownload,format=yuv420p" -vframes 1 -y /tmp/frame.jpg Can you please write an answer? I'll accept it.
Comments.UserDisplayName: Ivan Kolesnikov
Tags: <ffmpeg><nvidia><cuvid>
Title: How to extract a video frame using NVIDIA card
UserDisplayName: Ivan Kolesnikov
ThreadText: # How to extract a video frame using NVIDIA card
  
  (Asked by: username_0 on 2018-06-14)
  
  I want to extract a frame from the h264 video stream using NVIDIA card.   
  First of all we need to decode this stream via h264\_cuvid decoder:
  
  > ffmpeg -hwaccel cuvid -c:v h264\_cuvid -i ...
  
  **As I understand currently we can't extract a video frame using only NVIDIA card in FFmpeg as this functional doesn't exist, like doesn't exist a codec like mjpeg\_nvenc or something else. Please correct me if I wrong.**
  
  I think we should be able to decode a video stream on the NVIDIA card then extract a frame via CPU codec, for example, mjpeg:
  
  > ffmpeg -hwaccel cuvid -c:v h264\_cuvid -i video\_source -vcodec mjpeg
  > -vframes 1 /tmp/frame.jpg
  
  In this case we will get the following error:
  
  > Impossible to convert between the formats supported by the filter 'Parsed\_null\_0' and the filter 'auto\_scaler\_0'   
  > Error reinitializing
  > filters!   
  >  Failed to inject frame into filter network: Function not
  > implemented
  
  NVIDIA decode video to NV12(by default) or NV21 pixel format and it's not appropriate format for the mjpeg codec. Please also correct me if I wrong.   
  Let's try to change the output resolution and convert the pixel format via scale\_npp to yuvj420p as mjpeg codes support it:
  
  > ffmpeg -hwaccel cuvid -c:v h264\_cuvid -i video\_source -vcodec mjpeg
  > -vf "hwupload\_cuda,scale\_npp=w=1024:h=70:format=nv12:interp\_algo=lanczos,hwdownload,format=yuvj420p" -vframes 1 /tmp/frame.jpg
  
  I got the same error:
  
  > Impossible to convert between the formats supported by the filter 'Parsed\_null\_0' and the filter 'auto\_scaler\_0'   
  > Error reinitializing
  > filters!   
  >  Failed to inject frame into filter network: Function not
  > implemented
  
  According the [FFmpeg documentation](https://ffmpeg.org/ffmpeg-filters.html#scale_005fnpp) format conversation isn't supported: "*Note that automatic format negotiation and conversion is not yet supported for hardware frames*"
  
  How to decode an input h264 stream via h264\_cuvid decoder then convert the decoded video pixel format to yuvj420p and extract a frame via mjpeg codec?   
   Or please share your thoughts how to extract a frame from a video stream with decoding or decoding and encoding on NVIDIA card to any picture format.
  
  **Tags:** ffmpeg, nvidia, cuvid
  
  > **Comments:**
  > **username_1**: scale_npp supports yuv420p.  
  > **username_0**: @username_1 Thank you for the comment! I tried the following command: ffmpeg -hwaccel cuvid -c:v h264_cuvid -i video_source -vcodec mjpeg -vf "hwupload_cuda,scale_npp=w=1024:h=70:format=nv12:interp_algo=lanczos,hwdownload,format=yuv420p" -vframes 1 /tmp/frame.jpg And received the same error: "Impossible to convert between the formats supported by the filter 'Parsed_null_0' and the filter 'auto_scaler_0'  Error reinitializing filters!  Failed to inject frame into filter network: Function not implemented"  
  > **username_1**: The format in scale_npp needs to be changed to yuv420p  
  > **username_0**: @username_1 Thanks! I changed the formats to yuv420p in the command:   ffmpeg -hwaccel cuvid -c:v h264_cuvid -i video_source -vcodec mjpeg -vf "hwupload_cuda,scale_npp=w=1024:h=70:format=yuv420p:interp_algo=lanczos,hwdownload,format=yuv420p" -vframes 1 /tmp/frame.jpg Unfortunately, it didn't help and I got the same error.  
  > **username_1**: I don't have a compatible card to test with, but the decoded frames should already be on the GPU, so is hwupload required?  
  > **username_0**: @username_1 Thanks a lot! The correct command with resizing at the decoding step is: ffmpeg -hwaccel cuvid -c:v h264_cuvid -resize 1024x70 -i video_source -vf "scale_npp=format=yuv420p,hwdownload,format=yuv420p" -vframes 1 -y /tmp/frame.jpg Can you please write an answer? I'll accept it.  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_1 on 2018-06-15. Score: 4 | Accepted answer
  
  Since the video bitstream is being decoded on the GPU, CUDA upload isn't required.
  
  Command with format conversion is
  
  ```
  ffmpeg -hwaccel cuvid -c:v h264_cuvid -resize 1024x70 -i video_source \
         -vf "scale_npp=format=yuv420p,hwdownload,format=yuv420p" \
         -pix_fmt yuvj420p -color_range 2 -vframes 1 -y /tmp/frame.jpg
  
  ```
  
  
  ---
  
  ### Answer by username_0 on 2018-06-21. Score: 1
  
  Actually we can extract a video frame using only NVIDIA card via thumbnail\_cuda filter. For it is necessary to configure FFmpeg with:
  
  ```
  --enable-cuda-sdk --enable-filter=scale_cuda --enable-filter=thumbnail_cuda
  
  ```
  
  We can resize frames at the decoding step then not necessary to use scale\_npp filter. When we use the thumbnail\_cuda filter we can set NV12 as the output format to prevent additional pixel format convertation. NV12 will be converted to yuvj420p without yuv420p in the middle.
  
  The FFmpeg command to perform it for a h264 stream looks as follow:
  
  ```
  ffmpeg -hwaccel cuvid -c:v h264_cuvid -resize 120x70 -i video_source \
         -vf "thumbnail_cuda=2,hwdownload,format=nv12" \
         -vframes 1 frame.jpg
  
  ```
  
  If we need to deocde mpeg2, hevc, vp8, etc then we should choose an appropriate decoder from the list:
  
  ```
  ffmpeg -decoders | grep cuvid
  
   V..... h264_cuvid           Nvidia CUVID H264 decoder (codec h264)
   V..... hevc_cuvid           Nvidia CUVID HEVC decoder (codec hevc)
   V..... mjpeg_cuvid          Nvidia CUVID MJPEG decoder (codec mjpeg)
   V..... mpeg1_cuvid          Nvidia CUVID MPEG1VIDEO decoder (codec mpeg1video)
   V..... mpeg2_cuvid          Nvidia CUVID MPEG2VIDEO decoder (codec mpeg2video)
   V..... mpeg4_cuvid          Nvidia CUVID MPEG4 decoder (codec mpeg4)
   V..... vc1_cuvid            Nvidia CUVID VC1 decoder (codec vc1)
   V..... vp8_cuvid            Nvidia CUVID VP8 decoder (codec vp8)
   V..... vp9_cuvid            Nvidia CUVID VP9 decoder (codec vp9)
  
  ```
  
  
  ---
  
  