summaryrefslogtreecommitdiffstats
path: root/filters/f_autoconvert.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2019-10-02 23:00:28 +0200
committerwm4 <wm4@nowhere>2019-10-02 23:12:50 +0200
commit9b55009e8f6e81bdc19172b4469b58646464dc80 (patch)
tree296b626ed22927ba797efece7b6de913b2dd0dda /filters/f_autoconvert.c
parent55424c29d35ec96061c36537e1ad18cd9a281b5a (diff)
downloadmpv-9b55009e8f6e81bdc19172b4469b58646464dc80.tar.bz2
mpv-9b55009e8f6e81bdc19172b4469b58646464dc80.tar.xz
f_autoconvert: provide a function to determine if conversion works
This adds the function as seen in the f_autoconvert.h part of the patch. It's pretty simple, but goes along with an intrusive code move. I guess the resulting code is slightly nicer anyway.
Diffstat (limited to 'filters/f_autoconvert.c')
-rw-r--r--filters/f_autoconvert.c103
1 files changed, 62 insertions, 41 deletions
diff --git a/filters/f_autoconvert.c b/filters/f_autoconvert.c
index 2e039c260c..76c93363ca 100644
--- a/filters/f_autoconvert.c
+++ b/filters/f_autoconvert.c
@@ -169,33 +169,17 @@ void mp_autoconvert_add_srate(struct mp_autoconvert *c, int rate)
p->force_update = true;
}
-static void handle_video_frame(struct mp_filter *f)
+// If this returns true, and *out==NULL, no conversion is necessary.
+static bool build_image_converter(struct mp_autoconvert *c, struct mp_log *log,
+ struct mp_image *img, struct mp_filter **f_out)
{
+ struct mp_filter *f = c->f;
struct priv *p = f->priv;
- struct mp_image *img = p->sub.frame.data;
-
- if (p->force_update)
- p->in_imgfmt = p->in_subfmt = 0;
-
- if (img->imgfmt == p->in_imgfmt && img->params.hw_subfmt == p->in_subfmt) {
- mp_subfilter_continue(&p->sub);
- return;
- }
-
- if (!mp_subfilter_drain_destroy(&p->sub)) {
- p->in_imgfmt = p->in_subfmt = 0;
- return;
- }
-
- p->in_imgfmt = img->params.imgfmt;
- p->in_subfmt = img->params.hw_subfmt;
- p->force_update = false;
+ *f_out = NULL;
- if (!p->num_imgfmts) {
- mp_subfilter_continue(&p->sub);
- return;
- }
+ if (!p->num_imgfmts)
+ return true;
bool different_subfmt = false;
@@ -204,10 +188,8 @@ static void handle_video_frame(struct mp_filter *f)
bool samesubffmt = img->params.hw_subfmt == p->subfmts[n];
if (samefmt && !samesubffmt)
different_subfmt = true;
- if (samefmt && (samesubffmt || !p->subfmts[n])) {
- mp_subfilter_continue(&p->sub);
- return;
- }
+ if (samefmt && (samesubffmt || !p->subfmts[n]))
+ return true;
}
struct mp_stream_info *info = mp_filter_find_stream_info(f);
@@ -229,7 +211,7 @@ static void handle_video_frame(struct mp_filter *f)
// This should not happen. But not enough guarantee to make it an assert().
if (imgfmt_is_sw != !img->hwctx)
- MP_WARN(p, "Unexpected AVFrame/imgfmt hardware context mismatch.\n");
+ mp_warn(log, "Unexpected AVFrame/imgfmt hardware context mismatch.\n");
bool dst_all_hw = true;
bool dst_have_sw = false;
@@ -248,7 +230,7 @@ static void handle_video_frame(struct mp_filter *f)
// We can probably use this! Very lazy and very approximate.
struct mp_hwupload *upload = mp_hwupload_create(conv, fmts[0]);
if (upload) {
- MP_INFO(p, "HW-uploading to %s\n", mp_imgfmt_to_name(fmts[0]));
+ mp_info(log, "HW-uploading to %s\n", mp_imgfmt_to_name(fmts[0]));
filters[2] = upload->f;
fmts = upload->upload_fmts;
num_fmts = upload->num_upload_fmts;
@@ -257,7 +239,7 @@ static void handle_video_frame(struct mp_filter *f)
} else if (p->vo_convert && different_subfmt && info && info->hwdec_devs) {
for (int n = 0; subfmt_converters[n].hw_imgfmt; n++) {
if (subfmt_converters[n].hw_imgfmt == img->imgfmt) {
- MP_INFO(p, "Using HW sub-conversion.\n");
+ mp_info(log, "Using HW sub-conversion.\n");
filters[2] = subfmt_converters[n].create(conv);
if (filters[2]) {
need_sws = false;
@@ -270,10 +252,10 @@ static void handle_video_frame(struct mp_filter *f)
int src_fmt = img->imgfmt;
if (hw_to_sw) {
- MP_INFO(p, "HW-downloading from %s\n", mp_imgfmt_to_name(img->imgfmt));
+ mp_info(log, "HW-downloading from %s\n", mp_imgfmt_to_name(img->imgfmt));
int res_fmt = mp_image_hw_download_get_sw_format(img);
if (!res_fmt) {
- MP_ERR(p, "cannot copy surface of this format to CPU memory\n");
+ mp_err(log, "cannot copy surface of this format to CPU memory\n");
goto fail;
}
struct mp_hwdownload *hwd = mp_hwdownload_create(conv);
@@ -287,13 +269,13 @@ static void handle_video_frame(struct mp_filter *f)
// Create a new conversion filter.
struct mp_sws_filter *sws = mp_sws_filter_create(conv);
if (!sws) {
- MP_ERR(p, "error creating conversion filter\n");
- return;
+ mp_err(log, "error creating conversion filter\n");
+ goto fail;
}
int out = mp_sws_find_best_out_format(src_fmt, fmts, num_fmts);
if (!out) {
- MP_ERR(p, "can't find video conversion for %s\n",
+ mp_err(log, "can't find video conversion for %s\n",
mp_imgfmt_to_name(src_fmt));
goto fail;
}
@@ -303,7 +285,7 @@ static void handle_video_frame(struct mp_filter *f)
talloc_free(sws->f);
} else {
sws->out_format = out;
- MP_INFO(p, "Converting %s -> %s\n", mp_imgfmt_to_name(src_fmt),
+ mp_info(log, "Converting %s -> %s\n", mp_imgfmt_to_name(src_fmt),
mp_imgfmt_to_name(sws->out_format));
filters[1] = sws->f;
}
@@ -311,14 +293,53 @@ static void handle_video_frame(struct mp_filter *f)
mp_chain_filters(conv->ppins[0], conv->ppins[1], filters, 3);
- p->sub.filter = conv;
- mp_subfilter_continue(&p->sub);
- return;
+ *f_out = conv;
+ return true;
fail:
talloc_free(conv);
- mp_filter_internal_mark_failed(f);
- return;
+ return false;
+}
+
+bool mp_autoconvert_probe_input_video(struct mp_autoconvert *c,
+ struct mp_image *img)
+{
+ struct mp_filter *conv = NULL;
+ bool res = build_image_converter(c, mp_null_log, img, &conv);
+ talloc_free(conv);
+ return res;
+}
+
+static void handle_video_frame(struct mp_filter *f)
+{
+ struct priv *p = f->priv;
+
+ struct mp_image *img = p->sub.frame.data;
+
+ if (p->force_update)
+ p->in_imgfmt = p->in_subfmt = 0;
+
+ if (img->imgfmt == p->in_imgfmt && img->params.hw_subfmt == p->in_subfmt) {
+ mp_subfilter_continue(&p->sub);
+ return;
+ }
+
+ if (!mp_subfilter_drain_destroy(&p->sub)) {
+ p->in_imgfmt = p->in_subfmt = 0;
+ return;
+ }
+
+ p->in_imgfmt = img->params.imgfmt;
+ p->in_subfmt = img->params.hw_subfmt;
+ p->force_update = false;
+
+ struct mp_filter *conv = NULL;
+ if (build_image_converter(&p->public, p->log, img, &conv)) {
+ p->sub.filter = conv;
+ mp_subfilter_continue(&p->sub);
+ } else {
+ mp_filter_internal_mark_failed(f);
+ }
}
static void handle_audio_frame(struct mp_filter *f)