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 DRM_MAX_TS_DRM_PSSH_LEN 2048 39 #define DRM_MAX_TS_DRM_UUID_LEN 16 40 #define DRM_MAX_TS_DRM_INFO_NUM 64 41 42 #define GST_TYPE_MPEGTS_BASE \ 43 (mpegts_base_get_type()) 44 #define GST_MPEGTS_BASE(obj) \ 45 (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_MPEGTS_BASE,MpegTSBase)) 46 #define GST_MPEGTS_BASE_CLASS(klass) \ 47 (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_MPEGTS_BASE,MpegTSBaseClass)) 48 #define GST_IS_MPEGTS_BASE(obj) \ 49 (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_MPEGTS_BASE)) 50 #define GST_IS_MPEGTS_BASE_CLASS(klass) \ 51 (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_MPEGTS_BASE)) 52 #define GST_MPEGTS_BASE_GET_CLASS(obj) \ 53 (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_MPEGTS_BASE, MpegTSBaseClass)) 54 55 #define MPEG_TS_BASE_PACKETIZER(b) (((MpegTSBase*)b)->packetizer) 56 57 typedef struct _MpegTSBase MpegTSBase; 58 typedef struct _MpegTSBaseClass MpegTSBaseClass; 59 typedef struct _MpegTSBaseStream MpegTSBaseStream; 60 typedef struct _MpegTSBaseProgram MpegTSBaseProgram; 61 typedef struct _DrmInfo DrmInfo; 62 63 struct _MpegTSBaseStream 64 { 65 guint16 pid; 66 guint8 stream_type; 67 68 /* Content of the registration descriptor (if present) */ 69 guint32 registration_id; 70 71 GstMpegtsPMTStream *stream; 72 GstStream *stream_object; 73 gboolean in_collection; 74 gchar *stream_id; 75 }; 76 77 struct _MpegTSBaseProgram 78 { 79 gint program_number; 80 guint16 pmt_pid; 81 guint16 pcr_pid; 82 83 /* Content of the registration descriptor (if present) */ 84 guint32 registration_id; 85 86 GstMpegtsSection *section; 87 const GstMpegtsPMT *pmt; 88 89 MpegTSBaseStream **streams; 90 GList *stream_list; 91 gint patcount; 92 93 GstStreamCollection *collection; 94 95 /* Pending Tags for the program */ 96 GstTagList *tags; 97 guint event_id; 98 99 /* TRUE if the program is currently being used */ 100 gboolean active; 101 /* TRUE if this is the first program created */ 102 gboolean initial_program; 103 104 /* TRUE if the program shouldn't be freed */ 105 gboolean recycle; 106 }; 107 108 typedef enum { 109 /* PULL MODE */ 110 BASE_MODE_SCANNING, /* Looking for PAT/PMT */ 111 BASE_MODE_SEEKING, /* Seeking */ 112 BASE_MODE_STREAMING, /* Normal mode (pushing out data) */ 113 114 /* PUSH MODE */ 115 BASE_MODE_PUSHING 116 } MpegTSBaseMode; 117 118 struct _DrmInfo { 119 guint8 uuid[DRM_MAX_TS_DRM_UUID_LEN]; 120 guint8 pssh[DRM_MAX_TS_DRM_PSSH_LEN]; 121 guint pssh_len; 122 }; 123 124 struct _MpegTSBase { 125 GstElement element; 126 127 GstPad *sinkpad; 128 129 /* pull-based behaviour */ 130 MpegTSBaseMode mode; 131 132 /* Current pull offset (also set by seek handler) */ 133 guint64 seek_offset; 134 135 /* Cached packetsize */ 136 guint16 packetsize; 137 138 /* the following vars must be protected with the OBJECT_LOCK as they can be 139 * accessed from the application thread and the streaming thread */ 140 GPtrArray *programs; 141 142 GPtrArray *pat; 143 MpegTSPacketizer2 *packetizer; 144 145 /* arrays that say whether a pid is a known psi pid or a pes pid */ 146 /* Use MPEGTS_BIT_* to set/unset/check the values */ 147 guint8 *known_psi; 148 guint8 *is_pes; 149 150 gboolean disposed; 151 152 /* size of the MpegTSBaseProgram structure, can be overridden 153 * by subclasses if they have their own MpegTSBaseProgram subclasses. */ 154 gsize program_size; 155 156 /* size of the MpegTSBaseStream structure, can be overridden 157 * by subclasses if they have their own MpegTSBaseStream subclasses */ 158 gsize stream_size; 159 160 /* Whether we saw a PAT yet */ 161 gboolean seen_pat; 162 163 /* Upstream segment */ 164 GstSegment segment; 165 166 /* Downstream segment, for use by sub-classes */ 167 GstSegment out_segment; 168 169 /* Last received seek event seqnum (default GST_SEQNUM_INVALID) */ 170 guint last_seek_seqnum; 171 172 /* Whether to parse private section or not */ 173 gboolean parse_private_sections; 174 175 /* Whether to push data and/or sections to subclasses */ 176 gboolean push_data; 177 gboolean push_section; 178 gboolean push_unknown; 179 180 /* Whether the parent bin is streams-aware, meaning we can 181 * add/remove streams at any point in time */ 182 gboolean streams_aware; 183 184 /* Do not use the PCR stream for timestamp calculation. Useful for 185 * streams with broken/invalid PCR streams. */ 186 gboolean ignore_pcr; 187 188 /* Used for delayed seek events */ 189 GstEvent *seek_event; 190 191 guint8 drm_algo_tag; 192 193 gboolean is_drm; 194 195 DrmInfo *drm_info; 196 197 guint drm_info_num; 198 199 guint drm_info_total_num; 200 }; 201 202 struct _MpegTSBaseClass { 203 GstElementClass parent_class; 204 205 /* Virtual methods */ 206 void (*reset) (MpegTSBase *base); 207 GstFlowReturn (*push) (MpegTSBase *base, MpegTSPacketizerPacket *packet, GstMpegtsSection * section); 208 void (*inspect_packet) (MpegTSBase *base, MpegTSPacketizerPacket *packet); 209 /* takes ownership of @event */ 210 gboolean (*push_event) (MpegTSBase *base, GstEvent * event); 211 void (*handle_psi) (MpegTSBase *base, GstMpegtsSection * section); 212 213 /* program_started gets called when program's pmt arrives for first time */ 214 void (*program_started) (MpegTSBase *base, MpegTSBaseProgram *program); 215 /* program_stopped gets called when pat no longer has program's pmt */ 216 void (*program_stopped) (MpegTSBase *base, MpegTSBaseProgram *program); 217 void (*update_program) (MpegTSBase *base, MpegTSBaseProgram *program); 218 /* Whether mpegtbase can deactivate/free a program or whether the subclass will do it 219 * If the subclass responds TRUE, it should call mpegts_base_deactivate_and_free_program() 220 * when it wants to remove it */ 221 gboolean (*can_remove_program) (MpegTSBase *base, MpegTSBaseProgram *program); 222 223 /* stream_added is called whenever a new stream has been identified */ 224 gboolean (*stream_added) (MpegTSBase *base, MpegTSBaseStream *stream, MpegTSBaseProgram *program); 225 /* stream_removed is called whenever a stream is no longer referenced */ 226 void (*stream_removed) (MpegTSBase *base, MpegTSBaseStream *stream); 227 228 /* find_timestamps is called to find PCR */ 229 GstFlowReturn (*find_timestamps) (MpegTSBase * base, guint64 initoff, guint64 *offset); 230 231 /* seek is called to wait for seeking */ 232 GstFlowReturn (*seek) (MpegTSBase * base, GstEvent * event); 233 234 /* Drain all currently pending data */ 235 GstFlowReturn (*drain) (MpegTSBase * base); 236 237 /* flush all streams 238 * The hard inicator is used to flush completely on FLUSH_STOP events 239 * or partially in pull mode seeks of tsdemux */ 240 void (*flush) (MpegTSBase * base, gboolean hard); 241 242 /* Notifies subclasses input buffer has been handled */ 243 GstFlowReturn (*input_done) (MpegTSBase *base); 244 245 /* signals */ 246 void (*pat_info) (GstStructure *pat); 247 void (*pmt_info) (GstStructure *pmt); 248 void (*nit_info) (GstStructure *nit); 249 void (*sdt_info) (GstStructure *sdt); 250 void (*eit_info) (GstStructure *eit); 251 252 /* takes ownership of @query */ 253 gboolean (*sink_query) (MpegTSBase *base, GstQuery * query); 254 }; 255 256 #define MPEGTS_BIT_SET(field, offs) ((field)[(offs) >> 3] |= (1 << ((offs) & 0x7))) 257 #define MPEGTS_BIT_UNSET(field, offs) ((field)[(offs) >> 3] &= ~(1 << ((offs) & 0x7))) 258 #define MPEGTS_BIT_IS_SET(field, offs) ((field)[(offs) >> 3] & (1 << ((offs) & 0x7))) 259 260 G_GNUC_INTERNAL GType mpegts_base_get_type(void); 261 262 G_GNUC_INTERNAL MpegTSBaseProgram *mpegts_base_get_program (MpegTSBase * base, gint program_number); 263 G_GNUC_INTERNAL MpegTSBaseProgram *mpegts_base_add_program (MpegTSBase * base, gint program_number, guint16 pmt_pid); 264 265 G_GNUC_INTERNAL const GstMpegtsDescriptor *mpegts_get_descriptor_from_stream (MpegTSBaseStream * stream, guint8 tag); 266 G_GNUC_INTERNAL const GstMpegtsDescriptor *mpegts_get_descriptor_from_stream_with_extension (MpegTSBaseStream * stream, 267 guint8 tag, guint8 tag_extension); 268 G_GNUC_INTERNAL const GstMpegtsDescriptor *mpegts_get_descriptor_from_program (MpegTSBaseProgram * program, guint8 tag); 269 270 G_GNUC_INTERNAL gboolean 271 mpegts_base_handle_seek_event(MpegTSBase * base, GstPad * pad, GstEvent * event); 272 273 G_GNUC_INTERNAL gboolean gst_mpegtsbase_plugin_init (GstPlugin * plugin); 274 275 G_GNUC_INTERNAL void mpegts_base_deactivate_and_free_program (MpegTSBase *base, MpegTSBaseProgram *program); 276 277 G_END_DECLS 278 279 #endif /* GST_MPEG_TS_BASE_H */ 280