Line data Source code
1 : /*
2 : * GPAC - Multimedia Framework C SDK
3 : *
4 : * Authors: Jean Le Feuvre , Cyril Concolato, Romain Bouqueau
5 : * Copyright (c) Telecom ParisTech 2000-2020
6 : * All rights reserved
7 : *
8 : * This file is part of GPAC / MPEG2-TS multiplexer sub-project
9 : *
10 : * GPAC is free software; you can redistribute it and/or modify
11 : * it under the terms of the GNU Lesser General Public License as published by
12 : * the Free Software Foundation; either version 2, or (at your option)
13 : * any later version.
14 : *
15 : * GPAC is distributed in the hope that it will be useful,
16 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : * GNU Lesser General Public License for more details.
19 : *
20 : * You should have received a copy of the GNU Lesser General Public
21 : * License along with this library; see the file COPYING. If not, write to
22 : * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23 : *
24 : */
25 :
26 : #include <gpac/mpegts.h>
27 : #include <gpac/constants.h>
28 : #include <gpac/media_tools.h>
29 :
30 : #if !defined(GPAC_DISABLE_MPEG2TS_MUX)
31 :
32 : /* 90khz internal delay between two updates for bitrate compute per stream */
33 : #define BITRATE_UPDATE_WINDOW 90000
34 : /* length of adaptation_field_length; */
35 : #define ADAPTATION_LENGTH_LENGTH 1
36 : /* discontinuty flag, random access flag ... */
37 : #define ADAPTATION_FLAGS_LENGTH 1
38 : /* length of adaptation_extension_field_length; */
39 : #define ADAPTATION_EXTENSION_LENGTH_LENGTH 1
40 : /* AF des flags and co... */
41 : #define ADAPTATION_EXTENSION_FLAGS_LENGTH 1
42 : /* length of encoded pcr */
43 : #define PCR_LENGTH 6
44 :
45 : #define GF_LANG_UNKNOWN GF_4CC('u','n','d',' ')
46 :
47 : /*! DASH segment boundary information - these are internal to the muxer*/
48 : enum
49 : {
50 : /*! not a segment boundary*/
51 : GF_SEG_BOUNDARY_NONE=0,
52 : /*! segment start*/
53 : GF_SEG_BOUNDARY_START,
54 : /*! segment start with forced PMT - triggered by setting \ref struct __m2ts_mux.force_pat, triggers a forced PCR*/
55 : GF_SEG_BOUNDARY_FORCE_PMT,
56 : /*! segment start with forced PCR*/
57 : GF_SEG_BOUNDARY_FORCE_PCR,
58 : };
59 :
60 : static GFINLINE Bool gf_m2ts_time_less(GF_M2TS_Time *a, GF_M2TS_Time *b) {
61 149335 : if (a->sec>b->sec) return GF_FALSE;
62 145286 : if (a->sec==b->sec) return (a->nanosec<b->nanosec) ? GF_TRUE : GF_FALSE;
63 : return GF_TRUE;
64 : }
65 : static GFINLINE Bool gf_m2ts_time_equal(GF_M2TS_Time *a, GF_M2TS_Time *b) {
66 27437 : return ((a->sec==b->sec) && (a->nanosec == b->nanosec) );
67 : }
68 : static GFINLINE Bool gf_m2ts_time_less_or_equal(GF_M2TS_Time *a, GF_M2TS_Time *b) {
69 384211 : if (a->sec>b->sec) return GF_FALSE;
70 256400 : if (a->sec==b->sec) return (a->nanosec>b->nanosec) ? GF_FALSE : GF_TRUE;
71 : return GF_TRUE;
72 : }
73 :
74 123757 : static GFINLINE void gf_m2ts_time_inc(GF_M2TS_Time *time, u64 delta_inc_num, u32 delta_inc_den)
75 : {
76 : u64 n_sec;
77 : u64 sec;
78 :
79 : /*couldn't compute bitrate - we need to have more info*/
80 123757 : if (!delta_inc_den) return;
81 :
82 148993 : sec = delta_inc_num / delta_inc_den;
83 :
84 148993 : if (sec) {
85 19019 : time->sec += (u32) sec;
86 19019 : sec *= delta_inc_den;
87 19019 : delta_inc_num = delta_inc_num % sec;
88 : }
89 : /*move to nanosec - 0x3B9ACA00 = 1000*1000*1000 */
90 : n_sec = delta_inc_num;
91 148993 : n_sec *= 0x3B9ACA00;
92 148993 : n_sec /= delta_inc_den;
93 148993 : time->nanosec += (u32) n_sec;
94 274166 : while (time->nanosec >= 0x3B9ACA00) {
95 1416 : time->nanosec -= 0x3B9ACA00;
96 1416 : time->sec ++;
97 : }
98 : }
99 :
100 : static GFINLINE s32 gf_m2ts_time_diff_us(GF_M2TS_Time *a, GF_M2TS_Time *b)
101 : {
102 530 : s32 drift = b->nanosec;
103 1233 : drift -= a->nanosec;
104 1233 : drift /= 1000;
105 1233 : if (a->sec != b->sec) {
106 16 : drift += (b->sec - a->sec) * 1000000;
107 : }
108 : return drift;
109 : }
110 :
111 : /************************************
112 : * Section-related functions
113 : ************************************/
114 75 : void gf_m2ts_mux_table_update(GF_M2TS_Mux_Stream *stream, u8 table_id, u16 table_id_extension,
115 : u8 *table_payload, u32 table_payload_length,
116 : Bool use_syntax_indicator, Bool private_indicator,
117 : Bool use_checksum)
118 : {
119 : u32 overhead_size;
120 : u32 offset;
121 : u32 section_number, nb_sections;
122 : GF_M2TS_Mux_Table *table, *prev_table;
123 : u32 maxSectionLength;
124 : GF_M2TS_Mux_Section *section, *prev_sec;
125 :
126 : /* check if there is already a table with that id */
127 : prev_table = NULL;
128 75 : table = stream->tables;
129 150 : while (table) {
130 0 : if (table->table_id == table_id) {
131 : /* if yes, we need to flush the table and increase the version number */
132 0 : GF_M2TS_Mux_Section *sec = table->section;
133 0 : while (sec) {
134 0 : GF_M2TS_Mux_Section *sec2 = sec->next;
135 0 : gf_free(sec->data);
136 0 : gf_free(sec);
137 : sec = sec2;
138 : }
139 0 : table->version_number = (table->version_number + 1)%0x1F;
140 0 : break;
141 : }
142 : prev_table = table;
143 0 : table = table->next;
144 : }
145 :
146 75 : if (!table) {
147 : /* if no, the table is created */
148 75 : GF_SAFEALLOC(table, GF_M2TS_Mux_Table);
149 75 : if (!table) {
150 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: fail to allocate table id %d\n", stream->pid, table_id));
151 : return;
152 : }
153 75 : table->table_id = table_id;
154 75 : if (prev_table) prev_table->next = table;
155 75 : else stream->tables = table;
156 75 : table->version_number = stream->initial_version_number;
157 : }
158 :
159 75 : if (!table_payload_length) return;
160 :
161 75 : switch (table_id) {
162 : case GF_M2TS_TABLE_ID_PMT:
163 : case GF_M2TS_TABLE_ID_PAT:
164 : case GF_M2TS_TABLE_ID_SDT_ACTUAL:
165 : case GF_M2TS_TABLE_ID_SDT_OTHER:
166 : case GF_M2TS_TABLE_ID_TDT:
167 : case GF_M2TS_TABLE_ID_TOT:
168 : case GF_M2TS_TABLE_ID_BAT:
169 : maxSectionLength = 1024;
170 : break;
171 0 : case GF_M2TS_TABLE_ID_MPEG4_BIFS:
172 : case GF_M2TS_TABLE_ID_MPEG4_OD:
173 : maxSectionLength = 4096;
174 0 : break;
175 0 : default:
176 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: Cannot create sections for table id %d\n", stream->pid, table_id));
177 : return;
178 : }
179 :
180 : overhead_size = SECTION_HEADER_LENGTH;
181 75 : if (use_syntax_indicator) overhead_size += SECTION_ADDITIONAL_HEADER_LENGTH + CRC_LENGTH;
182 :
183 : section_number = 0;
184 : nb_sections = 1;
185 75 : while (nb_sections*(maxSectionLength - overhead_size)<table_payload_length) nb_sections++;
186 :
187 75 : switch (table_id) {
188 37 : case GF_M2TS_TABLE_ID_PMT:
189 37 : if (nb_sections > 1)
190 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] last section number for PMT shall be 0\n"));
191 : break;
192 : default:
193 : break;
194 : }
195 :
196 : prev_sec = NULL;
197 : offset = 0;
198 150 : while (offset < table_payload_length) {
199 : GF_BitStream *bs;
200 : u32 remain;
201 75 : GF_SAFEALLOC(section, GF_M2TS_Mux_Section);
202 75 : if (!section) {
203 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: fail to allocate section for table id %d\n", stream->pid, table_id));
204 : return;
205 : }
206 75 : remain = table_payload_length - offset;
207 75 : if (remain > maxSectionLength - overhead_size) {
208 0 : section->length = maxSectionLength;
209 : } else {
210 75 : section->length = remain + overhead_size;
211 : }
212 :
213 75 : bs = gf_bs_new(NULL,0,GF_BITSTREAM_WRITE);
214 :
215 : /* first header (not included in section length */
216 75 : gf_bs_write_int(bs, table_id, 8);
217 75 : gf_bs_write_int(bs, use_syntax_indicator, 1);
218 75 : gf_bs_write_int(bs, private_indicator, 1);
219 75 : gf_bs_write_int(bs, 3, 2); /* reserved bits are all set */
220 75 : gf_bs_write_int(bs, section->length - SECTION_HEADER_LENGTH, 12);
221 :
222 75 : if (use_syntax_indicator) {
223 : /* second header */
224 75 : gf_bs_write_int(bs, table_id_extension, 16);
225 75 : gf_bs_write_int(bs, 3, 2); /* reserved bits are all set */
226 75 : gf_bs_write_int(bs, table->version_number, 5);
227 75 : gf_bs_write_int(bs, 1, 1); /* current_next_indicator = 1: we don't send version in advance */
228 75 : gf_bs_write_int(bs, section_number, 8);
229 75 : section_number++;
230 75 : gf_bs_write_int(bs, nb_sections-1, 8);
231 : }
232 :
233 75 : gf_bs_write_data(bs, (char *) table_payload + offset, section->length - overhead_size);
234 75 : offset += section->length - overhead_size;
235 :
236 75 : if (use_syntax_indicator) {
237 : /* place holder for CRC */
238 75 : gf_bs_write_u32(bs, 0);
239 : }
240 :
241 75 : gf_bs_get_content(bs, §ion->data, §ion->length);
242 75 : gf_bs_del(bs);
243 :
244 75 : if (use_syntax_indicator) {
245 : u32 CRC;
246 75 : CRC = gf_crc_32((char *) section->data,section->length-CRC_LENGTH);
247 75 : section->data[section->length-4] = (CRC >> 24) & 0xFF;
248 75 : section->data[section->length-3] = (CRC >> 16) & 0xFF;
249 75 : section->data[section->length-2] = (CRC >> 8) & 0xFF;
250 75 : section->data[section->length-1] = CRC & 0xFF;
251 : }
252 :
253 75 : if (prev_sec) prev_sec->next = section;
254 75 : else table->section = section;
255 : prev_sec = section;
256 : }
257 75 : stream->current_table = stream->tables;
258 75 : stream->current_section = stream->current_table->section;
259 75 : stream->current_section_offset = 0;
260 :
261 75 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: Generating %d sections for table id %d - version number %d - extension ID %d\n", stream->pid, nb_sections, table_id, table->version_number, table_id_extension));
262 : }
263 :
264 12680 : void gf_m2ts_mux_table_update_bitrate(GF_M2TS_Mux *mux, GF_M2TS_Mux_Stream *stream)
265 : {
266 : GF_M2TS_Mux_Table *table;
267 :
268 : /*update PMT*/
269 12680 : if (stream->table_needs_update)
270 75 : stream->process(mux, stream);
271 :
272 12680 : stream->bit_rate = 0;
273 12680 : table = stream->tables;
274 38040 : while (table) {
275 12680 : GF_M2TS_Mux_Section *section = table->section;
276 38040 : while (section) {
277 : u32 nb_bytes = 0;
278 12680 : while (nb_bytes<section->length) nb_bytes += 188;
279 12680 : stream->bit_rate += nb_bytes;
280 12680 : section = section->next;
281 : }
282 12680 : table = table->next;
283 : }
284 12680 : stream->bit_rate *= 8;
285 12680 : stream->bit_rate *= 1000;
286 12680 : if (stream->refresh_rate_ms) {
287 12680 : stream->bit_rate /= stream->refresh_rate_ms;
288 0 : } else if (stream->table_needs_send) {
289 : /*no clue ... */
290 0 : stream->bit_rate /= 100;
291 : } else {
292 0 : stream->bit_rate = 0;
293 : }
294 12680 : }
295 :
296 2 : void gf_m2ts_mux_table_update_mpeg4(GF_M2TS_Mux_Stream *stream, u8 table_id, u16 table_id_extension,
297 : char *table_payload, u32 table_payload_length,
298 : Bool use_syntax_indicator, Bool private_indicator,
299 : Bool increment_version_number, Bool use_checksum)
300 : {
301 : GF_SLHeader hdr;
302 : u32 overhead_size;
303 : u32 offset, sl_size;
304 : u32 section_number, nb_sections;
305 : GF_M2TS_Mux_Table *table, *prev_table;
306 : /*max section length for MPEG-4 BIFS and OD*/
307 : u32 maxSectionLength = 4096;
308 : GF_M2TS_Mux_Section *section, *prev_sec;
309 :
310 : /* check if there is already a table with that id */
311 : prev_table = NULL;
312 2 : table = stream->tables;
313 4 : while (table) {
314 0 : if (table->table_id == table_id) {
315 : /* if yes, we need to flush the table and increase the version number */
316 0 : GF_M2TS_Mux_Section *sec = table->section;
317 0 : while (sec) {
318 0 : GF_M2TS_Mux_Section *sec2 = sec->next;
319 0 : gf_free(sec->data);
320 0 : gf_free(sec);
321 : sec = sec2;
322 : }
323 0 : if (increment_version_number)
324 0 : table->version_number = (table->version_number + 1)%0x1F;
325 : break;
326 : }
327 : prev_table = table;
328 0 : table = table->next;
329 : }
330 :
331 2 : if (!table) {
332 : /* if no, the table is created */
333 2 : GF_SAFEALLOC(table, GF_M2TS_Mux_Table);
334 2 : if (!table) {
335 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: fail to allocate table id %d\n", stream->pid, table_id));
336 0 : return;
337 : }
338 2 : table->table_id = table_id;
339 2 : if (prev_table) prev_table->next = table;
340 2 : else stream->tables = table;
341 : }
342 :
343 2 : if (!table_payload_length) return;
344 :
345 : overhead_size = SECTION_HEADER_LENGTH;
346 2 : if (use_syntax_indicator) overhead_size += SECTION_ADDITIONAL_HEADER_LENGTH + CRC_LENGTH;
347 :
348 : section_number = 0;
349 : nb_sections = 1;
350 2 : hdr = stream->sl_header;
351 2 : sl_size = gf_sl_get_header_size(stream->ifce->sl_config, &hdr);
352 : /*SL-packetized data doesn't fit in one section, we must repacketize*/
353 2 : if (sl_size + table_payload_length > maxSectionLength - overhead_size) {
354 : nb_sections = 0;
355 : offset = 0;
356 0 : hdr.accessUnitEndFlag = 0;
357 0 : while (offset<table_payload_length) {
358 0 : sl_size = gf_sl_get_header_size(stream->ifce->sl_config, &hdr);
359 : /*remove start flag*/
360 0 : hdr.accessUnitStartFlag = 0;
361 : /*fill each section but beware of last packet*/
362 0 : offset += maxSectionLength - overhead_size - sl_size;
363 0 : nb_sections++;
364 : }
365 : }
366 : prev_sec = NULL;
367 : offset = 0;
368 2 : hdr = stream->sl_header;
369 6 : while (offset < table_payload_length) {
370 : GF_BitStream *bs;
371 : u32 remain;
372 : u8 *slhdr;
373 : u32 slhdr_size;
374 2 : GF_SAFEALLOC(section, GF_M2TS_Mux_Section);
375 2 : if (!section) {
376 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: fail to allocate section for table id %d\n", stream->pid, table_id));
377 0 : return;
378 : }
379 :
380 2 : hdr.accessUnitEndFlag = (section_number+1==nb_sections) ? stream->sl_header.accessUnitEndFlag : 0;
381 2 : gf_sl_packetize(stream->ifce->sl_config, &hdr, NULL, 0, &slhdr, &slhdr_size);
382 2 : hdr.accessUnitStartFlag = 0;
383 :
384 2 : remain = table_payload_length - offset;
385 2 : if (remain > maxSectionLength - overhead_size - slhdr_size) {
386 0 : section->length = maxSectionLength;
387 : } else {
388 2 : section->length = remain + overhead_size + slhdr_size;
389 : }
390 2 : sl_size = section->length - overhead_size - slhdr_size;
391 :
392 2 : bs = gf_bs_new(NULL,0,GF_BITSTREAM_WRITE);
393 :
394 : /* first header (not included in section length */
395 2 : gf_bs_write_int(bs, table_id, 8);
396 2 : gf_bs_write_int(bs, use_syntax_indicator, 1);
397 2 : gf_bs_write_int(bs, private_indicator, 1);
398 2 : gf_bs_write_int(bs, 3, 2); /* reserved bits are all set */
399 2 : gf_bs_write_int(bs, section->length - SECTION_HEADER_LENGTH, 12);
400 :
401 2 : if (use_syntax_indicator) {
402 : /* second header */
403 2 : gf_bs_write_int(bs, table_id_extension, 16);
404 2 : gf_bs_write_int(bs, 3, 2); /* reserved bits are all set */
405 2 : gf_bs_write_int(bs, table->version_number, 5);
406 2 : gf_bs_write_int(bs, 1, 1); /* current_next_indicator = 1: we don't send version in advance */
407 2 : gf_bs_write_int(bs, section_number, 8);
408 : section_number++;
409 2 : gf_bs_write_int(bs, nb_sections-1, 8);
410 : }
411 :
412 : /*write sl header*/
413 2 : gf_bs_write_data(bs, slhdr, slhdr_size);
414 2 : gf_free(slhdr);
415 : /*write sl data*/
416 2 : gf_bs_write_data(bs, (char *) table_payload + offset, sl_size);
417 2 : offset += sl_size;
418 :
419 2 : if (use_syntax_indicator) {
420 : /* place holder for CRC */
421 2 : gf_bs_write_u32(bs, 0);
422 : }
423 :
424 2 : gf_bs_get_content(bs, §ion->data, §ion->length);
425 2 : gf_bs_del(bs);
426 :
427 2 : if (use_syntax_indicator) {
428 : u32 CRC;
429 2 : CRC = gf_crc_32((char *) section->data,section->length-CRC_LENGTH);
430 2 : section->data[section->length-4] = (CRC >> 24) & 0xFF;
431 2 : section->data[section->length-3] = (CRC >> 16) & 0xFF;
432 2 : section->data[section->length-2] = (CRC >> 8) & 0xFF;
433 2 : section->data[section->length-1] = CRC & 0xFF;
434 : }
435 :
436 2 : if (prev_sec) prev_sec->next = section;
437 2 : else table->section = section;
438 : prev_sec = section;
439 : }
440 2 : stream->current_table = stream->tables;
441 2 : stream->current_section = stream->current_table->section;
442 2 : stream->current_section_offset = 0;
443 2 : stream->table_needs_send = GF_TRUE;
444 :
445 2 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: Generating %d sections for MPEG-4 SL packet - version number %d - extension ID %d\n", stream->pid, nb_sections, table->version_number, table_id_extension));
446 :
447 : /*MPEG-4 tables are input streams for the mux, the bitrate is updated when fetching AUs*/
448 : }
449 :
450 21720 : static u32 gf_m2ts_add_adaptation(GF_M2TS_Mux_Program *prog, GF_BitStream *bs, u16 pid,
451 : Bool has_pcr, u64 pcr_time,
452 : Bool is_rap,
453 : u32 padding_length,
454 : char *af_descriptors, u32 af_descriptors_size, Bool set_discontinuity)
455 : {
456 : u32 adaptation_length;
457 :
458 21720 : adaptation_length = ADAPTATION_FLAGS_LENGTH + (has_pcr?PCR_LENGTH:0) + padding_length;
459 :
460 :
461 21720 : if (af_descriptors_size && af_descriptors) {
462 676 : adaptation_length += ADAPTATION_EXTENSION_LENGTH_LENGTH + ADAPTATION_EXTENSION_FLAGS_LENGTH + af_descriptors_size;
463 : }
464 :
465 21720 : gf_bs_write_int(bs, adaptation_length, 8);
466 21720 : gf_bs_write_int(bs, set_discontinuity ? 1 : 0, 1); // discontinuity indicator
467 21720 : gf_bs_write_int(bs, is_rap, 1); // random access indicator
468 21720 : gf_bs_write_int(bs, 0, 1); // es priority indicator
469 21720 : gf_bs_write_int(bs, has_pcr, 1); // PCR_flag
470 21720 : gf_bs_write_int(bs, 0, 1); // OPCR flag
471 21720 : gf_bs_write_int(bs, 0, 1); // splicing point flag
472 21720 : gf_bs_write_int(bs, 0, 1); // transport private data flag
473 21720 : gf_bs_write_int(bs, af_descriptors_size ? 1 : 0, 1); // adaptation field extension flag
474 21720 : if (has_pcr) {
475 : u64 PCR_base, PCR_ext;
476 10675 : PCR_base = pcr_time/300;
477 10675 : gf_bs_write_long_int(bs, PCR_base, 33);
478 10675 : gf_bs_write_int(bs, 0, 6); // reserved
479 : PCR_ext = pcr_time - PCR_base*300;
480 10675 : gf_bs_write_long_int(bs, PCR_ext, 9);
481 10675 : if (prog->last_pcr > pcr_time) {
482 0 : GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: Sending PCR "LLD" earlier than previous PCR "LLD" - drift %f sec - discontinuity set\n", pid, pcr_time, prog->last_pcr, (prog->last_pcr - pcr_time) /27000000.0 ));
483 : }
484 10675 : prog->last_pcr = pcr_time;
485 :
486 : #ifndef GPAC_DISABLE_LOG
487 10675 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: Adding adaptation field size %d - RAP %d - Padding %d - PCR "LLD"\n", pid, adaptation_length, is_rap, padding_length, pcr_time));
488 : } else {
489 11045 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: Adding adaptation field size %d - RAP %d - Padding %d\n", pid, adaptation_length, is_rap, padding_length));
490 : #endif
491 :
492 : }
493 :
494 21720 : if (af_descriptors_size) {
495 676 : gf_bs_write_int(bs, ADAPTATION_EXTENSION_FLAGS_LENGTH + af_descriptors_size, 8);
496 :
497 676 : gf_bs_write_int(bs, 0, 1); // ltw_flag
498 676 : gf_bs_write_int(bs, 0, 1); // piecewise_rate_flag
499 676 : gf_bs_write_int(bs, 0, 1); // seamless_splice_flag
500 676 : gf_bs_write_int(bs, 0, 1); // af_descriptor_not_present_flag
501 676 : gf_bs_write_int(bs, 0xF, 4); // reserved
502 :
503 676 : gf_bs_write_data(bs, af_descriptors, af_descriptors_size);
504 : }
505 :
506 21720 : gf_bs_write_byte(bs, 0xFF, padding_length); // stuffing byte
507 :
508 21720 : return adaptation_length + ADAPTATION_LENGTH_LENGTH;
509 : }
510 :
511 : //#define USE_AF_STUFFING
512 :
513 4684 : void gf_m2ts_mux_table_get_next_packet(GF_M2TS_Mux *mux, GF_M2TS_Mux_Stream *stream, char *packet)
514 : {
515 : GF_BitStream *bs;
516 : GF_M2TS_Mux_Table *table;
517 : GF_M2TS_Mux_Section *section;
518 : u32 payload_length, payload_start;
519 : u8 adaptation_field_control = GF_M2TS_ADAPTATION_NONE;
520 : #ifndef USE_AF_STUFFING
521 : u32 padded_bytes=0;
522 : #else
523 : u32 padding_length = 0;
524 : #endif
525 :
526 4684 : stream->table_needs_send = GF_FALSE;
527 4684 : table = stream->current_table;
528 4684 : if (!table) {
529 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] Invalid muxer state, table is NULL!\n"));
530 : return;
531 : }
532 :
533 4684 : section = stream->current_section;
534 : assert(section);
535 :
536 4684 : bs = mux->pck_bs;
537 4684 : gf_bs_reassign_buffer(bs, packet, 188);
538 :
539 4684 : gf_bs_write_int(bs, 0x47, 8); // sync
540 4684 : gf_bs_write_int(bs, 0, 1); // error indicator
541 4684 : if (stream->current_section_offset == 0) {
542 4683 : gf_bs_write_int(bs, 1, 1); // payload start indicator
543 : } else {
544 : /* No section concatenation yet!!!*/
545 1 : gf_bs_write_int(bs, 0, 1); // payload start indicator
546 : }
547 :
548 4684 : if (!stream->current_section_offset) payload_length = 183;
549 : else payload_length = 184;
550 :
551 : payload_start = payload_length;
552 :
553 4684 : if (section->length - stream->current_section_offset >= payload_length) {
554 :
555 : } else {
556 : //stuffing using adaptation field - seems not well handled by some equipments ...
557 : #ifdef USE_AF_STUFFING
558 : /* in all the following cases, we write an adaptation field */
559 : adaptation_field_control = GF_M2TS_ADAPTATION_AND_PAYLOAD;
560 : /* we need at least 2 bytes for adaptation field headers (no pcr) */
561 : payload_length -= 2;
562 : if (section->length - stream->current_section_offset >= payload_length) {
563 : padding_length = 0;
564 : } else {
565 : padding_length = payload_length - section->length + stream->current_section_offset;
566 : payload_length -= padding_length;
567 : }
568 : #else
569 : //stuffing according to annex C.3
570 4683 : padded_bytes = payload_length - section->length + stream->current_section_offset;
571 : payload_length = section->length - stream->current_section_offset;
572 : #endif
573 : }
574 :
575 : assert(payload_length + stream->current_section_offset <= section->length);
576 :
577 : //CC field shall not be incremented for if adaptation field only, rewind counter
578 : if (adaptation_field_control == GF_M2TS_ADAPTATION_ONLY) {
579 : if (!stream->continuity_counter) stream->continuity_counter=15;
580 : else stream->continuity_counter--;
581 : }
582 :
583 4684 : gf_bs_write_int(bs, 0, 1); /*priority indicator*/
584 4684 : gf_bs_write_int(bs, stream->pid, 13); /*pid*/
585 4684 : gf_bs_write_int(bs, 0, 2); /*scrambling indicator*/
586 4684 : gf_bs_write_int(bs, adaptation_field_control, 2); /*we do not use adaptation field for sections */
587 4684 : gf_bs_write_int(bs, stream->continuity_counter, 4); /*continuity counter*/
588 :
589 4684 : if (stream->continuity_counter < 15) stream->continuity_counter++;
590 262 : else stream->continuity_counter=0;
591 :
592 : #ifdef USE_AF_STUFFING
593 : if (adaptation_field_control != GF_M2TS_ADAPTATION_NONE)
594 : gf_m2ts_add_adaptation(stream->program, bs, stream->pid, 0, 0, 0, padding_length, NULL, 0, GF_FALSE);
595 : #endif
596 :
597 : /*pointer field*/
598 4684 : if (!stream->current_section_offset) {
599 : /* no concatenations of sections in ts packets, so start address is 0 */
600 4683 : gf_bs_write_u8(bs, 0);
601 : }
602 :
603 4684 : memcpy(packet+188-payload_start, section->data + stream->current_section_offset, payload_length);
604 4684 : stream->current_section_offset += payload_length;
605 : #ifndef USE_AF_STUFFING
606 4684 : if (padded_bytes) memset(packet+188-payload_start+payload_length, 0xFF, padded_bytes);
607 : #endif
608 :
609 4684 : if (stream->current_section_offset == section->length) {
610 4683 : stream->current_section_offset = 0;
611 4683 : stream->current_section = stream->current_section->next;
612 4683 : if (!stream->current_section) {
613 4683 : stream->current_table = stream->current_table->next;
614 : /*carousel table*/
615 4683 : if (!stream->current_table) {
616 4683 : if (stream->ifce) stream->refresh_rate_ms = stream->ifce->repeat_rate;
617 4683 : if (stream->refresh_rate_ms) {
618 4681 : stream->current_table = stream->tables;
619 : /*update ES time*/
620 4681 : gf_m2ts_time_inc(&stream->time, stream->refresh_rate_ms, 1000);
621 : }
622 : }
623 4683 : if (stream->current_table) stream->current_section = stream->current_table->section;
624 : }
625 : }
626 : /*updates number of bytes sent for bitrate compute (MPEG4 sections)*/
627 4684 : stream->bytes_since_last_time += 188;
628 : }
629 :
630 :
631 1165 : u32 gf_m2ts_stream_process_sdt(GF_M2TS_Mux *muxer, GF_M2TS_Mux_Stream *stream)
632 : {
633 1165 : if (stream->table_needs_update) { /* generate table payload */
634 : GF_M2TS_Mux_Program *prog;
635 : GF_BitStream *bs;
636 : u8 *payload;
637 : u32 size;
638 :
639 1 : bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
640 :
641 1 : gf_bs_write_u16(bs, muxer->ts_id);
642 1 : gf_bs_write_u8(bs, 0xFF); //reserved future use
643 :
644 1 : prog = muxer->programs;
645 3 : while (prog) {
646 : u32 len = 0;
647 1 : gf_bs_write_u16(bs, prog->number);
648 1 : gf_bs_write_int(bs, 0xFF, 6); //reserved future use
649 1 : gf_bs_write_int(bs, 0, 1); //EIT_schedule_flag
650 1 : gf_bs_write_int(bs, 0, 1); //EIT_present_following_flag
651 1 : gf_bs_write_int(bs, 4, 3); //running status
652 1 : gf_bs_write_int(bs, 0, 1); //free_CA_mode
653 :
654 1 : if (prog->name) len += (u32) strlen(prog->name);
655 1 : if (prog->provider) len += (u32) strlen(prog->provider);
656 :
657 1 : if (len) {
658 1 : len += 3;
659 1 : gf_bs_write_int(bs, len + 2, 12);
660 1 : gf_bs_write_u8(bs, GF_M2TS_DVB_SERVICE_DESCRIPTOR);
661 1 : gf_bs_write_u8(bs, len);
662 1 : gf_bs_write_u8(bs, 0x01);
663 1 : len = prog->provider ? (u32) strlen(prog->provider) : 0;
664 1 : gf_bs_write_u8(bs, len);
665 1 : if (prog->provider) gf_bs_write_data(bs, prog->provider, len);
666 :
667 1 : len = prog->name ? (u32) strlen(prog->name) : 0;
668 1 : gf_bs_write_u8(bs, len);
669 1 : if (prog->name) gf_bs_write_data(bs, prog->name, len);
670 : } else {
671 0 : gf_bs_write_int(bs, 0, 12);
672 : }
673 1 : prog = prog->next;
674 : }
675 1 : gf_bs_get_content(bs, &payload, &size);
676 1 : gf_bs_del(bs);
677 1 : gf_m2ts_mux_table_update(stream, GF_M2TS_TABLE_ID_SDT_ACTUAL, muxer->ts_id, payload, size, GF_TRUE, GF_FALSE, GF_FALSE);
678 1 : stream->table_needs_update = GF_FALSE;
679 1 : stream->table_needs_send = GF_TRUE;
680 1 : gf_free(payload);
681 : }
682 1165 : if (stream->table_needs_send)
683 : return 1;
684 1163 : if (stream->refresh_rate_ms)
685 : return 1;
686 0 : return 0;
687 : }
688 :
689 131667 : u32 gf_m2ts_stream_process_pat(GF_M2TS_Mux *muxer, GF_M2TS_Mux_Stream *stream)
690 : {
691 131667 : if (stream->table_needs_update) { /* generate table payload */
692 : GF_M2TS_Mux_Program *prog;
693 : GF_BitStream *bs;
694 : u8 *payload;
695 : u32 size;
696 :
697 37 : bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
698 37 : prog = muxer->programs;
699 111 : while (prog) {
700 37 : gf_bs_write_u16(bs, prog->number);
701 37 : gf_bs_write_int(bs, 0x7, 3); /*reserved*/
702 37 : gf_bs_write_int(bs, prog->pmt->pid, 13); /*reserved*/
703 37 : prog = prog->next;
704 : }
705 37 : gf_bs_get_content(bs, &payload, &size);
706 37 : gf_bs_del(bs);
707 37 : gf_m2ts_mux_table_update(stream, GF_M2TS_TABLE_ID_PAT, muxer->ts_id, payload, size, GF_TRUE, GF_FALSE, GF_FALSE);
708 37 : stream->table_needs_update = GF_FALSE;
709 37 : stream->table_needs_send = GF_TRUE;
710 37 : gf_free(payload);
711 : }
712 131667 : if (stream->table_needs_send)
713 : return 1;
714 131593 : if (stream->refresh_rate_ms)
715 : return 1;
716 0 : return 0;
717 : }
718 :
719 129319 : u32 gf_m2ts_stream_process_pmt(GF_M2TS_Mux *muxer, GF_M2TS_Mux_Stream *stream)
720 : {
721 129319 : if (stream->table_needs_update) { /* generate table payload */
722 : GF_M2TS_Mux_Stream *es;
723 : u8 *payload;
724 : u32 i;
725 : u32 length, nb_streams=0;
726 : u32 info_length = 0;
727 : GF_BitStream *bs;
728 :
729 37 : if (!stream->program->pcr)
730 0 : abort();
731 :
732 37 : bs = gf_bs_new(NULL,0,GF_BITSTREAM_WRITE);
733 37 : gf_bs_write_int(bs, 0x7, 3); // reserved
734 37 : gf_bs_write_int(bs, stream->program->pcr->pid, 13);
735 37 : gf_bs_write_int(bs, 0xF, 4); // reserved
736 :
737 :
738 37 : if (stream->program->loop_descriptors) {
739 39 : for (i=0; i<gf_list_count(stream->program->loop_descriptors); i++) {
740 2 : GF_M2TSDescriptor *desc = (GF_M2TSDescriptor*)gf_list_get(stream->program->loop_descriptors, i);
741 2 : info_length += 2 + desc->data_len;
742 : }
743 : }
744 :
745 37 : if (!stream->program->iod) {
746 36 : gf_bs_write_int(bs, info_length, 12); // program info length =0
747 : } else {
748 : u32 len;
749 : GF_ESD *esd;
750 : GF_BitStream *bs_iod;
751 : u8 *iod_data;
752 : u32 iod_data_len;
753 :
754 : /*rewrite SL config in IOD streams*/
755 1 : i=0;
756 4 : while (NULL != (esd = (GF_ESD*)gf_list_enum(((GF_ObjectDescriptor*)stream->program->iod)->ESDescriptors, &i))) {
757 2 : GF_M2TS_Mux_Stream *es_stream = stream->program->streams;
758 7 : while (es_stream) {
759 5 : if (es_stream->ifce && (es_stream->ifce->stream_id==esd->ESID)) {
760 : /*thay should be the same ...*/
761 2 : memcpy(esd->slConfig, es_stream->ifce->sl_config, sizeof(GF_SLConfig));
762 : break;
763 : }
764 3 : es_stream = es_stream->next;
765 : }
766 : }
767 :
768 1 : bs_iod = gf_bs_new(NULL,0,GF_BITSTREAM_WRITE);
769 1 : gf_odf_write_descriptor(bs_iod, stream->program->iod);
770 1 : gf_bs_get_content(bs_iod, &iod_data, &iod_data_len);
771 1 : gf_bs_del(bs_iod);
772 :
773 1 : len = iod_data_len + 4;
774 1 : gf_bs_write_int(bs, len + info_length, 12); // program info length
775 :
776 1 : gf_bs_write_int(bs, GF_M2TS_MPEG4_IOD_DESCRIPTOR, 8);
777 1 : len = iod_data_len + 2;
778 1 : gf_bs_write_int(bs, len, 8);
779 :
780 : /* Scope_of_IOD_label :
781 : 0x10 iod unique a l'int�rieur de programme
782 : 0x11 iod unoque dans le flux ts */
783 1 : gf_bs_write_int(bs, 2, 8);
784 :
785 1 : gf_bs_write_int(bs, 2, 8); // IOD_label
786 :
787 1 : gf_bs_write_data(bs, iod_data, iod_data_len);
788 1 : gf_free(iod_data);
789 : }
790 :
791 : /*write all other descriptors*/
792 37 : if (stream->program->loop_descriptors) {
793 39 : for (i=0; i<gf_list_count(stream->program->loop_descriptors); i++) {
794 2 : GF_M2TSDescriptor *desc = (GF_M2TSDescriptor*)gf_list_get(stream->program->loop_descriptors, i);
795 2 : gf_bs_write_int(bs, desc->tag, 8);
796 2 : gf_bs_write_int(bs, desc->data_len, 8);
797 2 : gf_bs_write_data(bs, desc->data, desc->data_len);
798 : }
799 : }
800 :
801 37 : es = stream->program->streams;
802 123 : while (es) {
803 : Bool has_lang = GF_FALSE;
804 : u32 es_info_length = 0;
805 49 : u8 type = es->mpeg2_stream_type;
806 49 : nb_streams++;
807 :
808 49 : switch (es->mpeg2_stream_type) {
809 : case GF_M2TS_AUDIO_AC3:
810 : case GF_M2TS_VIDEO_VC1:
811 : es_info_length += 2 + 4;
812 : type = GF_M2TS_PRIVATE_DATA;
813 : break;
814 0 : case GF_M2TS_AUDIO_EC3:
815 : es_info_length += 2;
816 : type = GF_M2TS_PRIVATE_DATA;
817 0 : break;
818 47 : default:
819 47 : if (es->force_reg_desc) {
820 : es_info_length += 2 + 4 + 4;
821 : type = GF_M2TS_PRIVATE_DATA;
822 : }
823 : break;
824 : }
825 :
826 49 : gf_bs_write_int(bs, type, 8);
827 49 : gf_bs_write_int(bs, 0x7, 3); // reserved
828 49 : gf_bs_write_int(bs, es->pid, 13);
829 49 : gf_bs_write_int(bs, 0xF, 4); // reserved
830 :
831 : /*calculate es_info_length*/
832 49 : if (stream->program->iod && es->ifce && !(es->ifce->caps & GF_ESI_STREAM_WITHOUT_MPEG4_SYSTEMS))
833 3 : es_info_length += 4;
834 :
835 : /*another loop descriptors*/
836 49 : if (es->loop_descriptors)
837 : {
838 52 : for (i=0; i<gf_list_count(es->loop_descriptors); i++)
839 : {
840 3 : GF_M2TSDescriptor *desc = (GF_M2TSDescriptor*)gf_list_get(es->loop_descriptors, i);
841 3 : es_info_length += 2 +desc->data_len;
842 : }
843 : }
844 :
845 49 : if (es->ifce && es->ifce->lang && (es->ifce->lang != GF_LANG_UNKNOWN) ) {
846 2 : es_info_length += 2 + 3;
847 : has_lang = GF_TRUE;
848 : }
849 :
850 49 : gf_bs_write_int(bs, es_info_length, 12);
851 :
852 49 : if (stream->program->iod && es->ifce && !(es->ifce->caps & GF_ESI_STREAM_WITHOUT_MPEG4_SYSTEMS)) {
853 3 : gf_bs_write_int(bs, GF_M2TS_MPEG4_SL_DESCRIPTOR, 8);
854 3 : gf_bs_write_int(bs, 2, 8);
855 3 : gf_bs_write_int(bs, es->ifce->stream_id, 16); // mpeg4_esid
856 : }
857 :
858 49 : if (has_lang) {
859 2 : gf_bs_write_int(bs, GF_M2TS_ISO_639_LANGUAGE_DESCRIPTOR, 8);
860 2 : gf_bs_write_int(bs, 3, 8);
861 2 : gf_bs_write_int(bs, (es->ifce->lang>>24) & 0xFF, 8);
862 2 : gf_bs_write_int(bs, (es->ifce->lang>>16) & 0xFF, 8);
863 2 : gf_bs_write_int(bs, es->ifce->lang & 0xFF, 8);
864 : }
865 :
866 49 : switch (es->mpeg2_stream_type) {
867 2 : case GF_M2TS_AUDIO_AC3:
868 2 : gf_bs_write_int(bs, GF_M2TS_REGISTRATION_DESCRIPTOR, 8);
869 2 : gf_bs_write_int(bs, 4, 8);
870 2 : gf_bs_write_int(bs, 'A', 8);
871 2 : gf_bs_write_int(bs, 'C', 8);
872 2 : gf_bs_write_int(bs, '-', 8);
873 2 : gf_bs_write_int(bs, '3', 8);
874 2 : break;
875 0 : case GF_M2TS_VIDEO_VC1:
876 0 : gf_bs_write_int(bs, GF_M2TS_REGISTRATION_DESCRIPTOR, 8);
877 0 : gf_bs_write_int(bs, 4, 8);
878 0 : gf_bs_write_int(bs, 'V', 8);
879 0 : gf_bs_write_int(bs, 'C', 8);
880 0 : gf_bs_write_int(bs, '-', 8);
881 0 : gf_bs_write_int(bs, '1', 8);
882 0 : break;
883 0 : case GF_M2TS_AUDIO_EC3:
884 0 : gf_bs_write_int(bs, GF_M2TS_DVB_EAC3_DESCRIPTOR, 8);
885 0 : gf_bs_write_int(bs, 0, 8); //check what is in this desc
886 0 : break;
887 47 : default:
888 47 : if (es->force_reg_desc && es->ifce && es->ifce->codecid) {
889 2 : gf_bs_write_int(bs, GF_M2TS_REGISTRATION_DESCRIPTOR, 8);
890 2 : gf_bs_write_int(bs, 8, 8);
891 2 : gf_bs_write_int(bs, GF_M2TS_RA_STREAM_GPAC, 32);
892 2 : gf_bs_write_int(bs, es->ifce->codecid, 32);
893 : }
894 : break;
895 : }
896 :
897 49 : if (es->loop_descriptors)
898 : {
899 52 : for (i=0; i<gf_list_count(es->loop_descriptors); i++)
900 : {
901 3 : GF_M2TSDescriptor *desc = (GF_M2TSDescriptor *)gf_list_get(es->loop_descriptors, i);
902 3 : gf_bs_write_int(bs, desc->tag, 8);
903 3 : gf_bs_write_int(bs, desc->data_len, 8);
904 3 : gf_bs_write_data(bs, desc->data, desc->data_len);
905 : }
906 : }
907 :
908 49 : es = es->next;
909 : }
910 :
911 37 : gf_bs_get_content(bs, &payload, &length);
912 37 : gf_bs_del(bs);
913 :
914 37 : gf_m2ts_mux_table_update(stream, GF_M2TS_TABLE_ID_PMT, stream->program->number, payload, length, GF_TRUE, GF_FALSE, GF_FALSE);
915 37 : stream->table_needs_update = GF_FALSE;
916 37 : stream->table_needs_send = GF_TRUE;
917 37 : gf_free(payload);
918 :
919 37 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: Updating PMT - Program Number %d - %d streams - size %d%s\n", stream->pid, stream->program->number, nb_streams, length, stream->program->iod ? " - MPEG-4 Systems detected":""));
920 : }
921 129319 : if (stream->table_needs_send)
922 : return 1;
923 129245 : if (stream->refresh_rate_ms)
924 : return 1;
925 0 : return 0;
926 : }
927 :
928 24107 : static void gf_m2ts_remap_timestamps_for_pes(GF_M2TS_Mux_Stream *stream, u32 pck_flags, u64 *dts, u64 *cts, u32 *duration)
929 : {
930 : u64 pcr_offset;
931 :
932 24107 : if (*dts > *cts) {
933 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: DTS "LLD" is greater than CTS "LLD" (like ISOBMF CTTSv1 input) - adjusting to CTS\n", stream->pid, *dts, *cts));
934 0 : *dts = *cts;
935 : }
936 :
937 : /*Rescale our timestamps and express them in PCR*/
938 24107 : if (stream->ts_scale.den) {
939 23916 : *cts = *cts * stream->ts_scale.num / stream->ts_scale.den ;
940 23916 : *dts = *dts * stream->ts_scale.num / stream->ts_scale.den ;
941 23916 : if (duration) *duration = (u32)( *duration * stream->ts_scale.num / stream->ts_scale.den ) ;
942 : }
943 24107 : if (!stream->program->initial_ts_set) {
944 36 : u32 nb_bits = (u32) (stream->program->mux->tot_pck_sent - stream->program->num_pck_at_pcr_init) * 1504;
945 36 : u64 nb_ticks = 90000*nb_bits / stream->program->mux->bit_rate;
946 36 : stream->program->initial_ts = *dts;
947 :
948 36 : if (stream->program->initial_ts > nb_ticks)
949 0 : stream->program->initial_ts -= nb_ticks;
950 : else
951 36 : stream->program->initial_ts = 0;
952 :
953 36 : stream->program->initial_ts_set = 1;
954 : }
955 24071 : else if ( (*dts < stream->program->initial_ts) && (stream->program->initial_ts_set==1)) {
956 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: DTS "LLD" is less than initial DTS "LLD" - adjusting\n", stream->pid, *dts, stream->program->initial_ts));
957 0 : stream->program->initial_ts = *dts;
958 : }
959 24071 : else if (*dts < stream->last_dts) {
960 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: DTS "LLD" is less than last sent DTS "LLD"\n", stream->pid, *dts, stream->last_dts));
961 0 : stream->last_dts = *dts;
962 : } else {
963 24071 : stream->last_dts = *dts;
964 : }
965 :
966 : /*offset our timestamps*/
967 24107 : *cts += stream->program->pcr_offset;
968 24107 : *dts += stream->program->pcr_offset;
969 :
970 : /*PCR offset, in 90000 hz not in 270000000*/
971 24107 : pcr_offset = stream->program->pcr_init_time/300;
972 24107 : *cts = *cts - stream->program->initial_ts + pcr_offset;
973 24107 : *dts = *dts - stream->program->initial_ts + pcr_offset;
974 24107 : }
975 :
976 42 : void id3_write_size(GF_BitStream *bs, u32 len)
977 : {
978 : u32 size;
979 :
980 42 : size = (len>>21) & 0x7F;
981 42 : gf_bs_write_int(bs, 0, 1);
982 42 : gf_bs_write_int(bs, size, 7);
983 :
984 42 : size = (len>>14) & 0x7F;
985 42 : gf_bs_write_int(bs, 0, 1);
986 42 : gf_bs_write_int(bs, size, 7);
987 :
988 42 : size = (len>>7) & 0x7F;
989 42 : gf_bs_write_int(bs, 0, 1);
990 42 : gf_bs_write_int(bs, size, 7);
991 :
992 42 : size = (len) & 0x7F;
993 42 : gf_bs_write_int(bs, 0, 1);
994 42 : gf_bs_write_int(bs, size, 7);
995 42 : }
996 :
997 21 : static void id3_tag_create(u8 **input, u32 *len)
998 : {
999 21 : GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
1000 21 : gf_bs_write_u8(bs, 'I');
1001 21 : gf_bs_write_u8(bs, 'D');
1002 21 : gf_bs_write_u8(bs, '3');
1003 21 : gf_bs_write_u8(bs, 4); //major
1004 21 : gf_bs_write_u8(bs, 0); //minor
1005 21 : gf_bs_write_u8(bs, 0); //flags
1006 :
1007 21 : id3_write_size(bs, *len + 10);
1008 :
1009 21 : gf_bs_write_u32(bs, GF_ID3V2_FRAME_TXXX);
1010 21 : id3_write_size(bs, *len); /* size of the text */
1011 21 : gf_bs_write_u8(bs, 0);
1012 21 : gf_bs_write_u8(bs, 0);
1013 21 : gf_bs_write_data(bs, *input, *len);
1014 21 : gf_free(*input);
1015 21 : gf_bs_get_content(bs, input, len);
1016 21 : gf_bs_del(bs);
1017 21 : }
1018 :
1019 13232 : static Bool gf_m2ts_adjust_next_stream_time_for_pcr(GF_M2TS_Mux *muxer, GF_M2TS_Mux_Stream *stream)
1020 : {
1021 : u32 pck_diff;
1022 : s32 us_diff;
1023 : GF_M2TS_Time next_pcr_time, stream_time;
1024 :
1025 13232 : if (!muxer->enable_forced_pcr) return 1;
1026 :
1027 703 : if (!muxer->bit_rate) return 1;
1028 :
1029 703 : next_pcr_time = stream->program->ts_time_at_pcr_init;
1030 703 : pck_diff = (u32) (stream->program->nb_pck_last_pcr - stream->program->num_pck_at_pcr_init);
1031 703 : gf_m2ts_time_inc(&next_pcr_time, pck_diff*1504, stream->program->mux->bit_rate);
1032 703 : gf_m2ts_time_inc(&next_pcr_time, stream->program->mux->pcr_update_ms, 1000);
1033 :
1034 703 : stream_time = stream->pcr_only_mode ? stream->next_time : stream->time;
1035 : //If next_pcr_time < stream->time, we need to inject pure pcr data
1036 : us_diff = gf_m2ts_time_diff_us(&next_pcr_time, &stream_time);
1037 703 : if (us_diff > 0) {
1038 530 : if (!stream->pcr_only_mode) {
1039 77 : stream->pcr_only_mode = GF_TRUE;
1040 77 : stream->next_time = stream->time;
1041 : }
1042 530 : stream->time = next_pcr_time;
1043 : /*if too ahead of mux time, don't insert PCR*/
1044 530 : us_diff = gf_m2ts_time_diff_us(&stream->program->mux->time, &stream->time);
1045 530 : if (us_diff>1000)
1046 : return 0;
1047 173 : } else if (stream->pcr_only_mode) {
1048 77 : stream->pcr_only_mode = GF_FALSE;
1049 77 : stream->time = stream->next_time;
1050 : }
1051 : return 1;
1052 : }
1053 :
1054 201807 : static u32 gf_m2ts_stream_process_pes(GF_M2TS_Mux *muxer, GF_M2TS_Mux_Stream *stream)
1055 : {
1056 : u64 time_inc;
1057 : Bool ret = GF_FALSE;
1058 :
1059 201807 : if (stream->mpeg2_stream_type==GF_M2TS_SYSTEMS_MPEG4_SECTIONS) {
1060 : /*section has just been updated */
1061 1058 : if (stream->table_needs_send)
1062 5 : return stream->scheduling_priority;
1063 : /*section is not completely sent yet or this is not the first section of the table*/
1064 1053 : if (stream->current_section && (stream->current_section_offset || stream->current_section!=stream->current_table->section))
1065 1 : return stream->scheduling_priority;
1066 1052 : if (stream->ifce->repeat_rate && stream->tables)
1067 0 : ret = stream->program->pcr_init_time ? stream->scheduling_priority : GF_FALSE;
1068 : }
1069 : /*PES packet not completely sent yet*/
1070 200749 : else if (stream->curr_pck.data_len && stream->pck_offset < stream->curr_pck.data_len) {
1071 : //if in pure PCR mode, check if we can fall back to regular mode and start sending the stream
1072 137756 : if ((stream == stream->program->pcr) && stream->pcr_only_mode) {
1073 530 : if (! gf_m2ts_adjust_next_stream_time_for_pcr(muxer, stream)) {
1074 : return 0;
1075 : }
1076 : }
1077 137506 : return stream->scheduling_priority;
1078 : }
1079 :
1080 : /*PULL mode*/
1081 64045 : if (stream->ifce->caps & GF_ESI_AU_PULL_CAP) {
1082 0 : if (stream->curr_pck.data_len) {
1083 : /*discard packet data if we use SL over PES*/
1084 0 : if (stream->discard_data) gf_free(stream->curr_pck.data);
1085 0 : if (stream->curr_pck.mpeg2_af_descriptors) gf_free(stream->curr_pck.mpeg2_af_descriptors);
1086 : /*release data*/
1087 0 : stream->ifce->input_ctrl(stream->ifce, GF_ESI_INPUT_DATA_RELEASE, NULL);
1088 : }
1089 0 : stream->pck_offset = 0;
1090 0 : stream->curr_pck.data_len = 0;
1091 0 : stream->discard_data = GF_FALSE;
1092 :
1093 : /*EOS*/
1094 0 : if (stream->ifce->caps & GF_ESI_STREAM_IS_OVER) return ret;
1095 : assert(stream->ifce->input_ctrl);
1096 0 : stream->ifce->input_ctrl(stream->ifce, GF_ESI_INPUT_DATA_PULL, &stream->curr_pck);
1097 : } else {
1098 : GF_M2TS_Packet *curr_pck;
1099 :
1100 64045 : if (!stream->pck_first && (stream->ifce->caps & GF_ESI_STREAM_IS_OVER))
1101 : return ret;
1102 :
1103 : /*flush input pipe*/
1104 59051 : if (stream->ifce->input_ctrl) stream->ifce->input_ctrl(stream->ifce, GF_ESI_INPUT_DATA_FLUSH, NULL);
1105 :
1106 59051 : if (stream->mx) gf_mx_p(stream->mx);
1107 :
1108 59051 : stream->pck_offset = 0;
1109 59051 : stream->curr_pck.data_len = 0;
1110 :
1111 : /*fill curr_pck*/
1112 59051 : curr_pck = stream->pck_first;
1113 59051 : if (!stream->program->pcr_init_time_set && (stream != stream->program->pcr)) {
1114 : curr_pck = NULL;
1115 : }
1116 59031 : if (!curr_pck) {
1117 39199 : if (stream->mx) gf_mx_v(stream->mx);
1118 : return ret;
1119 : }
1120 19852 : stream->curr_pck.cts = curr_pck->cts;
1121 19852 : stream->curr_pck.data = curr_pck->data;
1122 19852 : stream->curr_pck.data_len = curr_pck->data_len;
1123 19852 : stream->curr_pck.dts = curr_pck->dts;
1124 19852 : stream->curr_pck.duration = curr_pck->duration;
1125 19852 : stream->curr_pck.flags = curr_pck->flags;
1126 19852 : stream->curr_pck.sap_type = curr_pck->sap_type;
1127 19852 : stream->curr_pck.mpeg2_af_descriptors = curr_pck->mpeg2_af_descriptors;
1128 19852 : stream->curr_pck.mpeg2_af_descriptors_size = curr_pck->mpeg2_af_descriptors_size;
1129 :
1130 : /*discard first packet*/
1131 19852 : stream->pck_first = curr_pck->next;
1132 19852 : gf_free(curr_pck);
1133 19852 : stream->discard_data = GF_TRUE;
1134 :
1135 19852 : if (stream->mx) gf_mx_v(stream->mx);
1136 : }
1137 :
1138 19852 : if (!(stream->curr_pck.flags & GF_ESI_DATA_HAS_DTS))
1139 18140 : stream->curr_pck.dts = stream->curr_pck.cts;
1140 :
1141 : /*initializing the PCR*/
1142 19852 : if (!stream->program->pcr_init_time_set) {
1143 37 : if (stream==stream->program->pcr) {
1144 37 : if (stream->program->mux->init_pcr_value) {
1145 37 : stream->program->pcr_init_time = stream->program->mux->init_pcr_value-1;
1146 : } else {
1147 0 : while (!stream->program->pcr_init_time)
1148 0 : stream->program->pcr_init_time = gf_rand();
1149 : }
1150 :
1151 37 : if (stream->program->force_first_pts) {
1152 1 : u64 first_pts = stream->curr_pck.cts;
1153 1 : u64 first_dts = stream->curr_pck.dts;
1154 :
1155 1 : if (stream->ts_scale.den) {
1156 1 : first_pts = first_pts * stream->ts_scale.num / stream->ts_scale.den;
1157 1 : first_dts = first_dts * stream->ts_scale.num / stream->ts_scale.den;
1158 : }
1159 :
1160 : /*the final PTS is computed by:
1161 : force_first_pts = first_pts + stream->program->pcr_offset - stream->program->initial_ts + stream->program->pcr_init_time/300;
1162 : force_first_dts = first_dts + stream->program->pcr_offset - stream->program->initial_ts + stream->program->pcr_init_time/300;
1163 :
1164 : time_inc is computed as
1165 : time_inc = force_first_dts - stream->program->pcr_init_time/300;
1166 :
1167 : => time_inc = first_dts + stream->program->pcr_offset - stream->program->initial_ts + stream->program->pcr_init_time/300 - stream->program->pcr_init_time/300;
1168 :
1169 : => time_inc = first_dts + stream->program->pcr_offset - stream->program->initial_ts;
1170 :
1171 : we want at the initial time_inc=0, hence
1172 : stream->program->initial_ts = first_dts + stream->program->pcr_offset;
1173 :
1174 : */
1175 : /*
1176 : stream->program->pcr_init_time = first_dts*300 - stream->program->pcr_offset;
1177 : stream->program->initial_ts = first_pts + stream->program->pcr_offset + stream->program->pcr_init_time/300 - stream->program->force_first_pts;
1178 : */
1179 :
1180 1 : stream->program->initial_ts = first_dts + stream->program->pcr_offset;
1181 1 : stream->program->pcr_init_time = 300 * (stream->program->force_first_pts - first_pts - stream->program->pcr_offset + stream->program->initial_ts);
1182 :
1183 1 : stream->program->initial_ts_set = 2;
1184 : }
1185 :
1186 :
1187 37 : stream->program->pcr_init_time_set = GF_TRUE;
1188 37 : stream->program->ts_time_at_pcr_init = muxer->time;
1189 37 : stream->program->num_pck_at_pcr_init = muxer->tot_pck_sent;
1190 :
1191 37 : GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: Initializing PCR for program number %d: PCR %d - mux time %d:%09d\n", stream->pid, stream->program->number, stream->program->pcr_init_time, muxer->time.sec, muxer->time.nanosec));
1192 : } else {
1193 : /*PES has been sent, discard internal buffer*/
1194 0 : if (stream->discard_data) gf_free(stream->curr_pck.data);
1195 0 : if (stream->curr_pck.mpeg2_af_descriptors) gf_free(stream->curr_pck.mpeg2_af_descriptors);
1196 0 : stream->curr_pck.data = NULL;
1197 0 : stream->curr_pck.data_len = 0;
1198 0 : stream->curr_pck.mpeg2_af_descriptors = NULL;
1199 0 : stream->curr_pck.mpeg2_af_descriptors_size = 0;
1200 0 : stream->pck_offset = 0;
1201 : /*don't send until PCR is initialized*/
1202 0 : return 0;
1203 : }
1204 : }
1205 :
1206 : /*SL-encapsultaion*/
1207 19852 : switch (stream->mpeg2_stream_type) {
1208 2 : case GF_M2TS_SYSTEMS_MPEG4_SECTIONS:
1209 : /*update SL config*/
1210 2 : stream->sl_header.accessUnitStartFlag = (stream->curr_pck.flags & GF_ESI_DATA_AU_START) ? 1 : 0;
1211 2 : stream->sl_header.accessUnitEndFlag = (stream->curr_pck.flags & GF_ESI_DATA_AU_END) ? 1 : 0;
1212 : #if 0
1213 : assert(stream->sl_header.accessUnitLength + stream->curr_pck.data_len < 65536); /*stream->sl_header.accessUnitLength type is u16*/
1214 : stream->sl_header.accessUnitLength += stream->curr_pck.data_len;
1215 : #endif
1216 2 : stream->sl_header.randomAccessPointFlag = (stream->curr_pck.sap_type) ? 1: 0;
1217 2 : stream->sl_header.compositionTimeStampFlag = (stream->curr_pck.flags & GF_ESI_DATA_HAS_CTS) ? 1 : 0;
1218 2 : stream->sl_header.compositionTimeStamp = stream->curr_pck.cts;
1219 2 : stream->sl_header.decodingTimeStampFlag = (stream->curr_pck.flags & GF_ESI_DATA_HAS_DTS) ? 1: 0;
1220 2 : stream->sl_header.decodingTimeStamp = stream->curr_pck.dts;
1221 :
1222 2 : gf_m2ts_mux_table_update_mpeg4(stream, stream->table_id, muxer->ts_id, stream->curr_pck.data, stream->curr_pck.data_len, GF_TRUE, GF_FALSE, (stream->curr_pck.flags & GF_ESI_DATA_REPEAT) ? GF_FALSE : GF_TRUE, GF_FALSE);
1223 :
1224 : /*packet data is now copied in sections, discard it if not pull*/
1225 2 : if (!(stream->ifce->caps & GF_ESI_AU_PULL_CAP)) {
1226 2 : gf_free(stream->curr_pck.data);
1227 2 : stream->curr_pck.data = NULL;
1228 2 : stream->curr_pck.data_len = 0;
1229 2 : gf_free(stream->curr_pck.mpeg2_af_descriptors);
1230 2 : stream->curr_pck.mpeg2_af_descriptors = NULL;
1231 2 : stream->curr_pck.mpeg2_af_descriptors_size = 0;
1232 : }
1233 : break;
1234 0 : case GF_M2TS_SYSTEMS_MPEG4_PES:
1235 : {
1236 : char *src_data;
1237 : u32 src_data_len;
1238 :
1239 : /*update SL config*/
1240 0 : stream->sl_header.accessUnitStartFlag = (stream->curr_pck.flags & GF_ESI_DATA_AU_START) ? 1 : 0;
1241 0 : stream->sl_header.accessUnitEndFlag = (stream->curr_pck.flags & GF_ESI_DATA_AU_END) ? 1 : 0;
1242 : #if 0
1243 : assert(stream->sl_header.accessUnitLength + stream->curr_pck.data_len < 65536); /*stream->sl_header.accessUnitLength type is u16*/
1244 : stream->sl_header.accessUnitLength += stream->curr_pck.data_len;
1245 : #endif
1246 0 : stream->sl_header.randomAccessPointFlag = (stream->curr_pck.sap_type) ? 1: 0;
1247 0 : stream->sl_header.compositionTimeStampFlag = (stream->curr_pck.flags & GF_ESI_DATA_HAS_CTS) ? 1 : 0;
1248 0 : stream->sl_header.compositionTimeStamp = stream->curr_pck.cts;
1249 0 : stream->sl_header.decodingTimeStampFlag = (stream->curr_pck.flags & GF_ESI_DATA_HAS_DTS) ? 1: 0;
1250 0 : stream->sl_header.decodingTimeStamp = stream->curr_pck.dts;
1251 :
1252 0 : src_data = stream->curr_pck.data;
1253 0 : src_data_len = stream->curr_pck.data_len;
1254 0 : stream->curr_pck.data_len = 0;
1255 0 : stream->curr_pck.data = NULL;
1256 :
1257 0 : gf_sl_packetize(stream->ifce->sl_config, &stream->sl_header, src_data, src_data_len, &stream->curr_pck.data, &stream->curr_pck.data_len);
1258 :
1259 : /*discard src data*/
1260 0 : if (!(stream->ifce->caps & GF_ESI_AU_PULL_CAP)) {
1261 0 : gf_free(src_data);
1262 : }
1263 0 : GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: Encapsulating MPEG-4 SL Data (%p - %p) on PES - SL Header size %d\n", stream->pid, src_data, stream->curr_pck.data, stream->curr_pck.data_len - src_data_len));
1264 :
1265 : /*moving from PES to SL reallocates a new buffer, force discard even in pull mode*/
1266 0 : stream->discard_data = GF_TRUE;
1267 : }
1268 0 : break;
1269 : /*perform LATM encapsulation*/
1270 0 : case GF_M2TS_AUDIO_LATM_AAC:
1271 : {
1272 : u32 size, next_time;
1273 0 : GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
1274 0 : gf_bs_write_int(bs, 0x2B7, 11);
1275 0 : gf_bs_write_int(bs, 0, 13);
1276 :
1277 : /*same mux config = 0 (refresh aac config)*/
1278 0 : next_time = gf_sys_clock();
1279 0 : if (stream->ifce->decoder_config && (stream->latm_last_aac_time + stream->ifce->repeat_rate < next_time)) {
1280 : #ifndef GPAC_DISABLE_AV_PARSERS
1281 : GF_M4ADecSpecInfo cfg;
1282 : #endif
1283 0 : stream->latm_last_aac_time = next_time;
1284 :
1285 0 : gf_bs_write_int(bs, 0, 1);
1286 : /*mux config */
1287 0 : gf_bs_write_int(bs, 0, 1);/*audio mux version = 0*/
1288 0 : gf_bs_write_int(bs, 1, 1);/*allStreamsSameTimeFraming*/
1289 0 : gf_bs_write_int(bs, 0, 6);/*numSubFrames*/
1290 0 : gf_bs_write_int(bs, 0, 4);/*numProgram*/
1291 0 : gf_bs_write_int(bs, 0, 3);/*numLayer prog 1*/
1292 :
1293 : #ifndef GPAC_DISABLE_AV_PARSERS
1294 0 : gf_m4a_get_config(stream->ifce->decoder_config, stream->ifce->decoder_config_size, &cfg);
1295 0 : gf_m4a_write_config_bs(bs, &cfg);
1296 : #else
1297 : gf_bs_write_data(bs, stream->ifce->decoder_config, stream->ifce->decoder_config_size);
1298 : #endif
1299 :
1300 0 : gf_bs_write_int(bs, 0, 3);/*frameLengthType*/
1301 0 : gf_bs_write_int(bs, 0, 8);/*latmBufferFullness*/
1302 0 : gf_bs_write_int(bs, 0, 1);/*other data present*/
1303 0 : gf_bs_write_int(bs, 0, 1);/*crcCheckPresent*/
1304 : } else {
1305 0 : gf_bs_write_int(bs, 1, 1);
1306 : }
1307 : /*write payloadLengthInfo*/
1308 0 : size = stream->curr_pck.data_len;
1309 : while (1) {
1310 0 : if (size>=255) {
1311 0 : gf_bs_write_int(bs, 255, 8);
1312 0 : size -= 255;
1313 : } else {
1314 0 : gf_bs_write_int(bs, size, 8);
1315 : break;
1316 : }
1317 : }
1318 0 : stream->reframe_overhead = stream->curr_pck.data_len;
1319 0 : gf_bs_write_data(bs, stream->curr_pck.data, stream->curr_pck.data_len);
1320 0 : gf_bs_align(bs);
1321 0 : gf_free(stream->curr_pck.data);
1322 0 : gf_bs_get_content(bs, &stream->curr_pck.data, &stream->curr_pck.data_len);
1323 0 : gf_bs_del(bs);
1324 0 : stream->reframe_overhead = stream->curr_pck.data_len - stream->reframe_overhead;
1325 :
1326 : /*rewrite LATM frame header*/
1327 0 : size = stream->curr_pck.data_len - 2;
1328 0 : stream->curr_pck.data[1] |= (size>>8) & 0x1F;
1329 0 : stream->curr_pck.data[2] = (size) & 0xFF;
1330 : /*since we reallocated the packet data buffer, force a discard in pull mode*/
1331 0 : stream->discard_data = GF_TRUE;
1332 : }
1333 0 : break;
1334 : /*perform ADTS encapsulation*/
1335 11895 : case GF_M2TS_AUDIO_AAC:
1336 11895 : if (stream->ifce->decoder_config) {
1337 : GF_BitStream *bs;
1338 : #ifndef GPAC_DISABLE_AV_PARSERS
1339 : GF_M4ADecSpecInfo cfg;
1340 11895 : gf_m4a_get_config(stream->ifce->decoder_config, stream->ifce->decoder_config_size, &cfg);
1341 11895 : if (cfg.base_object_type>=5) cfg.base_object_type = GF_M4A_AAC_LC;
1342 : #endif
1343 11895 : bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
1344 :
1345 :
1346 11895 : gf_bs_write_int(bs, 0xFFF, 12);/*sync*/
1347 11895 : gf_bs_write_int(bs, 0, 1);/*mpeg2 aac*/
1348 11895 : gf_bs_write_int(bs, 0, 2); /*layer*/
1349 11895 : gf_bs_write_int(bs, 1, 1); /* protection_absent*/
1350 : #ifndef GPAC_DISABLE_AV_PARSERS
1351 11895 : gf_bs_write_int(bs, cfg.base_object_type-1, 2);
1352 11895 : gf_bs_write_int(bs, cfg.base_sr_index, 4);
1353 11895 : gf_bs_write_int(bs, 0, 1);
1354 11895 : if (cfg.program_config_element_present)
1355 0 : gf_bs_write_int(bs, 0, 3);
1356 : else
1357 11895 : gf_bs_write_int(bs, cfg.chan_cfg, 3);
1358 : #else
1359 : gf_bs_write_int(bs, GF_M4A_AAC_LC-1, 2);
1360 : gf_bs_write_int(bs, 1, 4); //FIXME
1361 : gf_bs_write_int(bs, 0, 1);
1362 : gf_bs_write_int(bs, 2, 3);//FIXME
1363 : #endif
1364 :
1365 11895 : gf_bs_write_int(bs, 0, 4);
1366 11895 : gf_bs_write_int(bs, 7+stream->curr_pck.data_len, 13);
1367 11895 : gf_bs_write_int(bs, 0x7FF, 11);
1368 :
1369 : /*base reframe overhead*/
1370 11895 : stream->reframe_overhead = 7;
1371 :
1372 : #ifndef GPAC_DISABLE_AV_PARSERS
1373 11895 : if (cfg.program_config_element_present) {
1374 0 : gf_bs_write_int(bs, 2, 2);
1375 :
1376 0 : u32 cpe_size = (u32) gf_bs_get_position(bs);
1377 0 : gf_m4a_write_program_config_element_bs(bs, &cfg);
1378 0 : stream->reframe_overhead += (u32) gf_bs_get_position(bs) - cpe_size;
1379 : } else
1380 : #endif
1381 11895 : gf_bs_write_int(bs, 0, 2);
1382 :
1383 :
1384 11895 : gf_bs_write_data(bs, stream->curr_pck.data, stream->curr_pck.data_len);
1385 11895 : gf_bs_align(bs);
1386 11895 : gf_free(stream->curr_pck.data);
1387 11895 : gf_bs_get_content(bs, &stream->curr_pck.data, &stream->curr_pck.data_len);
1388 11895 : gf_bs_del(bs);
1389 : }
1390 : /*since we reallocated the packet data buffer, force a discard in pull mode*/
1391 11895 : stream->discard_data = GF_TRUE;
1392 11895 : break;
1393 21 : case GF_M2TS_METADATA_PES:
1394 : case GF_M2TS_METADATA_ID3_HLS:
1395 : {
1396 21 : id3_tag_create(&stream->curr_pck.data, &stream->curr_pck.data_len);
1397 21 : stream->discard_data = GF_TRUE;
1398 : }
1399 21 : break;
1400 : default:
1401 : break;
1402 : }
1403 :
1404 19852 : if (stream->start_pes_at_rap && (stream->curr_pck.sap_type)
1405 : ) {
1406 0 : stream->program->mux->force_pat = GF_TRUE;
1407 : }
1408 :
1409 : /*rewrite timestamps for PES header*/
1410 19852 : gf_m2ts_remap_timestamps_for_pes(stream, stream->curr_pck.flags, &stream->curr_pck.dts, &stream->curr_pck.cts, &stream->curr_pck.duration);
1411 :
1412 : /*compute next interesting time in TS unit: this will be DTS of next packet*/
1413 19852 : stream->time = stream->program->ts_time_at_pcr_init;
1414 19852 : time_inc = stream->curr_pck.dts - stream->program->pcr_init_time/300;
1415 :
1416 : gf_m2ts_time_inc(&stream->time, time_inc, 90000);
1417 :
1418 19852 : if (stream == stream->program->pcr) {
1419 12702 : gf_m2ts_adjust_next_stream_time_for_pcr(muxer, stream);
1420 : }
1421 :
1422 19852 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: Next data schedule for %d:%09d - mux time %d:%09d\n", stream->pid, stream->time.sec, stream->time.nanosec, muxer->time.sec, muxer->time.nanosec));
1423 :
1424 : /*compute instant bitrate*/
1425 19852 : if (!stream->last_br_time) {
1426 581 : stream->last_br_time = stream->curr_pck.dts + 1;
1427 581 : stream->bytes_since_last_time = 0;
1428 581 : stream->pes_since_last_time = 0;
1429 : } else {
1430 19271 : u32 time_diff = (u32) (stream->curr_pck.dts + 1 - stream->last_br_time );
1431 19271 : if ((stream->pes_since_last_time > 4) && (time_diff >= BITRATE_UPDATE_WINDOW)) {
1432 : u32 bitrate;
1433 533 : u64 r = 8*stream->bytes_since_last_time;
1434 533 : r*=90000;
1435 533 : bitrate = (u32) (r / time_diff);
1436 :
1437 533 : if (stream->program->mux->fixed_rate || (stream->bit_rate < bitrate)) {
1438 133 : stream->bit_rate = bitrate;
1439 133 : stream->program->mux->needs_reconfig = GF_TRUE;
1440 : }
1441 533 : stream->last_br_time = 0;
1442 533 : stream->bytes_since_last_time = 0;
1443 533 : stream->pes_since_last_time = 0;
1444 : }
1445 : }
1446 :
1447 19852 : stream->pes_since_last_time ++;
1448 19852 : return stream->scheduling_priority;
1449 : }
1450 :
1451 : static GFINLINE u64 gf_m2ts_get_pcr(GF_M2TS_Mux_Stream *stream)
1452 : {
1453 : u64 pcr;
1454 : /*compute PCR*/
1455 30395 : if (stream->program->mux->fixed_rate) {
1456 676 : Double abs_pcr = (Double) (stream->program->mux->tot_pck_sent - stream->program->num_pck_at_pcr_init);
1457 676 : abs_pcr *= 27000000;
1458 676 : abs_pcr *= 1504;
1459 676 : abs_pcr /= stream->program->mux->bit_rate;
1460 676 : pcr = (u64) abs_pcr + stream->program->pcr_init_time;
1461 : }
1462 : /*in non-realtime mode with no fixed rate we only insert PCR based on DTS */
1463 : else {
1464 29719 : pcr = (stream->curr_pck.dts - stream->program->pcr_offset) * 300;
1465 : }
1466 : return pcr;
1467 : }
1468 :
1469 15827 : void gf_m2ts_stream_update_data_following(GF_M2TS_Mux_Stream *stream)
1470 : {
1471 : Bool ignore_next = GF_FALSE;
1472 15827 : stream->next_payload_size = 0;
1473 15827 : stream->next_next_payload_size = 0;
1474 15827 : stream->next_next_next_payload_size = 0;
1475 :
1476 15827 : stream->next_pck_flags = 0;
1477 15827 : stream->next_pck_sap = 0;
1478 15827 : stream->copy_from_next_packets = 0;
1479 :
1480 : //AU packing in single PES is disabled
1481 15827 : if (stream->force_single_au) return;
1482 :
1483 4506 : if (stream->ifce->caps & GF_ESI_AU_PULL_CAP) {
1484 : GF_ESIPacket test_pck;
1485 0 : test_pck.data_len = 0;
1486 : /*pull next data but do not release it since it might be needed later on*/
1487 0 : stream->ifce->input_ctrl(stream->ifce, GF_ESI_INPUT_DATA_PULL, &test_pck);
1488 0 : if (test_pck.data_len) {
1489 0 : stream->next_payload_size = test_pck.data_len;
1490 0 : stream->next_pck_flags = test_pck.flags;
1491 0 : stream->next_pck_sap = test_pck.sap_type;
1492 0 : stream->next_pck_cts = test_pck.cts;
1493 0 : stream->next_pck_dts = test_pck.dts;
1494 : }
1495 : } else {
1496 : /*flush input*/
1497 4506 : if (!stream->pck_first && stream->ifce->input_ctrl) stream->ifce->input_ctrl(stream->ifce, GF_ESI_INPUT_DATA_FLUSH, NULL);
1498 4506 : if (stream->pck_first) {
1499 4341 : stream->next_payload_size = stream->pck_first->data_len;
1500 4341 : stream->next_pck_cts = stream->pck_first->cts;
1501 4341 : stream->next_pck_dts = stream->pck_first->dts;
1502 4341 : stream->next_pck_flags = stream->pck_first->flags;
1503 4341 : stream->next_pck_sap = stream->pck_first->sap_type;
1504 :
1505 4341 : if (!stream->pck_first->next && stream->ifce->input_ctrl) stream->ifce->input_ctrl(stream->ifce, GF_ESI_INPUT_DATA_FLUSH, NULL);
1506 4341 : if (stream->pck_first->next) {
1507 3988 : stream->next_next_payload_size = stream->pck_first->next->data_len;
1508 3988 : if (!stream->pck_first->next->next && stream->ifce->input_ctrl) stream->ifce->input_ctrl(stream->ifce, GF_ESI_INPUT_DATA_FLUSH, NULL);
1509 3988 : if (stream->pck_first->next->next) {
1510 3928 : stream->next_next_next_payload_size = stream->pck_first->next->next->data_len;
1511 : }
1512 : }
1513 : }
1514 : }
1515 : /*consider we don't have the next AU if:
1516 : 1- we are asked to start new PES at RAP, just consider we don't have the next AU*/
1517 4506 : if (stream->start_pes_at_rap && stream->next_pck_sap) {
1518 : ignore_next = GF_TRUE;
1519 : // stream->program->mux->force_pat_pmt_state = GF_SEG_BOUNDARY_START;
1520 : }
1521 : /*if we have a RAP about to start on a stream in this program, force all other streams to stop merging data in their current PES*/
1522 4506 : else if (stream->program->mux->force_pat_pmt_state) {
1523 : ignore_next = GF_TRUE;
1524 : }
1525 :
1526 : if (ignore_next) {
1527 88 : stream->next_payload_size = 0;
1528 88 : stream->next_pck_cts = 0;
1529 88 : stream->next_pck_dts = 0;
1530 88 : stream->next_pck_flags = 0;
1531 88 : stream->next_pck_sap = 0;
1532 : }
1533 :
1534 4506 : if (stream->next_payload_size) {
1535 4255 : stream->next_payload_size += stream->reframe_overhead;
1536 4255 : if (stream->next_next_payload_size) {
1537 3902 : stream->next_next_payload_size += stream->reframe_overhead;
1538 3902 : if (stream->next_next_next_payload_size) {
1539 3842 : stream->next_next_next_payload_size += stream->reframe_overhead;
1540 : }
1541 : }
1542 :
1543 4255 : gf_m2ts_remap_timestamps_for_pes(stream, stream->next_pck_flags, &stream->next_pck_dts, &stream->next_pck_cts, NULL);
1544 :
1545 :
1546 4255 : if (!(stream->next_pck_flags & GF_ESI_DATA_HAS_DTS))
1547 4255 : stream->next_pck_dts = stream->next_pck_cts;
1548 : }
1549 : }
1550 :
1551 :
1552 15853 : Bool gf_m2ts_stream_compute_pes_length(GF_M2TS_Mux_Stream *stream, u32 payload_length)
1553 : {
1554 : assert(stream->pes_data_remain==0);
1555 15853 : stream->pes_data_len = stream->curr_pck.data_len - stream->pck_offset;
1556 :
1557 15853 : stream->copy_from_next_packets = 0;
1558 : /*if we have next payload ready, compute transmitted size*/
1559 15853 : if (stream->next_payload_size) {
1560 : u32 pck_size = stream->curr_pck.data_len - stream->pck_offset;
1561 : u32 ts_bytes = payload_length;
1562 :
1563 : /*finish this AU*/
1564 5283 : while (ts_bytes < pck_size) {
1565 1028 : ts_bytes += 184;
1566 : }
1567 :
1568 : /*current AU started in PES, don't start new AU - if enough data
1569 : still to be sent from current AU, don't send the complete AU
1570 : in order to avoid padding*/
1571 4255 : if (stream->prevent_two_au_start_in_pes && !stream->pck_offset) {
1572 0 : if (ts_bytes>184)
1573 0 : ts_bytes -= 184;
1574 : else
1575 : ts_bytes = pck_size;
1576 : }
1577 : /*try to fit in part of the next AU*/
1578 : else if (stream->next_payload_size) {
1579 : /*how much more TS packets do we need to send next AU ?*/
1580 8443 : while (ts_bytes < pck_size + stream->next_payload_size) {
1581 : //check we have enough bytes in the next 3 AUs if we increase by 1 TS packet the PES
1582 : //bytes_to_copy from next will be: ts_bytes + 184 - pck_size
1583 : //check bytes_to_copy is <= next_payload_size + next_next_payload_size + next_next_next_payload_size
1584 : //if not, do not add - we do not want to take the risk of having no data while filling a PES packet with an announced length
1585 4535 : if (ts_bytes + 184 > pck_size + stream->next_payload_size + stream->next_next_payload_size + stream->next_next_next_payload_size)
1586 : break;
1587 :
1588 : ts_bytes += 184;
1589 : }
1590 : /*don't end next AU in next PES if we don't want to start 2 AUs in one PES
1591 : if we don't have the N+2 AU size, don't try to pack it*/
1592 4255 : if ((stream->prevent_two_au_start_in_pes && (ts_bytes>pck_size + stream->next_payload_size))
1593 4255 : || !stream->next_next_payload_size
1594 : ) {
1595 353 : if (ts_bytes>184)
1596 154 : ts_bytes -= 184;
1597 : else
1598 : ts_bytes = pck_size + stream->next_payload_size;
1599 : }
1600 : }
1601 :
1602 : /*that's how much bytes we copy from the following AUs*/
1603 4255 : if (ts_bytes >= pck_size) {
1604 4115 : stream->copy_from_next_packets = ts_bytes - pck_size;
1605 : //very low rate case, we didn't enter the previous while loop:
1606 : //we can't fill the complete TS packet with the next two AUs, do not copy over
1607 4115 : if (stream->copy_from_next_packets > stream->next_payload_size + stream->next_next_payload_size + stream->next_next_next_payload_size)
1608 0 : stream->copy_from_next_packets = 0;
1609 : } else {
1610 140 : u32 skipped = pck_size-ts_bytes;
1611 140 : if (stream->pes_data_len > skipped)
1612 140 : stream->pes_data_len -= skipped;
1613 : }
1614 :
1615 4255 : if (stream->min_bytes_copy_from_next && stream->copy_from_next_packets) {
1616 : /*if we don't have enough space in the PES to store beginning of new AU, don't copy it and ask
1617 : to recompute header (we might no longer have DTS/CTS signaled)*/
1618 0 : if (stream->copy_from_next_packets < stream->min_bytes_copy_from_next) {
1619 0 : stream->copy_from_next_packets = 0;
1620 0 : stream->next_payload_size = 0;
1621 0 : stream->next_pck_flags = 0;
1622 0 : stream->next_pck_sap = 0;
1623 0 : return GF_FALSE;
1624 : }
1625 : /*if what will remain after copying next AU is less than the minimum safety copy only copy next AU and
1626 : realign n+2 AU start with PES*/
1627 0 : if ((stream->copy_from_next_packets > stream->next_payload_size)
1628 0 : && (stream->copy_from_next_packets - stream->next_payload_size < stream->min_bytes_copy_from_next)
1629 : ) {
1630 0 : stream->copy_from_next_packets = stream->next_payload_size;
1631 : }
1632 : }
1633 :
1634 4255 : if (stream->pck_offset && !stream->copy_from_next_packets && stream->next_payload_size) {
1635 26 : stream->copy_from_next_packets = 0;
1636 26 : stream->next_payload_size = 0;
1637 26 : stream->next_pck_flags = 0;
1638 26 : stream->next_pck_sap = 0;
1639 26 : return GF_FALSE;
1640 : }
1641 :
1642 4229 : if (stream->ifce->caps & GF_ESI_STREAM_IS_OVER) {
1643 : #if 0
1644 : while (stream->copy_from_next_packets > stream->next_payload_size) {
1645 : if (stream->copy_from_next_packets < 184) {
1646 : stream->copy_from_next_packets = 0;
1647 : break;
1648 : }
1649 : stream->copy_from_next_packets -= 184;
1650 : }
1651 : #endif
1652 3 : stream->pes_data_len += stream->next_payload_size;
1653 : } else {
1654 4226 : stream->pes_data_len += stream->copy_from_next_packets;
1655 : }
1656 : }
1657 15827 : stream->pes_data_remain = stream->pes_data_len;
1658 15827 : return GF_TRUE;
1659 : }
1660 :
1661 : static u32 gf_m2ts_stream_get_pes_header_length(GF_M2TS_Mux_Stream *stream)
1662 : {
1663 : u32 hdr_len, flags;
1664 134199 : flags = stream->pck_offset ? stream->next_pck_flags : stream->curr_pck.flags;
1665 :
1666 : /*not done with the current pes*/
1667 134199 : if (stream->pes_data_remain) return 0;
1668 : hdr_len = 9;
1669 : /*signal timing only if AU start in the PES*/
1670 31680 : if ( flags & GF_ESI_DATA_AU_START) {
1671 31583 : if (flags & GF_ESI_DATA_HAS_CTS) hdr_len += 5;
1672 31583 : if (flags & GF_ESI_DATA_HAS_DTS) hdr_len += 5;
1673 : }
1674 : return hdr_len;
1675 : }
1676 :
1677 15827 : u32 gf_m2ts_stream_add_pes_header(GF_BitStream *bs, GF_M2TS_Mux_Stream *stream)
1678 : {
1679 : u64 t, dts, cts;
1680 : u32 pes_len;
1681 : Bool use_pts, use_dts;
1682 :
1683 15827 : gf_bs_write_int(bs, 0x1, 24);//packet start code
1684 15827 : gf_bs_write_u8(bs, stream->mpeg2_stream_id);// stream id
1685 :
1686 : /*next AU start in current PES and current AU began in previous PES, use next AU timing*/
1687 15827 : if (stream->pck_offset && stream->copy_from_next_packets) {
1688 3909 : use_pts = (stream->next_pck_flags & GF_ESI_DATA_HAS_CTS) ? GF_TRUE : GF_FALSE;
1689 3909 : use_dts = (stream->next_pck_flags & GF_ESI_DATA_HAS_DTS) ? GF_TRUE : GF_FALSE;
1690 3909 : dts = stream->next_pck_dts;
1691 3909 : cts = stream->next_pck_cts;
1692 : }
1693 : /*we already sent the beginning of the AU*/
1694 11918 : else if (stream->pck_offset) {
1695 : use_pts = use_dts = GF_FALSE;
1696 : dts = cts = 0;
1697 : } else {
1698 11821 : use_pts = (stream->curr_pck.flags & GF_ESI_DATA_HAS_CTS) ? GF_TRUE : GF_FALSE;
1699 11821 : use_dts = (stream->curr_pck.flags & GF_ESI_DATA_HAS_DTS) ? GF_TRUE : GF_FALSE;
1700 11821 : dts = stream->curr_pck.dts;
1701 11821 : cts = stream->curr_pck.cts;
1702 : }
1703 :
1704 : /*PES packet length: number of bytes in the PES packet following the last byte of the field "pes packet length"*/
1705 : assert(stream->pes_data_len);
1706 15827 : pes_len = stream->pes_data_len + 3; // 3 = header size
1707 15827 : if (use_pts) pes_len += 5;
1708 15827 : if (use_dts) pes_len += 5;
1709 :
1710 15827 : if (pes_len>0xFFFF) pes_len = 0;
1711 15827 : gf_bs_write_int(bs, pes_len, 16); // pes packet length
1712 :
1713 15827 : gf_bs_write_int(bs, 0x2, 2); // reserved
1714 15827 : gf_bs_write_int(bs, 0x0, 2); // scrambling
1715 15827 : gf_bs_write_int(bs, 0x0, 1); // priority
1716 15827 : gf_bs_write_int(bs, stream->pck_offset ? 0 : 1, 1); // alignment indicator - we could also check start codes to see if we are aligned at slice/video packet level
1717 15827 : gf_bs_write_int(bs, 0x0, 1); // copyright
1718 15827 : gf_bs_write_int(bs, 0x0, 1); // original or copy
1719 :
1720 15827 : gf_bs_write_int(bs, use_pts, 1);
1721 15827 : gf_bs_write_int(bs, use_dts, 1);
1722 15827 : gf_bs_write_int(bs, 0x0, 6); //6 flags = 0 (ESCR, ES_rate, DSM_trick, additional_copy, PES_CRC, PES_extension)
1723 :
1724 15827 : gf_bs_write_int(bs, use_dts*5+use_pts*5, 8);
1725 :
1726 15827 : if (use_pts) {
1727 15730 : gf_bs_write_int(bs, use_dts ? 0x3 : 0x2, 4); // reserved '0011' || '0010'
1728 15730 : t = ((cts >> 30) & 0x7);
1729 15730 : gf_bs_write_long_int(bs, t, 3);
1730 15730 : gf_bs_write_int(bs, 1, 1); // marker bit
1731 15730 : t = ((cts >> 15) & 0x7fff);
1732 15730 : gf_bs_write_long_int(bs, t, 15);
1733 15730 : gf_bs_write_int(bs, 1, 1); // marker bit
1734 15730 : t = cts & 0x7fff;
1735 15730 : gf_bs_write_long_int(bs, t, 15);
1736 15730 : gf_bs_write_int(bs, 1, 1); // marker bit
1737 : }
1738 :
1739 15827 : if (use_dts) {
1740 1712 : gf_bs_write_int(bs, 0x1, 4); // reserved '0001'
1741 1712 : t = ((dts >> 30) & 0x7);
1742 1712 : gf_bs_write_long_int(bs, t, 3);
1743 1712 : gf_bs_write_int(bs, 1, 1); // marker bit
1744 1712 : t = ((dts >> 15) & 0x7fff);
1745 1712 : gf_bs_write_long_int(bs, t, 15);
1746 1712 : gf_bs_write_int(bs, 1, 1); // marker bit
1747 1712 : t = dts & 0x7fff;
1748 1712 : gf_bs_write_long_int(bs, t, 15);
1749 1712 : gf_bs_write_int(bs, 1, 1); // marker bit
1750 : }
1751 15827 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: Adding PES header at PCR "LLD" - has PTS %d ("LLU") - has DTS %d ("LLU") - Payload length %d\n", stream->pid, gf_m2ts_get_pcr(stream)/300, use_pts, cts, use_dts, dts, pes_len));
1752 :
1753 15827 : return pes_len+4; // 4 = start code + stream_id
1754 : }
1755 :
1756 118568 : void gf_m2ts_mux_pes_get_next_packet(GF_M2TS_Mux_Stream *stream, char *packet)
1757 : {
1758 : GF_BitStream *bs;
1759 : Bool needs_pcr, first_pass;
1760 : u32 adaptation_field_control, payload_length, payload_to_copy, padding_length, hdr_len, pos, copy_next;
1761 :
1762 : assert(stream->pid);
1763 118568 : bs = stream->program->mux->pck_bs;
1764 118568 : gf_bs_reassign_buffer(bs, packet, 188);
1765 :
1766 118568 : if (stream->pcr_only_mode) {
1767 : payload_length = 184 - 8;
1768 : needs_pcr = GF_TRUE;
1769 : adaptation_field_control = GF_M2TS_ADAPTATION_ONLY;
1770 : hdr_len = 0;
1771 : } else {
1772 : hdr_len = gf_m2ts_stream_get_pes_header_length(stream);
1773 :
1774 : /*we may need two pass in case we first compute hdr len and TS payload size by considering
1775 : we concatenate next au start in this PES but finally couldn't do it when computing PES len
1776 : and AU alignment constraint of the stream*/
1777 : first_pass = GF_TRUE;
1778 : while (1) {
1779 118398 : if (hdr_len) {
1780 15853 : if (first_pass)
1781 15827 : gf_m2ts_stream_update_data_following(stream);
1782 : hdr_len = gf_m2ts_stream_get_pes_header_length(stream);
1783 : }
1784 :
1785 : adaptation_field_control = GF_M2TS_ADAPTATION_NONE;
1786 118372 : payload_length = 184 - hdr_len;
1787 : needs_pcr = GF_FALSE;
1788 :
1789 118372 : if (stream == stream->program->pcr) {
1790 107512 : if (hdr_len)
1791 : needs_pcr = GF_TRUE;
1792 : /*if we forced inserting PAT/PMT before new RAP, also insert PCR here*/
1793 107512 : if (stream->program->mux->force_pat_pmt_state == GF_SEG_BOUNDARY_FORCE_PCR) {
1794 125 : stream->program->mux->force_pat_pmt_state = GF_SEG_BOUNDARY_NONE;
1795 : needs_pcr = GF_TRUE;
1796 : }
1797 :
1798 107387 : if (!needs_pcr && (stream->program->mux->real_time || stream->program->mux->fixed_rate) ) {
1799 : u64 clock;
1800 : u32 diff;
1801 214 : if (stream->program->mux->fixed_rate) {
1802 : //check if PCR, if send at next packet, exceeds requested PCR update time
1803 214 : clock = 1 + stream->program->mux->tot_pck_sent - stream->program->nb_pck_last_pcr;
1804 214 : clock *= 1504*1000000;
1805 214 : clock /= stream->program->mux->bit_rate;
1806 214 : if (clock >= 500 + stream->program->mux->pcr_update_ms*1000) {
1807 : needs_pcr = GF_TRUE;
1808 : }
1809 : }
1810 :
1811 214 : if (!needs_pcr && stream->program->mux->real_time) {
1812 0 : clock = gf_sys_clock_high_res();
1813 0 : diff = (u32) (clock - stream->program->sys_clock_at_last_pcr);
1814 :
1815 0 : if (diff >= 100 + stream->program->mux->pcr_update_ms*1000) {
1816 : needs_pcr = GF_TRUE;
1817 : }
1818 : }
1819 : }
1820 : }
1821 :
1822 107512 : if (needs_pcr) {
1823 : /*AF headers + PCR*/
1824 10475 : payload_length -= 8;
1825 : adaptation_field_control = GF_M2TS_ADAPTATION_AND_PAYLOAD;
1826 : }
1827 : //af descriptors are only inserted at the start of the pes for the time being
1828 118372 : if (hdr_len && stream->curr_pck.mpeg2_af_descriptors) {
1829 676 : if (adaptation_field_control == GF_M2TS_ADAPTATION_NONE) {
1830 330 : payload_length -= 2; //AF header but no PCR
1831 : adaptation_field_control = GF_M2TS_ADAPTATION_AND_PAYLOAD;
1832 : }
1833 676 : payload_length -= 2 + stream->curr_pck.mpeg2_af_descriptors_size; //AF extension field and AF descriptor
1834 : }
1835 :
1836 118372 : if (hdr_len) {
1837 : assert(!stream->pes_data_remain);
1838 15853 : if (! gf_m2ts_stream_compute_pes_length(stream, payload_length)) {
1839 : first_pass = GF_FALSE;
1840 26 : continue;
1841 : }
1842 :
1843 : assert(stream->pes_data_remain==stream->pes_data_len);
1844 : }
1845 : break;
1846 : }
1847 : }
1848 :
1849 118568 : copy_next = stream->copy_from_next_packets;
1850 118568 : payload_to_copy = stream->curr_pck.data_len - stream->pck_offset;
1851 : /*end of PES packet*/
1852 118568 : if (payload_to_copy >= stream->pes_data_remain) {
1853 : payload_to_copy = stream->pes_data_remain;
1854 : copy_next = 0;
1855 : }
1856 :
1857 :
1858 : /*packet exceed payload length*/
1859 118568 : if (payload_to_copy >= payload_length) {
1860 : padding_length = 0;
1861 : payload_to_copy = payload_length;
1862 : }
1863 : /*packet + next packet exceed payload length*/
1864 19914 : else if (payload_to_copy + copy_next >= payload_length) {
1865 : padding_length = 0;
1866 : }
1867 : /*packet + next packet less than payload length - pad */
1868 : else {
1869 : /*AF headers*/
1870 12017 : if (!needs_pcr) {
1871 10717 : if (adaptation_field_control == GF_M2TS_ADAPTATION_NONE) {
1872 10715 : payload_length -= 2;
1873 : adaptation_field_control = GF_M2TS_ADAPTATION_AND_PAYLOAD;
1874 : }
1875 : }
1876 : /*cannot add adaptation field for this TS packet with this payload, we need to split in 2 TS packets*/
1877 12017 : if (payload_length < payload_to_copy + copy_next) {
1878 : padding_length = 10;
1879 30 : payload_length -= padding_length;
1880 30 : if (payload_to_copy > payload_length)
1881 : payload_to_copy = payload_length;
1882 : } else {
1883 11987 : padding_length = payload_length - payload_to_copy - copy_next;
1884 11987 : payload_length -= padding_length;
1885 : }
1886 : }
1887 :
1888 : #ifndef GPAC_DISABLE_LOG
1889 118568 : if (hdr_len && gf_log_tool_level_on(GF_LOG_CONTAINER, GF_LOG_DEBUG) ) {
1890 0 : u64 pcr = (s64) gf_m2ts_get_pcr(stream)/300;
1891 0 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG2-TS Muxer] Start sending PES: PID %d - %d bytes - DTS "LLD" PCR "LLD" (diff %d) - stream time %d:%09d - mux time %d:%09d (%d us ahead of mux time)\n",
1892 : stream->pid, stream->curr_pck.data_len, stream->curr_pck.dts, pcr, (s64) stream->curr_pck.dts - (s64) pcr,
1893 : stream->time.sec, stream->time.nanosec, stream->program->mux->time.sec, stream->program->mux->time.nanosec,
1894 : gf_m2ts_time_diff_us(&stream->program->mux->time, &stream->time)
1895 : ));
1896 : }
1897 : #endif
1898 :
1899 : //CC field shall not be incremented for if adaptation field only, rewind counter
1900 118568 : if (adaptation_field_control == GF_M2TS_ADAPTATION_ONLY) {
1901 222 : if (!stream->continuity_counter) stream->continuity_counter=15;
1902 143 : else stream->continuity_counter--;
1903 : }
1904 :
1905 118568 : gf_bs_write_int(bs, 0x47, 8); // sync byte
1906 118568 : gf_bs_write_int(bs, 0, 1); // error indicator
1907 118568 : gf_bs_write_int(bs, hdr_len ? 1 : 0, 1); // start ind
1908 118568 : gf_bs_write_int(bs, 0, 1); // transport priority
1909 118568 : gf_bs_write_int(bs, stream->pid, 13); // pid
1910 118568 : gf_bs_write_int(bs, 0, 2); // scrambling
1911 118568 : gf_bs_write_int(bs, adaptation_field_control, 2); // we do not use adaptation field for sections
1912 118568 : gf_bs_write_int(bs, stream->continuity_counter, 4); // continuity counter
1913 :
1914 118568 : if (stream->continuity_counter < 15) stream->continuity_counter++;
1915 7459 : else stream->continuity_counter=0;
1916 :
1917 118568 : if (adaptation_field_control != GF_M2TS_ADAPTATION_NONE) {
1918 : Bool is_rap = GF_FALSE;
1919 : u64 pcr = 0;
1920 21720 : if (needs_pcr) {
1921 10675 : u64 now = gf_sys_clock_high_res();
1922 10675 : pcr = gf_m2ts_get_pcr(stream);
1923 :
1924 10675 : if (stream->program->mux->real_time || stream->program->mux->fixed_rate) {
1925 : u64 clock;
1926 173 : clock = stream->program->mux->tot_pck_sent - stream->program->nb_pck_last_pcr;
1927 173 : clock *= 1504000000;
1928 173 : clock /= stream->program->mux->bit_rate;
1929 :
1930 : //allow 2 ms drift
1931 173 : if (clock > 2000 + stream->program->mux->pcr_update_ms*1000) {
1932 0 : GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[MPEG2-TS Muxer] PCR sent %d us later than requested PCR send rate %d ms\n", (s32) (clock - stream->program->mux->pcr_update_ms*1000), stream->program->mux->pcr_update_ms ));
1933 : }
1934 :
1935 173 : if (stream->program->mux->real_time) {
1936 0 : u32 diff = (s32) (now - stream->program->sys_clock_at_last_pcr);
1937 : //since we currently only send the PCR when an AU is sent, it may happen that we exceed PCR the refresh rate depending in the target bitrate and frame rate.
1938 : //we only throw a warning when twiice the PCR refresh is exceeded
1939 0 : if (diff > 5000 + 2*stream->program->mux->pcr_update_ms*1000 ) {
1940 0 : GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[MPEG2-TS Muxer] Sending PCR %d us too late (PCR send rate %d ms)\n", (u32) (diff - stream->program->mux->pcr_update_ms*1000), stream->program->mux->pcr_update_ms ));
1941 : }
1942 : }
1943 : }
1944 :
1945 10675 : GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[MPEG2-TS Muxer] Inserted PCR "LLD" (%d @90kHz) at mux time %d:%09d\n", pcr, (u32) (pcr/300), stream->program->mux->time.sec, stream->program->mux->time.nanosec ));
1946 10675 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG2-TS Muxer] PCR diff to STB in ms %d - sys clock diff in ms %d - DTS diff %d\n", (u32) (pcr - stream->program->last_pcr) / 27000, now - stream->program->sys_clock_at_last_pcr, (stream->curr_pck.dts - stream->program->last_dts)/90));
1947 :
1948 10675 : stream->program->sys_clock_at_last_pcr = now;
1949 10675 : stream->program->last_dts = stream->curr_pck.dts;
1950 10675 : stream->program->nb_pck_last_pcr = stream->program->mux->tot_pck_sent;
1951 : }
1952 21720 : is_rap = (hdr_len && (stream->curr_pck.sap_type) ) ? GF_TRUE : GF_FALSE;
1953 21720 : gf_m2ts_add_adaptation(stream->program, bs, stream->pid, needs_pcr, pcr, is_rap, padding_length, hdr_len ? stream->curr_pck.mpeg2_af_descriptors : NULL, hdr_len ? stream->curr_pck.mpeg2_af_descriptors_size : 0, stream->set_initial_disc);
1954 21720 : stream->set_initial_disc = GF_FALSE;
1955 :
1956 21720 : if (stream->curr_pck.mpeg2_af_descriptors) {
1957 676 : gf_free(stream->curr_pck.mpeg2_af_descriptors);
1958 676 : stream->curr_pck.mpeg2_af_descriptors = NULL;
1959 676 : stream->curr_pck.mpeg2_af_descriptors_size = 0;
1960 : }
1961 :
1962 21720 : if (padding_length)
1963 11982 : stream->program->mux->tot_pes_pad_bytes += padding_length;
1964 : }
1965 118568 : stream->pck_sap_type = 0;
1966 118568 : stream->pck_sap_time = 0;
1967 118568 : if (hdr_len) {
1968 15827 : gf_m2ts_stream_add_pes_header(bs, stream);
1969 15827 : if (stream->curr_pck.sap_type) {
1970 9113 : stream->pck_sap_type = 1;
1971 9113 : stream->pck_sap_time = stream->curr_pck.cts;
1972 : }
1973 : }
1974 :
1975 118568 : pos = (u32) gf_bs_get_position(bs);
1976 :
1977 118568 : if (adaptation_field_control == GF_M2TS_ADAPTATION_ONLY) {
1978 : return;
1979 : }
1980 :
1981 : assert(stream->curr_pck.data_len - stream->pck_offset >= payload_to_copy);
1982 118346 : memcpy(packet+pos, stream->curr_pck.data + stream->pck_offset, payload_to_copy);
1983 118346 : stream->pck_offset += payload_to_copy;
1984 : assert(stream->pes_data_remain >= payload_to_copy);
1985 118346 : stream->pes_data_remain -= payload_to_copy;
1986 :
1987 : /*update stream time, including headers*/
1988 118346 : gf_m2ts_time_inc(&stream->time, 1504/*188*8*/, stream->program->mux->bit_rate);
1989 :
1990 118346 : if (stream->pck_offset == stream->curr_pck.data_len) {
1991 39440 : u64 pcr = gf_m2ts_get_pcr(stream)/300;
1992 19720 : if (stream->program->mux->real_time && !stream->program->mux->fixed_rate && gf_m2ts_time_less(&stream->time, &stream->program->mux->time) ) {
1993 0 : GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[MPEG2-TS Muxer] Sent PES TOO LATE: PID %d - DTS "LLD" - PCR "LLD" - stream time %d:%09d - mux time %d:%09d - current mux rate %d\n",
1994 : stream->pid, stream->curr_pck.dts, pcr,
1995 : stream->time.sec, stream->time.nanosec, stream->program->mux->time.sec, stream->program->mux->time.nanosec,
1996 : stream->program->mux->bit_rate
1997 : ));
1998 19720 : } else if (stream->curr_pck.dts < pcr) {
1999 503 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG2-TS Muxer] Sent PES %d us TOO LATE: PID %d - DTS "LLD" - size %d\n\tPCR "LLD" - stream time %d:%09d - mux time %d:%09d \n",
2000 : (pcr - stream->curr_pck.dts)*100/9, stream->pid, stream->curr_pck.dts, stream->curr_pck.data_len, pcr,
2001 : stream->time.sec, stream->time.nanosec, stream->program->mux->time.sec, stream->program->mux->time.nanosec
2002 : ));
2003 19217 : } else if (stream->curr_pck.cts < pcr) {
2004 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG2-TS Muxer] Sent PES %d us TOO LATE: PID %d - DTS "LLD" - size %d\n\tPCR "LLD" - stream time %d:%09d - mux time %d:%09d \n",
2005 : pcr - stream->curr_pck.dts, stream->pid, stream->curr_pck.dts, stream->curr_pck.data_len, pcr,
2006 : stream->time.sec, stream->time.nanosec, stream->program->mux->time.sec, stream->program->mux->time.nanosec
2007 : ));
2008 : } else {
2009 19217 : GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[MPEG2-TS Muxer] Sent PES: PID %d - DTS "LLD" - PCR "LLD" - stream time %d:%09d - mux time %d:%09d \n",
2010 : stream->pid, stream->curr_pck.dts, pcr,
2011 : stream->time.sec, stream->time.nanosec, stream->program->mux->time.sec, stream->program->mux->time.nanosec
2012 : ));
2013 :
2014 : }
2015 :
2016 : /*PES has been sent, discard internal buffer*/
2017 19720 : if (stream->discard_data) gf_free(stream->curr_pck.data);
2018 19720 : stream->curr_pck.data = NULL;
2019 19720 : stream->curr_pck.data_len = 0;
2020 19720 : if (stream->curr_pck.mpeg2_af_descriptors) gf_free(stream->curr_pck.mpeg2_af_descriptors);
2021 19720 : stream->curr_pck.mpeg2_af_descriptors = NULL;
2022 19720 : stream->curr_pck.mpeg2_af_descriptors_size = 0;
2023 19720 : stream->pck_offset = 0;
2024 :
2025 : //#ifndef GPAC_DISABLE_LOG
2026 : #if 0
2027 : if (gf_m2ts_time_less(&stream->program->mux->time, &stream->time) ) {
2028 : s32 drift = gf_m2ts_time_diff_us(&stream->program->mux->time, &stream->time);
2029 : GF_LOG( (drift>1000) ? GF_LOG_WARNING : GF_LOG_INFO, GF_LOG_CONTAINER, ("[MPEG2-TS Muxer] PES PID %d sent %d us too late\n", stream->pid, drift) );
2030 : }
2031 : #endif
2032 :
2033 : /*copy over from next PES to fill this TS packet*/
2034 19720 : if (stream->copy_from_next_packets) {
2035 8122 : pos += payload_to_copy;
2036 8122 : copy_next = payload_length - payload_to_copy;
2037 : /*we might need a more than one*/
2038 16365 : while (stream->pes_data_remain) {
2039 : u32 remain = 0;
2040 8029 : Bool res = stream->process(stream->program->mux, stream);
2041 8029 : if (!res) {
2042 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG2-TS Muxer] Not enough data to fill current PES (PID %d) - filling with 0xFF\n", stream->pid) );
2043 0 : memset(packet+pos, 0xFF, copy_next);
2044 :
2045 0 : if (stream->copy_from_next_packets > copy_next) {
2046 0 : stream->copy_from_next_packets -= copy_next;
2047 : } else {
2048 0 : stream->copy_from_next_packets = 0;
2049 : }
2050 : break;
2051 : }
2052 8029 : if (copy_next > stream->curr_pck.data_len) {
2053 121 : remain = copy_next - stream->curr_pck.data_len;
2054 : copy_next = stream->curr_pck.data_len;
2055 : }
2056 :
2057 8029 : memcpy(packet+pos, stream->curr_pck.data + stream->pck_offset, copy_next);
2058 8029 : stream->pck_offset += copy_next;
2059 : assert(stream->pes_data_remain >= copy_next);
2060 8029 : stream->pes_data_remain -= copy_next;
2061 :
2062 8029 : if (stream->copy_from_next_packets > copy_next) {
2063 7921 : stream->copy_from_next_packets -= copy_next;
2064 : } else {
2065 108 : stream->copy_from_next_packets = 0;
2066 : }
2067 :
2068 8029 : if (stream->pck_offset == stream->curr_pck.data_len) {
2069 : assert(!remain || (remain>=stream->min_bytes_copy_from_next));
2070 : /*PES has been sent, discard internal buffer*/
2071 130 : if (stream->discard_data) gf_free(stream->curr_pck.data);
2072 130 : stream->curr_pck.data = NULL;
2073 130 : stream->curr_pck.data_len = 0;
2074 130 : if (stream->curr_pck.mpeg2_af_descriptors) gf_free(stream->curr_pck.mpeg2_af_descriptors);
2075 130 : stream->curr_pck.mpeg2_af_descriptors = NULL;
2076 130 : stream->curr_pck.mpeg2_af_descriptors_size = 0;
2077 130 : stream->pck_offset = 0;
2078 : }
2079 8029 : if (!remain) break;
2080 121 : pos += copy_next;
2081 : copy_next = remain;
2082 : }
2083 : }
2084 11598 : else if (stream->program->mux->force_pat_pmt_state==GF_SEG_BOUNDARY_START) {
2085 0 : stream->program->mux->force_pat = GF_TRUE;
2086 : }
2087 : }
2088 118346 : stream->bytes_since_last_time += 188;
2089 : }
2090 :
2091 :
2092 124 : GF_M2TS_Mux_Stream *gf_m2ts_stream_new(u32 pid) {
2093 : GF_M2TS_Mux_Stream *stream;
2094 :
2095 124 : GF_SAFEALLOC(stream, GF_M2TS_Mux_Stream);
2096 124 : if (!stream) {
2097 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: fail to allocate\n", pid));
2098 : return NULL;
2099 : }
2100 124 : stream->pid = pid;
2101 124 : stream->process = gf_m2ts_stream_process_pes;
2102 :
2103 124 : return stream;
2104 : }
2105 :
2106 19852 : GF_Err gf_m2ts_output_ctrl(GF_ESInterface *_self, u32 ctrl_type, void *param)
2107 : {
2108 : GF_ESIPacket *esi_pck;
2109 :
2110 19852 : GF_M2TS_Mux_Stream *stream = (GF_M2TS_Mux_Stream *)_self->output_udta;
2111 19852 : switch (ctrl_type) {
2112 19852 : case GF_ESI_OUTPUT_DATA_DISPATCH:
2113 : esi_pck = (GF_ESIPacket *)param;
2114 :
2115 19852 : if (stream->force_new || (esi_pck->flags & GF_ESI_DATA_AU_START)) {
2116 19852 : if (stream->pck_reassembler) {
2117 0 : if (stream->mx) gf_mx_p(stream->mx);
2118 0 : if (!stream->pck_first) {
2119 0 : stream->pck_first = stream->pck_last = stream->pck_reassembler;
2120 : } else {
2121 0 : stream->pck_last->next = stream->pck_reassembler;
2122 0 : stream->pck_last = stream->pck_reassembler;
2123 : }
2124 0 : if (stream->mx) gf_mx_v(stream->mx);
2125 0 : stream->pck_reassembler = NULL;
2126 : }
2127 : }
2128 19852 : if (!stream->pck_reassembler) {
2129 19852 : GF_SAFEALLOC(stream->pck_reassembler, GF_M2TS_Packet);
2130 19852 : if (!stream->pck_reassembler) {
2131 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: fail to allocate packet reassembler\n", stream->pid));
2132 : return GF_OUT_OF_MEM;
2133 : }
2134 :
2135 19852 : stream->pck_reassembler->cts = esi_pck->cts;
2136 19852 : stream->pck_reassembler->dts = esi_pck->dts;
2137 19852 : stream->pck_reassembler->duration = esi_pck->duration;
2138 19852 : if (esi_pck->mpeg2_af_descriptors) {
2139 676 : stream->pck_reassembler->mpeg2_af_descriptors = (char*)gf_realloc(stream->pck_reassembler->mpeg2_af_descriptors, sizeof(u8)* (stream->pck_reassembler->mpeg2_af_descriptors_size + esi_pck->mpeg2_af_descriptors_size) );
2140 676 : memcpy(stream->pck_reassembler->mpeg2_af_descriptors + stream->pck_reassembler->mpeg2_af_descriptors_size, esi_pck->mpeg2_af_descriptors, sizeof(u8)* esi_pck->mpeg2_af_descriptors_size );
2141 676 : stream->pck_reassembler->mpeg2_af_descriptors_size += esi_pck->mpeg2_af_descriptors_size;
2142 : }
2143 : }
2144 :
2145 19852 : stream->force_new = (esi_pck->flags & GF_ESI_DATA_AU_END) ? GF_TRUE : GF_FALSE;
2146 :
2147 19852 : stream->pck_reassembler->data = (char*)gf_realloc(stream->pck_reassembler->data , sizeof(char)*(stream->pck_reassembler->data_len+esi_pck->data_len) );
2148 19852 : if (esi_pck->data_len)
2149 19841 : memcpy(stream->pck_reassembler->data + stream->pck_reassembler->data_len, esi_pck->data, esi_pck->data_len);
2150 19852 : stream->pck_reassembler->data_len += esi_pck->data_len;
2151 :
2152 19852 : stream->pck_reassembler->flags |= esi_pck->flags;
2153 19852 : if (esi_pck->sap_type) stream->pck_reassembler->sap_type = esi_pck->sap_type;
2154 19852 : if (stream->force_new) {
2155 19852 : if (stream->mx) gf_mx_p(stream->mx);
2156 19852 : if (!stream->pck_first) {
2157 11621 : stream->pck_first = stream->pck_last = stream->pck_reassembler;
2158 : } else {
2159 8231 : stream->pck_last->next = stream->pck_reassembler;
2160 8231 : stream->pck_last = stream->pck_reassembler;
2161 : }
2162 19852 : if (stream->mx) gf_mx_v(stream->mx);
2163 19852 : stream->pck_reassembler = NULL;
2164 : }
2165 : break;
2166 : }
2167 : return GF_OK;
2168 : }
2169 :
2170 2 : static void gf_m2ts_stream_set_default_slconfig(GF_M2TS_Mux_Stream *stream)
2171 : {
2172 2 : if (!stream->ifce->sl_config) {
2173 2 : stream->ifce->sl_config = (GF_SLConfig *)gf_odf_desc_new(GF_ODF_SLC_TAG);
2174 2 : stream->ifce->sl_config->useAccessUnitStartFlag = 1;
2175 2 : stream->ifce->sl_config->useAccessUnitEndFlag = 1;
2176 2 : stream->ifce->sl_config->useRandomAccessPointFlag = 1;
2177 2 : stream->ifce->sl_config->useTimestampsFlag = 1;
2178 : }
2179 2 : }
2180 :
2181 : static s32 gf_m2ts_find_stream(GF_M2TS_Mux_Program *program, u32 pid, u32 stream_id, GF_M2TS_Mux_Stream **out_stream)
2182 : {
2183 : s32 i=0;
2184 : GF_M2TS_Mux_Stream *st = program->streams;
2185 : if (out_stream) *out_stream = NULL;
2186 3 : while (st) {
2187 1 : if (pid && (st->pid == pid)) {
2188 : if (out_stream) *out_stream = st;
2189 : return i;
2190 : }
2191 1 : if (stream_id && (st->ifce->stream_id == stream_id)) {
2192 : if (out_stream) *out_stream = st;
2193 : return i;
2194 : }
2195 1 : st = st->next;
2196 1 : i++;
2197 : }
2198 : return -1;
2199 : }
2200 :
2201 :
2202 1 : static void gf_m2ts_stream_add_hierarchy_descriptor(GF_M2TS_Mux_Stream *stream)
2203 : {
2204 : GF_M2TSDescriptor *desc;
2205 : GF_BitStream *bs;
2206 : u32 data_len;
2207 1 : if (!stream || !stream->program || !stream->program->pmt) return;
2208 :
2209 1 : bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
2210 : /*reserved*/
2211 1 : gf_bs_write_int(bs, 1, 1);
2212 : /*temporal_scalability_flag: use the reserved value*/
2213 1 : gf_bs_write_int(bs, 1, 1);
2214 : /*spatial_scalability_flag: use the reserved value*/
2215 1 : gf_bs_write_int(bs, 1, 1);
2216 : /*quality_scalability_flag: use the reserved value*/
2217 1 : gf_bs_write_int(bs, 1, 1);
2218 : /*hierarchy_type: use the rerserved value*/
2219 1 : gf_bs_write_int(bs, 0, 4);
2220 : /*reserved*/
2221 1 : gf_bs_write_int(bs, 3, 2);
2222 : /*hierarchy_layer_index*/
2223 2 : gf_bs_write_int(bs, gf_m2ts_find_stream(stream->program, stream->pid, 0, NULL), 6);
2224 : /*tref_present_flag = 1 : NOT PRESENT*/
2225 1 : gf_bs_write_int(bs, 1, 1);
2226 : /*reserved*/
2227 1 : gf_bs_write_int(bs, 1, 1);
2228 : /*hierarchy_embedded_layer_index*/
2229 2 : gf_bs_write_int(bs, gf_m2ts_find_stream(stream->program, 0, stream->ifce->depends_on_stream, NULL), 6);
2230 : /*reserved*/
2231 1 : gf_bs_write_int(bs, 3, 2);
2232 : /*hierarchy_channel*/
2233 1 : gf_bs_write_int(bs, stream->ifce->stream_id, 6);
2234 :
2235 1 : GF_SAFEALLOC(desc, GF_M2TSDescriptor);
2236 1 : if (!desc) return;
2237 :
2238 1 : desc->tag = (u8) GF_M2TS_HIERARCHY_DESCRIPTOR;
2239 1 : gf_bs_get_content(bs, &desc->data, &data_len);
2240 1 : gf_bs_del(bs);
2241 1 : desc->data_len = (u8) data_len;
2242 1 : gf_list_add(stream->loop_descriptors, desc);
2243 : }
2244 :
2245 2 : static void gf_m2ts_stream_add_metadata_pointer_descriptor(GF_M2TS_Mux_Program *program)
2246 : {
2247 : GF_M2TSDescriptor *desc;
2248 : GF_BitStream *bs;
2249 : u32 data_len;
2250 2 : bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
2251 2 : gf_bs_write_u16(bs, 0xFFFF);
2252 2 : gf_bs_write_u32(bs, GF_M2TS_META_ID3);
2253 2 : gf_bs_write_u8(bs, 0xFF);
2254 2 : gf_bs_write_u32(bs, GF_M2TS_META_ID3);
2255 2 : gf_bs_write_u8(bs, 0); /* service id */
2256 2 : gf_bs_write_int(bs, 0, 1); /* locator */
2257 2 : gf_bs_write_int(bs, 0, 2); /* carriage flags */
2258 2 : gf_bs_write_int(bs, 0x1F, 5); /* reserved */
2259 2 : gf_bs_write_u16(bs, program->number);
2260 2 : GF_SAFEALLOC(desc, GF_M2TSDescriptor);
2261 2 : if (!desc) return;
2262 :
2263 2 : desc->tag = (u8) GF_M2TS_METADATA_POINTER_DESCRIPTOR;
2264 2 : gf_bs_get_content(bs, &desc->data, &data_len);
2265 2 : gf_bs_del(bs);
2266 2 : desc->data_len = (u8) data_len;
2267 2 : gf_list_add(program->loop_descriptors, desc);
2268 : }
2269 :
2270 2 : static void gf_m2ts_stream_add_metadata_descriptor(GF_M2TS_Mux_Stream *stream)
2271 : {
2272 : GF_M2TSDescriptor *desc;
2273 : GF_BitStream *bs;
2274 : u32 data_len;
2275 2 : bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
2276 2 : gf_bs_write_u16(bs, 0xFFFF);
2277 2 : gf_bs_write_u32(bs, GF_M2TS_META_ID3);
2278 2 : gf_bs_write_u8(bs, 0xFF);
2279 2 : gf_bs_write_u32(bs, GF_M2TS_META_ID3);
2280 2 : gf_bs_write_u8(bs, 0); /* service id */
2281 2 : gf_bs_write_int(bs, 0, 3); /* decoder config flags */
2282 2 : gf_bs_write_int(bs, 0, 1); /* dsmcc flag */
2283 2 : gf_bs_write_int(bs, 0xF, 4); /* reserved */
2284 2 : GF_SAFEALLOC(desc, GF_M2TSDescriptor);
2285 2 : if (!desc) return;
2286 :
2287 2 : desc->tag = (u8) GF_M2TS_METADATA_DESCRIPTOR;
2288 2 : gf_bs_get_content(bs, &desc->data, &data_len);
2289 2 : gf_bs_del(bs);
2290 2 : desc->data_len = (u8) data_len;
2291 2 : gf_list_add(stream->loop_descriptors, desc);
2292 : }
2293 :
2294 : GF_EXPORT
2295 49 : u32 gf_m2ts_mux_program_get_pmt_pid(GF_M2TS_Mux_Program *prog)
2296 : {
2297 49 : return prog->pmt ? prog->pmt->pid : 0;
2298 : }
2299 :
2300 : GF_EXPORT
2301 49 : u32 gf_m2ts_mux_program_get_pcr_pid(GF_M2TS_Mux_Program *prog)
2302 : {
2303 49 : return prog->pcr ? prog->pcr->pid : 0;
2304 : }
2305 :
2306 : GF_EXPORT
2307 49 : u32 gf_m2ts_mux_program_get_stream_count(GF_M2TS_Mux_Program *prog)
2308 : {
2309 49 : GF_M2TS_Mux_Stream *stream = prog->streams;
2310 : u32 count=0;
2311 111 : while (stream) {
2312 13 : count++;
2313 13 : stream = stream->next;
2314 : }
2315 49 : return count;
2316 : }
2317 :
2318 : GF_EXPORT
2319 49 : GF_M2TS_Mux_Stream *gf_m2ts_program_stream_add(GF_M2TS_Mux_Program *program, struct __elementary_stream_ifce *ifce, u32 pid, Bool is_pcr, Bool force_pes, Bool needs_mutex)
2320 : {
2321 : GF_M2TS_Mux_Stream *stream, *st;
2322 :
2323 49 : stream = gf_m2ts_stream_new(pid);
2324 49 : stream->ifce = ifce;
2325 49 : stream->pid = pid;
2326 49 : stream->program = program;
2327 49 : if (is_pcr) program->pcr = stream;
2328 49 : stream->loop_descriptors = gf_list_new();
2329 49 : stream->set_initial_disc = program->initial_disc_set;
2330 :
2331 49 : if (program->streams) {
2332 : /*if PCR keep stream at the beginning*/
2333 12 : if (is_pcr) {
2334 11 : stream->next = program->streams;
2335 11 : program->streams = stream;
2336 : } else {
2337 : st = program->streams;
2338 1 : while (st->next) st = st->next;
2339 1 : st->next = stream;
2340 : }
2341 : } else {
2342 37 : program->streams = stream;
2343 : }
2344 49 : if (program->pmt) program->pmt->table_needs_update = GF_TRUE;
2345 49 : stream->bit_rate = ifce->bit_rate;
2346 49 : stream->scheduling_priority = 1;
2347 :
2348 49 : stream->force_single_au = (stream->program->mux->au_pes_mode == GF_M2TS_PACK_ALL) ? GF_FALSE : GF_TRUE;
2349 :
2350 49 : switch (ifce->stream_type) {
2351 23 : case GF_STREAM_VISUAL:
2352 : /*just pick first valid stream_id in visual range*/
2353 23 : stream->mpeg2_stream_id = 0xE0;
2354 : /*for video streams, prevent sending two frames start in one PES. This will
2355 : introduce more overhead at very low bitrates where such cases happen, but will ensure proper timing
2356 : of each frame*/
2357 23 : stream->prevent_two_au_start_in_pes = GF_TRUE;
2358 23 : switch (ifce->codecid) {
2359 3 : case GF_CODECID_MPEG4_PART2:
2360 3 : stream->mpeg2_stream_type = GF_M2TS_VIDEO_MPEG4;
2361 3 : break;
2362 16 : case GF_CODECID_AVC:
2363 16 : stream->mpeg2_stream_type = GF_M2TS_VIDEO_H264;
2364 : /*make sure we send AU delim NALU in same PES as first VCL NAL: 6 bytes (start code + 1 nal hdr + AU delim)
2365 : + 4 byte start code + first nal header*/
2366 16 : stream->min_bytes_copy_from_next = 11;
2367 16 : break;
2368 0 : case GF_CODECID_SVC:
2369 0 : stream->mpeg2_stream_type = GF_M2TS_VIDEO_SVC;
2370 : /*make sure we send AU delim NALU in same PES as first VCL NAL: 6 bytes (start code + 1 nal hdr + AU delim)
2371 : + 4 byte start code + first nal header*/
2372 0 : stream->min_bytes_copy_from_next = 11;
2373 0 : gf_m2ts_stream_add_hierarchy_descriptor(stream);
2374 0 : break;
2375 1 : case GF_CODECID_HEVC:
2376 1 : stream->mpeg2_stream_type = GF_M2TS_VIDEO_HEVC;
2377 : //this is a bit crude and will need refinement
2378 1 : if (ifce->depends_on_stream) {
2379 : GF_M2TS_Mux_Stream *base_st;
2380 0 : stream->mpeg2_stream_type = GF_M2TS_VIDEO_HEVC_TEMPORAL;
2381 0 : gf_m2ts_stream_add_hierarchy_descriptor(stream);
2382 0 : stream->force_single_au = GF_TRUE;
2383 0 : gf_m2ts_find_stream(program, 0, ifce->depends_on_stream, &base_st);
2384 0 : if (base_st) base_st->force_single_au = GF_TRUE;
2385 : }
2386 :
2387 : /*make sure we send AU delim NALU in same PES as first VCL NAL: 7 bytes (4 start code + 2 nal header + 1 AU delim)
2388 : + 4 byte start code + first nal header*/
2389 1 : stream->min_bytes_copy_from_next = 12;
2390 1 : break;
2391 1 : case GF_CODECID_LHVC:
2392 : //FIXME - we need to check scalability type to see if we have MHVC, for now only use SHVC
2393 1 : stream->mpeg2_stream_type = GF_M2TS_VIDEO_SHVC;
2394 : /*make sure we send AU delim NALU in same PES as first VCL NAL: 7 bytes (4 start code + 2 nal header + 1 AU delim)
2395 : + 4 byte start code + first nal header*/
2396 1 : stream->min_bytes_copy_from_next = 12;
2397 1 : gf_m2ts_stream_add_hierarchy_descriptor(stream);
2398 : //force by default with SHVC since we don't have any delimiter / layer yet
2399 1 : stream->force_single_au = GF_TRUE;
2400 1 : break;
2401 1 : case GF_CODECID_MPEG1:
2402 1 : stream->mpeg2_stream_type = GF_M2TS_VIDEO_MPEG1;
2403 1 : break;
2404 0 : case GF_CODECID_MPEG2_SIMPLE:
2405 : case GF_CODECID_MPEG2_MAIN:
2406 : case GF_CODECID_MPEG2_SNR:
2407 : case GF_CODECID_MPEG2_SPATIAL:
2408 : case GF_CODECID_MPEG2_HIGH:
2409 : case GF_CODECID_MPEG2_422:
2410 0 : stream->mpeg2_stream_type = GF_M2TS_VIDEO_MPEG2;
2411 0 : break;
2412 : /*JPEG/PNG carried in MPEG-4 PES*/
2413 0 : case GF_CODECID_JPEG:
2414 : case GF_CODECID_PNG:
2415 0 : stream->mpeg2_stream_type = GF_M2TS_SYSTEMS_MPEG4_PES;
2416 0 : stream->force_single_au = GF_TRUE;
2417 0 : stream->mpeg2_stream_id = 0xFA;
2418 0 : gf_m2ts_stream_set_default_slconfig(stream);
2419 0 : break;
2420 0 : case GF_CODECID_VVC:
2421 0 : stream->mpeg2_stream_type = GF_M2TS_VIDEO_VVC;
2422 : /*make sure we send AU delim NALU in same PES as first VCL NAL: 7 bytes (4 start code + 2 nal header + 1 AU delim)
2423 : + 4 byte start code + first nal header*/
2424 0 : stream->min_bytes_copy_from_next = 12;
2425 0 : break;
2426 0 : case GF_CODECID_SMPTE_VC1:
2427 0 : stream->mpeg2_stream_type = GF_M2TS_VIDEO_VC1;
2428 0 : break;
2429 1 : default:
2430 1 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] Unsupported mpeg2-ts video type for codec %s, signaling as PES private using codec 4CC in registration descriptor\n", gf_codecid_name(ifce->codecid) ));
2431 :
2432 1 : stream->mpeg2_stream_type = GF_M2TS_PRIVATE_DATA;
2433 1 : stream->force_single_au = GF_TRUE;
2434 1 : stream->force_reg_desc = GF_TRUE;
2435 1 : break;
2436 : }
2437 : break;
2438 22 : case GF_STREAM_AUDIO:
2439 : /*just pick first valid stream_id in audio range*/
2440 22 : stream->mpeg2_stream_id = 0xC0;
2441 : //override default packing for audio
2442 22 : stream->force_single_au = (stream->program->mux->au_pes_mode == GF_M2TS_PACK_NONE) ? GF_TRUE : GF_FALSE;
2443 22 : switch (ifce->codecid) {
2444 0 : case GF_CODECID_MPEG_AUDIO:
2445 0 : stream->mpeg2_stream_type = GF_M2TS_AUDIO_MPEG1;
2446 0 : break;
2447 1 : case GF_CODECID_MPEG2_PART3:
2448 1 : stream->mpeg2_stream_type = GF_M2TS_AUDIO_MPEG2;
2449 1 : break;
2450 18 : case GF_CODECID_AAC_MPEG4:
2451 : case GF_CODECID_AAC_MPEG2_MP:
2452 : case GF_CODECID_AAC_MPEG2_LCP:
2453 : case GF_CODECID_AAC_MPEG2_SSRP:
2454 18 : if (ifce->caps & GF_ESI_AAC_USE_LATM)
2455 0 : stream->mpeg2_stream_type = GF_M2TS_AUDIO_LATM_AAC;
2456 : else
2457 18 : stream->mpeg2_stream_type = GF_M2TS_AUDIO_AAC;
2458 :
2459 18 : if (!ifce->repeat_rate) ifce->repeat_rate = 500;
2460 : break;
2461 2 : case GF_CODECID_AC3:
2462 2 : stream->mpeg2_stream_type = GF_M2TS_AUDIO_AC3;
2463 2 : break;
2464 0 : case GF_CODECID_EAC3:
2465 0 : stream->mpeg2_stream_type = GF_M2TS_AUDIO_EC3;
2466 0 : break;
2467 1 : default:
2468 1 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] Unsupported mpeg2-ts audio type for codec %s, signaling as PES private using codec 4CC in registration descriptor\n", gf_codecid_name(ifce->codecid) ));
2469 1 : stream->mpeg2_stream_type = GF_M2TS_PRIVATE_DATA;
2470 1 : stream->force_single_au = GF_TRUE;
2471 1 : stream->force_reg_desc = GF_TRUE;
2472 1 : break;
2473 : }
2474 : break;
2475 1 : case GF_STREAM_OD:
2476 : /*highest priority for OD streams as they are needed to process other streams*/
2477 1 : stream->scheduling_priority = 20;
2478 1 : stream->mpeg2_stream_id = 0xFA;
2479 1 : stream->table_id = GF_M2TS_TABLE_ID_MPEG4_OD;
2480 1 : gf_m2ts_stream_set_default_slconfig(stream);
2481 1 : if (force_pes) {
2482 0 : stream->mpeg2_stream_type = GF_M2TS_SYSTEMS_MPEG4_PES;
2483 0 : stream->force_single_au = GF_TRUE;
2484 : } else {
2485 1 : stream->mpeg2_stream_type = GF_M2TS_SYSTEMS_MPEG4_SECTIONS;
2486 : }
2487 : break;
2488 1 : case GF_STREAM_SCENE:
2489 1 : stream->mpeg2_stream_id = 0xFA;
2490 1 : stream->table_id = GF_M2TS_TABLE_ID_MPEG4_BIFS;
2491 1 : gf_m2ts_stream_set_default_slconfig(stream);
2492 :
2493 1 : if (force_pes) {
2494 0 : stream->mpeg2_stream_type = GF_M2TS_SYSTEMS_MPEG4_PES;
2495 0 : stream->force_single_au = GF_TRUE;
2496 : } else {
2497 1 : stream->mpeg2_stream_type = GF_M2TS_SYSTEMS_MPEG4_SECTIONS;
2498 : }
2499 : break;
2500 2 : case GF_STREAM_TEXT:
2501 2 : stream->mpeg2_stream_id = 0xBD;
2502 2 : stream->mpeg2_stream_type = GF_M2TS_METADATA_PES;
2503 2 : gf_m2ts_stream_add_metadata_pointer_descriptor(stream->program);
2504 2 : gf_m2ts_stream_add_metadata_descriptor(stream);
2505 2 : break;
2506 0 : default:
2507 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] Unsupported codec %s, signaling as raw data\n", gf_codecid_name(ifce->codecid) ));
2508 0 : stream->mpeg2_stream_id = 0xBD;
2509 0 : stream->mpeg2_stream_type = GF_M2TS_METADATA_PES;
2510 0 : break;
2511 : }
2512 :
2513 49 : if (! (ifce->caps & GF_ESI_STREAM_WITHOUT_MPEG4_SYSTEMS)) {
2514 : /*override signaling for all streams except BIFS/OD, to use MPEG-4 PES*/
2515 49 : if (program->mpeg4_signaling==GF_M2TS_MPEG4_SIGNALING_FULL) {
2516 0 : if (stream->mpeg2_stream_type != GF_M2TS_SYSTEMS_MPEG4_SECTIONS) {
2517 0 : stream->mpeg2_stream_type = GF_M2TS_SYSTEMS_MPEG4_PES;
2518 0 : stream->force_single_au = GF_TRUE;
2519 0 : stream->mpeg2_stream_id = 0xFA;/*ISO/IEC14496-1_SL-packetized_stream*/
2520 0 : gf_m2ts_stream_set_default_slconfig(stream);
2521 : }
2522 : }
2523 : }
2524 :
2525 49 : stream->ifce->output_ctrl = gf_m2ts_output_ctrl;
2526 49 : stream->ifce->output_udta = stream;
2527 49 : if (needs_mutex)
2528 0 : stream->mx = gf_mx_new("M2TS PID");
2529 :
2530 49 : if (ifce->timescale != 90000) {
2531 42 : stream->ts_scale.num = 90000;
2532 42 : stream->ts_scale.den = ifce->timescale;
2533 : }
2534 49 : return stream;
2535 : }
2536 :
2537 : #if 0 //unused
2538 : GF_Err gf_m2ts_program_stream_update_ts_scale(GF_ESInterface *_self, u32 time_scale)
2539 : {
2540 : GF_M2TS_Mux_Stream *stream = (GF_M2TS_Mux_Stream *)_self->output_udta;
2541 : if (!stream || !time_scale)
2542 : return GF_BAD_PARAM;
2543 :
2544 : stream->ts_scale.num = 90000;
2545 : stream->ts_scale.den = time_scale;
2546 : return GF_OK;
2547 : }
2548 : #endif
2549 :
2550 : GF_EXPORT
2551 50 : GF_M2TS_Mux_Program *gf_m2ts_mux_program_find(GF_M2TS_Mux *muxer, u32 program_number)
2552 : {
2553 50 : GF_M2TS_Mux_Program *program = muxer->programs;
2554 100 : while (program) {
2555 13 : if (program->number == program_number) return program;
2556 0 : program = program->next;
2557 : }
2558 : return NULL;
2559 : }
2560 :
2561 :
2562 : GF_EXPORT
2563 37 : u32 gf_m2ts_mux_program_count(GF_M2TS_Mux *muxer)
2564 : {
2565 : u32 num=0;
2566 37 : GF_M2TS_Mux_Program *program = muxer->programs;
2567 74 : while (program) {
2568 0 : num++;
2569 0 : program = program->next;
2570 : }
2571 37 : return num;
2572 : }
2573 :
2574 : GF_EXPORT
2575 37 : GF_M2TS_Mux_Program *gf_m2ts_mux_program_add(GF_M2TS_Mux *muxer, u32 program_number, u32 pmt_pid, u32 pmt_refresh_rate, u64 pcr_offset, u32 mpeg4_signaling, u32 pmt_version, Bool initial_disc, u64 force_first_pts)
2576 : {
2577 : GF_M2TS_Mux_Program *program;
2578 :
2579 37 : GF_SAFEALLOC(program, GF_M2TS_Mux_Program);
2580 37 : if (!program) return NULL;
2581 :
2582 37 : program->mux = muxer;
2583 37 : program->mpeg4_signaling = mpeg4_signaling;
2584 37 : program->pcr_offset = pcr_offset;
2585 37 : program->loop_descriptors = gf_list_new();
2586 :
2587 37 : program->number = program_number;
2588 37 : if (muxer->programs) {
2589 : GF_M2TS_Mux_Program *p = muxer->programs;
2590 0 : while (p->next) p = p->next;
2591 0 : p->next = program;
2592 : } else {
2593 37 : muxer->programs = program;
2594 : }
2595 37 : program->pmt = gf_m2ts_stream_new(pmt_pid);
2596 37 : program->pmt->program = program;
2597 37 : program->pmt->table_needs_update = GF_TRUE;
2598 37 : program->pmt->initial_version_number = pmt_version;
2599 37 : program->initial_disc_set = initial_disc;
2600 37 : program->pmt->set_initial_disc = initial_disc;
2601 37 : muxer->pat->table_needs_update = GF_TRUE;
2602 37 : program->pmt->process = gf_m2ts_stream_process_pmt;
2603 37 : program->force_first_pts = force_first_pts;
2604 37 : program->pmt->refresh_rate_ms = pmt_refresh_rate ? pmt_refresh_rate : (u32) -1;
2605 37 : return program;
2606 : }
2607 :
2608 : GF_EXPORT
2609 1 : void gf_m2ts_mux_program_set_name(GF_M2TS_Mux_Program *program, const char *program_name, const char *provider_name)
2610 : {
2611 1 : if (program->name) gf_free(program->name);
2612 1 : program->name = program_name ? gf_strdup(program_name) : NULL;
2613 :
2614 1 : if (program->provider) gf_free(program->provider);
2615 1 : program->provider = provider_name ? gf_strdup(provider_name) : NULL;
2616 :
2617 1 : if (program->mux->sdt) program->mux->sdt->table_needs_update = GF_TRUE;
2618 1 : }
2619 :
2620 : GF_EXPORT
2621 37 : GF_M2TS_Mux *gf_m2ts_mux_new(u32 mux_rate, u32 pat_refresh_rate, Bool real_time)
2622 : {
2623 : GF_M2TS_Mux *muxer;
2624 37 : GF_SAFEALLOC(muxer, GF_M2TS_Mux);
2625 37 : if (!muxer) return NULL;
2626 :
2627 37 : muxer->pat = gf_m2ts_stream_new(GF_M2TS_PID_PAT);
2628 37 : if (!muxer->pat) {
2629 0 : gf_free(muxer);
2630 0 : return NULL;
2631 : }
2632 37 : muxer->pat->process = gf_m2ts_stream_process_pat;
2633 37 : muxer->pat->refresh_rate_ms = pat_refresh_rate ? pat_refresh_rate : (u32) -1;
2634 37 : muxer->real_time = real_time;
2635 37 : muxer->bit_rate = mux_rate;
2636 37 : muxer->init_pcr_value = 0;
2637 37 : if (mux_rate) muxer->fixed_rate = GF_TRUE;
2638 :
2639 : /*format NULL packet*/
2640 37 : muxer->pck_bs = gf_bs_new(muxer->null_pck, 188, GF_BITSTREAM_WRITE);
2641 37 : gf_bs_write_int(muxer->pck_bs, 0x47, 8);
2642 37 : gf_bs_write_int(muxer->pck_bs, 0, 1);
2643 37 : gf_bs_write_int(muxer->pck_bs, 0, 1);
2644 37 : gf_bs_write_int(muxer->pck_bs, 0, 1);
2645 37 : gf_bs_write_int(muxer->pck_bs, 0x1FFF, 13);
2646 37 : gf_bs_write_int(muxer->pck_bs, 0, 2);
2647 37 : gf_bs_write_int(muxer->pck_bs, 1, 2);
2648 37 : gf_bs_write_int(muxer->pck_bs, 0, 4);
2649 :
2650 37 : gf_rand_init(GF_FALSE);
2651 37 : muxer->pcr_update_ms = 100;
2652 37 : return muxer;
2653 : }
2654 :
2655 : GF_EXPORT
2656 1 : void gf_m2ts_mux_enable_sdt(GF_M2TS_Mux *mux, u32 refresh_rate_ms)
2657 : {
2658 1 : if (!mux->sdt) {
2659 1 : mux->sdt = gf_m2ts_stream_new(GF_M2TS_PID_SDT_BAT_ST);
2660 1 : mux->sdt->process = gf_m2ts_stream_process_sdt;
2661 1 : mux->sdt->refresh_rate_ms = refresh_rate_ms;
2662 : }
2663 1 : mux->sdt->table_needs_update = GF_TRUE;
2664 1 : return;
2665 : }
2666 :
2667 :
2668 : GF_EXPORT
2669 37 : void gf_m2ts_mux_set_pcr_max_interval(GF_M2TS_Mux *muxer, u32 pcr_update_ms)
2670 : {
2671 37 : if (muxer && (pcr_update_ms<=100)) muxer->pcr_update_ms = pcr_update_ms;
2672 37 : }
2673 :
2674 124 : void gf_m2ts_mux_stream_del(GF_M2TS_Mux_Stream *st)
2675 : {
2676 325 : while (st->tables) {
2677 77 : GF_M2TS_Mux_Table *tab = st->tables->next;
2678 231 : while (st->tables->section) {
2679 77 : GF_M2TS_Mux_Section *sec = st->tables->section->next;
2680 77 : gf_free(st->tables->section->data);
2681 77 : gf_free(st->tables->section);
2682 77 : st->tables->section = sec;
2683 : }
2684 77 : gf_free(st->tables);
2685 77 : st->tables = tab;
2686 : }
2687 124 : while (st->pck_first) {
2688 : GF_M2TS_Packet *curr_pck = st->pck_first;
2689 0 : st->pck_first = curr_pck->next;
2690 0 : gf_free(curr_pck->data);
2691 0 : gf_free(curr_pck);
2692 : }
2693 124 : if (st->curr_pck.data) gf_free(st->curr_pck.data);
2694 124 : if (st->curr_pck.mpeg2_af_descriptors) gf_free(st->curr_pck.mpeg2_af_descriptors);
2695 124 : if (st->mx) gf_mx_del(st->mx);
2696 124 : if (st->loop_descriptors) {
2697 52 : while (gf_list_count(st->loop_descriptors) ) {
2698 3 : GF_M2TSDescriptor *desc = (GF_M2TSDescriptor*)gf_list_last(st->loop_descriptors);
2699 3 : gf_list_rem_last(st->loop_descriptors);
2700 3 : if (desc->data) gf_free(desc->data);
2701 3 : gf_free(desc);
2702 : }
2703 49 : gf_list_del(st->loop_descriptors);
2704 : }
2705 124 : gf_free(st);
2706 124 : }
2707 :
2708 37 : void gf_m2ts_mux_program_del(GF_M2TS_Mux_Program *prog)
2709 : {
2710 37 : if (prog->iod) {
2711 1 : gf_odf_desc_del(prog->iod);
2712 : }
2713 86 : while (prog->streams) {
2714 49 : GF_M2TS_Mux_Stream *st = prog->streams->next;
2715 49 : gf_m2ts_mux_stream_del(prog->streams);
2716 49 : prog->streams = st;
2717 : }
2718 37 : if (prog->loop_descriptors) {
2719 39 : while (gf_list_count(prog->loop_descriptors) ) {
2720 2 : GF_M2TSDescriptor *desc = (GF_M2TSDescriptor*)gf_list_last(prog->loop_descriptors);
2721 2 : gf_list_rem_last(prog->loop_descriptors);
2722 2 : if (desc->data) gf_free(desc->data);
2723 2 : gf_free(desc);
2724 : }
2725 37 : gf_list_del(prog->loop_descriptors);
2726 : }
2727 37 : gf_m2ts_mux_stream_del(prog->pmt);
2728 37 : if (prog->name) gf_free(prog->name);
2729 37 : if (prog->provider) gf_free(prog->provider);
2730 37 : gf_free(prog);
2731 37 : }
2732 :
2733 : GF_EXPORT
2734 0 : void gf_m2ts_program_stream_remove(GF_M2TS_Mux_Stream *stream)
2735 : {
2736 0 : GF_M2TS_Mux_Program *program = stream->program;
2737 0 : GF_M2TS_Mux_Stream *a_stream = program->streams;
2738 0 : if (a_stream==stream) {
2739 0 : program->streams = stream->next;
2740 : } else {
2741 0 : while (a_stream) {
2742 0 : if (a_stream->next == stream) {
2743 0 : a_stream->next = stream->next;
2744 0 : break;
2745 : }
2746 : a_stream = a_stream->next;
2747 : }
2748 : }
2749 0 : stream->next = NULL;
2750 0 : gf_m2ts_mux_stream_del(stream);
2751 0 : program->pmt->table_needs_update = GF_TRUE;
2752 0 : }
2753 :
2754 : GF_EXPORT
2755 37 : void gf_m2ts_mux_del(GF_M2TS_Mux *mux)
2756 : {
2757 111 : while (mux->programs) {
2758 37 : GF_M2TS_Mux_Program *p = mux->programs->next;
2759 37 : gf_m2ts_mux_program_del(mux->programs);
2760 37 : mux->programs = p;
2761 : }
2762 37 : gf_m2ts_mux_stream_del(mux->pat);
2763 37 : if (mux->sdt) gf_m2ts_mux_stream_del(mux->sdt);
2764 37 : if (mux->pck_bs) gf_bs_del(mux->pck_bs);
2765 :
2766 37 : gf_free(mux);
2767 37 : }
2768 :
2769 : GF_EXPORT
2770 6303 : void gf_m2ts_mux_update_config(GF_M2TS_Mux *mux, Bool reset_time)
2771 : {
2772 : GF_M2TS_Mux_Program *prog;
2773 :
2774 6303 : gf_m2ts_mux_table_update_bitrate(mux, mux->pat);
2775 6303 : if (mux->sdt) {
2776 74 : gf_m2ts_mux_table_update_bitrate(mux, mux->sdt);
2777 : }
2778 :
2779 6303 : if (!mux->fixed_rate) {
2780 5394 : mux->bit_rate = 0;
2781 :
2782 : /*get PAT bitrate*/
2783 5394 : mux->bit_rate += mux->pat->bit_rate;
2784 5394 : if (mux->sdt) {
2785 74 : mux->bit_rate += mux->sdt->bit_rate;
2786 : }
2787 : }
2788 :
2789 6303 : prog = mux->programs;
2790 18909 : while (prog) {
2791 6303 : GF_M2TS_Mux_Stream *stream = prog->streams;
2792 23230 : while (stream) {
2793 10624 : if (!mux->fixed_rate) {
2794 8806 : mux->bit_rate += stream->bit_rate;
2795 : }
2796 : /*reset mux time*/
2797 10624 : if (reset_time) stream->time.sec = stream->time.nanosec = 0;
2798 10624 : stream = stream->next;
2799 : }
2800 : /*get PMT bitrate*/
2801 6303 : gf_m2ts_mux_table_update_bitrate(mux, prog->pmt);
2802 :
2803 6303 : if (!mux->fixed_rate) {
2804 5394 : mux->bit_rate += prog->pmt->bit_rate;
2805 : }
2806 :
2807 6303 : prog = prog->next;
2808 : }
2809 :
2810 : /*reset mux time*/
2811 6303 : if (reset_time) {
2812 37 : mux->time.sec = mux->time.nanosec = 0;
2813 37 : mux->init_sys_time = 0;
2814 : }
2815 :
2816 6303 : if (!mux->bit_rate) {
2817 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG2-TS Muxer] No bitrates set in VBR mux mode, using 100kbps\n"));
2818 0 : mux->bit_rate=100000;
2819 : }
2820 6303 : }
2821 :
2822 : GF_EXPORT
2823 37 : u32 gf_m2ts_get_sys_clock(GF_M2TS_Mux *muxer)
2824 : {
2825 37 : return (u32) (gf_sys_clock_high_res() - muxer->init_sys_time)/1000;
2826 : }
2827 :
2828 : GF_EXPORT
2829 37 : u32 gf_m2ts_get_ts_clock(GF_M2TS_Mux *muxer)
2830 : {
2831 : u32 now, init;
2832 37 : init = muxer->init_ts_time.sec*1000 + muxer->init_ts_time.nanosec/1000000;
2833 37 : now = muxer->time.sec*1000 + muxer->time.nanosec/1000000;
2834 37 : return now-init;
2835 : }
2836 :
2837 : GF_EXPORT
2838 32993 : u64 gf_m2ts_get_ts_clock_90k(GF_M2TS_Mux *muxer)
2839 : {
2840 : u64 now, init;
2841 32993 : init = ((u64)muxer->init_ts_time.sec) * 90000;
2842 32993 : init += ((u64) muxer->init_ts_time.nanosec/1000) * 9 / 100;
2843 32993 : now = ((u64) muxer->time.sec)*90000;
2844 32993 : now += ((u64) muxer->time.nanosec/1000) * 9 / 100;
2845 32993 : return now - init;
2846 : }
2847 :
2848 : GF_EXPORT
2849 37 : GF_Err gf_m2ts_mux_use_single_au_pes_mode(GF_M2TS_Mux *muxer, GF_M2TS_PackMode au_pes_mode)
2850 : {
2851 37 : if (!muxer) return GF_BAD_PARAM;
2852 37 : muxer->au_pes_mode = au_pes_mode;
2853 37 : return GF_OK;
2854 : }
2855 :
2856 : GF_EXPORT
2857 48 : GF_Err gf_m2ts_mux_set_initial_pcr(GF_M2TS_Mux *muxer, u64 init_pcr_value)
2858 : {
2859 48 : if (!muxer) return GF_BAD_PARAM;
2860 48 : muxer->init_pcr_value = 1 + init_pcr_value;
2861 48 : return GF_OK;
2862 : }
2863 :
2864 : GF_EXPORT
2865 37 : GF_Err gf_m2ts_mux_enable_pcr_only_packets(GF_M2TS_Mux *muxer, Bool enable_forced_pcr)
2866 : {
2867 37 : if (!muxer) return GF_BAD_PARAM;
2868 37 : muxer->enable_forced_pcr = enable_forced_pcr;
2869 37 : return GF_OK;
2870 : }
2871 :
2872 :
2873 : GF_EXPORT
2874 131630 : const u8 *gf_m2ts_mux_process(GF_M2TS_Mux *muxer, GF_M2TSMuxState *status, u32 *usec_till_next)
2875 : {
2876 : GF_M2TS_Mux_Program *program;
2877 : GF_M2TS_Mux_Stream *stream, *stream_to_process;
2878 : GF_M2TS_Time time, max_time;
2879 : u32 nb_streams, nb_streams_done;
2880 : u64 now_us;
2881 : char *ret;
2882 : u32 res, highest_priority;
2883 : Bool flush_all_pes = GF_FALSE;
2884 : Bool check_max_time = GF_FALSE;
2885 :
2886 : nb_streams = nb_streams_done = 0;
2887 131630 : *status = GF_M2TS_STATE_IDLE;
2888 :
2889 131630 : muxer->sap_inserted = GF_FALSE;
2890 131630 : muxer->last_pid = 0;
2891 :
2892 131630 : now_us = gf_sys_clock_high_res();
2893 131630 : if (muxer->real_time) {
2894 0 : if (!muxer->init_sys_time) {
2895 : //init TS time
2896 0 : muxer->time.sec = muxer->time.nanosec = 0;
2897 0 : gf_m2ts_time_inc(&muxer->time, (u32) (muxer->init_pcr_value ? muxer->init_pcr_value-1 : 0), 27000000);
2898 0 : muxer->init_sys_time = now_us;
2899 0 : muxer->init_ts_time = muxer->time;
2900 : } else {
2901 0 : u64 us_diff = now_us - muxer->init_sys_time;
2902 0 : GF_M2TS_Time now = muxer->init_ts_time;
2903 : gf_m2ts_time_inc(&now, us_diff, 1000000);
2904 0 : if (gf_m2ts_time_less(&now, &muxer->time)) {
2905 0 : if (usec_till_next) {
2906 0 : u32 diff = muxer->time.sec - now.sec;
2907 0 : diff *= 1000000;
2908 0 : if (now.nanosec <= muxer->time.nanosec) {
2909 0 : diff += (muxer->time.nanosec - now.nanosec) / 1000;
2910 : } else {
2911 : assert(diff);
2912 0 : diff -= 1000000;
2913 0 : diff += (1000000000 + muxer->time.nanosec - now.nanosec) / 1000;
2914 : }
2915 0 : *usec_till_next = diff;
2916 : }
2917 : return NULL;
2918 : }
2919 : }
2920 : }
2921 :
2922 : stream_to_process = NULL;
2923 131630 : time = muxer->time;
2924 : max_time.sec = max_time.nanosec = 0;
2925 :
2926 : /*bitrate have changed*/
2927 131630 : if (muxer->needs_reconfig) {
2928 128 : gf_m2ts_mux_update_config(muxer, GF_FALSE);
2929 128 : muxer->needs_reconfig = GF_FALSE;
2930 : }
2931 :
2932 131630 : if (muxer->flush_pes_at_rap && muxer->force_pat) {
2933 124 : program = muxer->programs;
2934 372 : while (program) {
2935 124 : stream = program->streams;
2936 393 : while (stream) {
2937 145 : if (stream->pes_data_remain) {
2938 : flush_all_pes = GF_TRUE;
2939 : break;
2940 : }
2941 145 : stream = stream->next;
2942 : }
2943 124 : program = program->next;
2944 : }
2945 : }
2946 :
2947 124 : if (!flush_all_pes) {
2948 :
2949 : /*compare PAT and PMT with current mux time
2950 : if non-fixed rate, current mux time is the time of the last packet sent, time test is still valid - it will however not work
2951 : if min access unit duration from all streams is greater than the PSI refresh rate*/
2952 :
2953 : /*PAT*/
2954 131630 : res = muxer->pat->process(muxer, muxer->pat);
2955 217657 : if ((res && gf_m2ts_time_less_or_equal(&muxer->pat->time, &time)) || muxer->force_pat) {
2956 2333 : time = muxer->pat->time;
2957 : stream_to_process = muxer->pat;
2958 2333 : if (muxer->force_pat) {
2959 125 : muxer->force_pat = GF_FALSE;
2960 125 : muxer->force_pat_pmt_state = GF_SEG_BOUNDARY_FORCE_PMT;
2961 : }
2962 : /*force sending the PAT regardless of other streams*/
2963 : goto send_pck;
2964 : }
2965 :
2966 : /*SDT*/
2967 129297 : if (muxer->sdt && !muxer->force_pat_pmt_state) {
2968 1164 : res = muxer->sdt->process(muxer, muxer->sdt);
2969 1703 : if (res && gf_m2ts_time_less_or_equal(&muxer->sdt->time, &time) ) {
2970 15 : time = muxer->sdt->time;
2971 : stream_to_process = muxer->sdt;
2972 15 : goto send_pck;
2973 : }
2974 : }
2975 :
2976 : /*PMT, for each program*/
2977 129282 : program = muxer->programs;
2978 385513 : while (program) {
2979 129282 : res = program->pmt->process(muxer, program->pmt);
2980 213533 : if ((res && gf_m2ts_time_less_or_equal(&program->pmt->time, &time)) || (muxer->force_pat_pmt_state==GF_SEG_BOUNDARY_FORCE_PMT)) {
2981 2333 : time = program->pmt->time;
2982 : stream_to_process = program->pmt;
2983 2333 : if (muxer->force_pat_pmt_state==GF_SEG_BOUNDARY_FORCE_PMT)
2984 125 : muxer->force_pat_pmt_state = GF_SEG_BOUNDARY_FORCE_PCR;
2985 : /*force sending the PMT regardless of other streams*/
2986 : goto send_pck;
2987 : }
2988 126949 : program = program->next;
2989 : }
2990 : }
2991 :
2992 : /*if non-fixed rate, just pick the earliest data on all streams*/
2993 126949 : if (!muxer->fixed_rate) {
2994 122313 : if (!muxer->real_time) {
2995 : time.sec = 0xFFFFFFFF;
2996 : } else {
2997 : check_max_time = GF_TRUE;
2998 : }
2999 : }
3000 :
3001 : #define FORCE_PCR_FIRST 0
3002 :
3003 : #if FORCE_PCR_FIRST
3004 :
3005 : /*PCR stream, for each program (send them first to avoid PCR to never be sent)*/
3006 : program = muxer->programs;
3007 : while (program) {
3008 : stream = program->pcr;
3009 : if (!flush_all_pes || (stream->copy_from_next_packets + stream->pes_data_remain) ) {
3010 : res = stream->process(muxer, stream);
3011 : if (res && gf_m2ts_time_less_or_equal(&stream->time, &time)) {
3012 : time = stream->time;
3013 : stream_to_process = stream;
3014 : goto send_pck;
3015 : }
3016 : }
3017 : program = program->next;
3018 : }
3019 : #endif
3020 :
3021 : /*all streams for each program*/
3022 : highest_priority = 0;
3023 126949 : program = muxer->programs;
3024 380847 : while (program) {
3025 126949 : stream = program->streams;
3026 447676 : while (stream) {
3027 : #if FORCE_PCR_FIRST
3028 : if (stream != program->pcr)
3029 : #endif
3030 : {
3031 193778 : if (flush_all_pes && !stream->pes_data_remain) {
3032 0 : nb_streams++;
3033 0 : stream = stream->next;
3034 0 : continue;
3035 : }
3036 :
3037 193778 : res = stream->process(muxer, stream);
3038 : /*next is rap on this stream, check flushing of other pes (we could use a goto)*/
3039 193778 : if (!flush_all_pes && muxer->force_pat)
3040 : return gf_m2ts_mux_process(muxer, status, usec_till_next);
3041 :
3042 193778 : if (res) {
3043 : /*always schedule the earliest data*/
3044 27001 : if (gf_m2ts_time_less(&stream->time, &time)) {
3045 : highest_priority = res;
3046 121898 : time = stream->time;
3047 : stream_to_process = stream;
3048 : #if FORCE_PCR_FIRST
3049 : goto send_pck;
3050 : #endif
3051 : }
3052 27437 : else if (gf_m2ts_time_equal(&stream->time, &time)) {
3053 : /*if the same priority schedule base stream first*/
3054 76 : if ((res > highest_priority) || ((res == highest_priority) && !stream->ifce->depends_on_stream)) {
3055 : highest_priority = res;
3056 76 : time = stream->time;
3057 : stream_to_process = stream;
3058 : #if FORCE_PCR_FIRST
3059 : goto send_pck;
3060 : #endif
3061 : }
3062 27361 : } else if (check_max_time && gf_m2ts_time_less(&max_time, &stream->time)) {
3063 0 : max_time = stream->time;
3064 : }
3065 : }
3066 : }
3067 193778 : nb_streams++;
3068 193778 : if ((stream->ifce->caps & GF_ESI_STREAM_IS_OVER) && (!res || stream->refresh_rate_ms) )
3069 5032 : nb_streams_done ++;
3070 :
3071 193778 : stream = stream->next;
3072 : }
3073 126949 : program = program->next;
3074 : }
3075 :
3076 126949 : send_pck:
3077 :
3078 : ret = NULL;
3079 131630 : if (!stream_to_process) {
3080 8378 : if (nb_streams && (nb_streams==nb_streams_done)) {
3081 1212 : *status = GF_M2TS_STATE_EOS;
3082 : } else {
3083 7166 : *status = GF_M2TS_STATE_PADDING;
3084 : }
3085 : /* padding packets ?? */
3086 8378 : if (muxer->fixed_rate) {
3087 3591 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG2-TS Muxer] Inserting empty packet at %d:%09d\n", time.sec, time.nanosec));
3088 3591 : ret = muxer->null_pck;
3089 3591 : muxer->tot_pad_sent++;
3090 : }
3091 : } else {
3092 123252 : if (stream_to_process->tables) {
3093 4684 : gf_m2ts_mux_table_get_next_packet(muxer, stream_to_process, muxer->dst_pck);
3094 : } else {
3095 118568 : gf_m2ts_mux_pes_get_next_packet(stream_to_process, muxer->dst_pck);
3096 118568 : if (stream_to_process->pck_sap_type) {
3097 9113 : muxer->sap_inserted = GF_TRUE;
3098 9113 : muxer->sap_type = stream_to_process->pck_sap_type;
3099 9113 : muxer->sap_time = stream_to_process->pck_sap_time;
3100 : }
3101 118568 : muxer->last_pts = stream_to_process->curr_pck.cts;
3102 118568 : muxer->last_pid = stream_to_process->pid;
3103 : }
3104 :
3105 123252 : ret = muxer->dst_pck;
3106 123252 : *status = GF_M2TS_STATE_DATA;
3107 :
3108 123252 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG2-TS Muxer] Sending %s from PID %d at %d:%09d - mux time %d:%09d\n", stream_to_process->tables ? "table" : "PES", stream_to_process->pid, time.sec, time.nanosec, muxer->time.sec, muxer->time.nanosec));
3109 :
3110 123252 : if (nb_streams && (nb_streams==nb_streams_done))
3111 0 : *status = GF_M2TS_STATE_EOS;
3112 : }
3113 : if (ret) {
3114 126843 : muxer->tot_pck_sent++;
3115 : /*increment time*/
3116 126843 : if (muxer->fixed_rate ) {
3117 4708 : gf_m2ts_time_inc(&muxer->time, 1504/*188*8*/, muxer->bit_rate);
3118 : }
3119 122135 : else if (muxer->real_time) {
3120 0 : u64 us_diff = gf_sys_clock_high_res() - muxer->init_sys_time;
3121 0 : muxer->time = muxer->init_ts_time;
3122 : gf_m2ts_time_inc(&muxer->time, us_diff, 1000000);
3123 : }
3124 : /*if a stream was found, use it*/
3125 122135 : else if (stream_to_process) {
3126 85069 : if (gf_m2ts_time_less_or_equal(&muxer->time, &time))
3127 58172 : muxer->time = time;
3128 : }
3129 :
3130 126843 : muxer->pck_sent_over_br_window++;
3131 126843 : if (now_us - muxer->last_br_time_us > 1000000) {
3132 21 : u64 size = 8*188*muxer->pck_sent_over_br_window;
3133 21 : muxer->average_birate_kbps = (u32) (size*1000 / (now_us - muxer->last_br_time_us));
3134 21 : muxer->last_br_time_us = now_us;
3135 21 : muxer->pck_sent_over_br_window=0;
3136 : }
3137 4787 : } else if (muxer->real_time && !muxer->fixed_rate) {
3138 : // u64 us_diff = gf_sys_clock_high_res() - muxer->init_sys_time;
3139 : // muxer->time = muxer->init_ts_time;
3140 : // gf_m2ts_time_inc(&muxer->time, us_diff, 1000000);
3141 0 : muxer->time = max_time;
3142 : }
3143 : return ret;
3144 : }
3145 :
3146 : #endif /*GPAC_DISABLE_MPEG2TS_MUX*/
|