summaryrefslogtreecommitdiff
path: root/gst
diff options
context:
space:
mode:
Diffstat (limited to 'gst')
-rw-r--r--gst/dvdspu/gstdvdspu.c129
-rw-r--r--gst/dvdspu/gstdvdspu.h5
-rw-r--r--gst/dvdspu/gstspu-common.h1
-rw-r--r--gst/dvdspu/gstspu-pgs.c64
-rw-r--r--gst/dvdspu/gstspu-pgs.h2
-rw-r--r--gst/dvdspu/gstspu-vobsub-render.c78
-rw-r--r--gst/dvdspu/gstspu-vobsub.c16
-rw-r--r--gst/dvdspu/gstspu-vobsub.h2
8 files changed, 163 insertions, 134 deletions
diff --git a/gst/dvdspu/gstdvdspu.c b/gst/dvdspu/gstdvdspu.c
index 345992104..8f67d63f8 100644
--- a/gst/dvdspu/gstdvdspu.c
+++ b/gst/dvdspu/gstdvdspu.c
@@ -55,7 +55,7 @@ static GstStaticPadTemplate video_sink_factory =
GST_STATIC_PAD_TEMPLATE ("video",
GST_PAD_SINK,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("video/x-raw-yuv, " "format = (fourcc) { I420 }, "
+ GST_STATIC_CAPS ("video/x-raw, " "format = (string) { I420 }, "
"width = (int) [ 16, 4096 ], " "height = (int) [ 16, 4096 ]")
/* FIXME: Can support YV12 one day too */
);
@@ -63,7 +63,7 @@ GST_STATIC_PAD_TEMPLATE ("video",
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("video/x-raw-yuv, " "format = (fourcc) { I420 }, "
+ GST_STATIC_CAPS ("video/x-raw, " "format = (string) { I420 }, "
"width = (int) [ 16, 4096 ], " "height = (int) [ 16, 4096 ]")
/* FIXME: Can support YV12 one day too */
);
@@ -146,8 +146,6 @@ gst_dvd_spu_init (GstDVDSpu * dvdspu)
{
dvdspu->videosinkpad =
gst_pad_new_from_static_template (&video_sink_factory, "video");
- gst_pad_set_setcaps_function (dvdspu->videosinkpad,
- gst_dvd_spu_video_set_caps);
gst_pad_set_getcaps_function (dvdspu->videosinkpad,
gst_dvd_spu_video_proxy_getcaps);
gst_pad_set_chain_function (dvdspu->videosinkpad, gst_dvd_spu_video_chain);
@@ -162,8 +160,6 @@ gst_dvd_spu_init (GstDVDSpu * dvdspu)
gst_pad_new_from_static_template (&subpic_sink_factory, "subpicture");
gst_pad_set_chain_function (dvdspu->subpic_sinkpad, gst_dvd_spu_subpic_chain);
gst_pad_set_event_function (dvdspu->subpic_sinkpad, gst_dvd_spu_subpic_event);
- gst_pad_set_setcaps_function (dvdspu->subpic_sinkpad,
- gst_dvd_spu_subpic_set_caps);
gst_element_add_pad (GST_ELEMENT (dvdspu), dvdspu->videosinkpad);
gst_element_add_pad (GST_ELEMENT (dvdspu), dvdspu->subpic_sinkpad);
@@ -186,8 +182,8 @@ gst_dvd_spu_clear (GstDVDSpu * dvdspu)
gst_buffer_replace (&dvdspu->ref_frame, NULL);
gst_buffer_replace (&dvdspu->pending_frame, NULL);
- dvdspu->spu_state.fps_n = 25;
- dvdspu->spu_state.fps_d = 1;
+ dvdspu->spu_state.info.fps_n = 25;
+ dvdspu->spu_state.info.fps_d = 1;
gst_segment_init (&dvdspu->video_seg, GST_FORMAT_UNDEFINED);
}
@@ -296,39 +292,21 @@ gst_dvd_spu_video_set_caps (GstPad * pad, GstCaps * caps)
{
GstDVDSpu *dvdspu = GST_DVD_SPU (gst_pad_get_parent (pad));
gboolean res = FALSE;
- GstStructure *s;
- gint w, h;
+ GstVideoInfo info;
gint i;
- gint fps_n, fps_d;
SpuState *state;
- s = gst_caps_get_structure (caps, 0);
-
- if (!gst_structure_get_int (s, "width", &w) ||
- !gst_structure_get_int (s, "height", &h) ||
- !gst_structure_get_fraction (s, "framerate", &fps_n, &fps_d)) {
+ if (!gst_video_info_from_caps (&info, caps))
goto done;
- }
DVD_SPU_LOCK (dvdspu);
state = &dvdspu->spu_state;
- state->fps_n = fps_n;
- state->fps_d = fps_d;
-
- state->vid_height = h;
- state->Y_height = GST_ROUND_UP_2 (h);
- state->UV_height = state->Y_height / 2;
-
- if (state->vid_width != w) {
- state->vid_width = w;
- state->Y_stride = GST_ROUND_UP_4 (w);
- state->UV_stride = GST_ROUND_UP_4 (state->Y_stride / 2);
- for (i = 0; i < 3; i++) {
- state->comp_bufs[i] = g_realloc (state->comp_bufs[i],
- sizeof (guint32) * state->UV_stride);
- }
+ state->info = info;
+ for (i = 0; i < 3; i++) {
+ state->comp_bufs[i] = g_realloc (state->comp_bufs[i],
+ sizeof (guint32) * info.width);
}
DVD_SPU_UNLOCK (dvdspu);
@@ -376,6 +354,15 @@ gst_dvd_spu_video_event (GstPad * pad, GstEvent * event)
g_return_val_if_fail (dvdspu != NULL, FALSE);
switch (GST_EVENT_TYPE (event)) {
+ case GST_EVENT_CAPS:
+ {
+ GstCaps *caps;
+
+ gst_event_parse_caps (event, &caps);
+ res = gst_dvd_spu_video_set_caps (pad, caps);
+ gst_event_unref (event);
+ break;
+ }
case GST_EVENT_CUSTOM_DOWNSTREAM:
case GST_EVENT_CUSTOM_DOWNSTREAM_OOB:
{
@@ -513,7 +500,7 @@ dvdspu_handle_vid_buffer (GstDVDSpu * dvdspu, GstBuffer * buf)
GstClockTime next_ts = dvdspu->video_seg.position;
next_ts += gst_util_uint64_scale_int (GST_SECOND,
- dvdspu->spu_state.fps_d, dvdspu->spu_state.fps_n);
+ dvdspu->spu_state.info.fps_d, dvdspu->spu_state.info.fps_n);
/* NULL buffer was passed - use the reference frame and update the timestamp,
* or else there's nothing to draw, and just return GST_FLOW_OK */
@@ -600,16 +587,21 @@ no_ref_frame:
static void
gstspu_render (GstDVDSpu * dvdspu, GstBuffer * buf)
{
+ GstVideoFrame frame;
+
+ gst_video_frame_map (&frame, &dvdspu->spu_state.info, buf, GST_MAP_READWRITE);
+
switch (dvdspu->spu_input_type) {
case SPU_INPUT_TYPE_VOBSUB:
- gstspu_vobsub_render (dvdspu, buf);
+ gstspu_vobsub_render (dvdspu, &frame);
break;
case SPU_INPUT_TYPE_PGS:
- gstspu_pgs_render (dvdspu, buf);
+ gstspu_pgs_render (dvdspu, &frame);
break;
default:
break;
}
+ gst_video_frame_unmap (&frame);
}
/* With SPU LOCK */
@@ -839,6 +831,7 @@ gst_dvd_spu_subpic_chain (GstPad * pad, GstBuffer * buf)
{
GstDVDSpu *dvdspu = (GstDVDSpu *) (gst_object_get_parent (GST_OBJECT (pad)));
GstFlowReturn ret = GST_FLOW_OK;
+ gsize size;
g_return_val_if_fail (dvdspu != NULL, GST_FLOW_ERROR);
@@ -874,30 +867,31 @@ gst_dvd_spu_subpic_chain (GstPad * pad, GstBuffer * buf)
if (dvdspu->partial_spu == NULL)
goto done;
+ size = gst_buffer_get_size (dvdspu->partial_spu);
+
switch (dvdspu->spu_input_type) {
case SPU_INPUT_TYPE_VOBSUB:
- if (GST_BUFFER_SIZE (dvdspu->partial_spu) > 4) {
+ if (size > 4) {
+ guint8 *header[2];
guint16 packet_size;
- guint8 *data;
- data = GST_BUFFER_DATA (dvdspu->partial_spu);
- packet_size = GST_READ_UINT16_BE (data);
-
- if (packet_size == GST_BUFFER_SIZE (dvdspu->partial_spu)) {
+ gst_buffer_extract (dvdspu->partial_spu, 0, header, 2);
+ packet_size = GST_READ_UINT16_BE (header);
+ if (packet_size == size) {
submit_new_spu_packet (dvdspu, dvdspu->partial_spu);
dvdspu->partial_spu = NULL;
- } else if (packet_size < GST_BUFFER_SIZE (dvdspu->partial_spu)) {
+ } else if (packet_size < size) {
/* Somehow we collected too much - something is wrong. Drop the
* packet entirely and wait for a new one */
GST_DEBUG_OBJECT (dvdspu, "Discarding invalid SPU buffer of size %u",
- GST_BUFFER_SIZE (dvdspu->partial_spu));
+ size);
gst_buffer_unref (dvdspu->partial_spu);
dvdspu->partial_spu = NULL;
} else {
GST_LOG_OBJECT (dvdspu,
"SPU buffer claims to be of size %u. Collected %u so far.",
- packet_size, GST_BUFFER_SIZE (dvdspu->partial_spu));
+ packet_size, size);
}
}
break;
@@ -906,34 +900,42 @@ gst_dvd_spu_subpic_chain (GstPad * pad, GstBuffer * buf)
* we've collected */
guint8 packet_type;
guint16 packet_size;
- guint8 *data = GST_BUFFER_DATA (dvdspu->partial_spu);
- guint8 *end = data + GST_BUFFER_SIZE (dvdspu->partial_spu);
+ guint8 *data, *ptr, *end;
+ gsize size;
+ gboolean invalid = FALSE;
+
+ data = gst_buffer_map (dvdspu->partial_spu, &size, NULL, GST_MAP_READ);
+
+ ptr = data;
+ end = ptr + size;
/* FIXME: There's no need to walk the command set each time. We can set a
* marker and resume where we left off next time */
/* FIXME: Move the packet parsing and sanity checking into the format-specific modules */
- while (data != end) {
- if (data + 3 > end)
+ while (ptr != end) {
+ if (ptr + 3 > end)
break;
- packet_type = *data++;
- packet_size = GST_READ_UINT16_BE (data);
- data += 2;
- if (data + packet_size > end)
+ packet_type = *ptr++;
+ packet_size = GST_READ_UINT16_BE (ptr);
+ ptr += 2;
+ if (ptr + packet_size > end)
break;
- data += packet_size;
+ ptr += packet_size;
/* 0x80 is the END command for PGS packets */
- if (packet_type == 0x80 && data != end) {
+ if (packet_type == 0x80 && ptr != end) {
/* Extra cruft on the end of the packet -> assume invalid */
- gst_buffer_unref (dvdspu->partial_spu);
- dvdspu->partial_spu = NULL;
+ invalid = TRUE;
break;
}
}
+ gst_buffer_unmap (dvdspu->partial_spu, data, size);
- if (dvdspu->partial_spu && data == end) {
+ if (invalid) {
+ gst_buffer_unref (dvdspu->partial_spu);
+ dvdspu->partial_spu = NULL;
+ } else if (ptr == end) {
GST_DEBUG_OBJECT (dvdspu,
- "Have complete PGS packet of size %u. Enqueueing.",
- GST_BUFFER_SIZE (dvdspu->partial_spu));
+ "Have complete PGS packet of size %u. Enqueueing.", size);
submit_new_spu_packet (dvdspu, dvdspu->partial_spu);
dvdspu->partial_spu = NULL;
}
@@ -966,6 +968,15 @@ gst_dvd_spu_subpic_event (GstPad * pad, GstEvent * event)
/* Some events on the subpicture sink pad just get ignored, like
* FLUSH_START */
switch (GST_EVENT_TYPE (event)) {
+ case GST_EVENT_CAPS:
+ {
+ GstCaps *caps;
+
+ gst_event_parse_caps (event, &caps);
+ res = gst_dvd_spu_subpic_set_caps (pad, caps);
+ gst_event_unref (event);
+ break;
+ }
case GST_EVENT_CUSTOM_DOWNSTREAM:
case GST_EVENT_CUSTOM_DOWNSTREAM_OOB:
{
diff --git a/gst/dvdspu/gstdvdspu.h b/gst/dvdspu/gstdvdspu.h
index 22b48d1da..747b00259 100644
--- a/gst/dvdspu/gstdvdspu.h
+++ b/gst/dvdspu/gstdvdspu.h
@@ -69,10 +69,7 @@ struct SpuState {
GstClockTime next_ts; /* Next event TS in running time */
SpuStateFlags flags;
- gint fps_n, fps_d;
- gint16 vid_width, vid_height;
- gint16 Y_stride, UV_stride;
- gint16 Y_height, UV_height;
+ GstVideoInfo info;
guint32 *comp_bufs[3]; /* Compositing buffers for U+V & A */
guint16 comp_left;
diff --git a/gst/dvdspu/gstspu-common.h b/gst/dvdspu/gstspu-common.h
index 206e88203..ec0b3dfc4 100644
--- a/gst/dvdspu/gstspu-common.h
+++ b/gst/dvdspu/gstspu-common.h
@@ -20,6 +20,7 @@
#define __GSTSPU_COMMON_H__
#include <glib.h>
+#include <gst/video/video.h>
G_BEGIN_DECLS
diff --git a/gst/dvdspu/gstspu-pgs.c b/gst/dvdspu/gstspu-pgs.c
index a244ac993..955cf1a98 100644
--- a/gst/dvdspu/gstspu-pgs.c
+++ b/gst/dvdspu/gstspu-pgs.c
@@ -171,10 +171,11 @@ dump_rle_data (GstDVDSpu * dvdspu, guint8 * data, guint32 len)
static void
pgs_composition_object_render (PgsCompositionObject * obj, SpuState * state,
- GstBuffer * dest_buf)
+ GstVideoFrame * frame)
{
SpuColour *colour;
guint8 *planes[3]; /* YUV frame pointers */
+ gint strides[3];
guint8 *data, *end;
guint16 obj_w;
guint16 obj_h G_GNUC_UNUSED;
@@ -195,27 +196,27 @@ pgs_composition_object_render (PgsCompositionObject * obj, SpuState * state,
* window specified by the object's window_id */
/* Store the start of each plane */
- planes[0] = GST_BUFFER_DATA (dest_buf);
- planes[1] = planes[0] + (state->Y_height * state->Y_stride);
- planes[2] = planes[1] + (state->UV_height * state->UV_stride);
+ planes[0] = GST_VIDEO_FRAME_COMP_DATA (frame, 0);
+ planes[1] = GST_VIDEO_FRAME_COMP_DATA (frame, 1);
+ planes[2] = GST_VIDEO_FRAME_COMP_DATA (frame, 2);
- /* Sanity check */
- g_return_if_fail (planes[2] + (state->UV_height * state->UV_stride) <=
- GST_BUFFER_DATA (dest_buf) + GST_BUFFER_SIZE (dest_buf));
+ strides[0] = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);
+ strides[1] = GST_VIDEO_FRAME_COMP_STRIDE (frame, 1);
+ strides[2] = GST_VIDEO_FRAME_COMP_STRIDE (frame, 2);
- y = MIN (obj->y, state->Y_height);
+ y = MIN (obj->y, state->info.height);
- planes[0] += state->Y_stride * y;
- planes[1] += state->UV_stride * (y / 2);
- planes[2] += state->UV_stride * (y / 2);
+ planes[0] += strides[0] * y;
+ planes[1] += strides[1] * (y / 2);
+ planes[2] += strides[2] * (y / 2);
/* RLE data: */
obj_w = GST_READ_UINT16_BE (data);
obj_h = GST_READ_UINT16_BE (data + 2);
data += 4;
- min_x = MIN (obj->x, state->Y_stride);
- max_x = MIN (obj->x + obj_w, state->Y_stride);
+ min_x = MIN (obj->x, strides[0]);
+ max_x = MIN (obj->x + obj_w, strides[0]);
state->comp_left = x = min_x;
state->comp_right = max_x;
@@ -283,17 +284,17 @@ pgs_composition_object_render (PgsCompositionObject * obj, SpuState * state,
if (!run_len || x > max_x) {
x = min_x;
- planes[0] += state->Y_stride;
+ planes[0] += strides[0];
if (y % 2) {
gstspu_blend_comp_buffers (state, planes);
gstspu_clear_comp_buffers (state);
- planes[1] += state->UV_stride;
- planes[2] += state->UV_stride;
+ planes[1] += strides[1];
+ planes[2] += strides[2];
}
y++;
- if (y >= state->Y_height)
+ if (y >= state->info.height)
return; /* Hit the bottom */
}
}
@@ -678,17 +679,20 @@ parse_pgs_packet (GstDVDSpu * dvdspu, guint8 type, guint8 * payload,
gint
gstspu_exec_pgs_buffer (GstDVDSpu * dvdspu, GstBuffer * buf)
{
- guint8 *pos, *end;
+ guint8 *data, *pos, *end;
+ gsize size;
guint8 type;
guint16 packet_len;
- pos = GST_BUFFER_DATA (buf);
- end = pos + GST_BUFFER_SIZE (buf);
+ data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+
+ pos = data;
+ end = pos + size;
/* Need at least 3 bytes */
if (pos + 3 > end) {
PGS_DUMP ("Not enough bytes to be a PGS packet\n");
- return -1;
+ goto error;
}
PGS_DUMP ("Begin dumping command buffer of size %u ts %" GST_TIME_FORMAT "\n",
@@ -699,19 +703,27 @@ gstspu_exec_pgs_buffer (GstDVDSpu * dvdspu, GstBuffer * buf)
pos += 2;
if (pos + packet_len > end) {
+ gst_buffer_unmap (buf, data, size);
PGS_DUMP ("Invalid packet length %u (only have %u bytes)\n", packet_len,
end - pos);
- return -1;
+ goto error;
}
if (parse_pgs_packet (dvdspu, type, pos, packet_len))
- return -1;
+ goto error;
pos += packet_len;
} while (pos + 3 <= end);
PGS_DUMP ("End dumping command buffer with %u bytes remaining\n", end - pos);
- return (pos - GST_BUFFER_DATA (buf));
+ return (pos - data);
+
+ /* ERRORS */
+error:
+ {
+ gst_buffer_unmap (buf, data, size);
+ return -1;
+ }
}
void
@@ -746,7 +758,7 @@ gstspu_pgs_execute_event (GstDVDSpu * dvdspu)
}
void
-gstspu_pgs_render (GstDVDSpu * dvdspu, GstBuffer * buf)
+gstspu_pgs_render (GstDVDSpu * dvdspu, GstVideoFrame * frame)
{
SpuState *state = &dvdspu->spu_state;
PgsPresentationSegment *ps = &state->pgs.pres_seg;
@@ -758,7 +770,7 @@ gstspu_pgs_render (GstDVDSpu * dvdspu, GstBuffer * buf)
for (i = 0; i < ps->objects->len; i++) {
PgsCompositionObject *cur =
&g_array_index (ps->objects, PgsCompositionObject, i);
- pgs_composition_object_render (cur, state, buf);
+ pgs_composition_object_render (cur, state, frame);
}
}
diff --git a/gst/dvdspu/gstspu-pgs.h b/gst/dvdspu/gstspu-pgs.h
index 164f4d815..3304677f2 100644
--- a/gst/dvdspu/gstspu-pgs.h
+++ b/gst/dvdspu/gstspu-pgs.h
@@ -99,7 +99,7 @@ struct SpuPgsState {
void gstspu_pgs_handle_new_buf (GstDVDSpu * dvdspu, GstClockTime event_ts, GstBuffer *buf);
gboolean gstspu_pgs_execute_event (GstDVDSpu *dvdspu);
-void gstspu_pgs_render (GstDVDSpu *dvdspu, GstBuffer *buf);
+void gstspu_pgs_render (GstDVDSpu *dvdspu, GstVideoFrame *frame);
gboolean gstspu_pgs_handle_dvd_event (GstDVDSpu *dvdspu, GstEvent *event);
void gstspu_pgs_flush (GstDVDSpu *dvdspu);
diff --git a/gst/dvdspu/gstspu-vobsub-render.c b/gst/dvdspu/gstspu-vobsub-render.c
index 830017d33..1254d0aeb 100644
--- a/gst/dvdspu/gstspu-vobsub-render.c
+++ b/gst/dvdspu/gstspu-vobsub-render.c
@@ -138,7 +138,7 @@ gstspu_vobsub_get_nibble (SpuState * state, guint16 * rle_offset)
if (G_UNLIKELY (*rle_offset >= state->vobsub.max_offset))
return 0; /* Overran the buffer */
- ret = GST_BUFFER_DATA (state->vobsub.pix_buf)[(*rle_offset) / 2];
+ gst_buffer_extract (state->vobsub.pix_buf, (*rle_offset) / 2, &ret, 1);
/* If the offset is even, we shift the answer down 4 bits, otherwise not */
if (*rle_offset & 0x01)
@@ -384,24 +384,29 @@ gstspu_vobsub_clear_comp_buffers (SpuState * state)
}
void
-gstspu_vobsub_render (GstDVDSpu * dvdspu, GstBuffer * buf)
+gstspu_vobsub_render (GstDVDSpu * dvdspu, GstVideoFrame * frame)
{
SpuState *state = &dvdspu->spu_state;
guint8 *planes[3]; /* YUV frame pointers */
gint y, last_y;
+ gint width, height;
+ gint strides[3];
/* Set up our initial state */
if (G_UNLIKELY (state->vobsub.pix_buf == NULL))
return;
/* Store the start of each plane */
- planes[0] = GST_BUFFER_DATA (buf);
- planes[1] = planes[0] + (state->Y_height * state->Y_stride);
- planes[2] = planes[1] + (state->UV_height * state->UV_stride);
+ planes[0] = GST_VIDEO_FRAME_COMP_DATA (frame, 0);
+ planes[1] = GST_VIDEO_FRAME_COMP_DATA (frame, 1);
+ planes[2] = GST_VIDEO_FRAME_COMP_DATA (frame, 2);
- /* Sanity check */
- g_return_if_fail (planes[2] + (state->UV_height * state->UV_stride) <=
- GST_BUFFER_DATA (buf) + GST_BUFFER_SIZE (buf));
+ strides[0] = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);
+ strides[1] = GST_VIDEO_FRAME_COMP_STRIDE (frame, 1);
+ strides[2] = GST_VIDEO_FRAME_COMP_STRIDE (frame, 2);
+
+ width = GST_VIDEO_FRAME_WIDTH (frame);
+ height = GST_VIDEO_FRAME_HEIGHT (frame);
GST_DEBUG_OBJECT (dvdspu,
"Rendering SPU. disp_rect %d,%d to %d,%d. hl_rect %d,%d to %d,%d",
@@ -410,13 +415,12 @@ gstspu_vobsub_render (GstDVDSpu * dvdspu, GstBuffer * buf)
state->vobsub.hl_rect.left, state->vobsub.hl_rect.top,
state->vobsub.hl_rect.right, state->vobsub.hl_rect.bottom);
- GST_DEBUG_OBJECT (dvdspu, "video size %d,%d", state->vid_width,
- state->vid_height);
+ GST_DEBUG_OBJECT (dvdspu, "video size %d,%d", width, height);
/* When reading RLE data, we track the offset in nibbles... */
state->vobsub.cur_offsets[0] = state->vobsub.pix_data[0] * 2;
state->vobsub.cur_offsets[1] = state->vobsub.pix_data[1] * 2;
- state->vobsub.max_offset = GST_BUFFER_SIZE (state->vobsub.pix_buf) * 2;
+ state->vobsub.max_offset = gst_buffer_get_size (state->vobsub.pix_buf) * 2;
/* Update all the palette caches */
gstspu_vobsub_update_palettes (dvdspu, state);
@@ -436,18 +440,18 @@ gstspu_vobsub_render (GstDVDSpu * dvdspu, GstBuffer * buf)
state->vobsub.clip_rect.right = state->vobsub.disp_rect.right;
/* center the image when display rectangle exceeds the video width */
- if (state->vid_width <= state->vobsub.disp_rect.right) {
+ if (width <= state->vobsub.disp_rect.right) {
gint left, disp_width;
disp_width = state->vobsub.disp_rect.right - state->vobsub.disp_rect.left
+ 1;
- left = (state->vid_width - disp_width) / 2;
+ left = (width - disp_width) / 2;
state->vobsub.disp_rect.left = left;
state->vobsub.disp_rect.right = left + disp_width - 1;
/* if it clips to the right, shift it left, but only till zero */
- if (state->vobsub.disp_rect.right >= state->vid_width) {
- gint shift = state->vobsub.disp_rect.right - state->vid_width - 1;
+ if (state->vobsub.disp_rect.right >= width) {
+ gint shift = state->vobsub.disp_rect.right - width - 1;
if (shift > state->vobsub.disp_rect.left)
shift = state->vobsub.disp_rect.left;
state->vobsub.disp_rect.left -= shift;
@@ -459,8 +463,8 @@ gstspu_vobsub_render (GstDVDSpu * dvdspu, GstBuffer * buf)
state->vobsub.clip_rect.right = state->vobsub.disp_rect.right;
/* clip right after the shift */
- if (state->vobsub.clip_rect.right >= state->vid_width)
- state->vobsub.clip_rect.right = state->vid_width - 1;
+ if (state->vobsub.clip_rect.right >= width)
+ state->vobsub.clip_rect.right = width - 1;
GST_DEBUG_OBJECT (dvdspu,
"clipping width to %d,%d", state->vobsub.clip_rect.left,
@@ -472,10 +476,10 @@ gstspu_vobsub_render (GstDVDSpu * dvdspu, GstBuffer * buf)
* is and do something more clever. */
state->vobsub.clip_rect.top = state->vobsub.disp_rect.top;
state->vobsub.clip_rect.bottom = state->vobsub.disp_rect.bottom;
- if (state->vid_height <= state->vobsub.disp_rect.bottom) {
+ if (height <= state->vobsub.disp_rect.bottom) {
/* shift it up, but only till zero */
- gint shift = state->vobsub.disp_rect.bottom - state->vid_height - 1;
+ gint shift = state->vobsub.disp_rect.bottom - height - 1;
if (shift > state->vobsub.disp_rect.top)
shift = state->vobsub.disp_rect.top;
state->vobsub.disp_rect.top -= shift;
@@ -492,8 +496,8 @@ gstspu_vobsub_render (GstDVDSpu * dvdspu, GstBuffer * buf)
state->vobsub.clip_rect.bottom = state->vobsub.disp_rect.bottom;
/* clip right after the shift */
- if (state->vobsub.clip_rect.bottom >= state->vid_height)
- state->vobsub.clip_rect.bottom = state->vid_height - 1;
+ if (state->vobsub.clip_rect.bottom >= height)
+ state->vobsub.clip_rect.bottom = height - 1;
GST_DEBUG_OBJECT (dvdspu,
"clipping height to %d,%d", state->vobsub.clip_rect.top,
@@ -508,9 +512,9 @@ gstspu_vobsub_render (GstDVDSpu * dvdspu, GstBuffer * buf)
last_y = (state->vobsub.disp_rect.bottom - 1) & ~(0x01);
/* 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);
+ planes[0] += strides[0] * y;
+ planes[1] += strides[1] * (y / 2);
+ planes[2] += strides[2] * (y / 2);
for (state->vobsub.cur_Y = y; state->vobsub.cur_Y <= last_y;
state->vobsub.cur_Y++) {
@@ -526,7 +530,7 @@ gstspu_vobsub_render (GstDVDSpu * dvdspu, GstBuffer * buf)
gstspu_vobsub_render_line (state, planes, &state->vobsub.cur_offsets[0]);
if (!clip) {
/* Advance the luminance output pointer */
- planes[0] += state->Y_stride;
+ planes[0] += strides[0];
}
state->vobsub.cur_Y++;
@@ -539,9 +543,9 @@ gstspu_vobsub_render (GstDVDSpu * dvdspu, GstBuffer * buf)
gstspu_vobsub_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;
+ planes[0] += strides[0];
+ planes[1] += strides[1];
+ planes[2] += strides[2];
}
}
if (state->vobsub.cur_Y == state->vobsub.disp_rect.bottom) {
@@ -568,24 +572,22 @@ gstspu_vobsub_render (GstDVDSpu * dvdspu, GstBuffer * buf)
guint8 *cur;
gint16 pos;
- cur = GST_BUFFER_DATA (buf) + state->Y_stride * state->vobsub.disp_rect.top;
+ cur = GST_BUFFER_DATA (buf) + strides[0] * state->vobsub.disp_rect.top;
for (pos = state->vobsub.disp_rect.left + 1;
pos < state->vobsub.disp_rect.right; pos++)
cur[pos] = (cur[pos] / 2) + 0x8;
- cur =
- GST_BUFFER_DATA (buf) +
- state->Y_stride * state->vobsub.disp_rect.bottom;
+ cur = GST_BUFFER_DATA (buf) + strides[0] * state->vobsub.disp_rect.bottom;
for (pos = state->vobsub.disp_rect.left + 1;
pos < state->vobsub.disp_rect.right; pos++)
cur[pos] = (cur[pos] / 2) + 0x8;
- cur = GST_BUFFER_DATA (buf) + state->Y_stride * state->vobsub.disp_rect.top;
+ cur = GST_BUFFER_DATA (buf) + strides[0] * state->vobsub.disp_rect.top;
for (pos = state->vobsub.disp_rect.top;
pos <= state->vobsub.disp_rect.bottom; pos++) {
cur[state->vobsub.disp_rect.left] =
(cur[state->vobsub.disp_rect.left] / 2) + 0x8;
cur[state->vobsub.disp_rect.right] =
(cur[state->vobsub.disp_rect.right] / 2) + 0x8;
- cur += state->Y_stride;
+ cur += strides[0];
}
} while (0);
#endif
@@ -595,17 +597,17 @@ gstspu_vobsub_render (GstDVDSpu * dvdspu, GstBuffer * buf)
guint8 *cur;
gint16 pos;
- cur = GST_BUFFER_DATA (buf) + state->Y_stride * state->hl_rect.top;
+ cur = GST_BUFFER_DATA (buf) + strides[0] * state->hl_rect.top;
for (pos = state->hl_rect.left + 1; pos < state->hl_rect.right; pos++)
cur[pos] = (cur[pos] / 2) + 0x8;
- cur = GST_BUFFER_DATA (buf) + state->Y_stride * state->hl_rect.bottom;
+ cur = GST_BUFFER_DATA (buf) + strides[0] * state->hl_rect.bottom;
for (pos = state->hl_rect.left + 1; pos < state->hl_rect.right; pos++)
cur[pos] = (cur[pos] / 2) + 0x8;
- cur = GST_BUFFER_DATA (buf) + state->Y_stride * state->hl_rect.top;
+ cur = GST_BUFFER_DATA (buf) + strides[0] * state->hl_rect.top;
for (pos = state->hl_rect.top; pos <= state->hl_rect.bottom; pos++) {
cur[state->hl_rect.left] = (cur[state->hl_rect.left] / 2) + 0x8;
cur[state->hl_rect.right] = (cur[state->hl_rect.right] / 2) + 0x8;
- cur += state->Y_stride;
+ cur += strides[0];
}
}
#endif
diff --git a/gst/dvdspu/gstspu-vobsub.c b/gst/dvdspu/gstspu-vobsub.c
index 0a2380c9e..b1b76bb2e 100644
--- a/gst/dvdspu/gstspu-vobsub.c
+++ b/gst/dvdspu/gstspu-vobsub.c
@@ -323,13 +323,14 @@ gstspu_vobsub_handle_new_buf (GstDVDSpu * dvdspu, GstClockTime event_ts,
GstBuffer * buf)
{
guint8 *start, *end;
+ gsize size;
SpuState *state = &dvdspu->spu_state;
#if DUMP_DCSQ
gst_dvd_spu_dump_dcsq (dvdspu, event_ts, buf);
#endif
- if (G_UNLIKELY (GST_BUFFER_SIZE (buf) < 4))
+ if (G_UNLIKELY (gst_buffer_get_size (buf) < 4))
goto invalid;
if (state->vobsub.buf != NULL) {
@@ -339,8 +340,8 @@ gstspu_vobsub_handle_new_buf (GstDVDSpu * dvdspu, GstClockTime event_ts,
state->vobsub.buf = buf;
state->vobsub.base_ts = event_ts;
- start = GST_BUFFER_DATA (state->vobsub.buf);
- end = start + GST_BUFFER_SIZE (state->vobsub.buf);
+ start = gst_buffer_map (state->vobsub.buf, &size, NULL, GST_MAP_READ);
+ end = start + size;
/* Configure the first command block in this buffer as our initial blk */
state->vobsub.cur_cmd_blk = GST_READ_UINT16_BE (start + 2);
@@ -351,6 +352,7 @@ gstspu_vobsub_handle_new_buf (GstDVDSpu * dvdspu, GstClockTime event_ts,
g_free (state->vobsub.line_ctrl_i);
state->vobsub.line_ctrl_i = NULL;
}
+ gst_buffer_unmap (state->vobsub.buf, start, size);
return;
invalid:
@@ -363,6 +365,7 @@ gstspu_vobsub_execute_event (GstDVDSpu * dvdspu)
{
guint8 *start, *cmd_blk, *end;
guint16 next_blk;
+ gsize size;
SpuState *state = &dvdspu->spu_state;
if (state->vobsub.buf == NULL)
@@ -372,12 +375,13 @@ gstspu_vobsub_execute_event (GstDVDSpu * dvdspu)
" @ offset %u", GST_TIME_ARGS (state->next_ts),
state->vobsub.cur_cmd_blk);
- start = GST_BUFFER_DATA (state->vobsub.buf);
- end = start + GST_BUFFER_SIZE (state->vobsub.buf);
+ start = gst_buffer_map (state->vobsub.buf, &size, NULL, GST_MAP_READ);
+ end = start + size;
cmd_blk = start + state->vobsub.cur_cmd_blk;
if (G_UNLIKELY (cmd_blk + 5 >= end)) {
+ gst_buffer_unmap (state->vobsub.buf, start, size);
/* Invalid. Finish the buffer and loop again */
gst_dvd_spu_finish_spu_buf (dvdspu);
return FALSE;
@@ -392,9 +396,11 @@ gstspu_vobsub_execute_event (GstDVDSpu * dvdspu)
} else {
/* Next Block points to the current block, so we're finished with this
* SPU buffer */
+ gst_buffer_unmap (state->vobsub.buf, start, size);
gst_dvd_spu_finish_spu_buf (dvdspu);
return FALSE;
}
+ gst_buffer_unmap (state->vobsub.buf, start, size);
return TRUE;
}
diff --git a/gst/dvdspu/gstspu-vobsub.h b/gst/dvdspu/gstspu-vobsub.h
index 9b4196bc7..1a0588cd1 100644
--- a/gst/dvdspu/gstspu-vobsub.h
+++ b/gst/dvdspu/gstspu-vobsub.h
@@ -103,7 +103,7 @@ struct SpuVobsubState {
void gstspu_vobsub_handle_new_buf (GstDVDSpu * dvdspu, GstClockTime event_ts, GstBuffer *buf);
gboolean gstspu_vobsub_execute_event (GstDVDSpu *dvdspu);
-void gstspu_vobsub_render (GstDVDSpu *dvdspu, GstBuffer *buf);
+void gstspu_vobsub_render (GstDVDSpu *dvdspu, GstVideoFrame *frame);
gboolean gstspu_vobsub_handle_dvd_event (GstDVDSpu *dvdspu, GstEvent *event);
void gstspu_vobsub_flush (GstDVDSpu *dvdspu);