mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 01:45:33 +00:00
dvdsub: port to 0.11
This commit is contained in:
parent
f99001a05d
commit
e06c2d881b
5 changed files with 115 additions and 110 deletions
|
@ -210,7 +210,7 @@ dnl *** plug-ins to include ***
|
|||
|
||||
dnl Non ported plugins (non-dependant, then dependant)
|
||||
dnl Make sure you have a space before and after all plugins
|
||||
GST_PLUGINS_NONPORTED=" dvdsub iec958 synaesthesia xingmux \
|
||||
GST_PLUGINS_NONPORTED=" iec958 synaesthesia xingmux \
|
||||
mpegstream realmedia cdio dvdread twolame "
|
||||
AC_SUBST(GST_PLUGINS_NONPORTED)
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
plugin_LTLIBRARIES = libgstdvdsub.la
|
||||
|
||||
libgstdvdsub_la_SOURCES = gstdvdsubdec.c gstdvdsubparse.c
|
||||
libgstdvdsub_la_CFLAGS = $(GST_BASE_CFLAGS) $(GST_CFLAGS)
|
||||
libgstdvdsub_la_LIBADD = $(GST_BASE_LIBS) $(GST_LIBS)
|
||||
libgstdvdsub_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS)
|
||||
libgstdvdsub_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) -lgstvideo-$(GST_MAJORMINOR) $(GST_LIBS)
|
||||
libgstdvdsub_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
||||
libgstdvdsub_la_LIBTOOLFLAGS = --tag=disable-static
|
||||
|
||||
|
|
|
@ -28,7 +28,8 @@
|
|||
#include "gstdvdsubparse.h"
|
||||
#include <string.h>
|
||||
|
||||
GST_BOILERPLATE (GstDvdSubDec, gst_dvd_sub_dec, GstElement, GST_TYPE_ELEMENT);
|
||||
#define gst_dvd_sub_dec_parent_class parent_class
|
||||
G_DEFINE_TYPE (GstDvdSubDec, gst_dvd_sub_dec, GST_TYPE_ELEMENT);
|
||||
|
||||
static gboolean gst_dvd_sub_dec_src_event (GstPad * srcpad, GstEvent * event);
|
||||
static GstFlowReturn gst_dvd_sub_dec_chain (GstPad * pad, GstBuffer * buf);
|
||||
|
@ -37,7 +38,8 @@ static gboolean gst_dvd_sub_dec_handle_dvd_event (GstDvdSubDec * dec,
|
|||
GstEvent * event);
|
||||
static void gst_dvd_sub_dec_finalize (GObject * gobject);
|
||||
static void gst_setup_palette (GstDvdSubDec * dec);
|
||||
static void gst_dvd_sub_dec_merge_title (GstDvdSubDec * dec, GstBuffer * buf);
|
||||
static void gst_dvd_sub_dec_merge_title (GstDvdSubDec * dec,
|
||||
GstVideoFrame * frame);
|
||||
static GstClockTime gst_dvd_sub_dec_get_event_delay (GstDvdSubDec * dec);
|
||||
static gboolean gst_dvd_sub_dec_sink_event (GstPad * pad, GstEvent * event);
|
||||
static gboolean gst_dvd_sub_dec_sink_setcaps (GstPad * pad, GstCaps * caps);
|
||||
|
@ -48,13 +50,8 @@ static GstFlowReturn gst_send_subtitle_frame (GstDvdSubDec * dec,
|
|||
static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("video/x-raw-yuv, format = (fourcc) AYUV, "
|
||||
"width = (int) 720, height = (int) 576, framerate = (fraction) 0/1; "
|
||||
"video/x-raw-rgb, "
|
||||
"width = (int) 720, height = (int) 576, framerate = (fraction) 0/1, "
|
||||
"bpp = (int) 32, endianness = (int) 4321, red_mask = (int) 16711680, "
|
||||
"green_mask = (int) 65280, blue_mask = (int) 255, "
|
||||
" alpha_mask = (int) -16777216, depth = (int) 32")
|
||||
GST_STATIC_CAPS ("video/x-raw, format = (string) { AYUV, ARGB },"
|
||||
"width = (int) 720, height = (int) 576, framerate = (fraction) 0/1")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate subtitle_template = GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
|
@ -101,33 +98,30 @@ typedef struct RLE_state
|
|||
RLE_state;
|
||||
|
||||
static void
|
||||
gst_dvd_sub_dec_base_init (gpointer klass)
|
||||
gst_dvd_sub_dec_class_init (GstDvdSubDecClass * klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gstelement_class = (GstElementClass *) klass;
|
||||
|
||||
gobject_class->finalize = gst_dvd_sub_dec_finalize;
|
||||
|
||||
gst_element_class_add_pad_template (gstelement_class,
|
||||
gst_static_pad_template_get (&src_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_element_class_add_pad_template (gstelement_class,
|
||||
gst_static_pad_template_get (&subtitle_template));
|
||||
|
||||
gst_element_class_set_details_simple (element_class, "DVD subtitle decoder",
|
||||
"Codec/Decoder/Video", "Decodes DVD subtitles into AYUV video frames",
|
||||
gst_element_class_set_details_simple (gstelement_class,
|
||||
"DVD subtitle decoder", "Codec/Decoder/Video",
|
||||
"Decodes DVD subtitles into AYUV video frames",
|
||||
"Wim Taymans <wim.taymans@gmail.com>, "
|
||||
"Jan Schmidt <thaytan@mad.scientist.com>");
|
||||
}
|
||||
|
||||
static void
|
||||
gst_dvd_sub_dec_class_init (GstDvdSubDecClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
|
||||
gobject_class->finalize = gst_dvd_sub_dec_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_dvd_sub_dec_init (GstDvdSubDec * dec, GstDvdSubDecClass * klass)
|
||||
gst_dvd_sub_dec_init (GstDvdSubDec * dec)
|
||||
{
|
||||
GstPadTemplate *tmpl;
|
||||
|
||||
|
@ -137,7 +131,6 @@ gst_dvd_sub_dec_init (GstDvdSubDec * dec, GstDvdSubDecClass * klass)
|
|||
gst_pad_set_event_function (dec->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_dvd_sub_dec_sink_event));
|
||||
gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);
|
||||
gst_pad_set_setcaps_function (dec->sinkpad, gst_dvd_sub_dec_sink_setcaps);
|
||||
|
||||
tmpl = gst_static_pad_template_get (&src_template);
|
||||
dec->srcpad = gst_pad_new_from_template (tmpl, "src");
|
||||
|
@ -152,6 +145,7 @@ gst_dvd_sub_dec_init (GstDvdSubDec * dec, GstDvdSubDecClass * klass)
|
|||
dec->in_height = 576;
|
||||
|
||||
dec->partialbuf = NULL;
|
||||
dec->partialdata = NULL;
|
||||
dec->have_title = FALSE;
|
||||
dec->parse_pos = NULL;
|
||||
dec->forced_display = FALSE;
|
||||
|
@ -174,6 +168,7 @@ gst_dvd_sub_dec_finalize (GObject * gobject)
|
|||
GstDvdSubDec *dec = GST_DVD_SUB_DEC (gobject);
|
||||
|
||||
if (dec->partialbuf) {
|
||||
gst_buffer_unmap (dec->partialbuf, dec->partialdata, dec->partialsize);
|
||||
gst_buffer_unref (dec->partialbuf);
|
||||
dec->partialbuf = NULL;
|
||||
}
|
||||
|
@ -200,13 +195,12 @@ gst_dvd_sub_dec_src_event (GstPad * pad, GstEvent * event)
|
|||
static GstClockTime
|
||||
gst_dvd_sub_dec_get_event_delay (GstDvdSubDec * dec)
|
||||
{
|
||||
guchar *start = GST_BUFFER_DATA (dec->partialbuf);
|
||||
guchar *buf;
|
||||
guint16 ticks;
|
||||
GstClockTime event_delay;
|
||||
|
||||
/* If starting a new buffer, follow the first DCSQ ptr */
|
||||
if (dec->parse_pos == start) {
|
||||
if (dec->parse_pos == dec->partialdata) {
|
||||
buf = dec->parse_pos + dec->data_size;
|
||||
} else {
|
||||
buf = dec->parse_pos;
|
||||
|
@ -232,7 +226,7 @@ gst_dvd_sub_dec_parse_subpic (GstDvdSubDec * dec)
|
|||
{ GST_WARNING("Subtitle stream broken parsing %c", *buf); \
|
||||
broken = TRUE; break; }
|
||||
|
||||
guchar *start = GST_BUFFER_DATA (dec->partialbuf);
|
||||
guchar *start = dec->partialdata;
|
||||
guchar *buf;
|
||||
guchar *end;
|
||||
gboolean broken = FALSE;
|
||||
|
@ -568,18 +562,20 @@ gst_draw_rle_line (GstDvdSubDec * dec, guchar * buffer, RLE_state * state)
|
|||
* frame buffer.
|
||||
*/
|
||||
static void
|
||||
gst_dvd_sub_dec_merge_title (GstDvdSubDec * dec, GstBuffer * buf)
|
||||
gst_dvd_sub_dec_merge_title (GstDvdSubDec * dec, GstVideoFrame * frame)
|
||||
{
|
||||
gint y;
|
||||
gint Y_stride = 4 * dec->in_width;
|
||||
guchar *buffer = GST_BUFFER_DATA (dec->partialbuf);
|
||||
|
||||
gint Y_stride;
|
||||
guchar *buffer = dec->partialdata;
|
||||
gint hl_top, hl_bottom;
|
||||
gint last_y;
|
||||
RLE_state state;
|
||||
guint8 *Y_data;;
|
||||
|
||||
GST_DEBUG_OBJECT (dec, "Merging subtitle on frame at time %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
|
||||
GST_DEBUG_OBJECT (dec, "Merging subtitle on frame");
|
||||
|
||||
Y_data = GST_VIDEO_FRAME_PLANE_DATA (frame, 0);
|
||||
Y_stride = GST_VIDEO_FRAME_PLANE_STRIDE (frame, 0);
|
||||
|
||||
state.id = 0;
|
||||
state.aligned = 1;
|
||||
|
@ -641,7 +637,7 @@ gst_dvd_sub_dec_merge_title (GstDvdSubDec * dec, GstBuffer * buf)
|
|||
last_y = MIN (dec->bottom, dec->in_height);
|
||||
|
||||
y = dec->top;
|
||||
state.target = GST_BUFFER_DATA (buf) + 4 * dec->left + (y * Y_stride);
|
||||
state.target = Y_data + 4 * dec->left + (y * Y_stride);
|
||||
|
||||
/* Now draw scanlines until we hit last_y or end of RLE data */
|
||||
for (; ((state.offset[1] < dec->data_size + 2) && (y <= last_y)); y++) {
|
||||
|
@ -668,11 +664,16 @@ static void
|
|||
gst_send_empty_fill (GstDvdSubDec * dec, GstClockTime ts)
|
||||
{
|
||||
if (dec->next_ts < ts) {
|
||||
GstSegment seg;
|
||||
|
||||
GST_LOG_OBJECT (dec, "Sending newsegment update to advance time to %"
|
||||
GST_TIME_FORMAT, GST_TIME_ARGS (ts));
|
||||
|
||||
gst_pad_push_event (dec->srcpad,
|
||||
gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_TIME, ts, -1, ts));
|
||||
gst_segment_init (&seg, GST_FORMAT_TIME);
|
||||
seg.start = ts;
|
||||
seg.time = ts;
|
||||
|
||||
gst_pad_push_event (dec->srcpad, gst_event_new_segment (&seg));
|
||||
}
|
||||
dec->next_ts = ts;
|
||||
}
|
||||
|
@ -682,6 +683,8 @@ gst_send_subtitle_frame (GstDvdSubDec * dec, GstClockTime end_ts)
|
|||
{
|
||||
GstFlowReturn flow;
|
||||
GstBuffer *out_buf;
|
||||
GstVideoFrame frame;
|
||||
guint8 *data;
|
||||
gint x, y;
|
||||
|
||||
g_assert (dec->have_title);
|
||||
|
@ -693,19 +696,16 @@ gst_send_subtitle_frame (GstDvdSubDec * dec, GstClockTime end_ts)
|
|||
goto out;
|
||||
}
|
||||
|
||||
flow = gst_pad_alloc_buffer_and_set_caps (dec->srcpad, 0,
|
||||
4 * dec->in_width * dec->in_height, GST_PAD_CAPS (dec->srcpad), &out_buf);
|
||||
out_buf =
|
||||
gst_buffer_new_allocate (NULL, 4 * GST_VIDEO_INFO_SIZE (&dec->info), 3);
|
||||
gst_video_frame_map (&frame, &dec->info, out_buf, GST_MAP_READWRITE);
|
||||
|
||||
if (flow != GST_FLOW_OK) {
|
||||
GST_DEBUG_OBJECT (dec, "alloc buffer failed: flow = %s",
|
||||
gst_flow_get_name (flow));
|
||||
goto out;
|
||||
}
|
||||
data = GST_VIDEO_FRAME_PLANE_DATA (&frame, 0);
|
||||
|
||||
/* Clear the buffer */
|
||||
/* FIXME - move this into the buffer rendering code */
|
||||
for (y = 0; y < dec->in_height; y++) {
|
||||
guchar *line = GST_BUFFER_DATA (out_buf) + 4 * dec->in_width * y;
|
||||
guchar *line = data + 4 * dec->in_width * y;
|
||||
|
||||
for (x = 0; x < dec->in_width; x++) {
|
||||
line[0] = 0; /* A */
|
||||
|
@ -726,9 +726,11 @@ gst_send_subtitle_frame (GstDvdSubDec * dec, GstClockTime end_ts)
|
|||
/* FIXME: do we really want to honour the forced_display flag
|
||||
* for subtitles streans? */
|
||||
if (dec->visible || dec->forced_display) {
|
||||
gst_dvd_sub_dec_merge_title (dec, out_buf);
|
||||
gst_dvd_sub_dec_merge_title (dec, &frame);
|
||||
}
|
||||
|
||||
gst_video_frame_unmap (&frame);
|
||||
|
||||
dec->buf_dirty = FALSE;
|
||||
|
||||
GST_BUFFER_TIMESTAMP (out_buf) = dec->next_ts;
|
||||
|
@ -744,8 +746,6 @@ gst_send_subtitle_frame (GstDvdSubDec * dec, GstClockTime end_ts)
|
|||
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (out_buf)),
|
||||
GST_BUFFER_DURATION (out_buf));
|
||||
|
||||
gst_buffer_set_caps (out_buf, GST_PAD_CAPS (dec->srcpad));
|
||||
|
||||
flow = gst_pad_push (dec->srcpad, out_buf);
|
||||
|
||||
out:
|
||||
|
@ -807,7 +807,7 @@ gst_dvd_sub_dec_chain (GstPad * pad, GstBuffer * buf)
|
|||
dec = GST_DVD_SUB_DEC (GST_PAD_PARENT (pad));
|
||||
|
||||
GST_DEBUG_OBJECT (dec, "Have buffer of size %d, ts %"
|
||||
GST_TIME_FORMAT ", dur %" G_GINT64_FORMAT, GST_BUFFER_SIZE (buf),
|
||||
GST_TIME_FORMAT ", dur %" G_GINT64_FORMAT, gst_buffer_get_size (buf),
|
||||
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), GST_BUFFER_DURATION (buf));
|
||||
|
||||
if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
|
||||
|
@ -820,6 +820,7 @@ gst_dvd_sub_dec_chain (GstPad * pad, GstBuffer * buf)
|
|||
}
|
||||
|
||||
if (dec->have_title) {
|
||||
gst_buffer_unmap (dec->partialbuf, dec->partialdata, dec->partialsize);
|
||||
gst_buffer_unref (dec->partialbuf);
|
||||
dec->partialbuf = NULL;
|
||||
dec->have_title = FALSE;
|
||||
|
@ -832,14 +833,18 @@ gst_dvd_sub_dec_chain (GstPad * pad, GstBuffer * buf)
|
|||
if (dec->partialbuf) {
|
||||
GstBuffer *merge;
|
||||
|
||||
gst_buffer_unmap (dec->partialbuf, dec->partialdata, dec->partialsize);
|
||||
merge = gst_buffer_join (dec->partialbuf, buf);
|
||||
dec->partialbuf = merge;
|
||||
} else {
|
||||
dec->partialbuf = buf;
|
||||
}
|
||||
|
||||
data = GST_BUFFER_DATA (dec->partialbuf);
|
||||
size = GST_BUFFER_SIZE (dec->partialbuf);
|
||||
dec->partialdata =
|
||||
gst_buffer_map (dec->partialbuf, &dec->partialsize, NULL, GST_MAP_READ);
|
||||
|
||||
data = dec->partialdata;
|
||||
size = dec->partialsize;
|
||||
|
||||
if (size > 4) {
|
||||
dec->packet_size = GST_READ_UINT16_BE (data);
|
||||
|
@ -873,21 +878,20 @@ gst_dvd_sub_dec_sink_setcaps (GstPad * pad, GstCaps * caps)
|
|||
{
|
||||
GstDvdSubDec *dec = GST_DVD_SUB_DEC (gst_pad_get_parent (pad));
|
||||
gboolean ret = FALSE;
|
||||
guint32 fourcc = GST_MAKE_FOURCC ('A', 'Y', 'U', 'V');
|
||||
GstCaps *out_caps = NULL, *peer_caps = NULL;
|
||||
|
||||
GST_DEBUG_OBJECT (dec, "setcaps called with %" GST_PTR_FORMAT, caps);
|
||||
|
||||
dec->out_fourcc = fourcc;
|
||||
out_caps = gst_caps_new_simple ("video/x-raw-yuv",
|
||||
out_caps = gst_caps_new_simple ("video/x-raw",
|
||||
"format", G_TYPE_STRING, "AYUV",
|
||||
"width", G_TYPE_INT, dec->in_width,
|
||||
"height", G_TYPE_INT, dec->in_height,
|
||||
"format", GST_TYPE_FOURCC, dec->out_fourcc,
|
||||
"framerate", GST_TYPE_FRACTION, 0, 1, NULL);
|
||||
|
||||
peer_caps = gst_pad_get_allowed_caps (dec->srcpad);
|
||||
if (G_LIKELY (peer_caps)) {
|
||||
guint i = 0, n = 0;
|
||||
|
||||
n = gst_caps_get_size (peer_caps);
|
||||
GST_DEBUG_OBJECT (dec, "peer allowed caps (%u structure(s)) are %"
|
||||
GST_PTR_FORMAT, n, peer_caps);
|
||||
|
@ -895,25 +899,18 @@ gst_dvd_sub_dec_sink_setcaps (GstPad * pad, GstCaps * caps)
|
|||
for (i = 0; i < n; i++) {
|
||||
GstStructure *s = gst_caps_get_structure (peer_caps, i);
|
||||
/* Check if the peer pad support ARGB format, if yes change caps */
|
||||
if (gst_structure_has_name (s, "video/x-raw-rgb") &&
|
||||
gst_structure_has_field (s, "alpha_mask")) {
|
||||
if (gst_structure_has_name (s, "video/x-raw")) {
|
||||
gst_caps_unref (out_caps);
|
||||
GST_DEBUG_OBJECT (dec, "trying with fourcc %" GST_FOURCC_FORMAT,
|
||||
GST_FOURCC_ARGS (fourcc));
|
||||
out_caps = gst_caps_new_simple ("video/x-raw-rgb",
|
||||
GST_DEBUG_OBJECT (dec, "trying with ARGB");
|
||||
|
||||
out_caps = gst_caps_new_simple ("video/x-raw",
|
||||
"format", G_TYPE_STRING, "ARGB",
|
||||
"width", G_TYPE_INT, dec->in_width,
|
||||
"height", G_TYPE_INT, dec->in_height,
|
||||
"framerate", GST_TYPE_FRACTION, 0, 1,
|
||||
"bpp", G_TYPE_INT, 32,
|
||||
"depth", G_TYPE_INT, 32,
|
||||
"red_mask", G_TYPE_INT, 16711680,
|
||||
"green_mask", G_TYPE_INT, 65280,
|
||||
"blue_mask", G_TYPE_INT, 255,
|
||||
"alpha_mask", G_TYPE_INT, -16777216,
|
||||
"endianness", G_TYPE_INT, G_BIG_ENDIAN, NULL);
|
||||
"framerate", GST_TYPE_FRACTION, 0, 1, NULL);
|
||||
|
||||
if (gst_pad_peer_accept_caps (dec->srcpad, out_caps)) {
|
||||
GST_DEBUG_OBJECT (dec, "peer accepted format %" GST_FOURCC_FORMAT,
|
||||
GST_FOURCC_ARGS (fourcc));
|
||||
GST_DEBUG_OBJECT (dec, "peer accepted ARGB");
|
||||
/* If ARGB format then set the flag */
|
||||
dec->use_ARGB = TRUE;
|
||||
break;
|
||||
|
@ -925,7 +922,7 @@ gst_dvd_sub_dec_sink_setcaps (GstPad * pad, GstCaps * caps)
|
|||
GST_DEBUG_OBJECT (dec, "setting caps downstream to %" GST_PTR_FORMAT,
|
||||
out_caps);
|
||||
if (gst_pad_set_caps (dec->srcpad, out_caps)) {
|
||||
dec->out_fourcc = fourcc;
|
||||
gst_video_info_from_caps (&dec->info, out_caps);
|
||||
} else {
|
||||
GST_WARNING_OBJECT (dec, "failed setting downstream caps");
|
||||
gst_caps_unref (out_caps);
|
||||
|
@ -949,12 +946,19 @@ gst_dvd_sub_dec_sink_event (GstPad * pad, GstEvent * event)
|
|||
GST_LOG_OBJECT (dec, "%s event", GST_EVENT_TYPE_NAME (event));
|
||||
|
||||
switch (GST_EVENT_TYPE (event)) {
|
||||
case GST_EVENT_CAPS:
|
||||
{
|
||||
GstCaps *caps;
|
||||
|
||||
gst_event_parse_caps (event, &caps);
|
||||
ret = gst_dvd_sub_dec_sink_setcaps (pad, caps);
|
||||
gst_event_unref (event);
|
||||
break;
|
||||
}
|
||||
case GST_EVENT_CUSTOM_DOWNSTREAM:{
|
||||
GstClockTime ts = GST_EVENT_TIMESTAMP (event);
|
||||
|
||||
if (event->structure != NULL &&
|
||||
gst_structure_has_name (event->structure, "application/x-gst-dvd")) {
|
||||
|
||||
if (gst_event_has_name (event, "application/x-gst-dvd")) {
|
||||
if (GST_CLOCK_TIME_IS_VALID (ts))
|
||||
gst_dvd_sub_dec_advance_time (dec, ts);
|
||||
|
||||
|
@ -969,14 +973,13 @@ gst_dvd_sub_dec_sink_event (GstPad * pad, GstEvent * event)
|
|||
ret = gst_pad_event_default (pad, event);
|
||||
break;
|
||||
}
|
||||
case GST_EVENT_NEWSEGMENT:{
|
||||
gboolean update;
|
||||
GstFormat format;
|
||||
gint64 start, stop, pos;
|
||||
case GST_EVENT_SEGMENT:
|
||||
{
|
||||
GstSegment seg;
|
||||
|
||||
gst_event_parse_new_segment (event, &update, NULL, &format, &start,
|
||||
&stop, &pos);
|
||||
gst_event_copy_segment (event, &seg);
|
||||
|
||||
#if 0
|
||||
if (update) {
|
||||
/* update ... advance time */
|
||||
if (GST_CLOCK_TIME_IS_VALID (pos)) {
|
||||
|
@ -990,20 +993,24 @@ gst_dvd_sub_dec_sink_event (GstPad * pad, GstEvent * event)
|
|||
}
|
||||
gst_event_unref (event);
|
||||
ret = TRUE;
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
/* not just an update ... */
|
||||
|
||||
/* Turn off forced highlight display */
|
||||
// dec->forced_display = 0;
|
||||
// dec->current_button = 0;
|
||||
if (dec->partialbuf) {
|
||||
gst_buffer_unmap (dec->partialbuf, dec->partialdata,
|
||||
dec->partialsize);
|
||||
gst_buffer_unref (dec->partialbuf);
|
||||
dec->partialbuf = NULL;
|
||||
dec->have_title = FALSE;
|
||||
}
|
||||
|
||||
if (GST_CLOCK_TIME_IS_VALID (pos))
|
||||
dec->next_ts = pos;
|
||||
if (GST_CLOCK_TIME_IS_VALID (seg.time))
|
||||
dec->next_ts = seg.time;
|
||||
else
|
||||
dec->next_ts = GST_CLOCK_TIME_NONE;
|
||||
|
||||
|
@ -1020,6 +1027,7 @@ gst_dvd_sub_dec_sink_event (GstPad * pad, GstEvent * event)
|
|||
dec->current_button = 0;
|
||||
|
||||
if (dec->partialbuf) {
|
||||
gst_buffer_unmap (dec->partialbuf, dec->partialdata, dec->partialsize);
|
||||
gst_buffer_unref (dec->partialbuf);
|
||||
dec->partialbuf = NULL;
|
||||
dec->have_title = FALSE;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
*/
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/video/video.h>
|
||||
|
||||
#define GST_TYPE_DVD_SUB_DEC (gst_dvd_sub_dec_get_type())
|
||||
#define GST_DVD_SUB_DEC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DVD_SUB_DEC,GstDvdSubDec))
|
||||
|
@ -50,6 +51,8 @@ struct _GstDvdSubDec
|
|||
|
||||
/* Collect together subtitle buffers until we have a full control sequence */
|
||||
GstBuffer *partialbuf;
|
||||
guint8 *partialdata;
|
||||
gsize partialsize;
|
||||
gboolean have_title;
|
||||
|
||||
guchar subtitle_index[4];
|
||||
|
@ -64,8 +67,8 @@ struct _GstDvdSubDec
|
|||
Color_val palette_cache_rgb[4];
|
||||
Color_val hl_palette_cache_rgb[4];
|
||||
|
||||
GstVideoInfo info;
|
||||
gboolean use_ARGB;
|
||||
guint32 out_fourcc;
|
||||
GstClockTime next_ts;
|
||||
|
||||
/*
|
||||
|
|
|
@ -49,23 +49,9 @@ static GstFlowReturn gst_dvd_sub_parse_chain (GstPad * pad, GstBuffer * buf);
|
|||
|
||||
static GstStateChangeReturn gst_dvd_sub_parse_change_state (GstElement *
|
||||
element, GstStateChange transition);
|
||||
GST_BOILERPLATE (GstDvdSubParse, gst_dvd_sub_parse, GstElement,
|
||||
GST_TYPE_ELEMENT);
|
||||
|
||||
static void
|
||||
gst_dvd_sub_parse_base_init (gpointer g_class)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&src_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&sink_template));
|
||||
|
||||
gst_element_class_set_details_simple (element_class, "DVD subtitle parser",
|
||||
"Codec/Parser/Subtitle", "Parses and packetizes DVD subtitle streams",
|
||||
"Mark Nauwelaerts <mnauw@users.sourceforge.net>");
|
||||
}
|
||||
#define gst_dvd_sub_parse_parent_class parent_class
|
||||
G_DEFINE_TYPE (GstDvdSubParse, gst_dvd_sub_parse, GST_TYPE_ELEMENT);
|
||||
|
||||
static void
|
||||
gst_dvd_sub_parse_class_init (GstDvdSubParseClass * klass)
|
||||
|
@ -83,6 +69,15 @@ gst_dvd_sub_parse_class_init (GstDvdSubParseClass * klass)
|
|||
|
||||
gstelement_class->change_state =
|
||||
GST_DEBUG_FUNCPTR (gst_dvd_sub_parse_change_state);
|
||||
|
||||
gst_element_class_add_pad_template (gstelement_class,
|
||||
gst_static_pad_template_get (&src_template));
|
||||
gst_element_class_add_pad_template (gstelement_class,
|
||||
gst_static_pad_template_get (&sink_template));
|
||||
|
||||
gst_element_class_set_details_simple (gstelement_class, "DVD subtitle parser",
|
||||
"Codec/Parser/Subtitle", "Parses and packetizes DVD subtitle streams",
|
||||
"Mark Nauwelaerts <mnauw@users.sourceforge.net>");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -97,7 +92,7 @@ gst_dvd_sub_parse_finalize (GObject * object)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_dvd_sub_parse_init (GstDvdSubParse * parse, GstDvdSubParseClass * klass)
|
||||
gst_dvd_sub_parse_init (GstDvdSubParse * parse)
|
||||
{
|
||||
parse->sinkpad = gst_pad_new_from_static_template (&sink_template, "sink");
|
||||
gst_pad_set_chain_function (parse->sinkpad,
|
||||
|
@ -159,14 +154,14 @@ gst_dvd_sub_parse_chain (GstPad * pad, GstBuffer * buf)
|
|||
adapter = parse->adapter;
|
||||
|
||||
GST_LOG_OBJECT (parse, "%4u bytes, ts: %" GST_TIME_FORMAT,
|
||||
GST_BUFFER_SIZE (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
|
||||
gst_buffer_get_size (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
|
||||
|
||||
gst_adapter_push (adapter, buf);
|
||||
|
||||
if (!parse->needed) {
|
||||
const guint8 *data;
|
||||
guint8 data[2];
|
||||
|
||||
data = gst_adapter_peek (adapter, 2);
|
||||
gst_adapter_copy (adapter, data, 0, 2);
|
||||
parse->needed = GST_READ_UINT16_BE (data);
|
||||
}
|
||||
|
||||
|
@ -190,7 +185,6 @@ gst_dvd_sub_parse_chain (GstPad * pad, GstBuffer * buf)
|
|||
}
|
||||
outbuf = gst_adapter_take_buffer (adapter, parse->needed);
|
||||
/* decorate buffer */
|
||||
gst_buffer_set_caps (outbuf, GST_PAD_CAPS (parse->srcpad));
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = parse->stamp;
|
||||
/* reset state */
|
||||
parse->stamp = GST_CLOCK_TIME_NONE;
|
||||
|
|
Loading…
Reference in a new issue