[FFmpeg-trac] #7507(avfilter:new): hwupload: missing device platform

FFmpeg trac at avcodec.org
Thu Oct 25 17:24:40 EEST 2018

#7507: hwupload: missing device platform
             Reporter:  msiders      |                    Owner:
                 Type:  enhancement  |                   Status:  new
             Priority:  normal       |                Component:  avfilter
              Version:  unspecified  |               Resolution:
             Keywords:  hwupload,    |               Blocked By:
  hwaccel                            |  Reproduced by developer:  0
             Blocking:               |
Analyzed by developer:  0            |

Comment (by msiders):

 Hi jkqxz,

 Thank you for the tip regarding `init_hw_device`, `hwaccel_device` and
 `filter_hw_device` parameters. After review them I have a partial
 success... they work but only when the decoding is done in one GPU and the
 frames are outputing to the RAM. In this case I can then upload to the
 other GPU and compress them.

 But we still '''NEED''' a target parameter for the `hwupload`. The target
 "hw_device" is a must have for this filter!

 Let me to show this "simplified" example:

 - You can run it in a computer with intel CPU and a Nvidia video card
 (more simple for a fast test with Windows than Linux, as the drivers have
 direct support for CUVID and QSV and you don't need to install external

 ffmpeg \
  -init_hw_device qsv=qsv -init_hw_device cuda=cuda \
  -hwaccel cuda -hwaccel_device cuda \
  -c:v h264_cuvid -i input.ts \
  -filter_hw_device qsv -filter_complex
  -map [out2] \
  -c:v:0 h264_qsv \
  -f mpegts output.ts

 This example DOESN'T WORK!! And let me to explain the command line-by-

 1. Start the `ffmpeg` process.
 2. Init the libraries and hardware for GPU support in both QSV & CUVID (no
 errors, all OK).
 3. Select the nvidia card as the target DECODER. Without this line the
 decoder writes the frames in RAM memory, instead of GPU. So it's required
 to leave the frames in GPU memory after decoding them.
 4. Use the CUVID decoder for decoding the input file.
 5. Here the problem: Create a filter graph that it does: a copy of the GPU
 frames (I use this filter as an example of filter in the GPU "A"); then
 download from the GPU frames to the RAM memory; and upload to the GPU "B"
 because the use of the parameter `-filter_hw_device qsv`; and finally a
 filter in the GPU "B". This graph is apparently valid.
 6. This maps the output of the previous filter graph to route the frames
 to the encoder.
 7. Encode frames with the hardware encoder in the GPU "B".
 8. Write to the output file.

 But it fails with this error:

 [format @ 0000020ae7026c80] Setting 'pix_fmts' to value 'nv12|qsv'
 [auto_scaler_0 @ 0000020ae7027880] w:iw h:ih flags:'bilinear' interl:0
 [Parsed_hwdownload_1 @ 0000020ae7026a80] auto-inserting filter
 'auto_scaler_0' between the filter 'Parsed_split_0' and t
 he filter 'Parsed_hwdownload_1'
 Impossible to convert between the formats supported by the filter
 'Parsed_split_0' and the filter 'auto_scaler_0'

 What's the problem?
 Te problem is because the `-filter_hw_device qsv` is a '''GLOBAL
 setting'''. Then the `hwdownload` filter uses the GPU "B" as the source...
 and this is wrong.

 Not use at all the `-filter_hw_device` in this case and replace the
 complex_filter with:
 This should work as the `hwdownload` can get the hw_device context from
 the source stream, and the only ambiguity is in the target GPU for the

 I hope someone fixes this problem, or help me to fix my example.
 Thank you!

Ticket URL: <https://trac.ffmpeg.org/ticket/7507#comment:6>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker

More information about the FFmpeg-trac mailing list