vl: add support for bob deinterlacing
v2: return VDP_STATUS_INVALID_VIDEO_MIXER_PICTURE_STRUCTURE for unknown picture structure. Signed-off-by: Christian König <deathsimple@vodafone.de>
This commit is contained in:
parent
0f194fc9e4
commit
37f97e1753
|
@ -579,7 +579,8 @@ calc_src_and_dst(struct vl_compositor_layer *layer, unsigned width, unsigned hei
|
||||||
layer->src.br = calc_bottomright(size, src);
|
layer->src.br = calc_bottomright(size, src);
|
||||||
layer->dst.tl = calc_topleft(size, dst);
|
layer->dst.tl = calc_topleft(size, dst);
|
||||||
layer->dst.br = calc_bottomright(size, dst);
|
layer->dst.br = calc_bottomright(size, dst);
|
||||||
layer->size = size;
|
layer->zw.x = 0.0f;
|
||||||
|
layer->zw.y = size.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -591,25 +592,25 @@ gen_rect_verts(struct vertex2f *vb, struct vl_compositor_layer *layer)
|
||||||
vb[ 0].y = layer->dst.tl.y;
|
vb[ 0].y = layer->dst.tl.y;
|
||||||
vb[ 1].x = layer->src.tl.x;
|
vb[ 1].x = layer->src.tl.x;
|
||||||
vb[ 1].y = layer->src.tl.y;
|
vb[ 1].y = layer->src.tl.y;
|
||||||
vb[ 2] = layer->size;
|
vb[ 2] = layer->zw;
|
||||||
|
|
||||||
vb[ 3].x = layer->dst.br.x;
|
vb[ 3].x = layer->dst.br.x;
|
||||||
vb[ 3].y = layer->dst.tl.y;
|
vb[ 3].y = layer->dst.tl.y;
|
||||||
vb[ 4].x = layer->src.br.x;
|
vb[ 4].x = layer->src.br.x;
|
||||||
vb[ 4].y = layer->src.tl.y;
|
vb[ 4].y = layer->src.tl.y;
|
||||||
vb[ 5] = layer->size;
|
vb[ 5] = layer->zw;
|
||||||
|
|
||||||
vb[ 6].x = layer->dst.br.x;
|
vb[ 6].x = layer->dst.br.x;
|
||||||
vb[ 6].y = layer->dst.br.y;
|
vb[ 6].y = layer->dst.br.y;
|
||||||
vb[ 7].x = layer->src.br.x;
|
vb[ 7].x = layer->src.br.x;
|
||||||
vb[ 7].y = layer->src.br.y;
|
vb[ 7].y = layer->src.br.y;
|
||||||
vb[ 8] = layer->size;
|
vb[ 8] = layer->zw;
|
||||||
|
|
||||||
vb[ 9].x = layer->dst.tl.x;
|
vb[ 9].x = layer->dst.tl.x;
|
||||||
vb[ 9].y = layer->dst.br.y;
|
vb[ 9].y = layer->dst.br.y;
|
||||||
vb[10].x = layer->src.tl.x;
|
vb[10].x = layer->src.tl.x;
|
||||||
vb[10].y = layer->src.br.y;
|
vb[10].y = layer->src.br.y;
|
||||||
vb[11] = layer->size;
|
vb[11] = layer->zw;
|
||||||
}
|
}
|
||||||
|
|
||||||
static INLINE struct u_rect
|
static INLINE struct u_rect
|
||||||
|
@ -801,7 +802,8 @@ vl_compositor_set_buffer_layer(struct vl_compositor *c,
|
||||||
unsigned layer,
|
unsigned layer,
|
||||||
struct pipe_video_buffer *buffer,
|
struct pipe_video_buffer *buffer,
|
||||||
struct pipe_video_rect *src_rect,
|
struct pipe_video_rect *src_rect,
|
||||||
struct pipe_video_rect *dst_rect)
|
struct pipe_video_rect *dst_rect,
|
||||||
|
enum vl_compositor_deinterlace deinterlace)
|
||||||
{
|
{
|
||||||
struct pipe_sampler_view **sampler_views;
|
struct pipe_sampler_view **sampler_views;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
@ -811,8 +813,6 @@ vl_compositor_set_buffer_layer(struct vl_compositor *c,
|
||||||
assert(layer < VL_COMPOSITOR_MAX_LAYERS);
|
assert(layer < VL_COMPOSITOR_MAX_LAYERS);
|
||||||
|
|
||||||
c->used_layers |= 1 << layer;
|
c->used_layers |= 1 << layer;
|
||||||
c->layers[layer].fs = buffer->interlaced ? c->fs_weave : c->fs_video_buffer;
|
|
||||||
|
|
||||||
sampler_views = buffer->get_sampler_view_components(buffer);
|
sampler_views = buffer->get_sampler_view_components(buffer);
|
||||||
for (i = 0; i < 3; ++i) {
|
for (i = 0; i < 3; ++i) {
|
||||||
c->layers[layer].samplers[i] = c->sampler_linear;
|
c->layers[layer].samplers[i] = c->sampler_linear;
|
||||||
|
@ -822,6 +822,31 @@ vl_compositor_set_buffer_layer(struct vl_compositor *c,
|
||||||
calc_src_and_dst(&c->layers[layer], buffer->width, buffer->height,
|
calc_src_and_dst(&c->layers[layer], buffer->width, buffer->height,
|
||||||
src_rect ? *src_rect : default_rect(&c->layers[layer]),
|
src_rect ? *src_rect : default_rect(&c->layers[layer]),
|
||||||
dst_rect ? *dst_rect : default_rect(&c->layers[layer]));
|
dst_rect ? *dst_rect : default_rect(&c->layers[layer]));
|
||||||
|
|
||||||
|
if (buffer->interlaced) {
|
||||||
|
float half_a_line = 0.5f / c->layers[layer].zw.y;
|
||||||
|
switch(deinterlace) {
|
||||||
|
case VL_COMPOSITOR_WEAVE:
|
||||||
|
c->layers[layer].fs = c->fs_weave;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VL_COMPOSITOR_BOB_TOP:
|
||||||
|
c->layers[layer].zw.x = 0.25f;
|
||||||
|
c->layers[layer].src.tl.y += half_a_line;
|
||||||
|
c->layers[layer].src.br.y += half_a_line;
|
||||||
|
c->layers[layer].fs = c->fs_video_buffer;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VL_COMPOSITOR_BOB_BOTTOM:
|
||||||
|
c->layers[layer].zw.x = 0.75f;
|
||||||
|
c->layers[layer].src.tl.y -= half_a_line;
|
||||||
|
c->layers[layer].src.br.y -= half_a_line;
|
||||||
|
c->layers[layer].fs = c->fs_video_buffer;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else
|
||||||
|
c->layers[layer].fs = c->fs_video_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -44,6 +44,14 @@ struct pipe_context;
|
||||||
|
|
||||||
#define VL_COMPOSITOR_MAX_LAYERS 16
|
#define VL_COMPOSITOR_MAX_LAYERS 16
|
||||||
|
|
||||||
|
/* deinterlace allgorithem */
|
||||||
|
enum vl_compositor_deinterlace
|
||||||
|
{
|
||||||
|
VL_COMPOSITOR_WEAVE,
|
||||||
|
VL_COMPOSITOR_BOB_TOP,
|
||||||
|
VL_COMPOSITOR_BOB_BOTTOM
|
||||||
|
};
|
||||||
|
|
||||||
struct vl_compositor_layer
|
struct vl_compositor_layer
|
||||||
{
|
{
|
||||||
bool clearing;
|
bool clearing;
|
||||||
|
@ -56,7 +64,7 @@ struct vl_compositor_layer
|
||||||
struct {
|
struct {
|
||||||
struct vertex2f tl, br;
|
struct vertex2f tl, br;
|
||||||
} src, dst;
|
} src, dst;
|
||||||
struct vertex2f size;
|
struct vertex2f zw;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vl_compositor
|
struct vl_compositor
|
||||||
|
@ -148,7 +156,8 @@ vl_compositor_set_buffer_layer(struct vl_compositor *compositor,
|
||||||
unsigned layer,
|
unsigned layer,
|
||||||
struct pipe_video_buffer *buffer,
|
struct pipe_video_buffer *buffer,
|
||||||
struct pipe_video_rect *src_rect,
|
struct pipe_video_rect *src_rect,
|
||||||
struct pipe_video_rect *dst_rect);
|
struct pipe_video_rect *dst_rect,
|
||||||
|
enum vl_compositor_deinterlace deinterlace);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set a paletted sampler as a layer to render
|
* set a paletted sampler as a layer to render
|
||||||
|
|
|
@ -204,6 +204,7 @@ VdpStatus vlVdpVideoMixerRender(VdpVideoMixer mixer,
|
||||||
VdpLayer const *layers)
|
VdpLayer const *layers)
|
||||||
{
|
{
|
||||||
struct pipe_video_rect src_rect, dst_rect, dst_clip;
|
struct pipe_video_rect src_rect, dst_rect, dst_clip;
|
||||||
|
enum vl_compositor_deinterlace deinterlace;
|
||||||
unsigned layer = 0;
|
unsigned layer = 0;
|
||||||
|
|
||||||
vlVdpVideoMixer *vmixer;
|
vlVdpVideoMixer *vmixer;
|
||||||
|
@ -242,8 +243,26 @@ VdpStatus vlVdpVideoMixerRender(VdpVideoMixer mixer,
|
||||||
}
|
}
|
||||||
|
|
||||||
vl_compositor_clear_layers(&vmixer->compositor);
|
vl_compositor_clear_layers(&vmixer->compositor);
|
||||||
|
|
||||||
|
switch (current_picture_structure) {
|
||||||
|
case VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD:
|
||||||
|
deinterlace = VL_COMPOSITOR_BOB_TOP;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD:
|
||||||
|
deinterlace = VL_COMPOSITOR_BOB_BOTTOM;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME:
|
||||||
|
deinterlace = VL_COMPOSITOR_WEAVE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return VDP_STATUS_INVALID_VIDEO_MIXER_PICTURE_STRUCTURE;
|
||||||
|
};
|
||||||
vl_compositor_set_buffer_layer(&vmixer->compositor, layer++, surf->video_buffer,
|
vl_compositor_set_buffer_layer(&vmixer->compositor, layer++, surf->video_buffer,
|
||||||
RectToPipe(video_source_rect, &src_rect), NULL);
|
RectToPipe(video_source_rect, &src_rect), NULL,
|
||||||
|
deinterlace);
|
||||||
vl_compositor_render(&vmixer->compositor, dst->surface,
|
vl_compositor_render(&vmixer->compositor, dst->surface,
|
||||||
RectToPipe(destination_video_rect, &dst_rect),
|
RectToPipe(destination_video_rect, &dst_rect),
|
||||||
RectToPipe(destination_rect, &dst_clip),
|
RectToPipe(destination_rect, &dst_clip),
|
||||||
|
|
|
@ -406,7 +406,8 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
|
||||||
context_priv->decoder->flush(context_priv->decoder);
|
context_priv->decoder->flush(context_priv->decoder);
|
||||||
|
|
||||||
vl_compositor_clear_layers(compositor);
|
vl_compositor_clear_layers(compositor);
|
||||||
vl_compositor_set_buffer_layer(compositor, 0, surface_priv->video_buffer, &src_rect, NULL);
|
vl_compositor_set_buffer_layer(compositor, 0, surface_priv->video_buffer,
|
||||||
|
&src_rect, NULL, VL_COMPOSITOR_WEAVE);
|
||||||
|
|
||||||
if (subpicture_priv) {
|
if (subpicture_priv) {
|
||||||
XVMC_MSG(XVMC_TRACE, "[XvMC] Surface %p has subpicture %p.\n", surface, surface_priv->subpicture);
|
XVMC_MSG(XVMC_TRACE, "[XvMC] Surface %p has subpicture %p.\n", surface, surface_priv->subpicture);
|
||||||
|
|
Loading…
Reference in New Issue