/* GStreamer Musepack decoder plugin * Copyright (C) 2004 Ronald Bultje * * 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 #include #include "gstmusepackreader.h" static mpc_int32_t gst_musepack_reader_peek (void *this, void *ptr, mpc_int32_t size) { GstMusepackDec *musepackdec = GST_MUSEPACK_DEC (this); GstBuffer *buf = NULL; gint read; if (musepackdec->eos) { return 0; } do { if (GST_FLOW_OK != gst_pad_pull_range (musepackdec->sinkpad, musepackdec->offset, size, &buf)) { return 0; } read = GST_BUFFER_SIZE (buf); if (musepackdec->eos || musepackdec->flush_pending || musepackdec->seek_pending) { break; } /* FIX ME: do i have to handle those event in sink_event? */ /* we pipeline doesnt stop after receive EOS */ /* if (read != size) { GstEvent *event; guint32 remaining; gst_bytestream_get_status (bs, &remaining, &event); if (!event) { GST_ELEMENT_ERROR (gst_pad_get_parent (bs->pad), RESOURCE, READ, (NULL), (NULL)); goto done; } switch (GST_EVENT_TYPE (event)) { case GST_EVENT_INTERRUPT: gst_event_unref (event); goto done; case GST_EVENT_EOS: gst_event_unref (event); goto done; case GST_EVENT_FLUSH: gst_event_unref (event); break; case GST_EVENT_DISCONTINUOUS: gst_event_unref (event); break; default: gst_pad_event_default (bs->pad, event); break; } } */ } while (read != size); if (read != 0) { memcpy (ptr, GST_BUFFER_DATA (buf), read); } gst_buffer_unref (buf); return read; } static mpc_int32_t gst_musepack_reader_read (void *this, void *ptr, mpc_int32_t size) { GstMusepackDec *musepackdec = GST_MUSEPACK_DEC (this); gint read; /* read = peek + flush */ if ((read = gst_musepack_reader_peek (this, ptr, size)) > 0) { musepackdec->offset += read; } return read; } static mpc_bool_t gst_musepack_reader_seek (void *this, mpc_int32_t offset) { GstMusepackDec *musepackdec = GST_MUSEPACK_DEC (this); guint8 dummy; /* hacky hack - if we're after typefind, we'll fail because * typefind is still typefinding (heh :) ). So read first. */ gst_musepack_reader_peek (this, &dummy, 1); /* seek */ musepackdec->offset = offset; /* get discont */ if (gst_musepack_reader_peek (this, &dummy, 1) != 1) return FALSE; return TRUE; } static mpc_int32_t gst_musepack_reader_tell (void *this) { GstMusepackDec *musepackdec = GST_MUSEPACK_DEC (this); GstQuery *query; gint64 position; GstFormat format = GST_FORMAT_BYTES; query = gst_query_new_position (GST_FORMAT_BYTES); if (gst_pad_query (musepackdec->sinkpad, query)) { gst_query_parse_position (query, &format, &position); if (format != GST_FORMAT_BYTES) { GstFormat dest_format = GST_FORMAT_BYTES; if (!gst_musepackdec_src_convert (musepackdec->srcpad, format, position, &dest_format, &position)) { position = -1; } } } else { position = -1; } gst_query_unref (query); return position; } static mpc_int32_t gst_musepack_reader_get_size (void *this) { GstMusepackDec *musepackdec = GST_MUSEPACK_DEC (this); GstQuery *query; gint64 duration; GstFormat format = GST_FORMAT_BYTES; query = gst_query_new_duration (GST_FORMAT_BYTES); if (gst_pad_query (musepackdec->sinkpad, query)) { gst_query_parse_duration (query, &format, &duration); if (format != GST_FORMAT_BYTES) { GstFormat dest_format = GST_FORMAT_BYTES; if (!gst_musepackdec_src_convert (musepackdec->srcpad, format, duration, &dest_format, &duration)) { duration = -1; } } } else { duration = -1; } gst_query_unref (query); return duration; } static mpc_bool_t gst_musepack_reader_canseek (void *this) { return TRUE; } void gst_musepack_init_reader (mpc_reader * r, GstMusepackDec * musepackdec) { r->data = musepackdec; r->read = gst_musepack_reader_read; r->seek = gst_musepack_reader_seek; r->tell = gst_musepack_reader_tell; r->get_size = gst_musepack_reader_get_size; r->canseek = gst_musepack_reader_canseek; }