0
0
mirror of https://github.com/mpv-player/mpv.git synced 2024-09-20 03:52:22 +02:00

f_hwtransfer: change order in which hwdec upload formats are considered

Basically, instead of trusting the upload format, and picking the first
sw format that has a desired upload format, trust the sw format. So now
we pick the sw format first, and then select from the set of upload
formats supported by it.

This is probably more straightforward, and works around a crash with
vaapi:

  mpv 8bit.mkv --vf=format=vaapi --gpu-hwdec-interop=all

(Forces vaapi upload if hw decoding is not enabled.)

Unfortunately, this still does not work, because vaapi, FFmpeg, the VO
interop code, or all of them are doing something stupid. In particular,
this picks the yuv420p sw format, which doesn't really exist despiter
advertised (???????????????????????????????????????), and simply breaks.

See: #7350
This commit is contained in:
wm4 2020-01-11 22:28:47 +01:00
parent a3ddddff3a
commit a009b57c77

View File

@ -34,41 +34,43 @@ static bool update_format_decision(struct priv *p, int input_fmt)
p->last_input_fmt = 0;
int res = mp_imgfmt_select_best_list(u->upload_fmts, u->num_upload_fmts,
input_fmt);
if (!res)
// First find the closest sw fmt. Some hwdec APIs return crazy lists of
// "supported" formats, which then are not supported or crash (???), so
// the this is a good way to avoid problems.
// (Actually we should just have hardcoded everything instead of relying on
// this fragile bullshit FFmpeg API and the fragile bullshit hwdec drivers.)
int sw_fmt = mp_imgfmt_select_best_list(u->fmts, u->num_fmts, input_fmt);
if (!sw_fmt)
return false;
// Find which sw format we should use.
// NOTE: if there are ever any hw APIs that actually do expensive
// conversions on mismatching format uploads, we should probably first look
// which sw format is preferred?
// Dumb, but find index for u->fmts[index]==sw_fmt.
int index = -1;
for (int n = 0; n < u->num_upload_fmts; n++) {
if (u->upload_fmts[n] == res)
for (int n = 0; n < u->num_fmts; n++) {
if (u->fmts[n] == sw_fmt)
index = n;
}
if (index < 0)
return false;
for (int n = 0; n < u->num_fmts; n++) {
if (index >= u->fmt_upload_index[n] &&
index < u->fmt_upload_index[n] + u->fmt_upload_num[n])
{
p->last_input_fmt = input_fmt;
p->last_upload_fmt = u->upload_fmts[index];
p->last_sw_fmt = u->fmts[n];
MP_INFO(u->f, "upload %s -> %s (%s)\n",
mp_imgfmt_to_name(p->last_input_fmt),
mp_imgfmt_to_name(p->last_upload_fmt),
mp_imgfmt_to_name(p->last_sw_fmt));
return true;
}
}
// Now check the available upload formats. This is the format our sw frame
// has to be in, and which the upload API will take (probably).
return false;
int *upload_fmts = &u->upload_fmts[u->fmt_upload_index[index]];
int num_upload_fmts = u->fmt_upload_num[index];
int up_fmt = mp_imgfmt_select_best_list(upload_fmts, num_upload_fmts,
input_fmt);
if (!up_fmt)
return false;
p->last_input_fmt = input_fmt;
p->last_upload_fmt = up_fmt;
p->last_sw_fmt = sw_fmt;
MP_INFO(u->f, "upload %s -> %s (%s)\n",
mp_imgfmt_to_name(p->last_input_fmt),
mp_imgfmt_to_name(p->last_upload_fmt),
mp_imgfmt_to_name(p->last_sw_fmt));
return true;
}
int mp_hwupload_find_upload_format(struct mp_hwupload *u, int imgfmt)