summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@collabora.co.uk>2009-04-30 14:20:16 +0200
committerWim Taymans <wim.taymans@collabora.co.uk>2009-04-30 14:20:16 +0200
commit5704bc8f89c745a86dbe435a2e2c008c499e8132 (patch)
tree6ce821567937fbc15ace292e6d60b60231a12b28
parentf38cb76b5f2db479ab488bc1de2b53b5700f984a (diff)
dvdspu: do some basic clipping
Add some basic clipping of the subtitle region when the subtitle is bigger than the image we should put it on.
-rw-r--r--gst/dvdspu/gstdvdspu-render.c66
-rw-r--r--gst/dvdspu/gstdvdspu.h1
2 files changed, 54 insertions, 13 deletions
diff --git a/gst/dvdspu/gstdvdspu-render.c b/gst/dvdspu/gstdvdspu-render.c
index 23a6a0853..e3bae8b61 100644
--- a/gst/dvdspu/gstdvdspu-render.c
+++ b/gst/dvdspu/gstdvdspu-render.c
@@ -416,13 +416,7 @@ gst_dvd_spu_render_spu (GstDVDSpu * dvdspu, GstBuffer * buf)
state->hl_rect.left, state->hl_rect.top,
state->hl_rect.right, state->hl_rect.bottom);
- /* We start rendering from the first line of the display rect */
- y = state->disp_rect.top;
-
- /* Update our plane references to the first line of the disp_rect */
- planes[0] += state->Y_stride * y;
- planes[1] += state->UV_stride * (y / 2);
- planes[2] += state->UV_stride * (y / 2);
+ GST_DEBUG ("vid_disp %d,%d", state->vid_width, state->vid_height);
/* When reading RLE data, we track the offset in nibbles... */
state->cur_offsets[0] = state->pix_data[0] * 2;
@@ -442,18 +436,62 @@ gst_dvd_spu_render_spu (GstDVDSpu * dvdspu, GstBuffer * buf)
} else
state->cur_chg_col = NULL;
+ /* We start rendering from the first line of the display rect */
+ y = state->disp_rect.top;
/* start_y is always an even number and we render lines in pairs from there,
* accumulating 2 lines of chroma then blending it. We might need to render a
* single line at the end if the display rect ends on an even line too. */
last_y = (state->disp_rect.bottom - 1) & ~(0x01);
+
+ /* center the image when display rectangle exceeds the video width */
+ if (state->vid_width < state->disp_rect.right) {
+ gint diff, disp_width;
+
+ disp_width = state->disp_rect.left - state->disp_rect.right;
+ diff = (disp_width - state->vid_width) / 2;
+
+ /* fixme, this is not used yet */
+ state->clip_rect.left = state->disp_rect.left + diff;
+ state->clip_rect.right = state->disp_rect.right - diff;
+
+ GST_DEBUG ("clipping width to %d,%d", state->clip_rect.left,
+ state->clip_rect.right);
+ } else {
+ state->clip_rect.left = state->disp_rect.left;
+ state->clip_rect.right = state->disp_rect.right;
+ }
+
+ /* for the height, chop off the bottom bits of the diplay rectangle because we
+ * assume the picture is in the lower part. We should better check where it
+ * is and do something more clever. */
+ state->clip_rect.bottom = state->disp_rect.bottom;
+ if (state->vid_height < state->disp_rect.bottom) {
+ state->clip_rect.top = state->disp_rect.bottom - state->vid_height;
+ GST_DEBUG ("clipping height to %d,%d", state->clip_rect.top,
+ state->clip_rect.bottom);
+ } else {
+ state->clip_rect.top = state->disp_rect.top;
+ /* Update our plane references to the first line of the disp_rect */
+ planes[0] += state->Y_stride * y;
+ planes[1] += state->UV_stride * (y / 2);
+ planes[2] += state->UV_stride * (y / 2);
+ }
+
for (state->cur_Y = y; state->cur_Y <= last_y; state->cur_Y++) {
+ gboolean clip;
+
+ clip = (state->cur_Y < state->clip_rect.top
+ || state->cur_Y > state->clip_rect.bottom);
+
/* Reset the compositing buffer */
dvdspu_clear_comp_buffers (state);
/* Render even line */
state->comp_last_x_ptr = state->comp_last_x;
dvdspu_render_line (state, planes, &state->cur_offsets[0]);
- /* Advance the luminance output pointer */
- planes[0] += state->Y_stride;
+ if (!clip) {
+ /* Advance the luminance output pointer */
+ planes[0] += state->Y_stride;
+ }
state->cur_Y++;
/* Render odd line */
@@ -462,10 +500,12 @@ gst_dvd_spu_render_spu (GstDVDSpu * dvdspu, GstBuffer * buf)
/* Blend the accumulated UV compositing buffers onto the output */
dvdspu_blend_comp_buffers (state, planes);
- /* Update all the output pointers */
- planes[0] += state->Y_stride;
- planes[1] += state->UV_stride;
- planes[2] += state->UV_stride;
+ if (!clip) {
+ /* Update all the output pointers */
+ planes[0] += state->Y_stride;
+ planes[1] += state->UV_stride;
+ planes[2] += state->UV_stride;
+ }
}
if (state->cur_Y == state->disp_rect.bottom) {
g_assert ((state->disp_rect.bottom & 0x01) == 0);
diff --git a/gst/dvdspu/gstdvdspu.h b/gst/dvdspu/gstdvdspu.h
index 0432a3af9..dfc51f9e9 100644
--- a/gst/dvdspu/gstdvdspu.h
+++ b/gst/dvdspu/gstdvdspu.h
@@ -122,6 +122,7 @@ struct SpuState {
GstBuffer *pix_buf; /* Current SPU packet the pix_data references */
SpuRect disp_rect;
+ SpuRect clip_rect;
SpuRect hl_rect;
guint32 current_clut[16]; /* Colour lookup table from incoming events */