3 * Copyright (C) 2007 Alessandro Decina
6 * Alessandro Decina <alessandro@nnva.org>
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.
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.
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.
24 #ifndef GST_MPEGTS_PACKETIZER_H
25 #define GST_MPEGTS_PACKETIZER_H
28 #include <gst/base/gstadapter.h>
31 #include <gst/mpegts/mpegts.h>
32 #include "gstmpegdefs.h"
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
39 #define MPEGTS_MIN_PACKETSIZE MPEGTS_NORMAL_PACKETSIZE
40 #define MPEGTS_MAX_PACKETSIZE MPEGTS_ATSC_PACKETSIZE
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
51 #define MAX_WINDOW 512
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))
66 typedef struct _MpegTSPacketizer2 MpegTSPacketizer2;
67 typedef struct _MpegTSPacketizer2Class MpegTSPacketizer2Class;
72 guint continuity_counter;
74 /* Section data (always newly allocated) */
76 /* Current offset in section_data */
77 guint16 section_offset;
79 /* Values for pending section */
80 /* table_id of the pending section_data */
83 guint8 version_number;
84 guint16 subtable_extension;
85 guint8 section_number;
86 guint8 last_section_number;
90 /* Upstream offset of the data contained in the section */
92 } MpegTSPacketizerStream;
94 /* Maximum number of MpegTSPcr
95 * 256 should be sufficient for most multiplexes */
96 #define MAX_PCR_OBS_CHANNELS 256
98 /* PCR/offset structure */
99 typedef struct _PCROffset
101 /* PCR value (units: 1/27MHz) */
104 /* The offset (units: bytes) */
108 /* Flags used on groups */
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
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).
132 #define DEFAULT_ALLOCATED_OFFSET 16
133 typedef struct _PCROffsetGroup
135 /* Flags (see PCR_GROUP_FLAG_* above) */
138 /* First raw PCR of this group. Units: 1/27MHz.
139 * All values[].pcr are differences against first_pcr */
141 /* Offset of this group in bytes.
142 * All values[].offset are differences against first_offset */
143 guint64 first_offset;
145 /* Dynamically allocated table of PCROffset */
147 /* number of PCROffset allocated in values */
149 /* number of *actual* PCROffset contained in values */
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.
163 /* FIXME : Cache group bitrate ? */
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
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
177 /* The PCROffsetGroup we are filling.
178 * If NULL, a group needs to be identified */
179 PCROffsetGroup *group;
181 /* Table of pending values we are iterating over */
182 PCROffset pending[PCR_BITRATE_NEEDED];
184 /* base offset/pcr from the group */
186 guint64 first_offset;
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 */
193 /* The last PCROffset in pending[] */
194 PCROffset last_value;
196 /* Location of first pending PCR/offset observation in pending */
198 /* Location of last pending PCR/offset observation in pending */
200 /* Location of next write in pending */
203 /* bitrate is always in bytes per second */
205 /* cur_bitrate is the bitrate of the pending values: d(last-first) */
208 /* prev_bitrate is the bitrate between reference PCROffset
209 * and the first pending value. Used to detect changes
211 guint64 prev_bitrate;
214 typedef struct _MpegTSPCR
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];
228 gboolean window_filling;
231 gint64 prev_send_diff;
233 /* Offset to apply to PCR to handle wraparounds */
236 /* Used for bitrate calculation */
237 /* List of PCR/offset observations */
240 /* Current PCR/offset observations (used to update pcroffsets) */
241 PCROffsetCurrent *current;
244 struct _MpegTSPacketizer2 {
250 /* streams hashed by pid */
251 /* FIXME : be more memory efficient (see how it's done in mpegtsbase) */
252 MpegTSPacketizerStream **streams;
256 /* current offset of the tip of the adapter */
260 /* clock skew calculation */
261 gboolean calculate_skew;
263 /* offset/bitrate calculator */
264 gboolean calculate_offset;
266 /* Shortcuts for adapter usage */
272 /* Reference offset */
275 /* Number of seen pcr/offset observations (FIXME : kill later) */
276 guint nb_seen_offsets;
278 /* Last inputted timestamp */
279 GstClockTime last_in_time;
281 /* offset to observations table */
282 guint8 pcrtablelut[0x2000];
283 MpegTSPCR *observations[MAX_PCR_OBS_CHANNELS];
285 GstClockTime pcr_discont_threshold;
288 struct _MpegTSPacketizer2Class {
289 GObjectClass object_class;
292 #define FLAGS_SCRAMBLED(f) (f & 0xc0)
293 #define FLAGS_HAS_AFC(f) (f & 0x20)
294 #define FLAGS_HAS_PAYLOAD(f) (f & 0x10)
295 #define FLAGS_CONTINUITY_COUNTER(f) (f & 0x0f)
300 guint8 payload_unit_start_indicator;
311 } MpegTSPacketizerPacket;
316 /* the spec says sub_table_extension is the fourth and fifth byte of a
317 * section when the section_syntax_indicator is set to a value of "1". If
318 * section_syntax_indicator is 0, sub_table_extension will be set to 0 */
319 guint16 subtable_extension;
320 guint8 version_number;
321 guint8 last_section_number;
322 /* table of bits, whether the section was seen or not.
323 * Use MPEGTS_BIT_* macros to check */
324 /* Size is 32, because there's a maximum of 256 (32*8) section_number */
325 guint8 seen_section[32];
326 } MpegTSPacketizerStreamSubtable;
328 #define MPEGTS_BIT_SET(field, offs) ((field)[(offs) >> 3] |= (1 << ((offs) & 0x7)))
329 #define MPEGTS_BIT_UNSET(field, offs) ((field)[(offs) >> 3] &= ~(1 << ((offs) & 0x7)))
330 #define MPEGTS_BIT_IS_SET(field, offs) ((field)[(offs) >> 3] & (1 << ((offs) & 0x7)))
336 } MpegTSPacketizerPacketReturn;
338 G_GNUC_INTERNAL GType mpegts_packetizer_get_type(void);
340 G_GNUC_INTERNAL MpegTSPacketizer2 *mpegts_packetizer_new (void);
341 G_GNUC_INTERNAL void mpegts_packetizer_clear (MpegTSPacketizer2 *packetizer);
342 G_GNUC_INTERNAL void mpegts_packetizer_flush (MpegTSPacketizer2 *packetizer, gboolean hard);
343 G_GNUC_INTERNAL void mpegts_packetizer_push (MpegTSPacketizer2 *packetizer, GstBuffer *buffer);
344 G_GNUC_INTERNAL gboolean mpegts_packetizer_has_packets (MpegTSPacketizer2 *packetizer);
345 G_GNUC_INTERNAL MpegTSPacketizerPacketReturn mpegts_packetizer_next_packet (MpegTSPacketizer2 *packetizer,
346 MpegTSPacketizerPacket *packet);
347 G_GNUC_INTERNAL MpegTSPacketizerPacketReturn
348 mpegts_packetizer_process_next_packet(MpegTSPacketizer2 * packetizer);
349 G_GNUC_INTERNAL void mpegts_packetizer_clear_packet (MpegTSPacketizer2 *packetizer,
350 MpegTSPacketizerPacket *packet);
351 G_GNUC_INTERNAL void mpegts_packetizer_remove_stream(MpegTSPacketizer2 *packetizer,
354 G_GNUC_INTERNAL GstMpegtsSection *mpegts_packetizer_push_section (MpegTSPacketizer2 *packetzer,
355 MpegTSPacketizerPacket *packet, GList **remaining);
357 /* Only valid if calculate_offset is TRUE */
358 G_GNUC_INTERNAL GstClockTime
359 mpegts_packetizer_offset_to_ts (MpegTSPacketizer2 * packetizer,
360 guint64 offset, guint16 pcr_pid);
361 G_GNUC_INTERNAL guint64
362 mpegts_packetizer_ts_to_offset (MpegTSPacketizer2 * packetizer,
363 GstClockTime ts, guint16 pcr_pid);
364 G_GNUC_INTERNAL GstClockTime
365 mpegts_packetizer_pts_to_ts (MpegTSPacketizer2 * packetizer,
366 GstClockTime pts, guint16 pcr_pid);
367 G_GNUC_INTERNAL GstClockTime
368 mpegts_packetizer_get_current_time (MpegTSPacketizer2 * packetizer,
371 mpegts_packetizer_set_current_pcr_offset (MpegTSPacketizer2 * packetizer,
372 GstClockTime offset, guint16 pcr_pid);
374 mpegts_packetizer_set_reference_offset (MpegTSPacketizer2 * packetizer,
377 mpegts_packetizer_set_pcr_discont_threshold (MpegTSPacketizer2 * packetizer,
378 GstClockTime threshold);
381 #endif /* GST_MPEGTS_PACKETIZER_H */