dvdsub: port to 0.11

This commit is contained in:
Wim Taymans 2011-10-06 17:24:22 +02:00
parent f99001a05d
commit e06c2d881b
5 changed files with 115 additions and 110 deletions

View file

@ -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)

View file

@ -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

View file

@ -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;

View file

@ -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;
/*

View file

@ -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;