summaryrefslogtreecommitdiffstats
path: root/video/filter/vf_vavpp.c
diff options
context:
space:
mode:
Diffstat (limited to 'video/filter/vf_vavpp.c')
-rw-r--r--video/filter/vf_vavpp.c98
1 files changed, 42 insertions, 56 deletions
diff --git a/video/filter/vf_vavpp.c b/video/filter/vf_vavpp.c
index 1d131d0cde..b3adec0402 100644
--- a/video/filter/vf_vavpp.c
+++ b/video/filter/vf_vavpp.c
@@ -136,39 +136,45 @@ static void update_pipeline(struct vf_instance *vf)
p->pipe.num_output_colors = caps.num_output_color_standards;
mp_refqueue_set_refs(p->queue, caps.num_backward_references,
caps.num_forward_references);
+ mp_refqueue_set_mode(p->queue,
+ (p->deint_type >= 2 ? MP_MODE_OUTPUT_FIELDS : 0) |
+ (p->interlaced_only ? MP_MODE_INTERLACED_ONLY : 0));
return;
nodeint:
mp_refqueue_set_refs(p->queue, 0, 0);
+ mp_refqueue_set_mode(p->queue, 0);
}
-static inline int get_deint_field(struct vf_priv_s *p, int i,
- struct mp_image *mpi)
-{
- if (!p->do_deint || !(mpi->fields & MP_IMGFIELD_INTERLACED))
- return VA_FRAME_PICTURE;
- return !!(mpi->fields & MP_IMGFIELD_TOP_FIRST) ^ i ? VA_TOP_FIELD : VA_BOTTOM_FIELD;
-}
-
-static struct mp_image *render(struct vf_instance *vf, unsigned int flags)
+static struct mp_image *render(struct vf_instance *vf)
{
struct vf_priv_s *p = vf->priv;
struct mp_image *in = mp_refqueue_get(p->queue, 0);
+ struct mp_image *img = NULL;
+ bool need_end_picture = false;
+ bool success = false;
VASurfaceID in_id = va_surface_id(in);
if (!p->pipe.filters || in_id == VA_INVALID_ID)
- return NULL;
+ goto cleanup;
int r_w, r_h;
va_surface_get_uncropped_size(in, &r_w, &r_h);
- struct mp_image *img = mp_image_pool_get(p->pool, IMGFMT_VAAPI, r_w, r_h);
+ img = mp_image_pool_get(p->pool, IMGFMT_VAAPI, r_w, r_h);
if (!img)
- return NULL;
+ goto cleanup;
mp_image_set_size(img, in->w, in->h);
-
- bool need_end_picture = false;
- bool success = false;
+ mp_image_copy_attributes(img, in);
+
+ unsigned int flags = va_get_colorspace_flag(p->params.colorspace);
+ if (!mp_refqueue_is_interlaced(p->queue)) {
+ flags |= VA_FRAME_PICTURE;
+ } else if (mp_refqueue_is_top_field(p->queue)) {
+ flags |= VA_TOP_FIELD;
+ } else {
+ flags |= VA_BOTTOM_FIELD;
+ }
VASurfaceID id = va_surface_id(img);
if (id == VA_INVALID_ID)
@@ -194,7 +200,7 @@ static struct mp_image *render(struct vf_instance *vf, unsigned int flags)
goto cleanup;
filter_params->flags = flags & VA_TOP_FIELD ? 0 : VA_DEINTERLACING_BOTTOM_FIELD;
- if (!(in->fields & MP_IMGFIELD_TOP_FIRST))
+ if (!mp_refqueue_top_field_first(p->queue))
filter_params->flags |= VA_DEINTERLACING_BOTTOM_FIELD_FIRST;
vaUnmapBuffer(p->display, *(p->pipe.filters));
@@ -236,44 +242,6 @@ cleanup:
return NULL;
}
-static void output_frames(struct vf_instance *vf)
-{
- struct vf_priv_s *p = vf->priv;
-
- struct mp_image *in = mp_refqueue_get(p->queue, 0);
-
- if (!p->pipe.num_filters) { // no filtering
- vf_add_output_frame(vf, mp_image_new_ref(in));
- return;
- }
- unsigned int csp = va_get_colorspace_flag(p->params.colorspace);
- unsigned int field = get_deint_field(p, 0, in);
- if (field == VA_FRAME_PICTURE && p->interlaced_only) {
- vf_add_output_frame(vf, mp_image_new_ref(in));
- return;
- }
- struct mp_image *out1 = render(vf, field | csp);
- if (!out1) { // cannot render
- vf_add_output_frame(vf, mp_image_new_ref(in));
- return;
- }
- mp_image_copy_attributes(out1, in);
- vf_add_output_frame(vf, out1);
- // first-field only
- if (field == VA_FRAME_PICTURE || (p->do_deint && p->deint_type < 2))
- return;
- double next_pts = mp_refqueue_get_field_pts(p->queue, 1);
- if (next_pts == MP_NOPTS_VALUE) // no pts, skip it
- return;
- struct mp_image *out2 = render(vf, get_deint_field(p, 1, in) | csp);
- if (!out2) // cannot render
- return;
- mp_image_copy_attributes(out2, in);
- out2->pts = next_pts;
- vf_add_output_frame(vf, out2);
- return;
-}
-
static struct mp_image *upload(struct vf_instance *vf, struct mp_image *in)
{
struct vf_priv_s *p = vf->priv;
@@ -303,12 +271,29 @@ static int filter_ext(struct vf_instance *vf, struct mp_image *in)
}
mp_refqueue_add_input(p->queue, in);
+ return 0;
+}
- if (mp_refqueue_has_output(p->queue)) {
- output_frames(vf);
+static int filter_out(struct vf_instance *vf)
+{
+ struct vf_priv_s *p = vf->priv;
+
+ if (!mp_refqueue_has_output(p->queue))
+ return 0;
+
+ // no filtering
+ if (!p->pipe.num_filters || !mp_refqueue_should_deint(p->queue)) {
+ struct mp_image *in = mp_refqueue_get(p->queue, 0);
+ vf_add_output_frame(vf, mp_image_new_ref(in));
mp_refqueue_next(p->queue);
+ return 0;
}
+ struct mp_image *out = render(vf);
+ mp_refqueue_next_field(p->queue);
+ if (!out)
+ return -1; // cannot render
+ vf_add_output_frame(vf, out);
return 0;
}
@@ -463,6 +448,7 @@ static int vf_open(vf_instance_t *vf)
vf->reconfig = reconfig;
vf->filter_ext = filter_ext;
+ vf->filter_out = filter_out;
vf->query_format = query_format;
vf->uninit = uninit;
vf->control = control;