@@ -233,17 +233,28 @@ static bool build_image_converter(struct mp_autoconvert *c, struct mp_log *log,
233233 } else if (dst_all_hw && num_fmts > 0 ) {
234234 bool upload_created = false;
235235 int sw_fmt = imgfmt_is_sw ? img -> imgfmt : img -> params .hw_subfmt ;
236- // None of the targets accept the source's hardware format, so this is
237- // a transfer between two different devices, which cannot be done
238- // directly. Route the frame through system memory instead, which also
239- // lets the scaler fix up the sw format if the devices disagree.
240- bool download_first = !imgfmt_is_sw ;
241-
242236 for (int i = 0 ; i < num_fmts ; i ++ ) {
243237 // We can probably use this! Very lazy and very approximate.
244238 struct mp_hwupload upload = mp_hwupload_create (conv , fmts [i ],
245239 sw_fmt , false);
246240 if (upload .successful_init ) {
241+ // None of the targets accept the source's hardware format. If
242+ // the two can share frames the uploader maps them directly.
243+ // Otherwise this is a transfer between separate devices, which
244+ // libavutil cannot do, so route it through system memory. That
245+ // is also what makes a sw format conversion possible below.
246+ bool download_first = !imgfmt_is_sw &&
247+ !mp_hwupload_can_map (fmts [i ], img -> imgfmt );
248+
249+ if (download_first ) {
250+ mp_warn (log , "Transferring %s to %s through system memory. "
251+ "These are separate devices and cannot share "
252+ "frames, so every frame is copied twice. Use a "
253+ "decoder that outputs %s to avoid this.\n" ,
254+ mp_imgfmt_to_name (img -> imgfmt ),
255+ mp_imgfmt_to_name (fmts [i ]),
256+ mp_imgfmt_to_name (fmts [i ]));
257+ }
247258 mp_info (log , "HW-uploading to %s\n" , mp_imgfmt_to_name (fmts [i ]));
248259 filters [2 ] = upload .f ;
249260 hwupload_fmt = upload .selected_sw_imgfmt ;
0 commit comments