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 gchar *stream_id; 69 }; 70 71 struct _MpegTSBaseProgram 72 { 73 gint program_number; 74 guint16 pmt_pid; 75 guint16 pcr_pid; 76 77 /* Content of the registration descriptor (if present) */ 78 guint32 registration_id; 79 80 GstMpegtsSection *section; 81 const GstMpegtsPMT *pmt; 82 83 MpegTSBaseStream **streams; 84 GList *stream_list; 85 gint patcount; 86 87 GstStreamCollection *collection; 88 89 /* Pending Tags for the program */ 90 GstTagList *tags; 91 guint event_id; 92 93 /* TRUE if the program is currently being used */ 94 gboolean active; 95 /* TRUE if this is the first program created */ 96 gboolean initial_program; 97 }; 98 99 typedef enum { 100 /* PULL MODE */ 101 BASE_MODE_SCANNING, /* Looking for PAT/PMT */ 102 BASE_MODE_SEEKING, /* Seeking */ 103 BASE_MODE_STREAMING, /* Normal mode (pushing out data) */ 104 105 /* PUSH MODE */ 106 BASE_MODE_PUSHING 107 } MpegTSBaseMode; 108 109 struct _MpegTSBase { 110 GstElement element; 111 112 GstPad *sinkpad; 113 114 /* pull-based behaviour */ 115 MpegTSBaseMode mode; 116 117 /* Current pull offset (also set by seek handler) */ 118 guint64 seek_offset; 119 120 /* Cached packetsize */ 121 guint16 packetsize; 122 123 /* the following vars must be protected with the OBJECT_LOCK as they can be 124 * accessed from the application thread and the streaming thread */ 125 GHashTable *programs; 126 127 GPtrArray *pat; 128 MpegTSPacketizer2 *packetizer; 129 130 /* arrays that say whether a pid is a known psi pid or a pes pid */ 131 /* Use MPEGTS_BIT_* to set/unset/check the values */ 132 guint8 *known_psi; 133 guint8 *is_pes; 134 135 gboolean disposed; 136 137 /* size of the MpegTSBaseProgram structure, can be overridden 138 * by subclasses if they have their own MpegTSBaseProgram subclasses. */ 139 gsize program_size; 140 141 /* size of the MpegTSBaseStream structure, can be overridden 142 * by subclasses if they have their own MpegTSBaseStream subclasses */ 143 gsize stream_size; 144 145 /* Whether we saw a PAT yet */ 146 gboolean seen_pat; 147 148 /* Upstream segment */ 149 GstSegment segment; 150 151 /* Last received seek event seqnum (default GST_SEQNUM_INVALID) */ 152 guint last_seek_seqnum; 153 154 /* Whether to parse private section or not */ 155 gboolean parse_private_sections; 156 157 /* Whether to push data and/or sections to subclasses */ 158 gboolean push_data; 159 gboolean push_section; 160 161 /* Whether the parent bin is streams-aware, meaning we can 162 * add/remove streams at any point in time */ 163 gboolean streams_aware; 164 }; 165 166 struct _MpegTSBaseClass { 167 GstElementClass parent_class; 168 169 /* Virtual methods */ 170 void (*reset) (MpegTSBase *base); 171 GstFlowReturn (*push) (MpegTSBase *base, MpegTSPacketizerPacket *packet, GstMpegtsSection * section); 172 void (*inspect_packet) (MpegTSBase *base, MpegTSPacketizerPacket *packet); 173 /* takes ownership of @event */ 174 gboolean (*push_event) (MpegTSBase *base, GstEvent * event); 175 176 /* program_started gets called when program's pmt arrives for first time */ 177 void (*program_started) (MpegTSBase *base, MpegTSBaseProgram *program); 178 /* program_stopped gets called when pat no longer has program's pmt */ 179 void (*program_stopped) (MpegTSBase *base, MpegTSBaseProgram *program); 180 void (*update_program) (MpegTSBase *base, MpegTSBaseProgram *program); 181 /* Whether mpegtbase can deactivate/free a program or whether the subclass will do it 182 * If the subclass responds TRUE, it should call mpegts_base_deactivate_and_free_program() 183 * when it wants to remove it */ 184 gboolean (*can_remove_program) (MpegTSBase *base, MpegTSBaseProgram *program); 185 186 /* stream_added is called whenever a new stream has been identified */ 187 gboolean (*stream_added) (MpegTSBase *base, MpegTSBaseStream *stream, MpegTSBaseProgram *program); 188 /* stream_removed is called whenever a stream is no longer referenced */ 189 void (*stream_removed) (MpegTSBase *base, MpegTSBaseStream *stream); 190 191 /* find_timestamps is called to find PCR */ 192 GstFlowReturn (*find_timestamps) (MpegTSBase * base, guint64 initoff, guint64 *offset); 193 194 /* seek is called to wait for seeking */ 195 GstFlowReturn (*seek) (MpegTSBase * base, GstEvent * event); 196 197 /* Drain all currently pending data */ 198 GstFlowReturn (*drain) (MpegTSBase * base); 199 200 /* flush all streams 201 * The hard inicator is used to flush completelly on FLUSH_STOP events 202 * or partially in pull mode seeks of tsdemux */ 203 void (*flush) (MpegTSBase * base, gboolean hard); 204 205 /* Notifies subclasses input buffer has been handled */ 206 GstFlowReturn (*input_done) (MpegTSBase *base, GstBuffer *buffer); 207 208 /* signals */ 209 void (*pat_info) (GstStructure *pat); 210 void (*pmt_info) (GstStructure *pmt); 211 void (*nit_info) (GstStructure *nit); 212 void (*sdt_info) (GstStructure *sdt); 213 void (*eit_info) (GstStructure *eit); 214 215 /* takes ownership of @query */ 216 gboolean (*sink_query) (MpegTSBase *base, GstQuery * query); 217 }; 218 219 #define MPEGTS_BIT_SET(field, offs) ((field)[(offs) >> 3] |= (1 << ((offs) & 0x7))) 220 #define MPEGTS_BIT_UNSET(field, offs) ((field)[(offs) >> 3] &= ~(1 << ((offs) & 0x7))) 221 #define MPEGTS_BIT_IS_SET(field, offs) ((field)[(offs) >> 3] & (1 << ((offs) & 0x7))) 222 223 G_GNUC_INTERNAL GType mpegts_base_get_type(void); 224 225 G_GNUC_INTERNAL MpegTSBaseProgram *mpegts_base_get_program (MpegTSBase * base, gint program_number); 226 G_GNUC_INTERNAL MpegTSBaseProgram *mpegts_base_add_program (MpegTSBase * base, gint program_number, guint16 pmt_pid); 227 228 G_GNUC_INTERNAL const GstMpegtsDescriptor *mpegts_get_descriptor_from_stream (MpegTSBaseStream * stream, guint8 tag); 229 G_GNUC_INTERNAL const GstMpegtsDescriptor *mpegts_get_descriptor_from_program (MpegTSBaseProgram * program, guint8 tag); 230 231 G_GNUC_INTERNAL gboolean 232 mpegts_base_handle_seek_event(MpegTSBase * base, GstPad * pad, GstEvent * event); 233 234 G_GNUC_INTERNAL gboolean gst_mpegtsbase_plugin_init (GstPlugin * plugin); 235 236 G_GNUC_INTERNAL void mpegts_base_deactivate_and_free_program (MpegTSBase *base, MpegTSBaseProgram *program); 237 238 G_END_DECLS 239 240 #endif /* GST_MPEG_TS_BASE_H */ 241