dvdspu: port to 0.11
This commit is contained in:
parent
a9fc805e36
commit
11a7e26fd8
@ -55,7 +55,7 @@ static GstStaticPadTemplate video_sink_factory =
|
|||||||
GST_STATIC_PAD_TEMPLATE ("video",
|
GST_STATIC_PAD_TEMPLATE ("video",
|
||||||
GST_PAD_SINK,
|
GST_PAD_SINK,
|
||||||
GST_PAD_ALWAYS,
|
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 ]")
|
"width = (int) [ 16, 4096 ], " "height = (int) [ 16, 4096 ]")
|
||||||
/* FIXME: Can support YV12 one day too */
|
/* 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",
|
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
|
||||||
GST_PAD_SRC,
|
GST_PAD_SRC,
|
||||||
GST_PAD_ALWAYS,
|
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 ]")
|
"width = (int) [ 16, 4096 ], " "height = (int) [ 16, 4096 ]")
|
||||||
/* FIXME: Can support YV12 one day too */
|
/* FIXME: Can support YV12 one day too */
|
||||||
);
|
);
|
||||||
@ -146,8 +146,6 @@ gst_dvd_spu_init (GstDVDSpu * dvdspu)
|
|||||||
{
|
{
|
||||||
dvdspu->videosinkpad =
|
dvdspu->videosinkpad =
|
||||||
gst_pad_new_from_static_template (&video_sink_factory, "video");
|
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_pad_set_getcaps_function (dvdspu->videosinkpad,
|
||||||
gst_dvd_spu_video_proxy_getcaps);
|
gst_dvd_spu_video_proxy_getcaps);
|
||||||
gst_pad_set_chain_function (dvdspu->videosinkpad, gst_dvd_spu_video_chain);
|
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_new_from_static_template (&subpic_sink_factory, "subpicture");
|
||||||
gst_pad_set_chain_function (dvdspu->subpic_sinkpad, gst_dvd_spu_subpic_chain);
|
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_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->videosinkpad);
|
||||||
gst_element_add_pad (GST_ELEMENT (dvdspu), dvdspu->subpic_sinkpad);
|
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->ref_frame, NULL);
|
||||||
gst_buffer_replace (&dvdspu->pending_frame, NULL);
|
gst_buffer_replace (&dvdspu->pending_frame, NULL);
|
||||||
|
|
||||||
dvdspu->spu_state.fps_n = 25;
|
dvdspu->spu_state.info.fps_n = 25;
|
||||||
dvdspu->spu_state.fps_d = 1;
|
dvdspu->spu_state.info.fps_d = 1;
|
||||||
|
|
||||||
gst_segment_init (&dvdspu->video_seg, GST_FORMAT_UNDEFINED);
|
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));
|
GstDVDSpu *dvdspu = GST_DVD_SPU (gst_pad_get_parent (pad));
|
||||||
gboolean res = FALSE;
|
gboolean res = FALSE;
|
||||||
GstStructure *s;
|
GstVideoInfo info;
|
||||||
gint w, h;
|
|
||||||
gint i;
|
gint i;
|
||||||
gint fps_n, fps_d;
|
|
||||||
SpuState *state;
|
SpuState *state;
|
||||||
|
|
||||||
s = gst_caps_get_structure (caps, 0);
|
if (!gst_video_info_from_caps (&info, caps))
|
||||||
|
|
||||||
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)) {
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
|
||||||
|
|
||||||
DVD_SPU_LOCK (dvdspu);
|
DVD_SPU_LOCK (dvdspu);
|
||||||
|
|
||||||
state = &dvdspu->spu_state;
|
state = &dvdspu->spu_state;
|
||||||
|
|
||||||
state->fps_n = fps_n;
|
state->info = info;
|
||||||
state->fps_d = fps_d;
|
for (i = 0; i < 3; i++) {
|
||||||
|
state->comp_bufs[i] = g_realloc (state->comp_bufs[i],
|
||||||
state->vid_height = h;
|
sizeof (guint32) * info.width);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
DVD_SPU_UNLOCK (dvdspu);
|
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);
|
g_return_val_if_fail (dvdspu != NULL, FALSE);
|
||||||
|
|
||||||
switch (GST_EVENT_TYPE (event)) {
|
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:
|
||||||
case GST_EVENT_CUSTOM_DOWNSTREAM_OOB:
|
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;
|
GstClockTime next_ts = dvdspu->video_seg.position;
|
||||||
|
|
||||||
next_ts += gst_util_uint64_scale_int (GST_SECOND,
|
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,
|
/* 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 */
|
* or else there's nothing to draw, and just return GST_FLOW_OK */
|
||||||
@ -600,16 +587,21 @@ no_ref_frame:
|
|||||||
static void
|
static void
|
||||||
gstspu_render (GstDVDSpu * dvdspu, GstBuffer * buf)
|
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) {
|
switch (dvdspu->spu_input_type) {
|
||||||
case SPU_INPUT_TYPE_VOBSUB:
|
case SPU_INPUT_TYPE_VOBSUB:
|
||||||
gstspu_vobsub_render (dvdspu, buf);
|
gstspu_vobsub_render (dvdspu, &frame);
|
||||||
break;
|
break;
|
||||||
case SPU_INPUT_TYPE_PGS:
|
case SPU_INPUT_TYPE_PGS:
|
||||||
gstspu_pgs_render (dvdspu, buf);
|
gstspu_pgs_render (dvdspu, &frame);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
gst_video_frame_unmap (&frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* With SPU LOCK */
|
/* 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)));
|
GstDVDSpu *dvdspu = (GstDVDSpu *) (gst_object_get_parent (GST_OBJECT (pad)));
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
|
gsize size;
|
||||||
|
|
||||||
g_return_val_if_fail (dvdspu != NULL, GST_FLOW_ERROR);
|
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)
|
if (dvdspu->partial_spu == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
size = gst_buffer_get_size (dvdspu->partial_spu);
|
||||||
|
|
||||||
switch (dvdspu->spu_input_type) {
|
switch (dvdspu->spu_input_type) {
|
||||||
case SPU_INPUT_TYPE_VOBSUB:
|
case SPU_INPUT_TYPE_VOBSUB:
|
||||||
if (GST_BUFFER_SIZE (dvdspu->partial_spu) > 4) {
|
if (size > 4) {
|
||||||
|
guint8 *header[2];
|
||||||
guint16 packet_size;
|
guint16 packet_size;
|
||||||
guint8 *data;
|
|
||||||
|
|
||||||
data = GST_BUFFER_DATA (dvdspu->partial_spu);
|
gst_buffer_extract (dvdspu->partial_spu, 0, header, 2);
|
||||||
packet_size = GST_READ_UINT16_BE (data);
|
packet_size = GST_READ_UINT16_BE (header);
|
||||||
|
if (packet_size == size) {
|
||||||
if (packet_size == GST_BUFFER_SIZE (dvdspu->partial_spu)) {
|
|
||||||
submit_new_spu_packet (dvdspu, dvdspu->partial_spu);
|
submit_new_spu_packet (dvdspu, dvdspu->partial_spu);
|
||||||
dvdspu->partial_spu = NULL;
|
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
|
/* Somehow we collected too much - something is wrong. Drop the
|
||||||
* packet entirely and wait for a new one */
|
* packet entirely and wait for a new one */
|
||||||
GST_DEBUG_OBJECT (dvdspu, "Discarding invalid SPU buffer of size %u",
|
GST_DEBUG_OBJECT (dvdspu, "Discarding invalid SPU buffer of size %u",
|
||||||
GST_BUFFER_SIZE (dvdspu->partial_spu));
|
size);
|
||||||
|
|
||||||
gst_buffer_unref (dvdspu->partial_spu);
|
gst_buffer_unref (dvdspu->partial_spu);
|
||||||
dvdspu->partial_spu = NULL;
|
dvdspu->partial_spu = NULL;
|
||||||
} else {
|
} else {
|
||||||
GST_LOG_OBJECT (dvdspu,
|
GST_LOG_OBJECT (dvdspu,
|
||||||
"SPU buffer claims to be of size %u. Collected %u so far.",
|
"SPU buffer claims to be of size %u. Collected %u so far.",
|
||||||
packet_size, GST_BUFFER_SIZE (dvdspu->partial_spu));
|
packet_size, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -906,34 +900,42 @@ gst_dvd_spu_subpic_chain (GstPad * pad, GstBuffer * buf)
|
|||||||
* we've collected */
|
* we've collected */
|
||||||
guint8 packet_type;
|
guint8 packet_type;
|
||||||
guint16 packet_size;
|
guint16 packet_size;
|
||||||
guint8 *data = GST_BUFFER_DATA (dvdspu->partial_spu);
|
guint8 *data, *ptr, *end;
|
||||||
guint8 *end = data + GST_BUFFER_SIZE (dvdspu->partial_spu);
|
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
|
/* 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 */
|
* marker and resume where we left off next time */
|
||||||
/* FIXME: Move the packet parsing and sanity checking into the format-specific modules */
|
/* FIXME: Move the packet parsing and sanity checking into the format-specific modules */
|
||||||
while (data != end) {
|
while (ptr != end) {
|
||||||
if (data + 3 > end)
|
if (ptr + 3 > end)
|
||||||
break;
|
break;
|
||||||
packet_type = *data++;
|
packet_type = *ptr++;
|
||||||
packet_size = GST_READ_UINT16_BE (data);
|
packet_size = GST_READ_UINT16_BE (ptr);
|
||||||
data += 2;
|
ptr += 2;
|
||||||
if (data + packet_size > end)
|
if (ptr + packet_size > end)
|
||||||
break;
|
break;
|
||||||
data += packet_size;
|
ptr += packet_size;
|
||||||
/* 0x80 is the END command for PGS packets */
|
/* 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 */
|
/* Extra cruft on the end of the packet -> assume invalid */
|
||||||
gst_buffer_unref (dvdspu->partial_spu);
|
invalid = TRUE;
|
||||||
dvdspu->partial_spu = NULL;
|
|
||||||
break;
|
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,
|
GST_DEBUG_OBJECT (dvdspu,
|
||||||
"Have complete PGS packet of size %u. Enqueueing.",
|
"Have complete PGS packet of size %u. Enqueueing.", size);
|
||||||
GST_BUFFER_SIZE (dvdspu->partial_spu));
|
|
||||||
submit_new_spu_packet (dvdspu, dvdspu->partial_spu);
|
submit_new_spu_packet (dvdspu, dvdspu->partial_spu);
|
||||||
dvdspu->partial_spu = NULL;
|
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
|
/* Some events on the subpicture sink pad just get ignored, like
|
||||||
* FLUSH_START */
|
* FLUSH_START */
|
||||||
switch (GST_EVENT_TYPE (event)) {
|
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:
|
||||||
case GST_EVENT_CUSTOM_DOWNSTREAM_OOB:
|
case GST_EVENT_CUSTOM_DOWNSTREAM_OOB:
|
||||||
{
|
{
|
||||||
|
@ -69,10 +69,7 @@ struct SpuState {
|
|||||||
GstClockTime next_ts; /* Next event TS in running time */
|
GstClockTime next_ts; /* Next event TS in running time */
|
||||||
SpuStateFlags flags;
|
SpuStateFlags flags;
|
||||||
|
|
||||||
gint fps_n, fps_d;
|
GstVideoInfo info;
|
||||||
gint16 vid_width, vid_height;
|
|
||||||
gint16 Y_stride, UV_stride;
|
|
||||||
gint16 Y_height, UV_height;
|
|
||||||
|
|
||||||
guint32 *comp_bufs[3]; /* Compositing buffers for U+V & A */
|
guint32 *comp_bufs[3]; /* Compositing buffers for U+V & A */
|
||||||
guint16 comp_left;
|
guint16 comp_left;
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#define __GSTSPU_COMMON_H__
|
#define __GSTSPU_COMMON_H__
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
#include <gst/video/video.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
@ -171,10 +171,11 @@ dump_rle_data (GstDVDSpu * dvdspu, guint8 * data, guint32 len)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
pgs_composition_object_render (PgsCompositionObject * obj, SpuState * state,
|
pgs_composition_object_render (PgsCompositionObject * obj, SpuState * state,
|
||||||
GstBuffer * dest_buf)
|
GstVideoFrame * frame)
|
||||||
{
|
{
|
||||||
SpuColour *colour;
|
SpuColour *colour;
|
||||||
guint8 *planes[3]; /* YUV frame pointers */
|
guint8 *planes[3]; /* YUV frame pointers */
|
||||||
|
gint strides[3];
|
||||||
guint8 *data, *end;
|
guint8 *data, *end;
|
||||||
guint16 obj_w;
|
guint16 obj_w;
|
||||||
guint16 obj_h G_GNUC_UNUSED;
|
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 */
|
* window specified by the object's window_id */
|
||||||
|
|
||||||
/* Store the start of each plane */
|
/* Store the start of each plane */
|
||||||
planes[0] = GST_BUFFER_DATA (dest_buf);
|
planes[0] = GST_VIDEO_FRAME_COMP_DATA (frame, 0);
|
||||||
planes[1] = planes[0] + (state->Y_height * state->Y_stride);
|
planes[1] = GST_VIDEO_FRAME_COMP_DATA (frame, 1);
|
||||||
planes[2] = planes[1] + (state->UV_height * state->UV_stride);
|
planes[2] = GST_VIDEO_FRAME_COMP_DATA (frame, 2);
|
||||||
|
|
||||||
/* Sanity check */
|
strides[0] = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);
|
||||||
g_return_if_fail (planes[2] + (state->UV_height * state->UV_stride) <=
|
strides[1] = GST_VIDEO_FRAME_COMP_STRIDE (frame, 1);
|
||||||
GST_BUFFER_DATA (dest_buf) + GST_BUFFER_SIZE (dest_buf));
|
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[0] += strides[0] * y;
|
||||||
planes[1] += state->UV_stride * (y / 2);
|
planes[1] += strides[1] * (y / 2);
|
||||||
planes[2] += state->UV_stride * (y / 2);
|
planes[2] += strides[2] * (y / 2);
|
||||||
|
|
||||||
/* RLE data: */
|
/* RLE data: */
|
||||||
obj_w = GST_READ_UINT16_BE (data);
|
obj_w = GST_READ_UINT16_BE (data);
|
||||||
obj_h = GST_READ_UINT16_BE (data + 2);
|
obj_h = GST_READ_UINT16_BE (data + 2);
|
||||||
data += 4;
|
data += 4;
|
||||||
|
|
||||||
min_x = MIN (obj->x, state->Y_stride);
|
min_x = MIN (obj->x, strides[0]);
|
||||||
max_x = MIN (obj->x + obj_w, state->Y_stride);
|
max_x = MIN (obj->x + obj_w, strides[0]);
|
||||||
|
|
||||||
state->comp_left = x = min_x;
|
state->comp_left = x = min_x;
|
||||||
state->comp_right = max_x;
|
state->comp_right = max_x;
|
||||||
@ -283,17 +284,17 @@ pgs_composition_object_render (PgsCompositionObject * obj, SpuState * state,
|
|||||||
|
|
||||||
if (!run_len || x > max_x) {
|
if (!run_len || x > max_x) {
|
||||||
x = min_x;
|
x = min_x;
|
||||||
planes[0] += state->Y_stride;
|
planes[0] += strides[0];
|
||||||
|
|
||||||
if (y % 2) {
|
if (y % 2) {
|
||||||
gstspu_blend_comp_buffers (state, planes);
|
gstspu_blend_comp_buffers (state, planes);
|
||||||
gstspu_clear_comp_buffers (state);
|
gstspu_clear_comp_buffers (state);
|
||||||
|
|
||||||
planes[1] += state->UV_stride;
|
planes[1] += strides[1];
|
||||||
planes[2] += state->UV_stride;
|
planes[2] += strides[2];
|
||||||
}
|
}
|
||||||
y++;
|
y++;
|
||||||
if (y >= state->Y_height)
|
if (y >= state->info.height)
|
||||||
return; /* Hit the bottom */
|
return; /* Hit the bottom */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -678,17 +679,20 @@ parse_pgs_packet (GstDVDSpu * dvdspu, guint8 type, guint8 * payload,
|
|||||||
gint
|
gint
|
||||||
gstspu_exec_pgs_buffer (GstDVDSpu * dvdspu, GstBuffer * buf)
|
gstspu_exec_pgs_buffer (GstDVDSpu * dvdspu, GstBuffer * buf)
|
||||||
{
|
{
|
||||||
guint8 *pos, *end;
|
guint8 *data, *pos, *end;
|
||||||
|
gsize size;
|
||||||
guint8 type;
|
guint8 type;
|
||||||
guint16 packet_len;
|
guint16 packet_len;
|
||||||
|
|
||||||
pos = GST_BUFFER_DATA (buf);
|
data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
|
||||||
end = pos + GST_BUFFER_SIZE (buf);
|
|
||||||
|
pos = data;
|
||||||
|
end = pos + size;
|
||||||
|
|
||||||
/* Need at least 3 bytes */
|
/* Need at least 3 bytes */
|
||||||
if (pos + 3 > end) {
|
if (pos + 3 > end) {
|
||||||
PGS_DUMP ("Not enough bytes to be a PGS packet\n");
|
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",
|
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;
|
pos += 2;
|
||||||
|
|
||||||
if (pos + packet_len > end) {
|
if (pos + packet_len > end) {
|
||||||
|
gst_buffer_unmap (buf, data, size);
|
||||||
PGS_DUMP ("Invalid packet length %u (only have %u bytes)\n", packet_len,
|
PGS_DUMP ("Invalid packet length %u (only have %u bytes)\n", packet_len,
|
||||||
end - pos);
|
end - pos);
|
||||||
return -1;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parse_pgs_packet (dvdspu, type, pos, packet_len))
|
if (parse_pgs_packet (dvdspu, type, pos, packet_len))
|
||||||
return -1;
|
goto error;
|
||||||
|
|
||||||
pos += packet_len;
|
pos += packet_len;
|
||||||
} while (pos + 3 <= end);
|
} while (pos + 3 <= end);
|
||||||
|
|
||||||
PGS_DUMP ("End dumping command buffer with %u bytes remaining\n", end - pos);
|
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
|
void
|
||||||
@ -746,7 +758,7 @@ gstspu_pgs_execute_event (GstDVDSpu * dvdspu)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gstspu_pgs_render (GstDVDSpu * dvdspu, GstBuffer * buf)
|
gstspu_pgs_render (GstDVDSpu * dvdspu, GstVideoFrame * frame)
|
||||||
{
|
{
|
||||||
SpuState *state = &dvdspu->spu_state;
|
SpuState *state = &dvdspu->spu_state;
|
||||||
PgsPresentationSegment *ps = &state->pgs.pres_seg;
|
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++) {
|
for (i = 0; i < ps->objects->len; i++) {
|
||||||
PgsCompositionObject *cur =
|
PgsCompositionObject *cur =
|
||||||
&g_array_index (ps->objects, PgsCompositionObject, i);
|
&g_array_index (ps->objects, PgsCompositionObject, i);
|
||||||
pgs_composition_object_render (cur, state, buf);
|
pgs_composition_object_render (cur, state, frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ struct SpuPgsState {
|
|||||||
|
|
||||||
void gstspu_pgs_handle_new_buf (GstDVDSpu * dvdspu, GstClockTime event_ts, GstBuffer *buf);
|
void gstspu_pgs_handle_new_buf (GstDVDSpu * dvdspu, GstClockTime event_ts, GstBuffer *buf);
|
||||||
gboolean gstspu_pgs_execute_event (GstDVDSpu *dvdspu);
|
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);
|
gboolean gstspu_pgs_handle_dvd_event (GstDVDSpu *dvdspu, GstEvent *event);
|
||||||
void gstspu_pgs_flush (GstDVDSpu *dvdspu);
|
void gstspu_pgs_flush (GstDVDSpu *dvdspu);
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ gstspu_vobsub_get_nibble (SpuState * state, guint16 * rle_offset)
|
|||||||
if (G_UNLIKELY (*rle_offset >= state->vobsub.max_offset))
|
if (G_UNLIKELY (*rle_offset >= state->vobsub.max_offset))
|
||||||
return 0; /* Overran the buffer */
|
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 the offset is even, we shift the answer down 4 bits, otherwise not */
|
||||||
if (*rle_offset & 0x01)
|
if (*rle_offset & 0x01)
|
||||||
@ -384,24 +384,29 @@ gstspu_vobsub_clear_comp_buffers (SpuState * state)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gstspu_vobsub_render (GstDVDSpu * dvdspu, GstBuffer * buf)
|
gstspu_vobsub_render (GstDVDSpu * dvdspu, GstVideoFrame * frame)
|
||||||
{
|
{
|
||||||
SpuState *state = &dvdspu->spu_state;
|
SpuState *state = &dvdspu->spu_state;
|
||||||
guint8 *planes[3]; /* YUV frame pointers */
|
guint8 *planes[3]; /* YUV frame pointers */
|
||||||
gint y, last_y;
|
gint y, last_y;
|
||||||
|
gint width, height;
|
||||||
|
gint strides[3];
|
||||||
|
|
||||||
/* Set up our initial state */
|
/* Set up our initial state */
|
||||||
if (G_UNLIKELY (state->vobsub.pix_buf == NULL))
|
if (G_UNLIKELY (state->vobsub.pix_buf == NULL))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Store the start of each plane */
|
/* Store the start of each plane */
|
||||||
planes[0] = GST_BUFFER_DATA (buf);
|
planes[0] = GST_VIDEO_FRAME_COMP_DATA (frame, 0);
|
||||||
planes[1] = planes[0] + (state->Y_height * state->Y_stride);
|
planes[1] = GST_VIDEO_FRAME_COMP_DATA (frame, 1);
|
||||||
planes[2] = planes[1] + (state->UV_height * state->UV_stride);
|
planes[2] = GST_VIDEO_FRAME_COMP_DATA (frame, 2);
|
||||||
|
|
||||||
/* Sanity check */
|
strides[0] = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);
|
||||||
g_return_if_fail (planes[2] + (state->UV_height * state->UV_stride) <=
|
strides[1] = GST_VIDEO_FRAME_COMP_STRIDE (frame, 1);
|
||||||
GST_BUFFER_DATA (buf) + GST_BUFFER_SIZE (buf));
|
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,
|
GST_DEBUG_OBJECT (dvdspu,
|
||||||
"Rendering SPU. disp_rect %d,%d to %d,%d. hl_rect %d,%d to %d,%d",
|
"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.left, state->vobsub.hl_rect.top,
|
||||||
state->vobsub.hl_rect.right, state->vobsub.hl_rect.bottom);
|
state->vobsub.hl_rect.right, state->vobsub.hl_rect.bottom);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (dvdspu, "video size %d,%d", state->vid_width,
|
GST_DEBUG_OBJECT (dvdspu, "video size %d,%d", width, height);
|
||||||
state->vid_height);
|
|
||||||
|
|
||||||
/* When reading RLE data, we track the offset in nibbles... */
|
/* 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[0] = state->vobsub.pix_data[0] * 2;
|
||||||
state->vobsub.cur_offsets[1] = state->vobsub.pix_data[1] * 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 */
|
/* Update all the palette caches */
|
||||||
gstspu_vobsub_update_palettes (dvdspu, state);
|
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;
|
state->vobsub.clip_rect.right = state->vobsub.disp_rect.right;
|
||||||
|
|
||||||
/* center the image when display rectangle exceeds the video width */
|
/* 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;
|
gint left, disp_width;
|
||||||
|
|
||||||
disp_width = state->vobsub.disp_rect.right - state->vobsub.disp_rect.left
|
disp_width = state->vobsub.disp_rect.right - state->vobsub.disp_rect.left
|
||||||
+ 1;
|
+ 1;
|
||||||
left = (state->vid_width - disp_width) / 2;
|
left = (width - disp_width) / 2;
|
||||||
state->vobsub.disp_rect.left = left;
|
state->vobsub.disp_rect.left = left;
|
||||||
state->vobsub.disp_rect.right = left + disp_width - 1;
|
state->vobsub.disp_rect.right = left + disp_width - 1;
|
||||||
|
|
||||||
/* if it clips to the right, shift it left, but only till zero */
|
/* if it clips to the right, shift it left, but only till zero */
|
||||||
if (state->vobsub.disp_rect.right >= state->vid_width) {
|
if (state->vobsub.disp_rect.right >= width) {
|
||||||
gint shift = state->vobsub.disp_rect.right - state->vid_width - 1;
|
gint shift = state->vobsub.disp_rect.right - width - 1;
|
||||||
if (shift > state->vobsub.disp_rect.left)
|
if (shift > state->vobsub.disp_rect.left)
|
||||||
shift = state->vobsub.disp_rect.left;
|
shift = state->vobsub.disp_rect.left;
|
||||||
state->vobsub.disp_rect.left -= shift;
|
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;
|
state->vobsub.clip_rect.right = state->vobsub.disp_rect.right;
|
||||||
|
|
||||||
/* clip right after the shift */
|
/* clip right after the shift */
|
||||||
if (state->vobsub.clip_rect.right >= state->vid_width)
|
if (state->vobsub.clip_rect.right >= width)
|
||||||
state->vobsub.clip_rect.right = state->vid_width - 1;
|
state->vobsub.clip_rect.right = width - 1;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (dvdspu,
|
GST_DEBUG_OBJECT (dvdspu,
|
||||||
"clipping width to %d,%d", state->vobsub.clip_rect.left,
|
"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. */
|
* is and do something more clever. */
|
||||||
state->vobsub.clip_rect.top = state->vobsub.disp_rect.top;
|
state->vobsub.clip_rect.top = state->vobsub.disp_rect.top;
|
||||||
state->vobsub.clip_rect.bottom = state->vobsub.disp_rect.bottom;
|
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 */
|
/* 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)
|
if (shift > state->vobsub.disp_rect.top)
|
||||||
shift = state->vobsub.disp_rect.top;
|
shift = state->vobsub.disp_rect.top;
|
||||||
state->vobsub.disp_rect.top -= shift;
|
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;
|
state->vobsub.clip_rect.bottom = state->vobsub.disp_rect.bottom;
|
||||||
|
|
||||||
/* clip right after the shift */
|
/* clip right after the shift */
|
||||||
if (state->vobsub.clip_rect.bottom >= state->vid_height)
|
if (state->vobsub.clip_rect.bottom >= height)
|
||||||
state->vobsub.clip_rect.bottom = state->vid_height - 1;
|
state->vobsub.clip_rect.bottom = height - 1;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (dvdspu,
|
GST_DEBUG_OBJECT (dvdspu,
|
||||||
"clipping height to %d,%d", state->vobsub.clip_rect.top,
|
"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);
|
last_y = (state->vobsub.disp_rect.bottom - 1) & ~(0x01);
|
||||||
|
|
||||||
/* Update our plane references to the first line of the disp_rect */
|
/* Update our plane references to the first line of the disp_rect */
|
||||||
planes[0] += state->Y_stride * y;
|
planes[0] += strides[0] * y;
|
||||||
planes[1] += state->UV_stride * (y / 2);
|
planes[1] += strides[1] * (y / 2);
|
||||||
planes[2] += state->UV_stride * (y / 2);
|
planes[2] += strides[2] * (y / 2);
|
||||||
|
|
||||||
for (state->vobsub.cur_Y = y; state->vobsub.cur_Y <= last_y;
|
for (state->vobsub.cur_Y = y; state->vobsub.cur_Y <= last_y;
|
||||||
state->vobsub.cur_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]);
|
gstspu_vobsub_render_line (state, planes, &state->vobsub.cur_offsets[0]);
|
||||||
if (!clip) {
|
if (!clip) {
|
||||||
/* Advance the luminance output pointer */
|
/* Advance the luminance output pointer */
|
||||||
planes[0] += state->Y_stride;
|
planes[0] += strides[0];
|
||||||
}
|
}
|
||||||
state->vobsub.cur_Y++;
|
state->vobsub.cur_Y++;
|
||||||
|
|
||||||
@ -539,9 +543,9 @@ gstspu_vobsub_render (GstDVDSpu * dvdspu, GstBuffer * buf)
|
|||||||
gstspu_vobsub_blend_comp_buffers (state, planes);
|
gstspu_vobsub_blend_comp_buffers (state, planes);
|
||||||
|
|
||||||
/* Update all the output pointers */
|
/* Update all the output pointers */
|
||||||
planes[0] += state->Y_stride;
|
planes[0] += strides[0];
|
||||||
planes[1] += state->UV_stride;
|
planes[1] += strides[1];
|
||||||
planes[2] += state->UV_stride;
|
planes[2] += strides[2];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (state->vobsub.cur_Y == state->vobsub.disp_rect.bottom) {
|
if (state->vobsub.cur_Y == state->vobsub.disp_rect.bottom) {
|
||||||
@ -568,24 +572,22 @@ gstspu_vobsub_render (GstDVDSpu * dvdspu, GstBuffer * buf)
|
|||||||
guint8 *cur;
|
guint8 *cur;
|
||||||
gint16 pos;
|
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;
|
for (pos = state->vobsub.disp_rect.left + 1;
|
||||||
pos < state->vobsub.disp_rect.right; pos++)
|
pos < state->vobsub.disp_rect.right; pos++)
|
||||||
cur[pos] = (cur[pos] / 2) + 0x8;
|
cur[pos] = (cur[pos] / 2) + 0x8;
|
||||||
cur =
|
cur = GST_BUFFER_DATA (buf) + strides[0] * state->vobsub.disp_rect.bottom;
|
||||||
GST_BUFFER_DATA (buf) +
|
|
||||||
state->Y_stride * state->vobsub.disp_rect.bottom;
|
|
||||||
for (pos = state->vobsub.disp_rect.left + 1;
|
for (pos = state->vobsub.disp_rect.left + 1;
|
||||||
pos < state->vobsub.disp_rect.right; pos++)
|
pos < state->vobsub.disp_rect.right; pos++)
|
||||||
cur[pos] = (cur[pos] / 2) + 0x8;
|
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;
|
for (pos = state->vobsub.disp_rect.top;
|
||||||
pos <= state->vobsub.disp_rect.bottom; pos++) {
|
pos <= state->vobsub.disp_rect.bottom; pos++) {
|
||||||
cur[state->vobsub.disp_rect.left] =
|
cur[state->vobsub.disp_rect.left] =
|
||||||
(cur[state->vobsub.disp_rect.left] / 2) + 0x8;
|
(cur[state->vobsub.disp_rect.left] / 2) + 0x8;
|
||||||
cur[state->vobsub.disp_rect.right] =
|
cur[state->vobsub.disp_rect.right] =
|
||||||
(cur[state->vobsub.disp_rect.right] / 2) + 0x8;
|
(cur[state->vobsub.disp_rect.right] / 2) + 0x8;
|
||||||
cur += state->Y_stride;
|
cur += strides[0];
|
||||||
}
|
}
|
||||||
} while (0);
|
} while (0);
|
||||||
#endif
|
#endif
|
||||||
@ -595,17 +597,17 @@ gstspu_vobsub_render (GstDVDSpu * dvdspu, GstBuffer * buf)
|
|||||||
guint8 *cur;
|
guint8 *cur;
|
||||||
gint16 pos;
|
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++)
|
for (pos = state->hl_rect.left + 1; pos < state->hl_rect.right; pos++)
|
||||||
cur[pos] = (cur[pos] / 2) + 0x8;
|
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++)
|
for (pos = state->hl_rect.left + 1; pos < state->hl_rect.right; pos++)
|
||||||
cur[pos] = (cur[pos] / 2) + 0x8;
|
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++) {
|
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.left] = (cur[state->hl_rect.left] / 2) + 0x8;
|
||||||
cur[state->hl_rect.right] = (cur[state->hl_rect.right] / 2) + 0x8;
|
cur[state->hl_rect.right] = (cur[state->hl_rect.right] / 2) + 0x8;
|
||||||
cur += state->Y_stride;
|
cur += strides[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -323,13 +323,14 @@ gstspu_vobsub_handle_new_buf (GstDVDSpu * dvdspu, GstClockTime event_ts,
|
|||||||
GstBuffer * buf)
|
GstBuffer * buf)
|
||||||
{
|
{
|
||||||
guint8 *start, *end;
|
guint8 *start, *end;
|
||||||
|
gsize size;
|
||||||
SpuState *state = &dvdspu->spu_state;
|
SpuState *state = &dvdspu->spu_state;
|
||||||
|
|
||||||
#if DUMP_DCSQ
|
#if DUMP_DCSQ
|
||||||
gst_dvd_spu_dump_dcsq (dvdspu, event_ts, buf);
|
gst_dvd_spu_dump_dcsq (dvdspu, event_ts, buf);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (G_UNLIKELY (GST_BUFFER_SIZE (buf) < 4))
|
if (G_UNLIKELY (gst_buffer_get_size (buf) < 4))
|
||||||
goto invalid;
|
goto invalid;
|
||||||
|
|
||||||
if (state->vobsub.buf != NULL) {
|
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.buf = buf;
|
||||||
state->vobsub.base_ts = event_ts;
|
state->vobsub.base_ts = event_ts;
|
||||||
|
|
||||||
start = GST_BUFFER_DATA (state->vobsub.buf);
|
start = gst_buffer_map (state->vobsub.buf, &size, NULL, GST_MAP_READ);
|
||||||
end = start + GST_BUFFER_SIZE (state->vobsub.buf);
|
end = start + size;
|
||||||
|
|
||||||
/* Configure the first command block in this buffer as our initial blk */
|
/* Configure the first command block in this buffer as our initial blk */
|
||||||
state->vobsub.cur_cmd_blk = GST_READ_UINT16_BE (start + 2);
|
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);
|
g_free (state->vobsub.line_ctrl_i);
|
||||||
state->vobsub.line_ctrl_i = NULL;
|
state->vobsub.line_ctrl_i = NULL;
|
||||||
}
|
}
|
||||||
|
gst_buffer_unmap (state->vobsub.buf, start, size);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
invalid:
|
invalid:
|
||||||
@ -363,6 +365,7 @@ gstspu_vobsub_execute_event (GstDVDSpu * dvdspu)
|
|||||||
{
|
{
|
||||||
guint8 *start, *cmd_blk, *end;
|
guint8 *start, *cmd_blk, *end;
|
||||||
guint16 next_blk;
|
guint16 next_blk;
|
||||||
|
gsize size;
|
||||||
SpuState *state = &dvdspu->spu_state;
|
SpuState *state = &dvdspu->spu_state;
|
||||||
|
|
||||||
if (state->vobsub.buf == NULL)
|
if (state->vobsub.buf == NULL)
|
||||||
@ -372,12 +375,13 @@ gstspu_vobsub_execute_event (GstDVDSpu * dvdspu)
|
|||||||
" @ offset %u", GST_TIME_ARGS (state->next_ts),
|
" @ offset %u", GST_TIME_ARGS (state->next_ts),
|
||||||
state->vobsub.cur_cmd_blk);
|
state->vobsub.cur_cmd_blk);
|
||||||
|
|
||||||
start = GST_BUFFER_DATA (state->vobsub.buf);
|
start = gst_buffer_map (state->vobsub.buf, &size, NULL, GST_MAP_READ);
|
||||||
end = start + GST_BUFFER_SIZE (state->vobsub.buf);
|
end = start + size;
|
||||||
|
|
||||||
cmd_blk = start + state->vobsub.cur_cmd_blk;
|
cmd_blk = start + state->vobsub.cur_cmd_blk;
|
||||||
|
|
||||||
if (G_UNLIKELY (cmd_blk + 5 >= end)) {
|
if (G_UNLIKELY (cmd_blk + 5 >= end)) {
|
||||||
|
gst_buffer_unmap (state->vobsub.buf, start, size);
|
||||||
/* Invalid. Finish the buffer and loop again */
|
/* Invalid. Finish the buffer and loop again */
|
||||||
gst_dvd_spu_finish_spu_buf (dvdspu);
|
gst_dvd_spu_finish_spu_buf (dvdspu);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -392,9 +396,11 @@ gstspu_vobsub_execute_event (GstDVDSpu * dvdspu)
|
|||||||
} else {
|
} else {
|
||||||
/* Next Block points to the current block, so we're finished with this
|
/* Next Block points to the current block, so we're finished with this
|
||||||
* SPU buffer */
|
* SPU buffer */
|
||||||
|
gst_buffer_unmap (state->vobsub.buf, start, size);
|
||||||
gst_dvd_spu_finish_spu_buf (dvdspu);
|
gst_dvd_spu_finish_spu_buf (dvdspu);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
gst_buffer_unmap (state->vobsub.buf, start, size);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,7 @@ struct SpuVobsubState {
|
|||||||
|
|
||||||
void gstspu_vobsub_handle_new_buf (GstDVDSpu * dvdspu, GstClockTime event_ts, GstBuffer *buf);
|
void gstspu_vobsub_handle_new_buf (GstDVDSpu * dvdspu, GstClockTime event_ts, GstBuffer *buf);
|
||||||
gboolean gstspu_vobsub_execute_event (GstDVDSpu *dvdspu);
|
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);
|
gboolean gstspu_vobsub_handle_dvd_event (GstDVDSpu *dvdspu, GstEvent *event);
|
||||||
void gstspu_vobsub_flush (GstDVDSpu *dvdspu);
|
void gstspu_vobsub_flush (GstDVDSpu *dvdspu);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user