diff options
author | Wim Taymans <wim.taymans@collabora.co.uk> | 2011-10-08 15:16:25 +0200 |
---|---|---|
committer | Wim Taymans <wim.taymans@collabora.co.uk> | 2011-10-08 15:16:25 +0200 |
commit | 11a7e26fd85c777b63138e39a80ad1c776ecb08c (patch) | |
tree | 61037fe77572bf79134e144599aeb232caef38ba | |
parent | a9fc805e36dbbe7a9209e25a53a0fe7e802d3f87 (diff) |
dvdspu: port to 0.11
-rw-r--r-- | gst/dvdspu/gstdvdspu.c | 129 | ||||
-rw-r--r-- | gst/dvdspu/gstdvdspu.h | 5 | ||||
-rw-r--r-- | gst/dvdspu/gstspu-common.h | 1 | ||||
-rw-r--r-- | gst/dvdspu/gstspu-pgs.c | 64 | ||||
-rw-r--r-- | gst/dvdspu/gstspu-pgs.h | 2 | ||||
-rw-r--r-- | gst/dvdspu/gstspu-vobsub-render.c | 78 | ||||
-rw-r--r-- | gst/dvdspu/gstspu-vobsub.c | 16 | ||||
-rw-r--r-- | gst/dvdspu/gstspu-vobsub.h | 2 |
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); |