summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2020-01-11 22:28:47 +0100
committerwm4 <wm4@nowhere>2020-01-11 22:29:53 +0100
commita009b57c771490e1cb1341140443953279034a61 (patch)
tree823c1f8145eff83b2fe924c46d4331a9bf84037c
parenta3ddddff3a1eecd36ad7ef2d5db80d45cfbc7a2d (diff)
downloadmpv-a009b57c771490e1cb1341140443953279034a61.tar.bz2
mpv-a009b57c771490e1cb1341140443953279034a61.tar.xz
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
-rw-r--r--filters/f_hwtransfer.c54
1 files changed, 28 insertions, 26 deletions
diff --git a/filters/f_hwtransfer.c b/filters/f_hwtransfer.c
index 0c62644ff3..51ffbadbb9 100644
--- a/filters/f_hwtransfer.c
+++ b/filters/f_hwtransfer.c
@@ -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)