mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-09 10:59:39 +00:00
fde9b0096c
Original commit message from CVS: * ext/ogg/gstoggdemux.c: (gst_ogg_demux_submit_buffer), (gst_ogg_demux_get_data), (gst_ogg_demux_get_next_page), (gst_ogg_demux_get_prev_page), (gst_ogg_demux_do_seek), (gst_ogg_demux_perform_seek), (gst_ogg_demux_bisect_forward_serialno), (gst_ogg_demux_read_chain), (gst_ogg_demux_read_end_chain), (gst_ogg_demux_find_chains), (gst_ogg_demux_handle_page), (gst_ogg_demux_chain), (gst_ogg_demux_combine_flows), (gst_ogg_demux_loop_reverse), (gst_ogg_demux_loop): * ext/ogg/gstoggdemux.h: Properly propagate streaming errors when we are scanning the file for chains so that we don't crash when shut down. Might fix some crashers when quickly switching oggs in RB such as #332503 and #378436.
179 lines
5.4 KiB
C
179 lines
5.4 KiB
C
/* GStreamer
|
|
* Copyright (C) 2004 Wim Taymans <wim@fluendo.com>
|
|
*
|
|
* gstoggdemux.c: ogg stream demuxer
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
#ifndef __GST_OGG_DEMUX_H__
|
|
#define __GST_OGG_DEMUX_H__
|
|
|
|
#include <ogg/ogg.h>
|
|
|
|
#include <gst/gst.h>
|
|
|
|
G_BEGIN_DECLS
|
|
|
|
#define GST_TYPE_OGG_PAD (gst_ogg_pad_get_type())
|
|
#define GST_OGG_PAD(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OGG_PAD, GstOggPad))
|
|
#define GST_OGG_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OGG_PAD, GstOggPad))
|
|
#define GST_IS_OGG_PAD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OGG_PAD))
|
|
#define GST_IS_OGG_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OGG_PAD))
|
|
|
|
typedef struct _GstOggPad GstOggPad;
|
|
typedef struct _GstOggPadClass GstOggPadClass;
|
|
|
|
#define GST_TYPE_OGG_DEMUX (gst_ogg_demux_get_type())
|
|
#define GST_OGG_DEMUX(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OGG_DEMUX, GstOggDemux))
|
|
#define GST_OGG_DEMUX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OGG_DEMUX, GstOggDemux))
|
|
#define GST_IS_OGG_DEMUX(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OGG_DEMUX))
|
|
#define GST_IS_OGG_DEMUX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OGG_DEMUX))
|
|
|
|
static GType gst_ogg_demux_get_type (void);
|
|
|
|
typedef struct _GstOggDemux GstOggDemux;
|
|
typedef struct _GstOggDemuxClass GstOggDemuxClass;
|
|
typedef struct _GstOggChain GstOggChain;
|
|
|
|
/* all information needed for one ogg chain (relevant for chained bitstreams) */
|
|
struct _GstOggChain
|
|
{
|
|
GstOggDemux *ogg;
|
|
|
|
gint64 offset; /* starting offset of chain */
|
|
gint64 end_offset; /* end offset of chain */
|
|
gint64 bytes; /* number of bytes */
|
|
|
|
gboolean have_bos;
|
|
|
|
GArray *streams;
|
|
|
|
GstClockTime total_time; /* the total time of this chain, this is the MAX of
|
|
the totals of all streams */
|
|
GstClockTime begin_time; /* when this chain starts in the stream */
|
|
|
|
GstClockTime segment_start; /* the timestamp of the first sample, this is the MIN of
|
|
the start times of all streams. */
|
|
GstClockTime segment_stop; /* the timestamp of the last page, this is the MAX of the
|
|
streams. */
|
|
};
|
|
|
|
/* different modes for the pad */
|
|
typedef enum
|
|
{
|
|
GST_OGG_PAD_MODE_INIT, /* we are feeding our internal decoder to get info */
|
|
GST_OGG_PAD_MODE_STREAMING, /* we are streaming buffers to the outside */
|
|
} GstOggPadMode;
|
|
|
|
/* all information needed for one ogg stream */
|
|
struct _GstOggPad
|
|
{
|
|
GstPad pad; /* subclass GstPad */
|
|
|
|
gboolean have_type;
|
|
GstOggPadMode mode;
|
|
|
|
GstPad *elem_pad; /* sinkpad of internal element */
|
|
GstElement *element; /* internal element */
|
|
GstPad *elem_out; /* our sinkpad to receive buffers form the internal element */
|
|
|
|
GstOggChain *chain; /* the chain we are part of */
|
|
GstOggDemux *ogg; /* the ogg demuxer we are part of */
|
|
|
|
GList *headers;
|
|
|
|
gboolean is_skeleton;
|
|
gboolean have_fisbone;
|
|
gint64 granulerate_n;
|
|
gint64 granulerate_d;
|
|
guint32 preroll;
|
|
guint granuleshift;
|
|
|
|
gint serialno;
|
|
gint64 packetno;
|
|
gint64 current_granule;
|
|
|
|
GstClockTime start_time; /* the timestamp of the first sample */
|
|
|
|
gint64 first_granule; /* the granulepos of first page == first sample in next page */
|
|
GstClockTime first_time; /* the timestamp of the second page or granuletime of first page */
|
|
|
|
ogg_stream_state stream;
|
|
GList *continued;
|
|
|
|
gboolean discont;
|
|
GstFlowReturn last_ret; /* last return of _pad_push() */
|
|
|
|
gboolean dynamic; /* True if the internal element had dynamic pads */
|
|
guint padaddedid; /* The signal id for element::pad-added */
|
|
};
|
|
|
|
struct _GstOggPadClass
|
|
{
|
|
GstPadClass parent_class;
|
|
};
|
|
|
|
#define GST_CHAIN_LOCK(ogg) g_mutex_lock((ogg)->chain_lock)
|
|
#define GST_CHAIN_UNLOCK(ogg) g_mutex_unlock((ogg)->chain_lock)
|
|
|
|
struct _GstOggDemux
|
|
{
|
|
GstElement element;
|
|
|
|
GstPad *sinkpad;
|
|
|
|
gint64 length;
|
|
gint64 offset;
|
|
|
|
gboolean seekable;
|
|
gboolean running;
|
|
|
|
gboolean need_chains;
|
|
|
|
/* state */
|
|
GMutex *chain_lock; /* we need the lock to protect the chains */
|
|
GArray *chains; /* list of chains we know */
|
|
GstClockTime total_time;
|
|
|
|
GstOggChain *current_chain;
|
|
GstOggChain *building_chain;
|
|
|
|
/* playback start/stop positions */
|
|
GstSegment segment;
|
|
gboolean segment_running;
|
|
|
|
GstEvent *event;
|
|
GstEvent *newsegment; /* pending newsegment to be sent from _loop */
|
|
|
|
gint64 current_granule;
|
|
|
|
/* annodex stuff */
|
|
gboolean have_fishead;
|
|
gint64 basetime;
|
|
|
|
/* ogg stuff */
|
|
ogg_sync_state sync;
|
|
};
|
|
|
|
struct _GstOggDemuxClass
|
|
{
|
|
GstElementClass parent_class;
|
|
};
|
|
|
|
G_END_DECLS
|
|
|
|
#endif /* __GST_OGG_DEMUX_H__ */
|