1 /* GStreamer 2 * Copyright (C) 2004 Wim Taymans <wim@fluendo.com> 3 * 4 * gstoggdemux.c: ogg stream demuxer 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Library General Public 8 * License as published by the Free Software Foundation; either 9 * version 2 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Library General Public License for more details. 15 * 16 * You should have received a copy of the GNU Library General Public 17 * License along with this library; if not, write to the 18 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 19 * Boston, MA 02110-1301, USA. 20 */ 21 22 #ifndef __GST_OGG_DEMUX_H__ 23 #define __GST_OGG_DEMUX_H__ 24 25 #include <ogg/ogg.h> 26 27 #include <gst/gst.h> 28 #include <gst/base/gstflowcombiner.h> 29 30 #include "gstoggstream.h" 31 32 G_BEGIN_DECLS 33 34 #define GST_TYPE_OGG_PAD (gst_ogg_pad_get_type()) 35 #define GST_OGG_PAD(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OGG_PAD, GstOggPad)) 36 #define GST_OGG_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OGG_PAD, GstOggPad)) 37 #define GST_IS_OGG_PAD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OGG_PAD)) 38 #define GST_IS_OGG_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OGG_PAD)) 39 40 typedef struct _GstOggPad GstOggPad; 41 typedef struct _GstOggPadClass GstOggPadClass; 42 43 #define GST_TYPE_OGG_DEMUX (gst_ogg_demux_get_type()) 44 #define GST_OGG_DEMUX(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OGG_DEMUX, GstOggDemux)) 45 #define GST_OGG_DEMUX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OGG_DEMUX, GstOggDemux)) 46 #define GST_IS_OGG_DEMUX(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OGG_DEMUX)) 47 #define GST_IS_OGG_DEMUX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OGG_DEMUX)) 48 49 GType gst_ogg_demux_get_type (void); 50 51 typedef struct _GstOggDemux GstOggDemux; 52 typedef struct _GstOggDemuxClass GstOggDemuxClass; 53 typedef struct _GstOggChain GstOggChain; 54 55 /* all information needed for one ogg chain (relevant for chained bitstreams) */ 56 struct _GstOggChain 57 { 58 GstOggDemux *ogg; 59 60 gint64 offset; /* starting offset of chain */ 61 gint64 end_offset; /* end offset of chain */ 62 gint64 bytes; /* number of bytes */ 63 64 gboolean have_bos; 65 66 GArray *streams; 67 68 GstClockTime total_time; /* the total time of this chain, this is the MAX of 69 the totals of all streams */ 70 GstClockTime begin_time; /* when this chain starts in the stream */ 71 72 GstClockTime segment_start; /* the timestamp of the first sample, this is the MIN of 73 the start times of all streams. */ 74 GstClockTime segment_stop; /* the timestamp of the last page, this is the MAX of the 75 streams. */ 76 }; 77 78 /* all information needed for one ogg stream */ 79 struct _GstOggPad 80 { 81 GstPad pad; /* subclass GstPad */ 82 83 gboolean have_type; 84 85 GstOggChain *chain; /* the chain we are part of */ 86 GstOggDemux *ogg; /* the ogg demuxer we are part of */ 87 88 GstOggStream map; 89 90 gint64 packetno; 91 gint64 current_granule; 92 gint64 prev_granule; 93 gint64 keyframe_granule; 94 95 GstClockTime start_time; /* the timestamp of the first sample */ 96 97 gint64 first_granule; /* the granulepos of first page == first sample in next page */ 98 GstClockTime first_time; /* the timestamp of the second page or granuletime of first page */ 99 100 GstClockTime position; /* position when last push occured; used to detect when we 101 * need to send a newsegment update event for sparse streams */ 102 103 GList *continued; 104 105 gboolean discont; 106 GstFlowReturn last_ret; /* last return of _pad_push() */ 107 gboolean is_eos; 108 109 gboolean added; 110 111 /* push mode seeking */ 112 GstClockTime push_kf_time; 113 GstClockTime push_sync_time; 114 }; 115 116 struct _GstOggPadClass 117 { 118 GstPadClass parent_class; 119 }; 120 121 /** 122 * GstOggDemux: 123 * 124 * The ogg demuxer object structure. 125 */ 126 struct _GstOggDemux 127 { 128 GstElement element; 129 130 GstPad *sinkpad; 131 132 GstFlowCombiner *flowcombiner; 133 134 gint64 length; 135 gint64 read_offset; 136 gint64 offset; 137 138 gboolean pullmode; 139 gboolean running; 140 141 gboolean have_group_id; 142 guint group_id; 143 144 gboolean need_chains; 145 gboolean resync; 146 147 /* keep track of how large pages and packets are, 148 useful for skewing when seeking */ 149 guint64 max_packet_size, max_page_size; 150 151 gboolean check_index_overflow; 152 153 /* state */ 154 GMutex chain_lock; /* we need the lock to protect the chains */ 155 GArray *chains; /* list of chains we know */ 156 GstClockTime total_time; 157 gint bitrate; /* bitrate of the current chain */ 158 159 GstOggChain *current_chain; 160 GstOggChain *building_chain; 161 162 /* playback start/stop positions */ 163 GstSegment segment; 164 guint32 seqnum; 165 166 GstEvent *newsegment; /* pending newsegment to be sent from _loop */ 167 168 /* annodex stuff */ 169 gint64 basetime; 170 gint64 prestime; 171 172 /* push mode seeking support */ 173 GMutex push_lock; /* we need the lock to protect the push mode variables */ 174 gint64 push_byte_offset; /* where were are at in the stream, in bytes */ 175 gint64 push_byte_length; /* length in bytes of the stream, -1 if unknown */ 176 GstClockTime push_time_length; /* length in time of the stream */ 177 GstClockTime push_start_time; /* start time of the stream */ 178 GstClockTime push_time_offset; /* where were are at in the stream, in time */ 179 enum { PUSH_PLAYING, PUSH_DURATION, PUSH_BISECT1, PUSH_LINEAR1, PUSH_BISECT2, PUSH_LINEAR2 } push_state; 180 181 GstClockTime push_seek_time_original_target; 182 GstClockTime push_seek_time_original_stop; 183 GstClockTime push_seek_time_target; 184 gint64 push_last_seek_offset; 185 GstClockTime push_last_seek_time; 186 gint64 push_offset0, push_offset1; /* bisection search offset bounds */ 187 GstClockTime push_time0, push_time1; /* bisection search time bounds */ 188 189 double push_seek_rate; 190 GstSeekFlags push_seek_flags; 191 GstEvent *push_mode_seek_delayed_event; 192 gboolean push_disable_seeking; 193 gboolean seek_secant; 194 gboolean seek_undershot; 195 GstClockTime push_prev_seek_time; 196 197 gint push_bisection_steps[2]; 198 gint stats_bisection_steps[2]; 199 gint stats_bisection_max_steps[2]; 200 gint stats_nbisections; 201 202 /* ogg stuff */ 203 ogg_sync_state sync; 204 long chunk_size; 205 206 /* Seek events set up by the streaming thread in push mode */ 207 GstEvent *seek_event; 208 GThread *seek_event_thread; 209 GMutex seek_event_mutex; 210 GCond seek_event_cond; 211 gboolean seek_event_thread_stop; 212 gboolean seek_thread_started; 213 GCond thread_started_cond; 214 guint32 seek_event_drop_till; 215 }; 216 217 struct _GstOggDemuxClass 218 { 219 GstElementClass parent_class; 220 }; 221 222 gboolean gst_ogg_demux_plugin_init (GstPlugin * plugin); 223 224 G_END_DECLS 225 226 #endif /* __GST_OGG_DEMUX_H__ */ 227