summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2018-04-21 13:03:54 +0200
committerJan Ekström <jeebjp@gmail.com>2018-04-29 02:21:32 +0300
commitd8807ca8336ec7fa35504bd5313d598e32fcff8d (patch)
tree1b959b46398463e3334645cec007b753cd493b89
parentce4d227986cf394a80fc687290bc732bbd8dbf22 (diff)
downloadmpv-d8807ca8336ec7fa35504bd5313d598e32fcff8d.tar.bz2
mpv-d8807ca8336ec7fa35504bd5313d598e32fcff8d.tar.xz
f_output_chain: log input instead of output format
I think this is more intuitive. This requires a dedicated "out" dummy filter. But keep the "in" dummy filter for symmetry, like in the old filter code. (We could remove the "in" dummy filter, because the first actual filter would still show the real input format.)
-rw-r--r--filters/f_output_chain.c82
1 files changed, 38 insertions, 44 deletions
diff --git a/filters/f_output_chain.c b/filters/f_output_chain.c
index cd577a6ca2..00d5e75faf 100644
--- a/filters/f_output_chain.c
+++ b/filters/f_output_chain.c
@@ -39,7 +39,7 @@ struct chain {
// First input/last output of all_filters[].
struct mp_pin *filters_in, *filters_out;
- struct mp_user_filter *input, *output;
+ struct mp_user_filter *input, *output, *convert_wrapper;
struct mp_autoconvert *convert;
struct vo *vo;
@@ -62,10 +62,9 @@ struct mp_user_filter {
bool generated_label;
char *name;
bool is_output_converter;
- bool is_input;
- struct mp_image_params last_out_params;
- struct mp_aframe *last_out_aformat;
+ struct mp_image_params last_in_vformat;
+ struct mp_aframe *last_in_aformat;
int64_t last_in_pts, last_out_pts;
@@ -94,21 +93,20 @@ static void update_output_caps(struct chain *p)
}
}
-static bool check_out_format_change(struct mp_user_filter *u,
- struct mp_frame frame)
+static void check_in_format_change(struct mp_user_filter *u,
+ struct mp_frame frame)
{
struct chain *p = u->p;
- bool changed = false;
if (frame.type == MP_FRAME_VIDEO) {
struct mp_image *img = frame.data;
- if (!mp_image_params_equal(&img->params, &u->last_out_params)) {
+ if (!mp_image_params_equal(&img->params, &u->last_in_vformat)) {
MP_VERBOSE(p, "[%s] %s\n", u->name,
mp_image_params_to_str(&img->params));
- u->last_out_params = img->params;
+ u->last_in_vformat = img->params;
- if (u->is_input) {
+ if (u == p->input) {
p->public.input_params = img->params;
// Unfortunately there's no good place to update these.
@@ -116,35 +114,31 @@ static bool check_out_format_change(struct mp_user_filter *u,
// might init some support of them in the VO, and update
// the VO's format list.
update_output_caps(p);
- } else if (u->is_output_converter) {
+ } else if (u == p->output) {
p->public.output_params = img->params;
}
p->public.reconfig_happened = true;
- changed = true;
}
}
if (frame.type == MP_FRAME_AUDIO) {
struct mp_aframe *aframe = frame.data;
- if (!mp_aframe_config_equals(aframe, u->last_out_aformat)) {
+ if (!mp_aframe_config_equals(aframe, u->last_in_aformat)) {
MP_VERBOSE(p, "[%s] %s\n", u->name,
mp_aframe_format_str(aframe));
- mp_aframe_config_copy(u->last_out_aformat, aframe);
+ mp_aframe_config_copy(u->last_in_aformat, aframe);
- if (u->is_input) {
+ if (u == p->input) {
mp_aframe_config_copy(p->public.input_aformat, aframe);
- } else if (u->is_output_converter) {
+ } else if (u == p->output) {
mp_aframe_config_copy(p->public.output_aformat, aframe);
}
p->public.reconfig_happened = true;
- changed = true;
}
}
-
- return changed;
}
static void process_user(struct mp_filter *f)
@@ -187,6 +181,8 @@ static void process_user(struct mp_filter *f)
if (mp_pin_can_transfer_data(u->f->pins[0], f->ppins[0])) {
struct mp_frame frame = mp_pin_out_read(f->ppins[0]);
+ check_in_format_change(u, frame);
+
double pts = mp_frame_get_pts(frame);
if (pts != MP_NOPTS_VALUE)
u->last_in_pts = pts;
@@ -197,8 +193,6 @@ static void process_user(struct mp_filter *f)
if (mp_pin_can_transfer_data(f->ppins[1], u->f->pins[1])) {
struct mp_frame frame = mp_pin_out_read(u->f->pins[1]);
- check_out_format_change(u, frame);
-
double pts = mp_frame_get_pts(frame);
if (pts != MP_NOPTS_VALUE)
u->last_out_pts = pts;
@@ -241,7 +235,7 @@ static struct mp_user_filter *create_wrapper_filter(struct chain *p)
struct mp_user_filter *wrapper = f->priv;
wrapper->wrapper = f;
wrapper->p = p;
- wrapper->last_out_aformat = talloc_steal(wrapper, mp_aframe_create());
+ wrapper->last_in_aformat = talloc_steal(wrapper, mp_aframe_create());
mp_filter_add_pin(f, MP_PIN_IN, "in");
mp_filter_add_pin(f, MP_PIN_OUT, "out");
return wrapper;
@@ -325,8 +319,8 @@ void mp_output_chain_reset_harder(struct mp_output_chain *c)
struct mp_user_filter *u = p->all_filters[n];
u->failed = false;
- u->last_out_params = (struct mp_image_params){0};
- mp_aframe_reset(u->last_out_aformat);
+ u->last_in_vformat = (struct mp_image_params){0};
+ mp_aframe_reset(u->last_in_aformat);
}
if (p->type == MP_OUTPUT_CHAIN_AUDIO) {
@@ -400,20 +394,13 @@ static void on_audio_format_change(void *opaque)
{
struct chain *p = opaque;
- // Find the filter before p->convert, to get p->convert's input format.
- struct mp_user_filter *prev = NULL;
- for (int n = 0; n < p->num_all_filters; n++) {
- struct mp_user_filter *u = p->all_filters[n];
- if (u->is_output_converter)
- break;
- prev = u;
- }
-
- assert(prev); // there must have been one
-
// Let the f_output_chain user know what format to use. (Not quite proper,
- // since we overwrite what some other code normally automatically sets.)
- mp_aframe_config_copy(p->public.output_aformat, prev->last_out_aformat);
+ // since we overwrite what some other code normally automatically sets.
+ // The main issue is that this callback is called before output_aformat can
+ // be set, because we "block" the converter until the AO is reconfigured,
+ // and mp_autoconvert_format_change_continue() is called.)
+ mp_aframe_config_copy(p->public.output_aformat,
+ p->convert_wrapper->last_in_aformat);
// Ask for calling mp_output_chain_set_ao().
p->public.ao_needs_update = true;
@@ -708,7 +695,6 @@ struct mp_output_chain *mp_output_chain_create(struct mp_filter *parent,
if (!p->input->f)
abort();
p->input->name = "in";
- p->input->is_input = true;
MP_TARRAY_APPEND(p, p->pre_filters, p->num_pre_filters, p->input);
switch (type) {
@@ -716,20 +702,28 @@ struct mp_output_chain *mp_output_chain_create(struct mp_filter *parent,
case MP_OUTPUT_CHAIN_AUDIO: create_audio_things(p); break;
}
- p->output = create_wrapper_filter(p);
- p->convert = mp_autoconvert_create(p->output->wrapper);
+ p->convert_wrapper = create_wrapper_filter(p);
+ p->convert = mp_autoconvert_create(p->convert_wrapper->wrapper);
if (!p->convert)
abort();
- p->output->name = "convert";
- p->output->is_output_converter = true;
- p->output->f = p->convert->f;
- MP_TARRAY_APPEND(p, p->post_filters, p->num_post_filters, p->output);
+ p->convert_wrapper->name = "convert";
+ p->convert_wrapper->is_output_converter = true;
+ p->convert_wrapper->f = p->convert->f;
+ MP_TARRAY_APPEND(p, p->post_filters, p->num_post_filters, p->convert_wrapper);
if (type == MP_OUTPUT_CHAIN_AUDIO) {
p->convert->on_audio_format_change = on_audio_format_change;
p->convert->on_audio_format_change_opaque = p;
}
+ // Dummy filter for reporting and logging the output format.
+ p->output = create_wrapper_filter(p);
+ p->output->f = mp_bidir_nop_filter_create(p->output->wrapper);
+ if (!p->output->f)
+ abort();
+ p->output->name = "out";
+ MP_TARRAY_APPEND(p, p->post_filters, p->num_post_filters, p->output);
+
relink_filter_list(p);
reset(f);