diff options
Diffstat (limited to 'gst/cdxaparse/gstcdxastrip.c')
-rw-r--r-- | gst/cdxaparse/gstcdxastrip.c | 410 |
1 files changed, 0 insertions, 410 deletions
diff --git a/gst/cdxaparse/gstcdxastrip.c b/gst/cdxaparse/gstcdxastrip.c deleted file mode 100644 index 80bf7c87..00000000 --- a/gst/cdxaparse/gstcdxastrip.c +++ /dev/null @@ -1,410 +0,0 @@ -/* GStreamer CDXA sync strippper - * Copyright (C) 2004 Ronald Bultje <rbultje@ronald.bitfreak.net> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> -#include <gst/gst.h> -#include "gstcdxastrip.h" - -static void gst_cdxastrip_base_init (GstCDXAStripClass * klass); -static void gst_cdxastrip_class_init (GstCDXAStripClass * klass); -static void gst_cdxastrip_init (GstCDXAStrip * cdxastrip); - -static const GstEventMask *gst_cdxastrip_get_event_mask (GstPad * pad); -static gboolean gst_cdxastrip_handle_src_event (GstPad * pad, GstEvent * event); -static const GstFormat *gst_cdxastrip_get_src_formats (GstPad * pad); -static const GstQueryType *gst_cdxastrip_get_src_query_types (GstPad * pad); -static gboolean gst_cdxastrip_handle_src_query (GstPad * pad, - GstQueryType type, GstFormat * format, gint64 * value); - -static void gst_cdxastrip_chain (GstPad * pad, GstData * data); -static GstStateChangeReturn gst_cdxastrip_change_state (GstElement * element, - GstStateChange transition); - -static GstStaticPadTemplate sink_template_factory = -GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/x-vcd") - ); - -static GstStaticPadTemplate src_template_factory = -GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/mpeg, " "systemstream = (boolean) TRUE") - ); - -static GstElementClass *parent_class = NULL; - -GType -gst_cdxastrip_get_type (void) -{ - static GType cdxastrip_type = 0; - - if (!cdxastrip_type) { - static const GTypeInfo cdxastrip_info = { - sizeof (GstCDXAStripClass), - (GBaseInitFunc) gst_cdxastrip_base_init, - NULL, - (GClassInitFunc) gst_cdxastrip_class_init, - NULL, - NULL, - sizeof (GstCDXAStrip), - 0, - (GInstanceInitFunc) gst_cdxastrip_init, - }; - - cdxastrip_type = - g_type_register_static (GST_TYPE_ELEMENT, "GstCDXAStrip", - &cdxastrip_info, 0); - } - - return cdxastrip_type; -} - -static void -gst_cdxastrip_base_init (GstCDXAStripClass * klass) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - static const GstElementDetails gst_cdxastrip_details = - GST_ELEMENT_DETAILS ("(S)VCD stream parser", - "Codec/Parser", - "Strip (S)VCD stream from its syncheaders", - "Ronald Bultje <rbultje@ronald.bitfreak.net>"); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&sink_template_factory)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&src_template_factory)); - - gst_element_class_set_details (element_class, &gst_cdxastrip_details); -} - -static void -gst_cdxastrip_class_init (GstCDXAStripClass * klass) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - element_class->change_state = gst_cdxastrip_change_state; -} - -static void -gst_cdxastrip_init (GstCDXAStrip * cdxastrip) -{ - GST_OBJECT_FLAG_SET (cdxastrip, GST_ELEMENT_EVENT_AWARE); - - cdxastrip->sinkpad = - gst_pad_new_from_static_template (&sink_template_factory, "sink"); - gst_pad_set_chain_function (cdxastrip->sinkpad, gst_cdxastrip_chain); - gst_element_add_pad (GST_ELEMENT (cdxastrip), cdxastrip->sinkpad); - - cdxastrip->srcpad = - gst_pad_new_from_static_template (&src_template_factory, "src"); - gst_pad_set_formats_function (cdxastrip->srcpad, - gst_cdxastrip_get_src_formats); - gst_pad_set_event_mask_function (cdxastrip->srcpad, - gst_cdxastrip_get_event_mask); - gst_pad_set_event_function (cdxastrip->srcpad, - gst_cdxastrip_handle_src_event); - gst_pad_set_query_type_function (cdxastrip->srcpad, - gst_cdxastrip_get_src_query_types); - gst_pad_set_query_function (cdxastrip->srcpad, - gst_cdxastrip_handle_src_query); - gst_element_add_pad (GST_ELEMENT (cdxastrip), cdxastrip->srcpad); -} - -/* - * Stuff. - */ - -static const GstFormat * -gst_cdxastrip_get_src_formats (GstPad * pad) -{ - static const GstFormat formats[] = { - GST_FORMAT_BYTES, - 0 - }; - - return formats; -} - -static const GstQueryType * -gst_cdxastrip_get_src_query_types (GstPad * pad) -{ - static const GstQueryType types[] = { - GST_QUERY_TOTAL, - GST_QUERY_POSITION, - 0 - }; - - return types; -} - -static gboolean -gst_cdxastrip_handle_src_query (GstPad * pad, - GstQueryType type, GstFormat * format, gint64 * value) -{ - GstCDXAStrip *cdxa = GST_CDXASTRIP (gst_pad_get_parent (pad)); - - if (!gst_pad_query (GST_PAD_PEER (cdxa->sinkpad), type, format, value)) - return FALSE; - - if (*format != GST_FORMAT_BYTES) - return TRUE; - - switch (type) { - case GST_QUERY_TOTAL: - case GST_QUERY_POSITION:{ - gint num, rest; - - num = *value / GST_CDXA_SECTOR_SIZE; - rest = *value % GST_CDXA_SECTOR_SIZE; - - *value = num * GST_CDXA_DATA_SIZE; - if (rest > GST_CDXA_HEADER_SIZE) { - if (rest >= GST_CDXA_HEADER_SIZE + GST_CDXA_DATA_SIZE) - *value += GST_CDXA_DATA_SIZE; - else - *value += rest - GST_CDXA_HEADER_SIZE; - } - break; - } - default: - break; - } - - return TRUE; -} - -static const GstEventMask * -gst_cdxastrip_get_event_mask (GstPad * pad) -{ - static const GstEventMask masks[] = { - {GST_EVENT_SEEK, GST_SEEK_METHOD_SET | GST_SEEK_FLAG_KEY_UNIT}, - {0,} - }; - - return masks; -} - -static gboolean -gst_cdxastrip_handle_src_event (GstPad * pad, GstEvent * event) -{ - GstCDXAStrip *cdxa = GST_CDXASTRIP (gst_pad_get_parent (pad)); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_SEEK: - switch (GST_EVENT_SEEK_FORMAT (event)) { - case GST_FORMAT_BYTES:{ - GstEvent *new; - gint64 off; - gint num, rest; - - off = GST_EVENT_SEEK_OFFSET (event); - num = off / GST_CDXA_DATA_SIZE; - rest = off % GST_CDXA_DATA_SIZE; - off = num * GST_CDXA_SECTOR_SIZE; - if (rest > 0) - off += rest + GST_CDXA_HEADER_SIZE; - new = gst_event_new_seek (GST_EVENT_SEEK_TYPE (event), off); - gst_event_unref (event); - event = new; - } - default: - break; - } - break; - default: - break; - } - - return gst_pad_send_event (GST_PAD_PEER (cdxa->sinkpad), event); -} - -/* - * A sector is 2352 bytes long and is composed of: - * - * ! sync ! header ! subheader ! data ... ! edc ! - * ! 12 bytes ! 4 bytes ! 8 bytes ! 2324 bytes ! 4 bytes ! - * !-------------------------------------------------------! - * - * We strip the data out of it and send it to the srcpad. - * - * sync : 00 FF FF FF FF FF FF FF FF FF FF 00 - * header : hour minute second mode - * sub-header : track channel sub_mode coding repeat (4 bytes) - * edc : checksum - */ - -GstBuffer * -gst_cdxastrip_strip (GstBuffer * buf) -{ - GstBuffer *sub; - - g_assert (GST_BUFFER_SIZE (buf) >= GST_CDXA_SECTOR_SIZE); - - /* Skip CDXA headers, only keep data. - * FIXME: check sync, resync, ... */ - sub = gst_buffer_create_sub (buf, GST_CDXA_HEADER_SIZE, GST_CDXA_DATA_SIZE); - gst_buffer_unref (buf); - - return sub; -} - -/* - * -1 = no sync (discard buffer), - * otherwise offset indicates syncpoint in buffer. - */ - -gint -gst_cdxastrip_sync (GstBuffer * buf) -{ - guint size, off = 0; - guint8 *data; - - for (size = GST_BUFFER_SIZE (buf), data = GST_BUFFER_DATA (buf); - size >= 12; size--, data++, off++) { - /* we could do a checksum check as well, but who cares... */ - if (!memcmp (data, "\000\377\377\377\377\377\377\377\377\377\377\000", 12)) - return off; - } - - return -1; -} - -/* - * Do stuff. - */ - -static void -gst_cdxastrip_handle_event (GstCDXAStrip * cdxa, GstEvent * event) -{ - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_DISCONTINUOUS:{ - gint64 new_off, off; - - if (gst_event_discont_get_value (event, GST_FORMAT_BYTES, &new_off)) { - GstEvent *new; - gint chunknum, rest; - - chunknum = new_off / GST_CDXA_SECTOR_SIZE; - rest = new_off % GST_CDXA_SECTOR_SIZE; - off = chunknum * GST_CDXA_DATA_SIZE; - if (rest > GST_CDXA_HEADER_SIZE) { - if (rest >= GST_CDXA_HEADER_SIZE + GST_CDXA_DATA_SIZE) - off += GST_CDXA_DATA_SIZE; - else - off += rest - GST_CDXA_HEADER_SIZE; - } - new = gst_event_new_discontinuous (GST_EVENT_DISCONT_NEW_MEDIA (event), - GST_FORMAT_BYTES, new_off, GST_FORMAT_UNDEFINED); - gst_event_unref (event); - event = new; - } - gst_pad_event_default (cdxa->sinkpad, event); - break; - } - case GST_EVENT_FLUSH: - if (cdxa->cache) { - gst_buffer_unref (cdxa->cache); - cdxa->cache = NULL; - } - /* fall-through */ - default: - gst_pad_event_default (cdxa->sinkpad, event); - break; - } -} - -static void -gst_cdxastrip_chain (GstPad * pad, GstData * data) -{ - GstCDXAStrip *cdxa = GST_CDXASTRIP (gst_pad_get_parent (pad)); - GstBuffer *buf, *sub; - gint sync; - - if (GST_IS_EVENT (data)) { - gst_cdxastrip_handle_event (cdxa, GST_EVENT (data)); - return; - } - - buf = GST_BUFFER (data); - if (cdxa->cache) { - buf = gst_buffer_join (cdxa->cache, buf); - } - cdxa->cache = NULL; - - while (buf && GST_BUFFER_SIZE (buf) >= GST_CDXA_SECTOR_SIZE) { - /* sync */ - sync = gst_cdxastrip_sync (buf); - if (sync < 0) { - gst_buffer_unref (buf); - return; - } - sub = gst_buffer_create_sub (buf, sync, GST_BUFFER_SIZE (buf) - sync); - gst_buffer_unref (buf); - buf = sub; - if (GST_BUFFER_SIZE (buf) < GST_CDXA_SECTOR_SIZE) - break; - - /* one chunk */ - sub = gst_cdxastrip_strip (gst_buffer_ref (buf)); - gst_pad_push (cdxa->srcpad, GST_DATA (sub)); - - /* cache */ - if (GST_BUFFER_SIZE (buf) != GST_CDXA_SECTOR_SIZE) { - sub = gst_buffer_create_sub (buf, GST_CDXA_SECTOR_SIZE, - GST_BUFFER_SIZE (buf) - GST_CDXA_SECTOR_SIZE); - } else { - sub = NULL; - } - gst_buffer_unref (buf); - buf = sub; - } - - cdxa->cache = buf; -} - -static GstStateChangeReturn -gst_cdxastrip_change_state (GstElement * element, GstStateChange transition) -{ - GstCDXAStrip *cdxa = GST_CDXASTRIP (element); - - switch (transition) { - case GST_STATE_CHANGE_PAUSED_TO_READY: - if (cdxa->cache) { - gst_buffer_unref (cdxa->cache); - cdxa->cache = NULL; - } - break; - default: - break; - } - - if (parent_class->change_state) - return parent_class->change_state (element, transition); - - return GST_STATE_CHANGE_SUCCESS; -} |