summaryrefslogtreecommitdiffstats
path: root/video/filter/refqueue.c
diff options
context:
space:
mode:
Diffstat (limited to 'video/filter/refqueue.c')
-rw-r--r--video/filter/refqueue.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/video/filter/refqueue.c b/video/filter/refqueue.c
index 964fa29c08..031feb8c96 100644
--- a/video/filter/refqueue.c
+++ b/video/filter/refqueue.c
@@ -39,6 +39,7 @@ struct mp_refqueue {
int needed_past_frames;
int needed_future_frames;
int flags;
+ int field_parity;
bool second_field; // current frame has to output a second field yet
bool eof;
@@ -68,8 +69,7 @@ struct mp_refqueue *mp_refqueue_alloc(struct mp_filter *f)
q->filter = f;
q->conv = mp_autoconvert_create(f);
- if (!q->conv)
- abort();
+ MP_HANDLE_OOM(q->conv);
q->in = q->conv->f->pins[1];
mp_pin_connect(q->conv->f->pins[0], f->ppins[0]);
@@ -98,6 +98,11 @@ void mp_refqueue_set_mode(struct mp_refqueue *q, int flags)
q->flags = flags;
}
+void mp_refqueue_set_parity(struct mp_refqueue *q, int parity)
+{
+ q->field_parity = parity;
+}
+
// Whether the current frame should be deinterlaced.
bool mp_refqueue_should_deint(struct mp_refqueue *q)
{
@@ -115,7 +120,13 @@ bool mp_refqueue_is_top_field(struct mp_refqueue *q)
if (!mp_refqueue_has_output(q))
return false;
- return !!(q->queue[q->pos]->fields & MP_IMGFIELD_TOP_FIRST) ^ q->second_field;
+ bool tff = q->field_parity == MP_FIELD_PARITY_TFF;
+ bool bff = q->field_parity == MP_FIELD_PARITY_BFF;
+ bool ret = (!!(q->queue[q->pos]->fields & MP_IMGFIELD_TOP_FIRST) ^ q->second_field
+ && !tff && !bff); // Default parity
+ ret = ret || (tff && !q->second_field); // Check if top field is forced
+ ret = ret || (bff && q->second_field); // Check if bottom field is forced
+ return ret;
}
// Whether top-field-first mode is enabled.
@@ -124,7 +135,9 @@ bool mp_refqueue_top_field_first(struct mp_refqueue *q)
if (!mp_refqueue_has_output(q))
return false;
- return q->queue[q->pos]->fields & MP_IMGFIELD_TOP_FIRST;
+ bool tff = q->field_parity == MP_FIELD_PARITY_TFF;
+ bool bff = q->field_parity == MP_FIELD_PARITY_BFF;
+ return ((q->queue[q->pos]->fields & MP_IMGFIELD_TOP_FIRST) || tff) && !bff;
}
// Discard all state.
@@ -267,8 +280,6 @@ struct mp_image *mp_refqueue_execute_reinit(struct mp_refqueue *q)
mp_refqueue_flush(q);
q->in_format = mp_image_new_ref(cur);
- if (!q->in_format)
- abort();
mp_image_unref_data(q->in_format);
mp_refqueue_add_input(q, cur);
@@ -322,7 +333,7 @@ bool mp_refqueue_can_output(struct mp_refqueue *q)
if (!q->in_format || !!q->in_format->hwctx != !!img->hwctx ||
(img->hwctx && img->hwctx->data != q->in_format->hwctx->data) ||
- !mp_image_params_equal(&q->in_format->params, &img->params))
+ !mp_image_params_static_equal(&q->in_format->params, &img->params))
{
q->next = img;
q->eof = true;