1 /* 2 * mpegtsbase.h - GStreamer MPEG transport stream base class 3 * Copyright (C) 2009 Edward Hervey <edward.hervey@collabora.co.uk> 4 * 2007 Alessandro Decina 5 * Copyright (C) 2011, Hewlett-Packard Development Company, L.P. 6 * Author: Youness Alaoui <youness.alaoui@collabora.co.uk>, Collabora Ltd. 7 * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd. 8 * 9 * Authors: 10 * Alessandro Decina <alessandro@nnva.org> 11 * Edward Hervey <edward.hervey@collabora.co.uk> 12 * 13 * This library is free software; you can redistribute it and/or 14 * modify it under the terms of the GNU Library General Public 15 * License as published by the Free Software Foundation; either 16 * version 2 of the License, or (at your option) any later version. 17 * 18 * This library is distributed in the hope that it will be useful, 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 * Library General Public License for more details. 22 * 23 * You should have received a copy of the GNU Library General Public 24 * License along with this library; if not, write to the 25 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 26 * Boston, MA 02110-1301, USA. 27 */ 28 29 30 #ifndef GST_MPEG_TS_BASE_H 31 #define GST_MPEG_TS_BASE_H 32 33 #include <gst/gst.h> 34 #include "mpegtspacketizer.h" 35 36 G_BEGIN_DECLS 37 38 #define GST_TYPE_MPEGTS_BASE \ 39 (mpegts_base_get_type()) 40 #define GST_MPEGTS_BASE(obj) \ 41 (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_MPEGTS_BASE,MpegTSBase)) 42 #define GST_MPEGTS_BASE_CLASS(klass) \ 43 (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_MPEGTS_BASE,MpegTSBaseClass)) 44 #define GST_IS_MPEGTS_BASE(obj) \ 45 (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_MPEGTS_BASE)) 46 #define GST_IS_MPEGTS_BASE_CLASS(klass) \ 47 (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_MPEGTS_BASE)) 48 #define GST_MPEGTS_BASE_GET_CLASS(obj) \ 49 (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_MPEGTS_BASE, MpegTSBaseClass)) 50 51 #define MPEG_TS_BASE_PACKETIZER(b) (((MpegTSBase*)b)->packetizer) 52 53 typedef struct _MpegTSBase MpegTSBase; 54 typedef struct _MpegTSBaseClass MpegTSBaseClass; 55 typedef struct _MpegTSBaseStream MpegTSBaseStream; 56 typedef struct _MpegTSBaseProgram MpegTSBaseProgram; 57 58 struct _MpegTSBaseStream 59 { 60 guint16 pid; 61 guint8 stream_type; 62 63 /* Content of the registration descriptor (if present) */ 64 guint32 registration_id; 65 66 GstMpegtsPMTStream *stream; 67 GstStream *stream_object; 68 gboolean in_collection; 69 gchar *stream_id; 70 }; 71 72 struct _MpegTSBaseProgram 73 { 74 gint program_number; 75 guint16 pmt_pid; 76 guint16 pcr_pid; 77 78 /* Content of the registration descriptor (if present) */ 79 guint32 registration_id; 80 81 GstMpegtsSection *section; 82 const GstMpegtsPMT *pmt; 83 84 MpegTSBaseStream **streams; 85 GList *stream_list; 86 gint patcount; 87 88 GstStreamCollection *collection; 89 90 /* Pending Tags for the program */ 91 GstTagList *tags; 92 guint event_id; 93 94 /* TRUE if the program is currently being used */ 95 gboolean active; 96 /* TRUE if this is the first program created */ 97 gboolean initial_program; 98 99 /* TRUE if the program shouldn't be freed */ 100 gboolean recycle; 101 }; 102 103 typedef enum { 104 /* PULL MODE */ 105 BASE_MODE_SCANNING, /* Looking for PAT/PMT */ 106 BASE_MODE_SEEKING, /* Seeking */ 107 BASE_MODE_STREAMING, /* Normal mode (pushing out data) */ 108 109 /* PUSH MODE */ 110 BASE_MODE_PUSHING 111 } MpegTSBaseMode; 112 113 struct _MpegTSBase { 114 GstElement element; 115 116 GstPad *sinkpad; 117 118 /* pull-based behaviour */ 119 MpegTSBaseMode mode; 120 121 /* Current pull offset (also set by seek handler) */ 122 guint64 seek_offset; 123 124 /* Cached packetsize */ 125 guint16 packetsize; 126 127 /* the following vars must be protected with the OBJECT_LOCK as they can be 128 * accessed from the application thread and the streaming thread */ 129 GPtrArray *programs; 130 131 GPtrArray *pat; 132 MpegTSPacketizer2 *packetizer; 133 134 /* arrays that say whether a pid is a known psi pid or a pes pid */ 135 /* Use MPEGTS_BIT_* to set/unset/check the values */ 136 guint8 *known_psi; 137 guint8 *is_pes; 138 139 gboolean disposed; 140 141 /* size of the MpegTSBaseProgram structure, can be overridden 142 * by subclasses if they have their own MpegTSBaseProgram subclasses. */ 143 gsize program_size; 144 145 /* size of the MpegTSBaseStream structure, can be overridden 146 * by subclasses if they have their own MpegTSBaseStream subclasses */ 147 gsize stream_size; 148 149 /* Whether we saw a PAT yet */ 150 gboolean seen_pat; 151 152 /* Upstream segment */ 153 GstSegment segment; 154 155 /* Downstream segment, for use by sub-classes */ 156 GstSegment out_segment; 157 158 /* Last received seek event seqnum (default GST_SEQNUM_INVALID) */ 159 guint last_seek_seqnum; 160 161 /* Whether to parse private section or not */ 162 gboolean parse_private_sections; 163 164 /* Whether to push data and/or sections to subclasses */ 165 gboolean push_data; 166 gboolean push_section; 167 gboolean push_unknown; 168 169 /* Whether the parent bin is streams-aware, meaning we can 170 * add/remove streams at any point in time */ 171 gboolean streams_aware; 172 173 /* Do not use the PCR stream for timestamp calculation. Useful for 174 * streams with broken/invalid PCR streams. */ 175 gboolean ignore_pcr; 176 177 /* Used for delayed seek events */ 178 GstEvent *seek_event; 179 }; 180 181 struct _MpegTSBaseClass { 182 GstElementClass parent_class; 183 184 /* Virtual methods */ 185 void (*reset) (MpegTSBase *base); 186 GstFlowReturn (*push) (MpegTSBase *base, MpegTSPacketizerPacket *packet, GstMpegtsSection * section); 187 void (*inspect_packet) (MpegTSBase *base, MpegTSPacketizerPacket *packet); 188 /* takes ownership of @event */ 189 gboolean (*push_event) (MpegTSBase *base, GstEvent * event); 190 void (*handle_psi) (MpegTSBase *base, GstMpegtsSection * section); 191 192 /* program_started gets called when program's pmt arrives for first time */ 193 void (*program_started) (MpegTSBase *base, MpegTSBaseProgram *program); 194 /* program_stopped gets called when pat no longer has program's pmt */ 195 void (*program_stopped) (MpegTSBase *base, MpegTSBaseProgram *program); 196 void (*update_program) (MpegTSBase *base, MpegTSBaseProgram *program); 197 /* Whether mpegtbase can deactivate/free a program or whether the subclass will do it 198 * If the subclass responds TRUE, it should call mpegts_base_deactivate_and_free_program() 199 * when it wants to remove it */ 200 gboolean (*can_remove_program) (MpegTSBase *base, MpegTSBaseProgram *program); 201 202 /* stream_added is called whenever a new stream has been identified */ 203 gboolean (*stream_added) (MpegTSBase *base, MpegTSBaseStream *stream, MpegTSBaseProgram *program); 204 /* stream_removed is called whenever a stream is no longer referenced */ 205 void (*stream_removed) (MpegTSBase *base, MpegTSBaseStream *stream); 206 207 /* find_timestamps is called to find PCR */ 208 GstFlowReturn (*find_timestamps) (MpegTSBase * base, guint64 initoff, guint64 *offset); 209 210 /* seek is called to wait for seeking */ 211 GstFlowReturn (*seek) (MpegTSBase * base, GstEvent * event); 212 213 /* Drain all currently pending data */ 214 GstFlowReturn (*drain) (MpegTSBase * base); 215 216 /* flush all streams 217 * The hard inicator is used to flush completely on FLUSH_STOP events 218 * or partially in pull mode seeks of tsdemux */ 219 void (*flush) (MpegTSBase * base, gboolean hard); 220 221 /* Notifies subclasses input buffer has been handled */ 222 GstFlowReturn (*input_done) (MpegTSBase *base); 223 224 /* signals */ 225 void (*pat_info) (GstStructure *pat); 226 void (*pmt_info) (GstStructure *pmt); 227 void (*nit_info) (GstStructure *nit); 228 void (*sdt_info) (GstStructure *sdt); 229 void (*eit_info) (GstStructure *eit); 230 231 /* takes ownership of @query */ 232 gboolean (*sink_query) (MpegTSBase *base, GstQuery * query); 233 }; 234 235 #define MPEGTS_BIT_SET(field, offs) ((field)[(offs) >> 3] |= (1 << ((offs) & 0x7))) 236 #define MPEGTS_BIT_UNSET(field, offs) ((field)[(offs) >> 3] &= ~(1 << ((offs) & 0x7))) 237 #define MPEGTS_BIT_IS_SET(field, offs) ((field)[(offs) >> 3] & (1 << ((offs) & 0x7))) 238 239 G_GNUC_INTERNAL GType mpegts_base_get_type(void); 240 241 G_GNUC_INTERNAL MpegTSBaseProgram *mpegts_base_get_program (MpegTSBase * base, gint program_number); 242 G_GNUC_INTERNAL MpegTSBaseProgram *mpegts_base_add_program (MpegTSBase * base, gint program_number, guint16 pmt_pid); 243 244 G_GNUC_INTERNAL const GstMpegtsDescriptor *mpegts_get_descriptor_from_stream (MpegTSBaseStream * stream, guint8 tag); 245 G_GNUC_INTERNAL const GstMpegtsDescriptor *mpegts_get_descriptor_from_stream_with_extension (MpegTSBaseStream * stream, 246 guint8 tag, guint8 tag_extension); 247 G_GNUC_INTERNAL const GstMpegtsDescriptor *mpegts_get_descriptor_from_program (MpegTSBaseProgram * program, guint8 tag); 248 249 G_GNUC_INTERNAL gboolean 250 mpegts_base_handle_seek_event(MpegTSBase * base, GstPad * pad, GstEvent * event); 251 252 G_GNUC_INTERNAL gboolean gst_mpegtsbase_plugin_init (GstPlugin * plugin); 253 254 G_GNUC_INTERNAL void mpegts_base_deactivate_and_free_program (MpegTSBase *base, MpegTSBaseProgram *program); 255 256 G_END_DECLS 257 258 #endif /* GST_MPEG_TS_BASE_H */ 259