1 /* 2 * mpegtspacketizer.h - 3 * Copyright (C) 2007 Alessandro Decina 4 * 5 * Authors: 6 * Alessandro Decina <alessandro@nnva.org> 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Library General Public 10 * License as published by the Free Software Foundation; either 11 * version 2 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Library General Public License for more details. 17 * 18 * You should have received a copy of the GNU Library General Public 19 * License along with this library; if not, write to the 20 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 21 * Boston, MA 02110-1301, USA. 22 */ 23 24 #ifndef GST_MPEGTS_PACKETIZER_H 25 #define GST_MPEGTS_PACKETIZER_H 26 27 #include <gst/gst.h> 28 #include <gst/base/gstadapter.h> 29 #include <glib.h> 30 31 #include <gst/mpegts/mpegts.h> 32 #include "gstmpegdefs.h" 33 34 #define MPEGTS_NORMAL_PACKETSIZE 188 35 #define MPEGTS_M2TS_PACKETSIZE 192 36 #define MPEGTS_DVB_ASI_PACKETSIZE 204 37 #define MPEGTS_ATSC_PACKETSIZE 208 38 39 #define MPEGTS_MIN_PACKETSIZE MPEGTS_NORMAL_PACKETSIZE 40 #define MPEGTS_MAX_PACKETSIZE MPEGTS_ATSC_PACKETSIZE 41 42 #define MPEGTS_AFC_DISCONTINUITY_FLAG 0x80 43 #define MPEGTS_AFC_RANDOM_ACCESS_FLAG 0x40 44 #define MPEGTS_AFC_ELEMENTARY_STREAM_PRIORITY 0x20 45 #define MPEGTS_AFC_PCR_FLAG 0x10 46 #define MPEGTS_AFC_OPCR_FLAG 0x08 47 #define MPEGTS_AFC_SPLICING_POINT_FLAG 0x04 48 #define MPEGTS_AFC_TRANSPORT_PRIVATE_DATA_FLAG 0x02 49 #define MPEGTS_AFC_EXTENSION_FLAG 0x01 50 51 #define MAX_WINDOW 512 52 53 G_BEGIN_DECLS 54 55 #define GST_TYPE_MPEGTS_PACKETIZER \ 56 (mpegts_packetizer_get_type()) 57 #define GST_MPEGTS_PACKETIZER(obj) \ 58 (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_MPEGTS_PACKETIZER,MpegTSPacketizer2)) 59 #define GST_MPEGTS_PACKETIZER_CLASS(klass) \ 60 (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_MPEGTS_PACKETIZER,MpegTSPacketizer2Class)) 61 #define GST_IS_MPEGTS_PACKETIZER(obj) \ 62 (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_MPEGTS_PACKETIZER)) 63 #define GST_IS_MPEGTS_PACKETIZER_CLASS(klass) \ 64 (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_MPEGTS_PACKETIZER)) 65 66 typedef struct _MpegTSPacketizer2 MpegTSPacketizer2; 67 typedef struct _MpegTSPacketizer2Class MpegTSPacketizer2Class; 68 69 typedef struct 70 { 71 guint16 pid; 72 guint continuity_counter; 73 74 /* Section data (always newly allocated) */ 75 guint8 *section_data; 76 /* Current offset in section_data */ 77 guint16 section_offset; 78 79 /* Values for pending section */ 80 /* table_id of the pending section_data */ 81 guint8 table_id; 82 guint section_length; 83 guint8 version_number; 84 guint16 subtable_extension; 85 guint8 section_number; 86 guint8 last_section_number; 87 88 GSList *subtables; 89 90 /* Upstream offset of the data contained in the section */ 91 guint64 offset; 92 } MpegTSPacketizerStream; 93 94 /* Maximum number of MpegTSPcr 95 * 256 should be sufficient for most multiplexes */ 96 #define MAX_PCR_OBS_CHANNELS 256 97 98 /* PCR/offset structure */ 99 typedef struct _PCROffset 100 { 101 /* PCR value (units: 1/27MHz) */ 102 guint64 pcr; 103 104 /* The offset (units: bytes) */ 105 guint64 offset; 106 } PCROffset; 107 108 /* Flags used on groups */ 109 enum 110 { 111 /* Closed groups: There is a contiguous next group */ 112 PCR_GROUP_FLAG_CLOSED = 1 << 0, 113 /* estimated: the pcr_offset has been estimated and is not 114 * guaranteed to be 100% accurate */ 115 PCR_GROUP_FLAG_ESTIMATED = 1 << 1, 116 /* reset: there is a pcr reset between the end of this 117 * group and the next one. 118 * This flag is exclusive with CLOSED. */ 119 PCR_GROUP_FLAG_RESET = 1 << 2, 120 /* reset: there is a pcr wrapover between the end of this 121 * group and the next one. 122 * This flag is exclusive with CLOSED. */ 123 PCR_GROUP_FLAG_WRAPOVER = 1 << 3 124 }; 125 126 127 128 /* PCROffsetGroup: A group of PCR observations. 129 * All values in a group have got the same reference pcr and 130 * byte offset (first_pcr/first_offset). 131 */ 132 #define DEFAULT_ALLOCATED_OFFSET 16 133 typedef struct _PCROffsetGroup 134 { 135 /* Flags (see PCR_GROUP_FLAG_* above) */ 136 guint flags; 137 138 /* First raw PCR of this group. Units: 1/27MHz. 139 * All values[].pcr are differences against first_pcr */ 140 guint64 first_pcr; 141 /* Offset of this group in bytes. 142 * All values[].offset are differences against first_offset */ 143 guint64 first_offset; 144 145 /* Dynamically allocated table of PCROffset */ 146 PCROffset *values; 147 /* number of PCROffset allocated in values */ 148 guint nb_allocated; 149 /* number of *actual* PCROffset contained in values */ 150 guint last_value; 151 152 /* Offset since the very first PCR value observed in the whole 153 * stream. Units: 1/27MHz. 154 * This will take into account gaps/wraparounds/resets/... and is 155 * used to determine running times. 156 * The value is only guaranteed to be 100% accurate if the group 157 * does not have the ESTIMATED flag. 158 * If the value is estimated, the pcr_offset shall be recalculated 159 * (based on previous groups) whenever it is accessed. 160 */ 161 guint64 pcr_offset; 162 163 /* FIXME : Cache group bitrate ? */ 164 } PCROffsetGroup; 165 166 /* Number of PCRs needed before bitrate estimation can start */ 167 /* Note: the reason we use 10 is because PCR should normally be 168 * received at least every 100ms so this gives us close to 169 * a 1s moving window to calculate bitrate */ 170 #define PCR_BITRATE_NEEDED 10 171 172 /* PCROffsetCurrent: The PCR/Offset window iterator 173 * This is used to estimate/observe incoming PCR/offset values 174 * Points to a group (which it is filling) */ 175 typedef struct _PCROffsetCurrent 176 { 177 /* The PCROffsetGroup we are filling. 178 * If NULL, a group needs to be identified */ 179 PCROffsetGroup *group; 180 181 /* Table of pending values we are iterating over */ 182 PCROffset pending[PCR_BITRATE_NEEDED]; 183 184 /* base offset/pcr from the group */ 185 guint64 first_pcr; 186 guint64 first_offset; 187 188 /* The previous reference PCROffset 189 * This corresponds to the last entry of the group we are filling 190 * and is used to calculate prev_bitrate */ 191 PCROffset prev; 192 193 /* The last PCROffset in pending[] */ 194 PCROffset last_value; 195 196 /* Location of first pending PCR/offset observation in pending */ 197 guint first; 198 /* Location of last pending PCR/offset observation in pending */ 199 guint last; 200 /* Location of next write in pending */ 201 guint write; 202 203 /* bitrate is always in bytes per second */ 204 205 /* cur_bitrate is the bitrate of the pending values: d(last-first) */ 206 guint64 cur_bitrate; 207 208 /* prev_bitrate is the bitrate between reference PCROffset 209 * and the first pending value. Used to detect changes 210 * in bitrate */ 211 guint64 prev_bitrate; 212 } PCROffsetCurrent; 213 214 typedef struct _MpegTSPCR 215 { 216 guint16 pid; 217 218 /* Following variables are only active/used when 219 * calculate_skew is TRUE */ 220 GstClockTime base_time; 221 GstClockTime base_pcrtime; 222 GstClockTime prev_out_time; 223 GstClockTime prev_in_time; 224 GstClockTime last_pcrtime; 225 gint64 window[MAX_WINDOW]; 226 guint window_pos; 227 guint window_size; 228 gboolean window_filling; 229 gint64 window_min; 230 gint64 skew; 231 gint64 prev_send_diff; 232 233 /* Offset to apply to PCR to handle wraparounds */ 234 guint64 pcroffset; 235 236 /* Used for bitrate calculation */ 237 /* List of PCR/offset observations */ 238 GList *groups; 239 240 /* Current PCR/offset observations (used to update pcroffsets) */ 241 PCROffsetCurrent *current; 242 } MpegTSPCR; 243 244 struct _MpegTSPacketizer2 { 245 GObject parent; 246 247 GMutex group_lock; 248 249 GstAdapter *adapter; 250 /* streams hashed by pid */ 251 /* FIXME : be more memory efficient (see how it's done in mpegtsbase) */ 252 MpegTSPacketizerStream **streams; 253 gboolean disposed; 254 guint16 packet_size; 255 256 /* current offset of the tip of the adapter */ 257 guint64 offset; 258 gboolean empty; 259 260 /* clock skew calculation */ 261 gboolean calculate_skew; 262 263 /* offset/bitrate calculator */ 264 gboolean calculate_offset; 265 266 /* Shortcuts for adapter usage */ 267 guint8 *map_data; 268 gsize map_offset; 269 gsize map_size; 270 gboolean need_sync; 271 272 /* Reference offset */ 273 guint64 refoffset; 274 275 /* Number of seen pcr/offset observations (FIXME : kill later) */ 276 guint nb_seen_offsets; 277 278 /* Last inputted timestamp */ 279 GstClockTime last_in_time; 280 281 /* offset to observations table */ 282 guint8 pcrtablelut[0x2000]; 283 MpegTSPCR *observations[MAX_PCR_OBS_CHANNELS]; 284 guint8 lastobsid; 285 GstClockTime pcr_discont_threshold; 286 287 /* PTS/DTS of last buffer */ 288 GstClockTime last_pts; 289 GstClockTime last_dts; 290 291 /* Extra time offset to handle values before initial PCR. 292 * This will be added to all converted timestamps */ 293 GstClockTime extra_shift; 294 }; 295 296 struct _MpegTSPacketizer2Class { 297 GObjectClass object_class; 298 }; 299 300 #define FLAGS_SCRAMBLED(f) (f & 0xc0) 301 #define FLAGS_HAS_AFC(f) (f & 0x20) 302 #define FLAGS_HAS_PAYLOAD(f) (f & 0x10) 303 #define FLAGS_CONTINUITY_COUNTER(f) (f & 0x0f) 304 305 typedef struct 306 { 307 gint16 pid; 308 guint8 payload_unit_start_indicator; 309 guint8 scram_afc_cc; 310 guint8 *payload; 311 312 guint8 *data_start; 313 guint8 *data_end; 314 guint8 *data; 315 316 guint8 afc_flags; 317 guint64 pcr; 318 guint64 offset; 319 } MpegTSPacketizerPacket; 320 321 typedef struct 322 { 323 guint8 table_id; 324 /* the spec says sub_table_extension is the fourth and fifth byte of a 325 * section when the section_syntax_indicator is set to a value of "1". If 326 * section_syntax_indicator is 0, sub_table_extension will be set to 0 */ 327 guint16 subtable_extension; 328 guint8 version_number; 329 guint8 last_section_number; 330 /* table of bits, whether the section was seen or not. 331 * Use MPEGTS_BIT_* macros to check */ 332 /* Size is 32, because there's a maximum of 256 (32*8) section_number */ 333 guint8 seen_section[32]; 334 } MpegTSPacketizerStreamSubtable; 335 336 #define MPEGTS_BIT_SET(field, offs) ((field)[(offs) >> 3] |= (1 << ((offs) & 0x7))) 337 #define MPEGTS_BIT_UNSET(field, offs) ((field)[(offs) >> 3] &= ~(1 << ((offs) & 0x7))) 338 #define MPEGTS_BIT_IS_SET(field, offs) ((field)[(offs) >> 3] & (1 << ((offs) & 0x7))) 339 340 typedef enum { 341 PACKET_BAD = FALSE, 342 PACKET_OK = TRUE, 343 PACKET_NEED_MORE 344 } MpegTSPacketizerPacketReturn; 345 346 G_GNUC_INTERNAL GType mpegts_packetizer_get_type(void); 347 348 G_GNUC_INTERNAL MpegTSPacketizer2 *mpegts_packetizer_new (void); 349 G_GNUC_INTERNAL void mpegts_packetizer_clear (MpegTSPacketizer2 *packetizer); 350 G_GNUC_INTERNAL void mpegts_packetizer_flush (MpegTSPacketizer2 *packetizer, gboolean hard); 351 G_GNUC_INTERNAL void mpegts_packetizer_push (MpegTSPacketizer2 *packetizer, GstBuffer *buffer); 352 G_GNUC_INTERNAL gboolean mpegts_packetizer_has_packets (MpegTSPacketizer2 *packetizer); 353 G_GNUC_INTERNAL MpegTSPacketizerPacketReturn mpegts_packetizer_next_packet (MpegTSPacketizer2 *packetizer, 354 MpegTSPacketizerPacket *packet); 355 G_GNUC_INTERNAL MpegTSPacketizerPacketReturn 356 mpegts_packetizer_process_next_packet(MpegTSPacketizer2 * packetizer); 357 G_GNUC_INTERNAL void mpegts_packetizer_clear_packet (MpegTSPacketizer2 *packetizer, 358 MpegTSPacketizerPacket *packet); 359 G_GNUC_INTERNAL void mpegts_packetizer_remove_stream(MpegTSPacketizer2 *packetizer, 360 gint16 pid); 361 362 G_GNUC_INTERNAL GstMpegtsSection *mpegts_packetizer_push_section (MpegTSPacketizer2 *packetzer, 363 MpegTSPacketizerPacket *packet, GList **remaining); 364 365 /* Only valid if calculate_offset is TRUE */ 366 G_GNUC_INTERNAL GstClockTime 367 mpegts_packetizer_offset_to_ts (MpegTSPacketizer2 * packetizer, 368 guint64 offset, guint16 pcr_pid); 369 G_GNUC_INTERNAL guint64 370 mpegts_packetizer_ts_to_offset (MpegTSPacketizer2 * packetizer, 371 GstClockTime ts, guint16 pcr_pid); 372 G_GNUC_INTERNAL GstClockTime 373 mpegts_packetizer_pts_to_ts (MpegTSPacketizer2 * packetizer, 374 GstClockTime pts, guint16 pcr_pid); 375 G_GNUC_INTERNAL GstClockTime 376 mpegts_packetizer_get_current_time (MpegTSPacketizer2 * packetizer, 377 guint16 pcr_pid); 378 G_GNUC_INTERNAL void 379 mpegts_packetizer_set_current_pcr_offset (MpegTSPacketizer2 * packetizer, 380 GstClockTime offset, guint16 pcr_pid); 381 G_GNUC_INTERNAL void 382 mpegts_packetizer_set_reference_offset (MpegTSPacketizer2 * packetizer, 383 guint64 refoffset); 384 G_GNUC_INTERNAL void 385 mpegts_packetizer_set_pcr_discont_threshold (MpegTSPacketizer2 * packetizer, 386 GstClockTime threshold); 387 G_END_DECLS 388 389 #endif /* GST_MPEGTS_PACKETIZER_H */ 390