Line | Branch | Exec | Source |
---|---|---|---|
1 | /* | ||
2 | * MPEG-2 transport stream (aka DVB) muxer | ||
3 | * Copyright (c) 2003 Fabrice Bellard | ||
4 | * | ||
5 | * This file is part of FFmpeg. | ||
6 | * | ||
7 | * FFmpeg is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU Lesser General Public | ||
9 | * License as published by the Free Software Foundation; either | ||
10 | * version 2.1 of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * FFmpeg is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with FFmpeg; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
20 | */ | ||
21 | |||
22 | #include "libavutil/avassert.h" | ||
23 | #include "libavutil/bswap.h" | ||
24 | #include "libavutil/crc.h" | ||
25 | #include "libavutil/dict.h" | ||
26 | #include "libavutil/intreadwrite.h" | ||
27 | #include "libavutil/mathematics.h" | ||
28 | #include "libavutil/mem.h" | ||
29 | #include "libavutil/opt.h" | ||
30 | |||
31 | #include "libavcodec/ac3_parser_internal.h" | ||
32 | #include "libavcodec/bytestream.h" | ||
33 | #include "libavcodec/defs.h" | ||
34 | #include "libavcodec/h264.h" | ||
35 | #include "libavcodec/hevc/hevc.h" | ||
36 | #include "libavcodec/vvc.h" | ||
37 | #include "libavcodec/startcode.h" | ||
38 | |||
39 | #include "avformat.h" | ||
40 | #include "avio_internal.h" | ||
41 | #include "internal.h" | ||
42 | #include "mpegts.h" | ||
43 | #include "mux.h" | ||
44 | |||
45 | #define PCR_TIME_BASE 27000000 | ||
46 | |||
47 | /* write DVB SI sections */ | ||
48 | |||
49 | #define DVB_PRIVATE_NETWORK_START 0xff01 | ||
50 | |||
51 | /*********************************************/ | ||
52 | /* mpegts section writer */ | ||
53 | |||
54 | typedef struct MpegTSSection { | ||
55 | int pid; | ||
56 | int cc; | ||
57 | int discontinuity; | ||
58 | void (*write_packet)(struct MpegTSSection *s, const uint8_t *packet); | ||
59 | void *opaque; | ||
60 | } MpegTSSection; | ||
61 | |||
62 | typedef struct MpegTSService { | ||
63 | MpegTSSection pmt; /* MPEG-2 PMT table context */ | ||
64 | int sid; /* service ID */ | ||
65 | uint8_t name[256]; | ||
66 | uint8_t provider_name[256]; | ||
67 | int pcr_pid; | ||
68 | AVProgram *program; | ||
69 | } MpegTSService; | ||
70 | |||
71 | // service_type values as defined in ETSI 300 468 | ||
72 | enum { | ||
73 | MPEGTS_SERVICE_TYPE_DIGITAL_TV = 0x01, | ||
74 | MPEGTS_SERVICE_TYPE_DIGITAL_RADIO = 0x02, | ||
75 | MPEGTS_SERVICE_TYPE_TELETEXT = 0x03, | ||
76 | MPEGTS_SERVICE_TYPE_ADVANCED_CODEC_DIGITAL_RADIO = 0x0A, | ||
77 | MPEGTS_SERVICE_TYPE_MPEG2_DIGITAL_HDTV = 0x11, | ||
78 | MPEGTS_SERVICE_TYPE_ADVANCED_CODEC_DIGITAL_SDTV = 0x16, | ||
79 | MPEGTS_SERVICE_TYPE_ADVANCED_CODEC_DIGITAL_HDTV = 0x19, | ||
80 | MPEGTS_SERVICE_TYPE_HEVC_DIGITAL_HDTV = 0x1F, | ||
81 | }; | ||
82 | typedef struct MpegTSWrite { | ||
83 | const AVClass *av_class; | ||
84 | MpegTSSection pat; /* MPEG-2 PAT table */ | ||
85 | MpegTSSection sdt; /* MPEG-2 SDT table context */ | ||
86 | MpegTSSection nit; /* MPEG-2 NIT table context */ | ||
87 | MpegTSService **services; | ||
88 | AVPacket *pkt; | ||
89 | int64_t sdt_period; /* SDT period in PCR time base */ | ||
90 | int64_t pat_period; /* PAT/PMT period in PCR time base */ | ||
91 | int64_t nit_period; /* NIT period in PCR time base */ | ||
92 | int nb_services; | ||
93 | int64_t first_pcr; | ||
94 | int first_dts_checked; | ||
95 | int64_t next_pcr; | ||
96 | int mux_rate; ///< set to 1 when VBR | ||
97 | int pes_payload_size; | ||
98 | int64_t total_size; | ||
99 | |||
100 | int transport_stream_id; | ||
101 | int original_network_id; | ||
102 | int service_id; | ||
103 | int service_type; | ||
104 | |||
105 | int pmt_start_pid; | ||
106 | int start_pid; | ||
107 | int m2ts_mode; | ||
108 | int m2ts_video_pid; | ||
109 | int m2ts_audio_pid; | ||
110 | int m2ts_pgssub_pid; | ||
111 | int m2ts_textsub_pid; | ||
112 | |||
113 | int pcr_period_ms; | ||
114 | #define MPEGTS_FLAG_REEMIT_PAT_PMT 0x01 | ||
115 | #define MPEGTS_FLAG_AAC_LATM 0x02 | ||
116 | #define MPEGTS_FLAG_PAT_PMT_AT_FRAMES 0x04 | ||
117 | #define MPEGTS_FLAG_SYSTEM_B 0x08 | ||
118 | #define MPEGTS_FLAG_DISCONT 0x10 | ||
119 | #define MPEGTS_FLAG_NIT 0x20 | ||
120 | #define MPEGTS_FLAG_OMIT_RAI 0x40 | ||
121 | int flags; | ||
122 | int copyts; | ||
123 | int tables_version; | ||
124 | int64_t pat_period_us; | ||
125 | int64_t sdt_period_us; | ||
126 | int64_t nit_period_us; | ||
127 | int64_t last_pat_ts; | ||
128 | int64_t last_sdt_ts; | ||
129 | int64_t last_nit_ts; | ||
130 | |||
131 | uint8_t provider_name[256]; | ||
132 | |||
133 | int omit_video_pes_length; | ||
134 | } MpegTSWrite; | ||
135 | |||
136 | /* a PES packet header is generated every DEFAULT_PES_HEADER_FREQ packets */ | ||
137 | #define DEFAULT_PES_HEADER_FREQ 16 | ||
138 | #define DEFAULT_PES_PAYLOAD_SIZE ((DEFAULT_PES_HEADER_FREQ - 1) * 184 + 170) | ||
139 | |||
140 | /* The section length is 12 bits. The first 2 are set to 0, the remaining | ||
141 | * 10 bits should not exceed 1021. */ | ||
142 | #define SECTION_LENGTH 1020 | ||
143 | |||
144 | /* NOTE: 4 bytes must be left at the end for the crc32 */ | ||
145 | 1205 | static void mpegts_write_section(MpegTSSection *s, uint8_t *buf, int len) | |
146 | { | ||
147 | unsigned int crc; | ||
148 | unsigned char packet[TS_PACKET_SIZE]; | ||
149 | const unsigned char *buf_ptr; | ||
150 | unsigned char *q; | ||
151 | int first, b, len1, left; | ||
152 | |||
153 | 2410 | crc = av_bswap32(av_crc(av_crc_get_table(AV_CRC_32_IEEE), | |
154 | 1205 | -1, buf, len - 4)); | |
155 | |||
156 | 1205 | buf[len - 4] = (crc >> 24) & 0xff; | |
157 | 1205 | buf[len - 3] = (crc >> 16) & 0xff; | |
158 | 1205 | buf[len - 2] = (crc >> 8) & 0xff; | |
159 | 1205 | buf[len - 1] = crc & 0xff; | |
160 | |||
161 | /* send each packet */ | ||
162 | 1205 | buf_ptr = buf; | |
163 |
2/2✓ Branch 0 taken 1205 times.
✓ Branch 1 taken 1205 times.
|
2410 | while (len > 0) { |
164 | 1205 | first = buf == buf_ptr; | |
165 | 1205 | q = packet; | |
166 | 1205 | *q++ = 0x47; | |
167 | 1205 | b = s->pid >> 8; | |
168 |
1/2✓ Branch 0 taken 1205 times.
✗ Branch 1 not taken.
|
1205 | if (first) |
169 | 1205 | b |= 0x40; | |
170 | 1205 | *q++ = b; | |
171 | 1205 | *q++ = s->pid; | |
172 | 1205 | s->cc = s->cc + 1 & 0xf; | |
173 | 1205 | *q++ = 0x10 | s->cc; | |
174 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1205 times.
|
1205 | if (s->discontinuity) { |
175 | ✗ | q[-1] |= 0x20; | |
176 | ✗ | *q++ = 1; | |
177 | ✗ | *q++ = 0x80; | |
178 | ✗ | s->discontinuity = 0; | |
179 | } | ||
180 |
1/2✓ Branch 0 taken 1205 times.
✗ Branch 1 not taken.
|
1205 | if (first) |
181 | 1205 | *q++ = 0; /* 0 offset */ | |
182 | 1205 | len1 = TS_PACKET_SIZE - (q - packet); | |
183 |
1/2✓ Branch 0 taken 1205 times.
✗ Branch 1 not taken.
|
1205 | if (len1 > len) |
184 | 1205 | len1 = len; | |
185 | 1205 | memcpy(q, buf_ptr, len1); | |
186 | 1205 | q += len1; | |
187 | /* add known padding data */ | ||
188 | 1205 | left = TS_PACKET_SIZE - (q - packet); | |
189 |
1/2✓ Branch 0 taken 1205 times.
✗ Branch 1 not taken.
|
1205 | if (left > 0) |
190 | 1205 | memset(q, 0xff, left); | |
191 | |||
192 | 1205 | s->write_packet(s, packet); | |
193 | |||
194 | 1205 | buf_ptr += len1; | |
195 | 1205 | len -= len1; | |
196 | } | ||
197 | 1205 | } | |
198 | |||
199 | 4829 | static inline void put16(uint8_t **q_ptr, int val) | |
200 | { | ||
201 | uint8_t *q; | ||
202 | 4829 | q = *q_ptr; | |
203 | 4829 | *q++ = val >> 8; | |
204 | 4829 | *q++ = val; | |
205 | 4829 | *q_ptr = q; | |
206 | 4829 | } | |
207 | |||
208 | 1205 | static int mpegts_write_section1(MpegTSSection *s, int tid, int id, | |
209 | int version, int sec_num, int last_sec_num, | ||
210 | uint8_t *buf, int len) | ||
211 | { | ||
212 | uint8_t section[1024], *q; | ||
213 | unsigned int tot_len; | ||
214 | /* reserved_future_use field must be set to 1 for SDT and NIT */ | ||
215 |
3/4✓ Branch 0 taken 1046 times.
✓ Branch 1 taken 159 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1046 times.
|
1205 | unsigned int flags = (tid == SDT_TID || tid == NIT_TID) ? 0xf000 : 0xb000; |
216 | |||
217 | 1205 | tot_len = 3 + 5 + len + 4; | |
218 | /* check if not too big */ | ||
219 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1205 times.
|
1205 | if (tot_len > 1024) |
220 | ✗ | return AVERROR_INVALIDDATA; | |
221 | |||
222 | 1205 | q = section; | |
223 | 1205 | *q++ = tid; | |
224 | 1205 | put16(&q, flags | (len + 5 + 4)); /* 5 byte header + 4 byte CRC */ | |
225 | 1205 | put16(&q, id); | |
226 | 1205 | *q++ = 0xc1 | (version << 1); /* current_next_indicator = 1 */ | |
227 | 1205 | *q++ = sec_num; | |
228 | 1205 | *q++ = last_sec_num; | |
229 | 1205 | memcpy(q, buf, len); | |
230 | |||
231 | 1205 | mpegts_write_section(s, section, tot_len); | |
232 | 1205 | return 0; | |
233 | } | ||
234 | |||
235 | /*********************************************/ | ||
236 | /* mpegts writer */ | ||
237 | |||
238 | #define DEFAULT_PROVIDER_NAME "FFmpeg" | ||
239 | #define DEFAULT_SERVICE_NAME "Service" | ||
240 | |||
241 | /* we retransmit the SI info at this rate */ | ||
242 | #define SDT_RETRANS_TIME 500 | ||
243 | #define PAT_RETRANS_TIME 100 | ||
244 | #define PCR_RETRANS_TIME 20 | ||
245 | #define NIT_RETRANS_TIME 500 | ||
246 | |||
247 | typedef struct MpegTSWriteStream { | ||
248 | int pid; /* stream associated pid */ | ||
249 | int cc; | ||
250 | int discontinuity; | ||
251 | int payload_size; | ||
252 | int first_timestamp_checked; ///< first pts/dts check needed | ||
253 | int prev_payload_key; | ||
254 | int64_t payload_pts; | ||
255 | int64_t payload_dts; | ||
256 | int payload_flags; | ||
257 | uint8_t *payload; | ||
258 | AVFormatContext *amux; | ||
259 | int data_st_warning; | ||
260 | |||
261 | int64_t pcr_period; /* PCR period in PCR time base */ | ||
262 | int64_t last_pcr; | ||
263 | |||
264 | /* For Opus */ | ||
265 | int opus_queued_samples; | ||
266 | int opus_pending_trim_start; | ||
267 | |||
268 | DVBAC3Descriptor *dvb_ac3_desc; | ||
269 | } MpegTSWriteStream; | ||
270 | |||
271 | 523 | static void mpegts_write_pat(AVFormatContext *s) | |
272 | { | ||
273 | 523 | MpegTSWrite *ts = s->priv_data; | |
274 | MpegTSService *service; | ||
275 | uint8_t data[SECTION_LENGTH], *q; | ||
276 | int i; | ||
277 | |||
278 | 523 | q = data; | |
279 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 523 times.
|
523 | if (ts->flags & MPEGTS_FLAG_NIT) { |
280 | ✗ | put16(&q, 0x0000); | |
281 | ✗ | put16(&q, NIT_PID); | |
282 | } | ||
283 |
2/2✓ Branch 0 taken 523 times.
✓ Branch 1 taken 523 times.
|
1046 | for (i = 0; i < ts->nb_services; i++) { |
284 | 523 | service = ts->services[i]; | |
285 | 523 | put16(&q, service->sid); | |
286 | 523 | put16(&q, 0xe000 | service->pmt.pid); | |
287 | } | ||
288 | 523 | mpegts_write_section1(&ts->pat, PAT_TID, ts->transport_stream_id, ts->tables_version, 0, 0, | |
289 | 523 | data, q - data); | |
290 | 523 | } | |
291 | |||
292 | 318 | static void putbuf(uint8_t **q_ptr, const uint8_t *buf, size_t len) | |
293 | { | ||
294 | 318 | memcpy(*q_ptr, buf, len); | |
295 | 318 | *q_ptr += len; | |
296 | 318 | } | |
297 | |||
298 | ✗ | static int put_arib_caption_descriptor(AVFormatContext *s, uint8_t **q_ptr, | |
299 | AVCodecParameters *codecpar) | ||
300 | { | ||
301 | uint8_t stream_identifier; | ||
302 | uint16_t data_component_id; | ||
303 | ✗ | uint8_t *q = *q_ptr; | |
304 | |||
305 | ✗ | switch (codecpar->profile) { | |
306 | ✗ | case AV_PROFILE_ARIB_PROFILE_A: | |
307 | ✗ | stream_identifier = 0x30; | |
308 | ✗ | data_component_id = 0x0008; | |
309 | ✗ | break; | |
310 | ✗ | case AV_PROFILE_ARIB_PROFILE_C: | |
311 | ✗ | stream_identifier = 0x87; | |
312 | ✗ | data_component_id = 0x0012; | |
313 | ✗ | break; | |
314 | ✗ | default: | |
315 | ✗ | av_log(s, AV_LOG_ERROR, | |
316 | "Unset/unknown ARIB caption profile %d utilized!\n", | ||
317 | codecpar->profile); | ||
318 | ✗ | return AVERROR_INVALIDDATA; | |
319 | } | ||
320 | |||
321 | // stream_identifier_descriptor | ||
322 | ✗ | *q++ = 0x52; // descriptor_tag | |
323 | ✗ | *q++ = 1; // descriptor_length | |
324 | ✗ | *q++ = stream_identifier; // component_tag: stream_identifier | |
325 | |||
326 | // data_component_descriptor, defined in ARIB STD-B10, part 2, 6.2.20 | ||
327 | ✗ | *q++ = 0xFD; // descriptor_tag: ARIB data coding type descriptor | |
328 | ✗ | *q++ = 3; // descriptor_length | |
329 | ✗ | put16(&q, data_component_id); // data_component_id | |
330 | // additional_arib_caption_info: defined in ARIB STD-B24, fascicle 1, Part 3, 9.6.1 | ||
331 | // Here we utilize a pre-defined set of values defined in ARIB TR-B14, | ||
332 | // Fascicle 2, 4.2.8.5 for PMT usage, with the reserved bits in the middle | ||
333 | // set to 1 (as that is what every broadcaster seems to be doing in | ||
334 | // production). | ||
335 | ✗ | *q++ = 0x3D; // DMF('0011'), Reserved('11'), Timing('01') | |
336 | |||
337 | ✗ | *q_ptr = q; | |
338 | |||
339 | ✗ | return 0; | |
340 | } | ||
341 | |||
342 | 33 | static void put_registration_descriptor(uint8_t **q_ptr, uint32_t tag) | |
343 | { | ||
344 | 33 | uint8_t *q = *q_ptr; | |
345 | 33 | *q++ = REGISTRATION_DESCRIPTOR; | |
346 | 33 | *q++ = 4; | |
347 | 33 | *q++ = tag; | |
348 | 33 | *q++ = tag >> 8; | |
349 | 33 | *q++ = tag >> 16; | |
350 | 33 | *q++ = tag >> 24; | |
351 | 33 | *q_ptr = q; | |
352 | 33 | } | |
353 | |||
354 | 532 | static int get_dvb_stream_type(AVFormatContext *s, AVStream *st) | |
355 | { | ||
356 | 532 | MpegTSWrite *ts = s->priv_data; | |
357 | 532 | MpegTSWriteStream *ts_st = st->priv_data; | |
358 | int stream_type; | ||
359 | |||
360 |
4/23✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 42 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 448 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✓ Branch 22 taken 33 times.
|
532 | switch (st->codecpar->codec_id) { |
361 | 9 | case AV_CODEC_ID_MPEG1VIDEO: | |
362 | case AV_CODEC_ID_MPEG2VIDEO: | ||
363 | 9 | stream_type = STREAM_TYPE_VIDEO_MPEG2; | |
364 | 9 | break; | |
365 | ✗ | case AV_CODEC_ID_MPEG4: | |
366 | ✗ | stream_type = STREAM_TYPE_VIDEO_MPEG4; | |
367 | ✗ | break; | |
368 | 42 | case AV_CODEC_ID_H264: | |
369 | 42 | stream_type = STREAM_TYPE_VIDEO_H264; | |
370 | 42 | break; | |
371 | ✗ | case AV_CODEC_ID_HEVC: | |
372 | ✗ | stream_type = STREAM_TYPE_VIDEO_HEVC; | |
373 | ✗ | break; | |
374 | ✗ | case AV_CODEC_ID_VVC: | |
375 | ✗ | stream_type = STREAM_TYPE_VIDEO_VVC; | |
376 | ✗ | break; | |
377 | ✗ | case AV_CODEC_ID_CAVS: | |
378 | ✗ | stream_type = STREAM_TYPE_VIDEO_CAVS; | |
379 | ✗ | break; | |
380 | ✗ | case AV_CODEC_ID_AVS2: | |
381 | ✗ | stream_type = STREAM_TYPE_VIDEO_AVS2; | |
382 | ✗ | break; | |
383 | ✗ | case AV_CODEC_ID_AVS3: | |
384 | ✗ | stream_type = STREAM_TYPE_VIDEO_AVS3; | |
385 | ✗ | break; | |
386 | ✗ | case AV_CODEC_ID_DIRAC: | |
387 | ✗ | stream_type = STREAM_TYPE_VIDEO_DIRAC; | |
388 | ✗ | break; | |
389 | ✗ | case AV_CODEC_ID_VC1: | |
390 | ✗ | stream_type = STREAM_TYPE_VIDEO_VC1; | |
391 | ✗ | break; | |
392 | 448 | case AV_CODEC_ID_MP2: | |
393 | case AV_CODEC_ID_MP3: | ||
394 |
1/2✓ Branch 0 taken 448 times.
✗ Branch 1 not taken.
|
448 | if ( st->codecpar->sample_rate > 0 |
395 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 448 times.
|
448 | && st->codecpar->sample_rate < 32000) { |
396 | ✗ | stream_type = STREAM_TYPE_AUDIO_MPEG2; | |
397 | } else { | ||
398 | 448 | stream_type = STREAM_TYPE_AUDIO_MPEG1; | |
399 | } | ||
400 | 448 | break; | |
401 | ✗ | case AV_CODEC_ID_AAC: | |
402 | ✗ | stream_type = (ts->flags & MPEGTS_FLAG_AAC_LATM) | |
403 | ? STREAM_TYPE_AUDIO_AAC_LATM | ||
404 | ✗ | : STREAM_TYPE_AUDIO_AAC; | |
405 | ✗ | break; | |
406 | ✗ | case AV_CODEC_ID_AAC_LATM: | |
407 | ✗ | stream_type = STREAM_TYPE_AUDIO_AAC_LATM; | |
408 | ✗ | break; | |
409 | ✗ | case AV_CODEC_ID_AC3: | |
410 | ✗ | stream_type = (ts->flags & MPEGTS_FLAG_SYSTEM_B) | |
411 | ? STREAM_TYPE_PRIVATE_DATA | ||
412 | ✗ | : STREAM_TYPE_AUDIO_AC3; | |
413 | ✗ | break; | |
414 | ✗ | case AV_CODEC_ID_EAC3: | |
415 | ✗ | stream_type = (ts->flags & MPEGTS_FLAG_SYSTEM_B) | |
416 | ? STREAM_TYPE_PRIVATE_DATA | ||
417 | ✗ | : STREAM_TYPE_AUDIO_EAC3; | |
418 | ✗ | break; | |
419 | ✗ | case AV_CODEC_ID_DTS: | |
420 | ✗ | stream_type = STREAM_TYPE_AUDIO_DTS; | |
421 | ✗ | break; | |
422 | ✗ | case AV_CODEC_ID_TRUEHD: | |
423 | ✗ | stream_type = STREAM_TYPE_AUDIO_TRUEHD; | |
424 | ✗ | break; | |
425 | ✗ | case AV_CODEC_ID_OPUS: | |
426 | ✗ | stream_type = STREAM_TYPE_PRIVATE_DATA; | |
427 | ✗ | break; | |
428 | ✗ | case AV_CODEC_ID_TIMED_ID3: | |
429 | ✗ | stream_type = STREAM_TYPE_METADATA; | |
430 | ✗ | break; | |
431 | ✗ | case AV_CODEC_ID_SMPTE_2038: | |
432 | ✗ | stream_type = STREAM_TYPE_PRIVATE_DATA; | |
433 | ✗ | break; | |
434 | ✗ | case AV_CODEC_ID_DVB_SUBTITLE: | |
435 | case AV_CODEC_ID_DVB_TELETEXT: | ||
436 | case AV_CODEC_ID_ARIB_CAPTION: | ||
437 | ✗ | stream_type = STREAM_TYPE_PRIVATE_DATA; | |
438 | ✗ | break; | |
439 | ✗ | case AV_CODEC_ID_SMPTE_KLV: | |
440 | ✗ | if (st->codecpar->profile == AV_PROFILE_KLVA_SYNC) { | |
441 | ✗ | stream_type = STREAM_TYPE_METADATA; | |
442 | } else { | ||
443 | ✗ | stream_type = STREAM_TYPE_PRIVATE_DATA; | |
444 | } | ||
445 | ✗ | break; | |
446 | 33 | default: | |
447 | 33 | av_log_once(s, AV_LOG_WARNING, AV_LOG_DEBUG, &ts_st->data_st_warning, | |
448 | "Stream %d, codec %s, is muxed as a private data stream " | ||
449 | "and may not be recognized upon reading.\n", st->index, | ||
450 | 33 | avcodec_get_name(st->codecpar->codec_id)); | |
451 | 33 | stream_type = STREAM_TYPE_PRIVATE_DATA; | |
452 | 33 | break; | |
453 | } | ||
454 | |||
455 | 532 | return stream_type; | |
456 | } | ||
457 | |||
458 | ✗ | static int get_m2ts_stream_type(AVFormatContext *s, AVStream *st) | |
459 | { | ||
460 | int stream_type; | ||
461 | ✗ | MpegTSWriteStream *ts_st = st->priv_data; | |
462 | |||
463 | ✗ | switch (st->codecpar->codec_id) { | |
464 | ✗ | case AV_CODEC_ID_MPEG2VIDEO: | |
465 | ✗ | stream_type = STREAM_TYPE_VIDEO_MPEG2; | |
466 | ✗ | break; | |
467 | ✗ | case AV_CODEC_ID_H264: | |
468 | ✗ | stream_type = STREAM_TYPE_VIDEO_H264; | |
469 | ✗ | break; | |
470 | ✗ | case AV_CODEC_ID_VC1: | |
471 | ✗ | stream_type = STREAM_TYPE_VIDEO_VC1; | |
472 | ✗ | break; | |
473 | ✗ | case AV_CODEC_ID_HEVC: | |
474 | ✗ | stream_type = STREAM_TYPE_VIDEO_HEVC; | |
475 | ✗ | break; | |
476 | ✗ | case AV_CODEC_ID_PCM_BLURAY: | |
477 | ✗ | stream_type = 0x80; | |
478 | ✗ | break; | |
479 | ✗ | case AV_CODEC_ID_AC3: | |
480 | ✗ | stream_type = 0x81; | |
481 | ✗ | break; | |
482 | ✗ | case AV_CODEC_ID_DTS: | |
483 | ✗ | stream_type = (st->codecpar->ch_layout.nb_channels > 6) ? 0x85 : 0x82; | |
484 | ✗ | break; | |
485 | ✗ | case AV_CODEC_ID_TRUEHD: | |
486 | ✗ | stream_type = 0x83; | |
487 | ✗ | break; | |
488 | ✗ | case AV_CODEC_ID_EAC3: | |
489 | ✗ | stream_type = 0x84; | |
490 | ✗ | break; | |
491 | ✗ | case AV_CODEC_ID_HDMV_PGS_SUBTITLE: | |
492 | ✗ | stream_type = 0x90; | |
493 | ✗ | break; | |
494 | ✗ | case AV_CODEC_ID_HDMV_TEXT_SUBTITLE: | |
495 | ✗ | stream_type = 0x92; | |
496 | ✗ | break; | |
497 | ✗ | default: | |
498 | ✗ | av_log_once(s, AV_LOG_WARNING, AV_LOG_DEBUG, &ts_st->data_st_warning, | |
499 | "Stream %d, codec %s, is muxed as a private data stream " | ||
500 | "and may not be recognized upon reading.\n", st->index, | ||
501 | ✗ | avcodec_get_name(st->codecpar->codec_id)); | |
502 | ✗ | stream_type = STREAM_TYPE_PRIVATE_DATA; | |
503 | ✗ | break; | |
504 | } | ||
505 | |||
506 | ✗ | return stream_type; | |
507 | } | ||
508 | |||
509 | 523 | static int mpegts_write_pmt(AVFormatContext *s, MpegTSService *service) | |
510 | { | ||
511 | 523 | MpegTSWrite *ts = s->priv_data; | |
512 | uint8_t data[SECTION_LENGTH], *q, *desc_length_ptr, *program_info_length_ptr; | ||
513 | 523 | int val, stream_type, i, err = 0; | |
514 | |||
515 | 523 | q = data; | |
516 | 523 | put16(&q, 0xe000 | service->pcr_pid); | |
517 | |||
518 | 523 | program_info_length_ptr = q; | |
519 | 523 | q += 2; /* patched after */ | |
520 | |||
521 | /* put program info here */ | ||
522 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 523 times.
|
523 | if (ts->m2ts_mode) { |
523 | ✗ | put_registration_descriptor(&q, MKTAG('H', 'D', 'M', 'V')); | |
524 | ✗ | *q++ = 0x88; // descriptor_tag - hdmv_copy_control_descriptor | |
525 | ✗ | *q++ = 0x04; // descriptor_length | |
526 | ✗ | put16(&q, 0x0fff); // CA_System_ID | |
527 | ✗ | *q++ = 0xfc; // private_data_byte | |
528 | ✗ | *q++ = 0xfc; // private_data_byte | |
529 | } | ||
530 | |||
531 | 523 | val = 0xf000 | (q - program_info_length_ptr - 2); | |
532 | 523 | program_info_length_ptr[0] = val >> 8; | |
533 | 523 | program_info_length_ptr[1] = val; | |
534 | |||
535 |
2/2✓ Branch 0 taken 532 times.
✓ Branch 1 taken 523 times.
|
1055 | for (i = 0; i < s->nb_streams; i++) { |
536 | 532 | AVStream *st = s->streams[i]; | |
537 | 532 | MpegTSWriteStream *ts_st = st->priv_data; | |
538 | 532 | AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0); | |
539 | 532 | const char default_language[] = "und"; | |
540 |
3/4✓ Branch 0 taken 42 times.
✓ Branch 1 taken 490 times.
✓ Branch 2 taken 42 times.
✗ Branch 3 not taken.
|
532 | const char *language = lang && strlen(lang->value) >= 3 ? lang->value : default_language; |
541 | 532 | enum AVCodecID codec_id = st->codecpar->codec_id; | |
542 | |||
543 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 532 times.
|
532 | if (s->nb_programs) { |
544 | ✗ | int k, found = 0; | |
545 | ✗ | AVProgram *program = service->program; | |
546 | |||
547 | ✗ | for (k = 0; k < program->nb_stream_indexes; k++) | |
548 | ✗ | if (program->stream_index[k] == i) { | |
549 | ✗ | found = 1; | |
550 | ✗ | break; | |
551 | } | ||
552 | |||
553 | ✗ | if (!found) | |
554 | ✗ | continue; | |
555 | } | ||
556 | |||
557 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 532 times.
|
532 | if (q - data > SECTION_LENGTH - 32) { |
558 | ✗ | err = 1; | |
559 | ✗ | break; | |
560 | } | ||
561 | |||
562 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 532 times.
|
532 | stream_type = ts->m2ts_mode ? get_m2ts_stream_type(s, st) : get_dvb_stream_type(s, st); |
563 | |||
564 | 532 | *q++ = stream_type; | |
565 | 532 | put16(&q, 0xe000 | ts_st->pid); | |
566 | 532 | desc_length_ptr = q; | |
567 | 532 | q += 2; /* patched after */ | |
568 | |||
569 | /* write optional descriptors here */ | ||
570 |
2/5✓ Branch 0 taken 481 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 51 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
532 | switch (st->codecpar->codec_type) { |
571 | 481 | case AVMEDIA_TYPE_AUDIO: | |
572 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 481 times.
|
481 | if (codec_id == AV_CODEC_ID_AC3) |
573 | ✗ | put_registration_descriptor(&q, MKTAG('A', 'C', '-', '3')); | |
574 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 481 times.
|
481 | if (codec_id == AV_CODEC_ID_EAC3) |
575 | ✗ | put_registration_descriptor(&q, MKTAG('E', 'A', 'C', '3')); | |
576 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 481 times.
|
481 | if (ts->flags & MPEGTS_FLAG_SYSTEM_B) { |
577 | ✗ | if (codec_id == AV_CODEC_ID_AC3) { | |
578 | ✗ | DVBAC3Descriptor *dvb_ac3_desc = ts_st->dvb_ac3_desc; | |
579 | |||
580 | ✗ | *q++=0x6a; // AC3 descriptor see A038 DVB SI | |
581 | ✗ | if (dvb_ac3_desc) { | |
582 | ✗ | int len = 1 + | |
583 | ✗ | !!(dvb_ac3_desc->component_type_flag) + | |
584 | ✗ | !!(dvb_ac3_desc->bsid_flag) + | |
585 | ✗ | !!(dvb_ac3_desc->mainid_flag) + | |
586 | ✗ | !!(dvb_ac3_desc->asvc_flag); | |
587 | |||
588 | ✗ | *q++ = len; | |
589 | ✗ | *q++ = dvb_ac3_desc->component_type_flag << 7 | dvb_ac3_desc->bsid_flag << 6 | | |
590 | ✗ | dvb_ac3_desc->mainid_flag << 5 | dvb_ac3_desc->asvc_flag << 4; | |
591 | |||
592 | ✗ | if (dvb_ac3_desc->component_type_flag) *q++ = dvb_ac3_desc->component_type; | |
593 | ✗ | if (dvb_ac3_desc->bsid_flag) *q++ = dvb_ac3_desc->bsid; | |
594 | ✗ | if (dvb_ac3_desc->mainid_flag) *q++ = dvb_ac3_desc->mainid; | |
595 | ✗ | if (dvb_ac3_desc->asvc_flag) *q++ = dvb_ac3_desc->asvc; | |
596 | } else { | ||
597 | ✗ | *q++=1; // 1 byte, all flags sets to 0 | |
598 | ✗ | *q++=0; // omit all fields... | |
599 | } | ||
600 | ✗ | } else if (codec_id == AV_CODEC_ID_EAC3) { | |
601 | ✗ | *q++=0x7a; // EAC3 descriptor see A038 DVB SI | |
602 | ✗ | *q++=1; // 1 byte, all flags sets to 0 | |
603 | ✗ | *q++=0; // omit all fields... | |
604 | } | ||
605 | } | ||
606 |
2/2✓ Branch 0 taken 33 times.
✓ Branch 1 taken 448 times.
|
481 | if (codec_id == AV_CODEC_ID_S302M) |
607 | 33 | put_registration_descriptor(&q, MKTAG('B', 'S', 'S', 'D')); | |
608 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 481 times.
|
481 | if (codec_id == AV_CODEC_ID_OPUS) { |
609 | ✗ | int ch = st->codecpar->ch_layout.nb_channels; | |
610 | |||
611 | /* 6 bytes registration descriptor, 4 bytes Opus audio descriptor */ | ||
612 | ✗ | if (q - data > SECTION_LENGTH - 6 - 4) { | |
613 | ✗ | err = 1; | |
614 | ✗ | break; | |
615 | } | ||
616 | |||
617 | ✗ | put_registration_descriptor(&q, MKTAG('O', 'p', 'u', 's')); | |
618 | |||
619 | ✗ | *q++ = 0x7f; /* DVB extension descriptor */ | |
620 | ✗ | *q++ = 2; | |
621 | ✗ | *q++ = 0x80; | |
622 | |||
623 | ✗ | if (st->codecpar->extradata && st->codecpar->extradata_size >= 19) { | |
624 | ✗ | if (st->codecpar->extradata[18] == 0 && ch <= 2) { | |
625 | /* RTP mapping family */ | ||
626 | ✗ | *q++ = ch; | |
627 | ✗ | } else if (st->codecpar->extradata[18] == 1 && ch <= 8 && | |
628 | ✗ | st->codecpar->extradata_size >= 21 + ch) { | |
629 | static const uint8_t coupled_stream_counts[9] = { | ||
630 | 1, 0, 1, 1, 2, 2, 2, 3, 3 | ||
631 | }; | ||
632 | static const uint8_t channel_map_a[8][8] = { | ||
633 | {0}, | ||
634 | {0, 1}, | ||
635 | {0, 2, 1}, | ||
636 | {0, 1, 2, 3}, | ||
637 | {0, 4, 1, 2, 3}, | ||
638 | {0, 4, 1, 2, 3, 5}, | ||
639 | {0, 4, 1, 2, 3, 5, 6}, | ||
640 | {0, 6, 1, 2, 3, 4, 5, 7}, | ||
641 | }; | ||
642 | static const uint8_t channel_map_b[8][8] = { | ||
643 | {0}, | ||
644 | {0, 1}, | ||
645 | {0, 1, 2}, | ||
646 | {0, 1, 2, 3}, | ||
647 | {0, 1, 2, 3, 4}, | ||
648 | {0, 1, 2, 3, 4, 5}, | ||
649 | {0, 1, 2, 3, 4, 5, 6}, | ||
650 | {0, 1, 2, 3, 4, 5, 6, 7}, | ||
651 | }; | ||
652 | /* Vorbis mapping family */ | ||
653 | |||
654 | ✗ | if (st->codecpar->extradata[19] == ch - coupled_stream_counts[ch] && | |
655 | ✗ | st->codecpar->extradata[20] == coupled_stream_counts[ch] && | |
656 | ✗ | memcmp(&st->codecpar->extradata[21], channel_map_a[ch - 1], ch) == 0) { | |
657 | ✗ | *q++ = ch; | |
658 | ✗ | } else if (ch >= 2 && st->codecpar->extradata[19] == ch && | |
659 | ✗ | st->codecpar->extradata[20] == 0 && | |
660 | ✗ | memcmp(&st->codecpar->extradata[21], channel_map_b[ch - 1], ch) == 0) { | |
661 | ✗ | *q++ = ch | 0x80; | |
662 | } else { | ||
663 | /* Unsupported, could write an extended descriptor here */ | ||
664 | ✗ | av_log(s, AV_LOG_ERROR, "Unsupported Opus Vorbis-style channel mapping"); | |
665 | ✗ | *q++ = 0xff; | |
666 | } | ||
667 | } else { | ||
668 | /* Unsupported */ | ||
669 | ✗ | av_log(s, AV_LOG_ERROR, "Unsupported Opus channel mapping for family %d", st->codecpar->extradata[18]); | |
670 | ✗ | *q++ = 0xff; | |
671 | } | ||
672 | ✗ | } else if (ch <= 2) { | |
673 | /* Assume RTP mapping family */ | ||
674 | ✗ | *q++ = ch; | |
675 | } else { | ||
676 | /* Unsupported */ | ||
677 | ✗ | av_log(s, AV_LOG_ERROR, "Unsupported Opus channel mapping"); | |
678 | ✗ | *q++ = 0xff; | |
679 | } | ||
680 | } | ||
681 | |||
682 |
1/2✓ Branch 0 taken 481 times.
✗ Branch 1 not taken.
|
481 | if (language != default_language || |
683 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 481 times.
|
481 | st->disposition & (AV_DISPOSITION_CLEAN_EFFECTS | |
684 | AV_DISPOSITION_HEARING_IMPAIRED | | ||
685 | AV_DISPOSITION_VISUAL_IMPAIRED)) { | ||
686 | const char *p, *next; | ||
687 | uint8_t *len_ptr; | ||
688 | |||
689 | ✗ | *q++ = ISO_639_LANGUAGE_DESCRIPTOR; | |
690 | ✗ | len_ptr = q++; | |
691 | ✗ | *len_ptr = 0; | |
692 | |||
693 | ✗ | for (p = next = language; next && *len_ptr < 255 / 4 * 4; p = next + 1) { | |
694 | ✗ | if (q - data > SECTION_LENGTH - 4) { | |
695 | ✗ | err = 1; | |
696 | ✗ | break; | |
697 | } | ||
698 | ✗ | next = strchr(p, ','); | |
699 | ✗ | if (strlen(p) != 3 && (!next || next != p + 3)) | |
700 | ✗ | continue; /* not a 3-letter code */ | |
701 | |||
702 | ✗ | *q++ = *p++; | |
703 | ✗ | *q++ = *p++; | |
704 | ✗ | *q++ = *p++; | |
705 | |||
706 | ✗ | if (st->disposition & AV_DISPOSITION_CLEAN_EFFECTS) | |
707 | ✗ | *q++ = 0x01; | |
708 | ✗ | else if (st->disposition & AV_DISPOSITION_HEARING_IMPAIRED) | |
709 | ✗ | *q++ = 0x02; | |
710 | ✗ | else if (st->disposition & AV_DISPOSITION_VISUAL_IMPAIRED) | |
711 | ✗ | *q++ = 0x03; | |
712 | else | ||
713 | ✗ | *q++ = 0; /* undefined type */ | |
714 | |||
715 | ✗ | *len_ptr += 4; | |
716 | } | ||
717 | |||
718 | ✗ | if (*len_ptr == 0) | |
719 | ✗ | q -= 2; /* no language codes were written */ | |
720 | } | ||
721 | 481 | break; | |
722 | ✗ | case AVMEDIA_TYPE_SUBTITLE: | |
723 | ✗ | if (codec_id == AV_CODEC_ID_DVB_SUBTITLE) { | |
724 | uint8_t *len_ptr; | ||
725 | ✗ | int extradata_copied = 0; | |
726 | |||
727 | ✗ | *q++ = 0x59; /* subtitling_descriptor */ | |
728 | ✗ | len_ptr = q++; | |
729 | |||
730 | ✗ | while (strlen(language) >= 3) { | |
731 | ✗ | if (sizeof(data) - (q - data) < 8) { /* 8 bytes per DVB subtitle substream data */ | |
732 | ✗ | err = 1; | |
733 | ✗ | break; | |
734 | } | ||
735 | ✗ | *q++ = *language++; | |
736 | ✗ | *q++ = *language++; | |
737 | ✗ | *q++ = *language++; | |
738 | /* Skip comma */ | ||
739 | ✗ | if (*language != '\0') | |
740 | ✗ | language++; | |
741 | |||
742 | ✗ | if (st->codecpar->extradata_size - extradata_copied >= 5) { | |
743 | ✗ | *q++ = st->codecpar->extradata[extradata_copied + 4]; /* subtitling_type */ | |
744 | ✗ | memcpy(q, st->codecpar->extradata + extradata_copied, 4); /* composition_page_id and ancillary_page_id */ | |
745 | ✗ | extradata_copied += 5; | |
746 | ✗ | q += 4; | |
747 | } else { | ||
748 | /* subtitling_type: | ||
749 | * 0x10 - normal with no monitor aspect ratio criticality | ||
750 | * 0x20 - for the hard of hearing with no monitor aspect ratio criticality */ | ||
751 | ✗ | *q++ = (st->disposition & AV_DISPOSITION_HEARING_IMPAIRED) ? 0x20 : 0x10; | |
752 | ✗ | if ((st->codecpar->extradata_size == 4) && (extradata_copied == 0)) { | |
753 | /* support of old 4-byte extradata format */ | ||
754 | ✗ | memcpy(q, st->codecpar->extradata, 4); /* composition_page_id and ancillary_page_id */ | |
755 | ✗ | extradata_copied += 4; | |
756 | ✗ | q += 4; | |
757 | } else { | ||
758 | ✗ | put16(&q, 1); /* composition_page_id */ | |
759 | ✗ | put16(&q, 1); /* ancillary_page_id */ | |
760 | } | ||
761 | } | ||
762 | } | ||
763 | |||
764 | ✗ | *len_ptr = q - len_ptr - 1; | |
765 | ✗ | } else if (codec_id == AV_CODEC_ID_DVB_TELETEXT) { | |
766 | ✗ | uint8_t *len_ptr = NULL; | |
767 | ✗ | int extradata_copied = 0; | |
768 | |||
769 | /* The descriptor tag. teletext_descriptor */ | ||
770 | ✗ | *q++ = 0x56; | |
771 | ✗ | len_ptr = q++; | |
772 | |||
773 | ✗ | while (strlen(language) >= 3 && q - data < sizeof(data) - 6) { | |
774 | ✗ | *q++ = *language++; | |
775 | ✗ | *q++ = *language++; | |
776 | ✗ | *q++ = *language++; | |
777 | /* Skip comma */ | ||
778 | ✗ | if (*language != '\0') | |
779 | ✗ | language++; | |
780 | |||
781 | ✗ | if (st->codecpar->extradata_size - 1 > extradata_copied) { | |
782 | ✗ | memcpy(q, st->codecpar->extradata + extradata_copied, 2); | |
783 | ✗ | extradata_copied += 2; | |
784 | ✗ | q += 2; | |
785 | } else { | ||
786 | /* The Teletext descriptor: | ||
787 | * teletext_type: This 5-bit field indicates the type of Teletext page indicated. (0x01 Initial Teletext page) | ||
788 | * teletext_magazine_number: This is a 3-bit field which identifies the magazine number. | ||
789 | * teletext_page_number: This is an 8-bit field giving two 4-bit hex digits identifying the page number. */ | ||
790 | ✗ | *q++ = 0x08; | |
791 | ✗ | *q++ = 0x00; | |
792 | } | ||
793 | } | ||
794 | |||
795 | ✗ | *len_ptr = q - len_ptr - 1; | |
796 | ✗ | } else if (codec_id == AV_CODEC_ID_ARIB_CAPTION) { | |
797 | ✗ | if (put_arib_caption_descriptor(s, &q, st->codecpar) < 0) | |
798 | ✗ | break; | |
799 | } | ||
800 | ✗ | break; | |
801 | 51 | case AVMEDIA_TYPE_VIDEO: | |
802 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
|
51 | if (stream_type == STREAM_TYPE_VIDEO_DIRAC) { |
803 | ✗ | put_registration_descriptor(&q, MKTAG('d', 'r', 'a', 'c')); | |
804 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
|
51 | } else if (stream_type == STREAM_TYPE_VIDEO_VC1) { |
805 | ✗ | put_registration_descriptor(&q, MKTAG('V', 'C', '-', '1')); | |
806 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
51 | } else if (stream_type == STREAM_TYPE_VIDEO_HEVC && s->strict_std_compliance <= FF_COMPLIANCE_NORMAL) { |
807 | ✗ | put_registration_descriptor(&q, MKTAG('H', 'E', 'V', 'C')); | |
808 |
3/6✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 51 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 51 times.
|
51 | } else if (stream_type == STREAM_TYPE_VIDEO_CAVS || stream_type == STREAM_TYPE_VIDEO_AVS2 || |
809 | stream_type == STREAM_TYPE_VIDEO_AVS3) { | ||
810 | ✗ | put_registration_descriptor(&q, MKTAG('A', 'V', 'S', 'V')); | |
811 | } | ||
812 | 51 | break; | |
813 | ✗ | case AVMEDIA_TYPE_DATA: | |
814 | ✗ | if (codec_id == AV_CODEC_ID_SMPTE_KLV) { | |
815 | ✗ | put_registration_descriptor(&q, MKTAG('K', 'L', 'V', 'A')); | |
816 | ✗ | } else if (codec_id == AV_CODEC_ID_SMPTE_2038) { | |
817 | ✗ | put_registration_descriptor(&q, MKTAG('V', 'A', 'N', 'C')); | |
818 | ✗ | } else if (codec_id == AV_CODEC_ID_TIMED_ID3) { | |
819 | ✗ | const char *tag = "ID3 "; | |
820 | ✗ | *q++ = METADATA_DESCRIPTOR; | |
821 | ✗ | *q++ = 13; | |
822 | ✗ | put16(&q, 0xffff); /* metadata application format */ | |
823 | ✗ | putbuf(&q, tag, strlen(tag)); | |
824 | ✗ | *q++ = 0xff; /* metadata format */ | |
825 | ✗ | putbuf(&q, tag, strlen(tag)); | |
826 | ✗ | *q++ = 0; /* metadata service ID */ | |
827 | ✗ | *q++ = 0xF; /* metadata_locator_record_flag|MPEG_carriage_flags|reserved */ | |
828 | } | ||
829 | ✗ | break; | |
830 | } | ||
831 | |||
832 | 532 | val = 0xf000 | (q - desc_length_ptr - 2); | |
833 | 532 | desc_length_ptr[0] = val >> 8; | |
834 | 532 | desc_length_ptr[1] = val; | |
835 | } | ||
836 | |||
837 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 523 times.
|
523 | if (err) |
838 | ✗ | av_log(s, AV_LOG_ERROR, | |
839 | "The PMT section cannot fit stream %d and all following streams.\n" | ||
840 | "Try reducing the number of languages in the audio streams " | ||
841 | "or the total number of streams.\n", i); | ||
842 | |||
843 | 523 | mpegts_write_section1(&service->pmt, PMT_TID, service->sid, ts->tables_version, 0, 0, | |
844 | 523 | data, q - data); | |
845 | 523 | return 0; | |
846 | } | ||
847 | |||
848 | 159 | static void mpegts_write_sdt(AVFormatContext *s) | |
849 | { | ||
850 | 159 | MpegTSWrite *ts = s->priv_data; | |
851 | MpegTSService *service; | ||
852 | uint8_t data[SECTION_LENGTH], *q, *desc_list_len_ptr, *desc_len_ptr; | ||
853 | int i, running_status, free_ca_mode, val; | ||
854 | |||
855 | 159 | q = data; | |
856 | 159 | put16(&q, ts->original_network_id); | |
857 | 159 | *q++ = 0xff; | |
858 |
2/2✓ Branch 0 taken 159 times.
✓ Branch 1 taken 159 times.
|
318 | for (i = 0; i < ts->nb_services; i++) { |
859 | 159 | service = ts->services[i]; | |
860 | 159 | put16(&q, service->sid); | |
861 | 159 | *q++ = 0xfc | 0x00; /* currently no EIT info */ | |
862 | 159 | desc_list_len_ptr = q; | |
863 | 159 | q += 2; | |
864 | 159 | running_status = 4; /* running */ | |
865 | 159 | free_ca_mode = 0; | |
866 | |||
867 | /* write only one descriptor for the service name and provider */ | ||
868 | 159 | *q++ = 0x48; | |
869 | 159 | desc_len_ptr = q; | |
870 | 159 | q++; | |
871 | 159 | *q++ = ts->service_type; | |
872 | 159 | putbuf(&q, service->provider_name, service->provider_name[0] + 1); | |
873 | 159 | putbuf(&q, service->name, service->name[0] + 1); | |
874 | 159 | desc_len_ptr[0] = q - desc_len_ptr - 1; | |
875 | |||
876 | /* fill descriptor length */ | ||
877 | 159 | val = (running_status << 13) | (free_ca_mode << 12) | | |
878 | 159 | (q - desc_list_len_ptr - 2); | |
879 | 159 | desc_list_len_ptr[0] = val >> 8; | |
880 | 159 | desc_list_len_ptr[1] = val; | |
881 | } | ||
882 | 159 | mpegts_write_section1(&ts->sdt, SDT_TID, ts->transport_stream_id, ts->tables_version, 0, 0, | |
883 | 159 | data, q - data); | |
884 | 159 | } | |
885 | |||
886 | ✗ | static void mpegts_write_nit(AVFormatContext *s) | |
887 | { | ||
888 | ✗ | MpegTSWrite *ts = s->priv_data; | |
889 | uint8_t data[SECTION_LENGTH], *q, *desc_len_ptr, *loop_len_ptr; | ||
890 | |||
891 | ✗ | q = data; | |
892 | |||
893 | //network_descriptors_length | ||
894 | ✗ | put16(&q, 0xf000 | (ts->provider_name[0] + 2)); | |
895 | |||
896 | //network_name_descriptor | ||
897 | ✗ | *q++ = 0x40; | |
898 | ✗ | putbuf(&q, ts->provider_name, ts->provider_name[0] + 1); | |
899 | |||
900 | //transport_stream_loop_length | ||
901 | ✗ | loop_len_ptr = q; | |
902 | ✗ | q += 2; | |
903 | |||
904 | ✗ | put16(&q, ts->transport_stream_id); | |
905 | ✗ | put16(&q, ts->original_network_id); | |
906 | |||
907 | //transport_descriptors_length | ||
908 | ✗ | desc_len_ptr = q; | |
909 | ✗ | q += 2; | |
910 | |||
911 | //service_list_descriptor | ||
912 | ✗ | *q++ = 0x41; | |
913 | ✗ | *q++ = 3 * ts->nb_services; | |
914 | ✗ | for (int i = 0; i < ts->nb_services; i++) { | |
915 | ✗ | put16(&q, ts->services[i]->sid); | |
916 | ✗ | *q++ = ts->service_type; | |
917 | } | ||
918 | |||
919 | //calculate lengths | ||
920 | ✗ | put16(&desc_len_ptr, 0xf000 | q - (desc_len_ptr + 2)); | |
921 | ✗ | put16(&loop_len_ptr, 0xf000 | q - (loop_len_ptr + 2)); | |
922 | |||
923 | ✗ | mpegts_write_section1(&ts->nit, NIT_TID, ts->original_network_id, ts->tables_version, 0, 0, | |
924 | ✗ | data, q - data); | |
925 | ✗ | } | |
926 | |||
927 | /* This stores a string in buf with the correct encoding and also sets the | ||
928 | * first byte as the length. !str is accepted for an empty string. | ||
929 | * If the string is already encoded, invalid UTF-8 or has no multibyte sequence | ||
930 | * then we keep it as is, otherwise we signal UTF-8 encoding. */ | ||
931 | 60 | static int encode_str8(uint8_t *buf, const char *str) | |
932 | { | ||
933 | size_t str_len; | ||
934 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 60 times.
|
60 | if (!str) |
935 | ✗ | str = ""; | |
936 | 60 | str_len = strlen(str); | |
937 |
2/4✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 60 times.
|
60 | if (str[0] && (unsigned)str[0] >= 0x20) { /* Make sure the string is not already encoded. */ |
938 | 60 | const uint8_t *q = str; | |
939 | 60 | int has_multibyte = 0; | |
940 |
2/2✓ Branch 0 taken 419 times.
✓ Branch 1 taken 60 times.
|
479 | while (*q) { |
941 | uint32_t code; | ||
942 |
3/8✓ Branch 0 taken 419 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 419 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 419 times.
|
419 | GET_UTF8(code, *q++, goto invalid;) /* Is it valid UTF-8? */ |
943 | 419 | has_multibyte |= (code > 127); /* Does it have multibyte UTF-8 chars in it? */ | |
944 | } | ||
945 |
1/2✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
|
60 | if (has_multibyte) { /* If we have multibyte chars and valid UTF-8, then encode as such! */ |
946 | ✗ | if (str_len > 254) | |
947 | ✗ | return AVERROR(EINVAL); | |
948 | ✗ | buf[0] = str_len + 1; | |
949 | ✗ | buf[1] = 0x15; | |
950 | ✗ | memcpy(&buf[2], str, str_len); | |
951 | ✗ | return 0; | |
952 | } | ||
953 | } | ||
954 | 60 | invalid: | |
955 | /* Otherwise let's just encode the string as is! */ | ||
956 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 60 times.
|
60 | if (str_len > 255) |
957 | ✗ | return AVERROR(EINVAL); | |
958 | 60 | buf[0] = str_len; | |
959 | 60 | memcpy(&buf[1], str, str_len); | |
960 | 60 | return 0; | |
961 | } | ||
962 | |||
963 | ✗ | static int64_t get_pcr(const MpegTSWrite *ts) | |
964 | { | ||
965 | ✗ | return av_rescale(ts->total_size + 11, 8 * PCR_TIME_BASE, ts->mux_rate) + | |
966 | ✗ | ts->first_pcr; | |
967 | } | ||
968 | |||
969 | 65648 | static void write_packet(AVFormatContext *s, const uint8_t *packet) | |
970 | { | ||
971 | 65648 | MpegTSWrite *ts = s->priv_data; | |
972 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 65648 times.
|
65648 | if (ts->m2ts_mode) { |
973 | ✗ | int64_t pcr = get_pcr(s->priv_data); | |
974 | ✗ | uint32_t tp_extra_header = pcr % 0x3fffffff; | |
975 | ✗ | tp_extra_header = AV_RB32(&tp_extra_header); | |
976 | ✗ | avio_write(s->pb, (unsigned char *) &tp_extra_header, | |
977 | sizeof(tp_extra_header)); | ||
978 | } | ||
979 | 65648 | avio_write(s->pb, packet, TS_PACKET_SIZE); | |
980 | 65648 | ts->total_size += TS_PACKET_SIZE; | |
981 | 65648 | } | |
982 | |||
983 | 1205 | static void section_write_packet(MpegTSSection *s, const uint8_t *packet) | |
984 | { | ||
985 | 1205 | AVFormatContext *ctx = s->opaque; | |
986 | 1205 | write_packet(ctx, packet); | |
987 | 1205 | } | |
988 | |||
989 | 20 | static MpegTSService *mpegts_add_service(AVFormatContext *s, int sid, | |
990 | const AVDictionary *metadata, | ||
991 | AVProgram *program) | ||
992 | { | ||
993 | 20 | MpegTSWrite *ts = s->priv_data; | |
994 | MpegTSService *service; | ||
995 | AVDictionaryEntry *title, *provider; | ||
996 | char default_service_name[32]; | ||
997 | const char *service_name; | ||
998 | const char *provider_name; | ||
999 | |||
1000 | 20 | title = av_dict_get(metadata, "service_name", NULL, 0); | |
1001 |
1/2✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
|
20 | if (!title) |
1002 | 20 | title = av_dict_get(metadata, "title", NULL, 0); | |
1003 | 20 | snprintf(default_service_name, sizeof(default_service_name), "%s%02d", DEFAULT_SERVICE_NAME, ts->nb_services + 1); | |
1004 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 19 times.
|
20 | service_name = title ? title->value : default_service_name; |
1005 | 20 | provider = av_dict_get(metadata, "service_provider", NULL, 0); | |
1006 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
|
20 | provider_name = provider ? provider->value : DEFAULT_PROVIDER_NAME; |
1007 | |||
1008 | 20 | service = av_mallocz(sizeof(MpegTSService)); | |
1009 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
|
20 | if (!service) |
1010 | ✗ | return NULL; | |
1011 | 20 | service->pmt.pid = ts->pmt_start_pid + ts->nb_services; | |
1012 | 20 | service->sid = sid; | |
1013 | 20 | service->pcr_pid = 0x1fff; | |
1014 |
2/4✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 20 times.
|
40 | if (encode_str8(service->provider_name, provider_name) < 0 || |
1015 | 20 | encode_str8(service->name, service_name) < 0) { | |
1016 | ✗ | av_log(s, AV_LOG_ERROR, "Too long service or provider name\n"); | |
1017 | ✗ | goto fail; | |
1018 | } | ||
1019 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
|
20 | if (av_dynarray_add_nofree(&ts->services, &ts->nb_services, service) < 0) |
1020 | ✗ | goto fail; | |
1021 | |||
1022 | 20 | service->pmt.write_packet = section_write_packet; | |
1023 | 20 | service->pmt.opaque = s; | |
1024 | 20 | service->pmt.cc = 15; | |
1025 | 20 | service->pmt.discontinuity= ts->flags & MPEGTS_FLAG_DISCONT; | |
1026 | 20 | service->program = program; | |
1027 | |||
1028 | 20 | return service; | |
1029 | ✗ | fail: | |
1030 | ✗ | av_free(service); | |
1031 | ✗ | return NULL; | |
1032 | } | ||
1033 | |||
1034 | 20 | static void enable_pcr_generation_for_stream(AVFormatContext *s, AVStream *pcr_st) | |
1035 | { | ||
1036 | 20 | MpegTSWrite *ts = s->priv_data; | |
1037 | 20 | MpegTSWriteStream *ts_st = pcr_st->priv_data; | |
1038 | |||
1039 |
2/4✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 20 times.
|
20 | if (ts->mux_rate > 1 || ts->pcr_period_ms >= 0) { |
1040 | ✗ | int pcr_period_ms = ts->pcr_period_ms == -1 ? PCR_RETRANS_TIME : ts->pcr_period_ms; | |
1041 | ✗ | ts_st->pcr_period = av_rescale(pcr_period_ms, PCR_TIME_BASE, 1000); | |
1042 | } else { | ||
1043 | /* By default, for VBR we select the highest multiple of frame duration which is less than 100 ms. */ | ||
1044 | 20 | int64_t frame_period = 0; | |
1045 |
2/2✓ Branch 0 taken 14 times.
✓ Branch 1 taken 6 times.
|
20 | if (pcr_st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { |
1046 | 14 | int frame_size = av_get_audio_frame_duration2(pcr_st->codecpar, 0); | |
1047 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 13 times.
|
14 | if (!frame_size) { |
1048 | 1 | av_log(s, AV_LOG_WARNING, "frame size not set\n"); | |
1049 | 1 | frame_size = 512; | |
1050 | } | ||
1051 | 14 | frame_period = av_rescale_rnd(frame_size, PCR_TIME_BASE, pcr_st->codecpar->sample_rate, AV_ROUND_UP); | |
1052 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | } else if (pcr_st->avg_frame_rate.num) { |
1053 | 6 | frame_period = av_rescale_rnd(pcr_st->avg_frame_rate.den, PCR_TIME_BASE, pcr_st->avg_frame_rate.num, AV_ROUND_UP); | |
1054 | } | ||
1055 |
2/4✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
|
20 | if (frame_period > 0 && frame_period <= PCR_TIME_BASE / 10) |
1056 | 20 | ts_st->pcr_period = frame_period * (PCR_TIME_BASE / 10 / frame_period); | |
1057 | else | ||
1058 | ✗ | ts_st->pcr_period = 1; | |
1059 | } | ||
1060 | |||
1061 | // output a PCR as soon as possible | ||
1062 | 20 | ts_st->last_pcr = ts->first_pcr - ts_st->pcr_period; | |
1063 | 20 | } | |
1064 | |||
1065 | 20 | static void select_pcr_streams(AVFormatContext *s) | |
1066 | { | ||
1067 | 20 | MpegTSWrite *ts = s->priv_data; | |
1068 | |||
1069 |
2/2✓ Branch 0 taken 20 times.
✓ Branch 1 taken 20 times.
|
40 | for (int i = 0; i < ts->nb_services; i++) { |
1070 | 20 | MpegTSService *service = ts->services[i]; | |
1071 | 20 | AVStream *pcr_st = NULL; | |
1072 | 20 | AVProgram *program = service->program; | |
1073 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
|
20 | int nb_streams = program ? program->nb_stream_indexes : s->nb_streams; |
1074 | |||
1075 |
2/2✓ Branch 0 taken 21 times.
✓ Branch 1 taken 20 times.
|
41 | for (int j = 0; j < nb_streams; j++) { |
1076 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
|
21 | AVStream *st = s->streams[program ? program->stream_index[j] : j]; |
1077 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 20 times.
|
21 | if (!pcr_st || |
1078 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
1 | pcr_st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) |
1079 | { | ||
1080 | 20 | pcr_st = st; | |
1081 | } | ||
1082 | } | ||
1083 | |||
1084 |
1/2✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
|
20 | if (pcr_st) { |
1085 | 20 | MpegTSWriteStream *ts_st = pcr_st->priv_data; | |
1086 | 20 | service->pcr_pid = ts_st->pid; | |
1087 | 20 | enable_pcr_generation_for_stream(s, pcr_st); | |
1088 | 20 | av_log(s, AV_LOG_VERBOSE, "service %i using PCR in pid=%i, pcr_period=%"PRId64"ms\n", | |
1089 | service->sid, service->pcr_pid, av_rescale(ts_st->pcr_period, 1000, PCR_TIME_BASE)); | ||
1090 | } | ||
1091 | } | ||
1092 | 20 | } | |
1093 | |||
1094 | 20 | static int mpegts_init(AVFormatContext *s) | |
1095 | { | ||
1096 | 20 | MpegTSWrite *ts = s->priv_data; | |
1097 | AVDictionaryEntry *provider; | ||
1098 | const char *provider_name; | ||
1099 | int i, j; | ||
1100 | int ret; | ||
1101 | |||
1102 |
1/2✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
|
20 | if (ts->m2ts_mode == -1) { |
1103 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
|
20 | if (av_match_ext(s->url, "m2ts")) { |
1104 | ✗ | ts->m2ts_mode = 1; | |
1105 | } else { | ||
1106 | 20 | ts->m2ts_mode = 0; | |
1107 | } | ||
1108 | } | ||
1109 | |||
1110 | 20 | ts->m2ts_video_pid = M2TS_VIDEO_PID; | |
1111 | 20 | ts->m2ts_audio_pid = M2TS_AUDIO_START_PID; | |
1112 | 20 | ts->m2ts_pgssub_pid = M2TS_PGSSUB_START_PID; | |
1113 | 20 | ts->m2ts_textsub_pid = M2TS_TEXTSUB_PID; | |
1114 | |||
1115 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
|
20 | if (ts->m2ts_mode) { |
1116 | ✗ | ts->pmt_start_pid = M2TS_PMT_PID; | |
1117 | ✗ | if (s->nb_programs > 1) { | |
1118 | ✗ | av_log(s, AV_LOG_ERROR, "Only one program is allowed in m2ts mode!\n"); | |
1119 | ✗ | return AVERROR(EINVAL); | |
1120 | } | ||
1121 | } | ||
1122 | |||
1123 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
|
20 | if (s->max_delay < 0) /* Not set by the caller */ |
1124 | ✗ | s->max_delay = 0; | |
1125 | |||
1126 | // round up to a whole number of TS packets | ||
1127 | 20 | ts->pes_payload_size = (ts->pes_payload_size + 14 + 183) / 184 * 184 - 14; | |
1128 | |||
1129 |
1/2✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
|
20 | if (!s->nb_programs) { |
1130 | /* allocate a single DVB service */ | ||
1131 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
|
20 | if (!mpegts_add_service(s, ts->service_id, s->metadata, NULL)) |
1132 | ✗ | return AVERROR(ENOMEM); | |
1133 | } else { | ||
1134 | ✗ | for (i = 0; i < s->nb_programs; i++) { | |
1135 | ✗ | AVProgram *program = s->programs[i]; | |
1136 | ✗ | if (!mpegts_add_service(s, program->id, program->metadata, program)) | |
1137 | ✗ | return AVERROR(ENOMEM); | |
1138 | } | ||
1139 | } | ||
1140 | |||
1141 | 20 | ts->pat.pid = PAT_PID; | |
1142 | /* Initialize at 15 so that it wraps and is equal to 0 for the | ||
1143 | * first packet we write. */ | ||
1144 | 20 | ts->pat.cc = 15; | |
1145 | 20 | ts->pat.discontinuity= ts->flags & MPEGTS_FLAG_DISCONT; | |
1146 | 20 | ts->pat.write_packet = section_write_packet; | |
1147 | 20 | ts->pat.opaque = s; | |
1148 | |||
1149 | 20 | ts->sdt.pid = SDT_PID; | |
1150 | 20 | ts->sdt.cc = 15; | |
1151 | 20 | ts->sdt.discontinuity= ts->flags & MPEGTS_FLAG_DISCONT; | |
1152 | 20 | ts->sdt.write_packet = section_write_packet; | |
1153 | 20 | ts->sdt.opaque = s; | |
1154 | |||
1155 | 20 | ts->nit.pid = NIT_PID; | |
1156 | 20 | ts->nit.cc = 15; | |
1157 | 20 | ts->nit.discontinuity= ts->flags & MPEGTS_FLAG_DISCONT; | |
1158 | 20 | ts->nit.write_packet = section_write_packet; | |
1159 | 20 | ts->nit.opaque = s; | |
1160 | |||
1161 | 20 | ts->pkt = ffformatcontext(s)->pkt; | |
1162 | |||
1163 | /* assign pids to each stream */ | ||
1164 |
2/2✓ Branch 0 taken 21 times.
✓ Branch 1 taken 20 times.
|
41 | for (i = 0; i < s->nb_streams; i++) { |
1165 | 21 | AVStream *st = s->streams[i]; | |
1166 | MpegTSWriteStream *ts_st; | ||
1167 | |||
1168 | 21 | ts_st = av_mallocz(sizeof(MpegTSWriteStream)); | |
1169 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
|
21 | if (!ts_st) { |
1170 | ✗ | return AVERROR(ENOMEM); | |
1171 | } | ||
1172 | 21 | st->priv_data = ts_st; | |
1173 | |||
1174 | 21 | avpriv_set_pts_info(st, 33, 1, 90000); | |
1175 | |||
1176 | 21 | ts_st->payload = av_mallocz(ts->pes_payload_size); | |
1177 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
|
21 | if (!ts_st->payload) { |
1178 | ✗ | return AVERROR(ENOMEM); | |
1179 | } | ||
1180 | |||
1181 | /* MPEG pid values < 16 are reserved. Applications which set st->id in | ||
1182 | * this range are assigned a calculated pid. */ | ||
1183 |
1/2✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
|
21 | if (st->id < 16) { |
1184 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
|
21 | if (ts->m2ts_mode) { |
1185 | ✗ | switch (st->codecpar->codec_type) { | |
1186 | ✗ | case AVMEDIA_TYPE_VIDEO: | |
1187 | ✗ | ts_st->pid = ts->m2ts_video_pid++; | |
1188 | ✗ | break; | |
1189 | ✗ | case AVMEDIA_TYPE_AUDIO: | |
1190 | ✗ | ts_st->pid = ts->m2ts_audio_pid++; | |
1191 | ✗ | break; | |
1192 | ✗ | case AVMEDIA_TYPE_SUBTITLE: | |
1193 | ✗ | switch (st->codecpar->codec_id) { | |
1194 | ✗ | case AV_CODEC_ID_HDMV_PGS_SUBTITLE: | |
1195 | ✗ | ts_st->pid = ts->m2ts_pgssub_pid++; | |
1196 | ✗ | break; | |
1197 | ✗ | case AV_CODEC_ID_HDMV_TEXT_SUBTITLE: | |
1198 | ✗ | ts_st->pid = ts->m2ts_textsub_pid++; | |
1199 | ✗ | break; | |
1200 | } | ||
1201 | ✗ | break; | |
1202 | } | ||
1203 | ✗ | if (ts->m2ts_video_pid > M2TS_VIDEO_PID + 1 || | |
1204 | ✗ | ts->m2ts_audio_pid > M2TS_AUDIO_START_PID + 32 || | |
1205 | ✗ | ts->m2ts_pgssub_pid > M2TS_PGSSUB_START_PID + 32 || | |
1206 | ✗ | ts->m2ts_textsub_pid > M2TS_TEXTSUB_PID + 1 || | |
1207 | ✗ | ts_st->pid < 16) { | |
1208 | ✗ | av_log(s, AV_LOG_ERROR, "Cannot automatically assign PID for stream %d\n", st->index); | |
1209 | ✗ | return AVERROR(EINVAL); | |
1210 | } | ||
1211 | } else { | ||
1212 | 21 | ts_st->pid = ts->start_pid + i; | |
1213 | } | ||
1214 | } else { | ||
1215 | ✗ | ts_st->pid = st->id; | |
1216 | } | ||
1217 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
|
21 | if (ts_st->pid >= 0x1FFF) { |
1218 | ✗ | av_log(s, AV_LOG_ERROR, | |
1219 | "Invalid stream id %d, must be less than 8191\n", st->id); | ||
1220 | ✗ | return AVERROR(EINVAL); | |
1221 | } | ||
1222 |
2/2✓ Branch 0 taken 21 times.
✓ Branch 1 taken 21 times.
|
42 | for (j = 0; j < ts->nb_services; j++) { |
1223 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
|
21 | if (ts->services[j]->pmt.pid > LAST_OTHER_PID) { |
1224 | ✗ | av_log(s, AV_LOG_ERROR, | |
1225 | ✗ | "Invalid PMT PID %d, must be less than %d\n", ts->services[j]->pmt.pid, LAST_OTHER_PID + 1); | |
1226 | ✗ | return AVERROR(EINVAL); | |
1227 | } | ||
1228 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
|
21 | if (ts_st->pid == ts->services[j]->pmt.pid) { |
1229 | ✗ | av_log(s, AV_LOG_ERROR, "PID %d cannot be both elementary and PMT PID\n", ts_st->pid); | |
1230 | ✗ | return AVERROR(EINVAL); | |
1231 | } | ||
1232 | } | ||
1233 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 21 times.
|
22 | for (j = 0; j < i; j++) { |
1234 | 1 | MpegTSWriteStream *ts_st_prev = s->streams[j]->priv_data; | |
1235 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (ts_st_prev->pid == ts_st->pid) { |
1236 | ✗ | av_log(s, AV_LOG_ERROR, "Duplicate stream id %d\n", ts_st->pid); | |
1237 | ✗ | return AVERROR(EINVAL); | |
1238 | } | ||
1239 | } | ||
1240 | 21 | ts_st->payload_pts = AV_NOPTS_VALUE; | |
1241 | 21 | ts_st->payload_dts = AV_NOPTS_VALUE; | |
1242 | 21 | ts_st->cc = 15; | |
1243 | 21 | ts_st->discontinuity = ts->flags & MPEGTS_FLAG_DISCONT; | |
1244 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
|
21 | if (st->codecpar->codec_id == AV_CODEC_ID_AAC && |
1245 | ✗ | st->codecpar->extradata_size > 0) { | |
1246 | AVStream *ast; | ||
1247 | ✗ | ts_st->amux = avformat_alloc_context(); | |
1248 | ✗ | if (!ts_st->amux) { | |
1249 | ✗ | return AVERROR(ENOMEM); | |
1250 | } | ||
1251 | ✗ | ts_st->amux->oformat = | |
1252 | ✗ | av_guess_format((ts->flags & MPEGTS_FLAG_AAC_LATM) ? "latm" : "adts", | |
1253 | NULL, NULL); | ||
1254 | ✗ | if (!ts_st->amux->oformat) { | |
1255 | ✗ | return AVERROR(EINVAL); | |
1256 | } | ||
1257 | ✗ | if (!(ast = avformat_new_stream(ts_st->amux, NULL))) { | |
1258 | ✗ | return AVERROR(ENOMEM); | |
1259 | } | ||
1260 | ✗ | ret = avcodec_parameters_copy(ast->codecpar, st->codecpar); | |
1261 | ✗ | if (ret != 0) | |
1262 | ✗ | return ret; | |
1263 | ✗ | ast->time_base = st->time_base; | |
1264 | ✗ | ret = avformat_write_header(ts_st->amux, NULL); | |
1265 | ✗ | if (ret < 0) | |
1266 | ✗ | return ret; | |
1267 | } | ||
1268 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
|
21 | if (st->codecpar->codec_id == AV_CODEC_ID_OPUS) { |
1269 | ✗ | ts_st->opus_pending_trim_start = st->codecpar->initial_padding * 48000 / st->codecpar->sample_rate; | |
1270 | } | ||
1271 | } | ||
1272 | |||
1273 |
1/2✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
|
20 | if (ts->copyts < 1) |
1274 | 20 | ts->first_pcr = av_rescale(s->max_delay, PCR_TIME_BASE, AV_TIME_BASE); | |
1275 | |||
1276 | 20 | select_pcr_streams(s); | |
1277 | |||
1278 | 20 | ts->last_pat_ts = AV_NOPTS_VALUE; | |
1279 | 20 | ts->last_sdt_ts = AV_NOPTS_VALUE; | |
1280 | 20 | ts->last_nit_ts = AV_NOPTS_VALUE; | |
1281 | 20 | ts->pat_period = av_rescale(ts->pat_period_us, PCR_TIME_BASE, AV_TIME_BASE); | |
1282 | 20 | ts->sdt_period = av_rescale(ts->sdt_period_us, PCR_TIME_BASE, AV_TIME_BASE); | |
1283 | 20 | ts->nit_period = av_rescale(ts->nit_period_us, PCR_TIME_BASE, AV_TIME_BASE); | |
1284 | |||
1285 | /* assign provider name */ | ||
1286 | 20 | provider = av_dict_get(s->metadata, "service_provider", NULL, 0); | |
1287 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
|
20 | provider_name = provider ? provider->value : DEFAULT_PROVIDER_NAME; |
1288 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
|
20 | if (encode_str8(ts->provider_name, provider_name) < 0) { |
1289 | ✗ | av_log(s, AV_LOG_ERROR, "Too long provider name\n"); | |
1290 | ✗ | return AVERROR(EINVAL); | |
1291 | } | ||
1292 | |||
1293 |
1/2✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
|
20 | if (ts->mux_rate == 1) |
1294 | 20 | av_log(s, AV_LOG_VERBOSE, "muxrate VBR, "); | |
1295 | else | ||
1296 | ✗ | av_log(s, AV_LOG_VERBOSE, "muxrate %d, ", ts->mux_rate); | |
1297 | 20 | av_log(s, AV_LOG_VERBOSE, | |
1298 | "sdt every %"PRId64" ms, pat/pmt every %"PRId64" ms", | ||
1299 | av_rescale(ts->sdt_period, 1000, PCR_TIME_BASE), | ||
1300 | av_rescale(ts->pat_period, 1000, PCR_TIME_BASE)); | ||
1301 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
|
20 | if (ts->flags & MPEGTS_FLAG_NIT) |
1302 | ✗ | av_log(s, AV_LOG_VERBOSE, ", nit every %"PRId64" ms", av_rescale(ts->nit_period, 1000, PCR_TIME_BASE)); | |
1303 | 20 | av_log(s, AV_LOG_VERBOSE, "\n"); | |
1304 | |||
1305 | 20 | return 0; | |
1306 | } | ||
1307 | |||
1308 | /* send SDT, NIT, PAT and PMT tables regularly */ | ||
1309 | 64443 | static void retransmit_si_info(AVFormatContext *s, int force_pat, int force_sdt, int force_nit, int64_t pcr) | |
1310 | { | ||
1311 | 64443 | MpegTSWrite *ts = s->priv_data; | |
1312 | int i; | ||
1313 | |||
1314 |
4/6✓ Branch 0 taken 64443 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 64423 times.
✓ Branch 3 taken 20 times.
✓ Branch 4 taken 64423 times.
✗ Branch 5 not taken.
|
64443 | if ((pcr != AV_NOPTS_VALUE && ts->last_sdt_ts == AV_NOPTS_VALUE) || |
1315 |
4/4✓ Branch 0 taken 64330 times.
✓ Branch 1 taken 93 times.
✓ Branch 2 taken 46 times.
✓ Branch 3 taken 64284 times.
|
64423 | (pcr != AV_NOPTS_VALUE && pcr - ts->last_sdt_ts >= ts->sdt_period) || |
1316 | force_sdt | ||
1317 | ) { | ||
1318 |
1/2✓ Branch 0 taken 159 times.
✗ Branch 1 not taken.
|
159 | if (pcr != AV_NOPTS_VALUE) |
1319 | 159 | ts->last_sdt_ts = FFMAX(pcr, ts->last_sdt_ts); | |
1320 | 159 | mpegts_write_sdt(s); | |
1321 | } | ||
1322 |
4/6✓ Branch 0 taken 64443 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 64423 times.
✓ Branch 3 taken 20 times.
✓ Branch 4 taken 64423 times.
✗ Branch 5 not taken.
|
64443 | if ((pcr != AV_NOPTS_VALUE && ts->last_pat_ts == AV_NOPTS_VALUE) || |
1323 |
4/4✓ Branch 0 taken 63966 times.
✓ Branch 1 taken 457 times.
✓ Branch 2 taken 46 times.
✓ Branch 3 taken 63920 times.
|
64423 | (pcr != AV_NOPTS_VALUE && pcr - ts->last_pat_ts >= ts->pat_period) || |
1324 | force_pat) { | ||
1325 |
1/2✓ Branch 0 taken 523 times.
✗ Branch 1 not taken.
|
523 | if (pcr != AV_NOPTS_VALUE) |
1326 | 523 | ts->last_pat_ts = FFMAX(pcr, ts->last_pat_ts); | |
1327 | 523 | mpegts_write_pat(s); | |
1328 |
2/2✓ Branch 0 taken 523 times.
✓ Branch 1 taken 523 times.
|
1046 | for (i = 0; i < ts->nb_services; i++) |
1329 | 523 | mpegts_write_pmt(s, ts->services[i]); | |
1330 | } | ||
1331 |
4/6✓ Branch 0 taken 64443 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 64423 times.
✓ Branch 3 taken 20 times.
✓ Branch 4 taken 64423 times.
✗ Branch 5 not taken.
|
64443 | if ((pcr != AV_NOPTS_VALUE && ts->last_nit_ts == AV_NOPTS_VALUE) || |
1332 |
4/4✓ Branch 0 taken 64073 times.
✓ Branch 1 taken 350 times.
✓ Branch 2 taken 46 times.
✓ Branch 3 taken 64027 times.
|
64423 | (pcr != AV_NOPTS_VALUE && pcr - ts->last_nit_ts >= ts->nit_period) || |
1333 | force_nit | ||
1334 | ) { | ||
1335 |
1/2✓ Branch 0 taken 416 times.
✗ Branch 1 not taken.
|
416 | if (pcr != AV_NOPTS_VALUE) |
1336 | 416 | ts->last_nit_ts = FFMAX(pcr, ts->last_nit_ts); | |
1337 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 416 times.
|
416 | if (ts->flags & MPEGTS_FLAG_NIT) |
1338 | ✗ | mpegts_write_nit(s); | |
1339 | } | ||
1340 | 64443 | } | |
1341 | |||
1342 | 3925 | static int write_pcr_bits(uint8_t *buf, int64_t pcr) | |
1343 | { | ||
1344 | 3925 | int64_t pcr_low = pcr % 300, pcr_high = pcr / 300; | |
1345 | |||
1346 | 3925 | *buf++ = pcr_high >> 25; | |
1347 | 3925 | *buf++ = pcr_high >> 17; | |
1348 | 3925 | *buf++ = pcr_high >> 9; | |
1349 | 3925 | *buf++ = pcr_high >> 1; | |
1350 | 3925 | *buf++ = pcr_high << 7 | pcr_low >> 8 | 0x7e; | |
1351 | 3925 | *buf++ = pcr_low; | |
1352 | |||
1353 | 3925 | return 6; | |
1354 | } | ||
1355 | |||
1356 | /* Write a single null transport stream packet */ | ||
1357 | ✗ | static void mpegts_insert_null_packet(AVFormatContext *s) | |
1358 | { | ||
1359 | uint8_t *q; | ||
1360 | uint8_t buf[TS_PACKET_SIZE]; | ||
1361 | |||
1362 | ✗ | q = buf; | |
1363 | ✗ | *q++ = 0x47; | |
1364 | ✗ | *q++ = 0x00 | 0x1f; | |
1365 | ✗ | *q++ = 0xff; | |
1366 | ✗ | *q++ = 0x10; | |
1367 | ✗ | memset(q, 0x0FF, TS_PACKET_SIZE - (q - buf)); | |
1368 | ✗ | write_packet(s, buf); | |
1369 | ✗ | } | |
1370 | |||
1371 | /* Write a single transport stream packet with a PCR and no payload */ | ||
1372 | ✗ | static void mpegts_insert_pcr_only(AVFormatContext *s, AVStream *st) | |
1373 | { | ||
1374 | ✗ | MpegTSWrite *ts = s->priv_data; | |
1375 | ✗ | MpegTSWriteStream *ts_st = st->priv_data; | |
1376 | uint8_t *q; | ||
1377 | uint8_t buf[TS_PACKET_SIZE]; | ||
1378 | |||
1379 | ✗ | q = buf; | |
1380 | ✗ | *q++ = 0x47; | |
1381 | ✗ | *q++ = ts_st->pid >> 8; | |
1382 | ✗ | *q++ = ts_st->pid; | |
1383 | ✗ | *q++ = 0x20 | ts_st->cc; /* Adaptation only */ | |
1384 | /* Continuity Count field does not increment (see 13818-1 section 2.4.3.3) */ | ||
1385 | ✗ | *q++ = TS_PACKET_SIZE - 5; /* Adaptation Field Length */ | |
1386 | ✗ | *q++ = 0x10; /* Adaptation flags: PCR present */ | |
1387 | ✗ | if (ts_st->discontinuity) { | |
1388 | ✗ | q[-1] |= 0x80; | |
1389 | ✗ | ts_st->discontinuity = 0; | |
1390 | } | ||
1391 | |||
1392 | /* PCR coded into 6 bytes */ | ||
1393 | ✗ | q += write_pcr_bits(q, get_pcr(ts)); | |
1394 | |||
1395 | /* stuffing bytes */ | ||
1396 | ✗ | memset(q, 0xFF, TS_PACKET_SIZE - (q - buf)); | |
1397 | ✗ | write_packet(s, buf); | |
1398 | ✗ | } | |
1399 | |||
1400 | 4118 | static void write_pts(uint8_t *q, int fourbits, int64_t pts) | |
1401 | { | ||
1402 | int val; | ||
1403 | |||
1404 | 4118 | val = fourbits << 4 | (((pts >> 30) & 0x07) << 1) | 1; | |
1405 | 4118 | *q++ = val; | |
1406 | 4118 | val = (((pts >> 15) & 0x7fff) << 1) | 1; | |
1407 | 4118 | *q++ = val >> 8; | |
1408 | 4118 | *q++ = val; | |
1409 | 4118 | val = (((pts) & 0x7fff) << 1) | 1; | |
1410 | 4118 | *q++ = val >> 8; | |
1411 | 4118 | *q++ = val; | |
1412 | 4118 | } | |
1413 | |||
1414 | /* Set an adaptation field flag in an MPEG-TS packet*/ | ||
1415 | 7780 | static void set_af_flag(uint8_t *pkt, int flag) | |
1416 | { | ||
1417 | // expect at least one flag to set | ||
1418 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7780 times.
|
7780 | av_assert0(flag); |
1419 | |||
1420 |
2/2✓ Branch 0 taken 3928 times.
✓ Branch 1 taken 3852 times.
|
7780 | if ((pkt[3] & 0x20) == 0) { |
1421 | // no AF yet, set adaptation field flag | ||
1422 | 3928 | pkt[3] |= 0x20; | |
1423 | // 1 byte length, no flags | ||
1424 | 3928 | pkt[4] = 1; | |
1425 | 3928 | pkt[5] = 0; | |
1426 | } | ||
1427 | 7780 | pkt[5] |= flag; | |
1428 | 7780 | } | |
1429 | |||
1430 | /* Extend the adaptation field by size bytes */ | ||
1431 | 3925 | static void extend_af(uint8_t *pkt, int size) | |
1432 | { | ||
1433 | // expect already existing adaptation field | ||
1434 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3925 times.
|
3925 | av_assert0(pkt[3] & 0x20); |
1435 | 3925 | pkt[4] += size; | |
1436 | 3925 | } | |
1437 | |||
1438 | /* Get a pointer to MPEG-TS payload (right after TS packet header) */ | ||
1439 | 11705 | static uint8_t *get_ts_payload_start(uint8_t *pkt) | |
1440 | { | ||
1441 |
1/2✓ Branch 0 taken 11705 times.
✗ Branch 1 not taken.
|
11705 | if (pkt[3] & 0x20) |
1442 | 11705 | return pkt + 5 + pkt[4]; | |
1443 | else | ||
1444 | ✗ | return pkt + 4; | |
1445 | } | ||
1446 | |||
1447 | 3997 | static int get_pes_stream_id(AVFormatContext *s, AVStream *st, int stream_id, int *async) | |
1448 | { | ||
1449 | 3997 | MpegTSWrite *ts = s->priv_data; | |
1450 | 3997 | *async = 0; | |
1451 |
2/2✓ Branch 0 taken 151 times.
✓ Branch 1 taken 3846 times.
|
3997 | if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { |
1452 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 151 times.
|
151 | if (st->codecpar->codec_id == AV_CODEC_ID_DIRAC) |
1453 | ✗ | return STREAM_ID_EXTENDED_STREAM_ID; | |
1454 | else | ||
1455 | 151 | return STREAM_ID_VIDEO_STREAM_0; | |
1456 |
1/2✓ Branch 0 taken 3846 times.
✗ Branch 1 not taken.
|
3846 | } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && |
1457 |
2/2✓ Branch 0 taken 66 times.
✓ Branch 1 taken 3780 times.
|
3846 | (st->codecpar->codec_id == AV_CODEC_ID_MP2 || |
1458 |
1/2✓ Branch 0 taken 66 times.
✗ Branch 1 not taken.
|
66 | st->codecpar->codec_id == AV_CODEC_ID_MP3 || |
1459 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
|
66 | st->codecpar->codec_id == AV_CODEC_ID_AAC)) { |
1460 | 3780 | return STREAM_ID_AUDIO_STREAM_0; | |
1461 |
1/2✓ Branch 0 taken 66 times.
✗ Branch 1 not taken.
|
66 | } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && |
1462 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
|
66 | st->codecpar->codec_id == AV_CODEC_ID_AC3 && |
1463 | ✗ | ts->m2ts_mode) { | |
1464 | ✗ | return STREAM_ID_EXTENDED_STREAM_ID; | |
1465 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
|
66 | } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA && |
1466 | ✗ | st->codecpar->codec_id == AV_CODEC_ID_TIMED_ID3) { | |
1467 | ✗ | return STREAM_ID_PRIVATE_STREAM_1; | |
1468 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
|
66 | } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) { |
1469 | ✗ | if (st->codecpar->codec_id == AV_CODEC_ID_SMPTE_KLV && | |
1470 | stream_id == STREAM_ID_PRIVATE_STREAM_1) /* asynchronous KLV */ | ||
1471 | ✗ | *async = 1; | |
1472 | ✗ | return stream_id != -1 ? stream_id : STREAM_ID_METADATA_STREAM; | |
1473 | } else { | ||
1474 | 66 | return STREAM_ID_PRIVATE_STREAM_1; | |
1475 | } | ||
1476 | } | ||
1477 | |||
1478 | /* Add a PES header to the front of the payload, and segment into an integer | ||
1479 | * number of TS packets. The final TS packet is padded using an oversized | ||
1480 | * adaptation header to exactly fill the last TS packet. | ||
1481 | * NOTE: 'payload' contains a complete PES payload. */ | ||
1482 | 3997 | static void mpegts_write_pes(AVFormatContext *s, AVStream *st, | |
1483 | const uint8_t *payload, int payload_size, | ||
1484 | int64_t pts, int64_t dts, int key, int stream_id) | ||
1485 | { | ||
1486 | 3997 | MpegTSWriteStream *ts_st = st->priv_data; | |
1487 | 3997 | MpegTSWrite *ts = s->priv_data; | |
1488 | uint8_t buf[TS_PACKET_SIZE]; | ||
1489 | uint8_t *q; | ||
1490 | int val, is_start, len, header_len, write_pcr, flags; | ||
1491 | int afc_len, stuffing_len; | ||
1492 | 3997 | int is_dvb_subtitle = (st->codecpar->codec_id == AV_CODEC_ID_DVB_SUBTITLE); | |
1493 | 3997 | int is_dvb_teletext = (st->codecpar->codec_id == AV_CODEC_ID_DVB_TELETEXT); | |
1494 | 3997 | int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE); | |
1495 |
5/6✓ Branch 0 taken 151 times.
✓ Branch 1 taken 3846 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 142 times.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
|
3997 | int force_pat = st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && key && !ts_st->prev_payload_key; |
1496 | 3997 | int force_sdt = 0; | |
1497 | 3997 | int force_nit = 0; | |
1498 | |||
1499 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 3997 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
3997 | av_assert0(ts_st->payload != buf || st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO); |
1500 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 3997 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
3997 | if (ts->flags & MPEGTS_FLAG_PAT_PMT_AT_FRAMES && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { |
1501 | ✗ | force_pat = 1; | |
1502 | } | ||
1503 | |||
1504 |
2/2✓ Branch 0 taken 61 times.
✓ Branch 1 taken 3936 times.
|
3997 | if (ts->flags & MPEGTS_FLAG_REEMIT_PAT_PMT) { |
1505 | 61 | force_pat = 1; | |
1506 | 61 | force_sdt = 1; | |
1507 | 61 | force_nit = 1; | |
1508 | 61 | ts->flags &= ~MPEGTS_FLAG_REEMIT_PAT_PMT; | |
1509 | } | ||
1510 | |||
1511 | 3997 | is_start = 1; | |
1512 |
2/2✓ Branch 0 taken 64443 times.
✓ Branch 1 taken 3997 times.
|
68440 | while (payload_size > 0) { |
1513 | 64443 | int64_t pcr = AV_NOPTS_VALUE; | |
1514 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 64443 times.
|
64443 | if (ts->mux_rate > 1) |
1515 | ✗ | pcr = get_pcr(ts); | |
1516 |
1/2✓ Branch 0 taken 64443 times.
✗ Branch 1 not taken.
|
64443 | else if (dts != AV_NOPTS_VALUE) |
1517 | 64443 | pcr = (dts - delay) * 300; | |
1518 | |||
1519 | 64443 | retransmit_si_info(s, force_pat, force_sdt, force_nit, pcr); | |
1520 | 64443 | force_pat = 0; | |
1521 | 64443 | force_sdt = 0; | |
1522 | 64443 | force_nit = 0; | |
1523 | |||
1524 | 64443 | write_pcr = 0; | |
1525 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 64443 times.
|
64443 | if (ts->mux_rate > 1) { |
1526 | /* Send PCR packets for all PCR streams if needed */ | ||
1527 | ✗ | pcr = get_pcr(ts); | |
1528 | ✗ | if (pcr >= ts->next_pcr) { | |
1529 | ✗ | int64_t next_pcr = INT64_MAX; | |
1530 | ✗ | for (int i = 0; i < s->nb_streams; i++) { | |
1531 | /* Make the current stream the last, because for that we | ||
1532 | * can insert the pcr into the payload later */ | ||
1533 | ✗ | int st2_index = i < st->index ? i : (i + 1 == s->nb_streams ? st->index : i + 1); | |
1534 | ✗ | AVStream *st2 = s->streams[st2_index]; | |
1535 | ✗ | MpegTSWriteStream *ts_st2 = st2->priv_data; | |
1536 | ✗ | if (ts_st2->pcr_period) { | |
1537 | ✗ | if (pcr - ts_st2->last_pcr >= ts_st2->pcr_period) { | |
1538 | ✗ | ts_st2->last_pcr = FFMAX(pcr - ts_st2->pcr_period, ts_st2->last_pcr + ts_st2->pcr_period); | |
1539 | ✗ | if (st2 != st) { | |
1540 | ✗ | mpegts_insert_pcr_only(s, st2); | |
1541 | ✗ | pcr = get_pcr(ts); | |
1542 | } else { | ||
1543 | ✗ | write_pcr = 1; | |
1544 | } | ||
1545 | } | ||
1546 | ✗ | next_pcr = FFMIN(next_pcr, ts_st2->last_pcr + ts_st2->pcr_period); | |
1547 | } | ||
1548 | } | ||
1549 | ✗ | ts->next_pcr = next_pcr; | |
1550 | } | ||
1551 | ✗ | if (dts != AV_NOPTS_VALUE && (dts - pcr / 300) > delay) { | |
1552 | /* pcr insert gets priority over null packet insert */ | ||
1553 | ✗ | if (write_pcr) | |
1554 | ✗ | mpegts_insert_pcr_only(s, st); | |
1555 | else | ||
1556 | ✗ | mpegts_insert_null_packet(s); | |
1557 | /* recalculate write_pcr and possibly retransmit si_info */ | ||
1558 | ✗ | continue; | |
1559 | } | ||
1560 |
3/4✓ Branch 0 taken 64398 times.
✓ Branch 1 taken 45 times.
✓ Branch 2 taken 64398 times.
✗ Branch 3 not taken.
|
64443 | } else if (ts_st->pcr_period && pcr != AV_NOPTS_VALUE) { |
1561 |
4/4✓ Branch 0 taken 3200 times.
✓ Branch 1 taken 61198 times.
✓ Branch 2 taken 2648 times.
✓ Branch 3 taken 552 times.
|
64398 | if (pcr - ts_st->last_pcr >= ts_st->pcr_period && is_start) { |
1562 | 2648 | ts_st->last_pcr = FFMAX(pcr - ts_st->pcr_period, ts_st->last_pcr + ts_st->pcr_period); | |
1563 | 2648 | write_pcr = 1; | |
1564 | } | ||
1565 | } | ||
1566 | |||
1567 | /* prepare packet header */ | ||
1568 | 64443 | q = buf; | |
1569 | 64443 | *q++ = 0x47; | |
1570 | 64443 | val = ts_st->pid >> 8; | |
1571 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 64443 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
64443 | if (ts->m2ts_mode && st->codecpar->codec_id == AV_CODEC_ID_AC3) |
1572 | ✗ | val |= 0x20; | |
1573 |
2/2✓ Branch 0 taken 3997 times.
✓ Branch 1 taken 60446 times.
|
64443 | if (is_start) |
1574 | 3997 | val |= 0x40; | |
1575 | 64443 | *q++ = val; | |
1576 | 64443 | *q++ = ts_st->pid; | |
1577 | 64443 | ts_st->cc = ts_st->cc + 1 & 0xf; | |
1578 | 64443 | *q++ = 0x10 | ts_st->cc; // payload indicator + CC | |
1579 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 64443 times.
|
64443 | if (ts_st->discontinuity) { |
1580 | ✗ | set_af_flag(buf, 0x80); | |
1581 | ✗ | q = get_ts_payload_start(buf); | |
1582 | ✗ | ts_st->discontinuity = 0; | |
1583 | } | ||
1584 |
3/4✓ Branch 0 taken 64443 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 61686 times.
✓ Branch 3 taken 2757 times.
|
64443 | if (!(ts->flags & MPEGTS_FLAG_OMIT_RAI) && |
1585 |
4/6✓ Branch 0 taken 3855 times.
✓ Branch 1 taken 57831 times.
✓ Branch 2 taken 3855 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3855 times.
✗ Branch 5 not taken.
|
61686 | key && is_start && pts != AV_NOPTS_VALUE && |
1586 | !is_dvb_teletext /* adaptation+payload forbidden for teletext (ETSI EN 300 472 V1.3.1 4.1) */) { | ||
1587 | // set Random Access for key frames | ||
1588 |
2/2✓ Branch 0 taken 3852 times.
✓ Branch 1 taken 3 times.
|
3855 | if (ts_st->pcr_period) |
1589 | 3852 | write_pcr = 1; | |
1590 | 3855 | set_af_flag(buf, 0x40); | |
1591 | 3855 | q = get_ts_payload_start(buf); | |
1592 | } | ||
1593 |
2/2✓ Branch 0 taken 3925 times.
✓ Branch 1 taken 60518 times.
|
64443 | if (write_pcr) { |
1594 | 3925 | set_af_flag(buf, 0x10); | |
1595 | 3925 | q = get_ts_payload_start(buf); | |
1596 | // add 11, pcr references the last byte of program clock reference base | ||
1597 |
2/4✓ Branch 0 taken 3925 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3925 times.
|
3925 | if (dts != AV_NOPTS_VALUE && dts < pcr / 300) |
1598 | ✗ | av_log(s, AV_LOG_WARNING, "dts < pcr, TS is invalid\n"); | |
1599 | 3925 | extend_af(buf, write_pcr_bits(q, pcr)); | |
1600 | 3925 | q = get_ts_payload_start(buf); | |
1601 | } | ||
1602 |
2/2✓ Branch 0 taken 3997 times.
✓ Branch 1 taken 60446 times.
|
64443 | if (is_start) { |
1603 | 3997 | int pes_extension = 0; | |
1604 | 3997 | int pes_header_stuffing_bytes = 0; | |
1605 | int async; | ||
1606 | /* write PES header */ | ||
1607 | 3997 | *q++ = 0x00; | |
1608 | 3997 | *q++ = 0x00; | |
1609 | 3997 | *q++ = 0x01; | |
1610 | 3997 | *q++ = stream_id = get_pes_stream_id(s, st, stream_id, &async); | |
1611 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3997 times.
|
3997 | if (async) |
1612 | ✗ | pts = dts = AV_NOPTS_VALUE; | |
1613 | |||
1614 | 3997 | header_len = 0; | |
1615 | |||
1616 |
2/4✓ Branch 0 taken 3997 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3997 times.
✗ Branch 3 not taken.
|
3997 | if (stream_id != STREAM_ID_PROGRAM_STREAM_MAP && |
1617 |
1/2✓ Branch 0 taken 3997 times.
✗ Branch 1 not taken.
|
3997 | stream_id != STREAM_ID_PADDING_STREAM && |
1618 |
1/2✓ Branch 0 taken 3997 times.
✗ Branch 1 not taken.
|
3997 | stream_id != STREAM_ID_PRIVATE_STREAM_2 && |
1619 |
1/2✓ Branch 0 taken 3997 times.
✗ Branch 1 not taken.
|
3997 | stream_id != STREAM_ID_ECM_STREAM && |
1620 |
1/2✓ Branch 0 taken 3997 times.
✗ Branch 1 not taken.
|
3997 | stream_id != STREAM_ID_EMM_STREAM && |
1621 |
1/2✓ Branch 0 taken 3997 times.
✗ Branch 1 not taken.
|
3997 | stream_id != STREAM_ID_PROGRAM_STREAM_DIRECTORY && |
1622 |
1/2✓ Branch 0 taken 3997 times.
✗ Branch 1 not taken.
|
3997 | stream_id != STREAM_ID_DSMCC_STREAM && |
1623 | stream_id != STREAM_ID_TYPE_E_STREAM) { | ||
1624 | |||
1625 | 3997 | flags = 0; | |
1626 |
1/2✓ Branch 0 taken 3997 times.
✗ Branch 1 not taken.
|
3997 | if (pts != AV_NOPTS_VALUE) { |
1627 | 3997 | header_len += 5; | |
1628 | 3997 | flags |= 0x80; | |
1629 | } | ||
1630 |
4/6✓ Branch 0 taken 3997 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3997 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 121 times.
✓ Branch 5 taken 3876 times.
|
3997 | if (dts != AV_NOPTS_VALUE && pts != AV_NOPTS_VALUE && dts != pts) { |
1631 | 121 | header_len += 5; | |
1632 | 121 | flags |= 0x40; | |
1633 | } | ||
1634 |
2/2✓ Branch 0 taken 151 times.
✓ Branch 1 taken 3846 times.
|
3997 | if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && |
1635 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 151 times.
|
151 | st->codecpar->codec_id == AV_CODEC_ID_DIRAC) { |
1636 | /* set PES_extension_flag */ | ||
1637 | ✗ | pes_extension = 1; | |
1638 | ✗ | flags |= 0x01; | |
1639 | |||
1640 | /* One byte for PES2 extension flag + | ||
1641 | * one byte for extension length + | ||
1642 | * one byte for extension id */ | ||
1643 | ✗ | header_len += 3; | |
1644 | } | ||
1645 | /* for Blu-ray AC3 Audio the PES Extension flag should be as follow | ||
1646 | * otherwise it will not play sound on blu-ray | ||
1647 | */ | ||
1648 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3997 times.
|
3997 | if (ts->m2ts_mode && |
1649 | ✗ | st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && | |
1650 | ✗ | st->codecpar->codec_id == AV_CODEC_ID_AC3) { | |
1651 | /* set PES_extension_flag */ | ||
1652 | ✗ | pes_extension = 1; | |
1653 | ✗ | flags |= 0x01; | |
1654 | ✗ | header_len += 3; | |
1655 | } | ||
1656 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3997 times.
|
3997 | if (is_dvb_teletext) { |
1657 | ✗ | pes_header_stuffing_bytes = 0x24 - header_len; | |
1658 | ✗ | header_len = 0x24; | |
1659 | } | ||
1660 | 3997 | len = payload_size + header_len + 3; | |
1661 | /* 3 extra bytes should be added to DVB subtitle payload: 0x20 0x00 at the beginning and trailing 0xff */ | ||
1662 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3997 times.
|
3997 | if (is_dvb_subtitle) { |
1663 | ✗ | len += 3; | |
1664 | ✗ | payload_size++; | |
1665 | } | ||
1666 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3997 times.
|
3997 | if (len > 0xffff) |
1667 | ✗ | len = 0; | |
1668 |
3/4✓ Branch 0 taken 3997 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 151 times.
✓ Branch 3 taken 3846 times.
|
3997 | if (ts->omit_video_pes_length && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { |
1669 | 151 | len = 0; | |
1670 | } | ||
1671 | 3997 | *q++ = len >> 8; | |
1672 | 3997 | *q++ = len; | |
1673 | 3997 | val = 0x80; | |
1674 | /* data alignment indicator is required for subtitle and data streams */ | ||
1675 |
2/4✓ Branch 0 taken 3997 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3997 times.
|
3997 | if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE || st->codecpar->codec_type == AVMEDIA_TYPE_DATA) |
1676 | ✗ | val |= 0x04; | |
1677 | 3997 | *q++ = val; | |
1678 | 3997 | *q++ = flags; | |
1679 | 3997 | *q++ = header_len; | |
1680 |
1/2✓ Branch 0 taken 3997 times.
✗ Branch 1 not taken.
|
3997 | if (pts != AV_NOPTS_VALUE) { |
1681 | 3997 | write_pts(q, flags >> 6, pts); | |
1682 | 3997 | q += 5; | |
1683 | } | ||
1684 |
4/6✓ Branch 0 taken 3997 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3997 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 121 times.
✓ Branch 5 taken 3876 times.
|
3997 | if (dts != AV_NOPTS_VALUE && pts != AV_NOPTS_VALUE && dts != pts) { |
1685 | 121 | write_pts(q, 1, dts); | |
1686 | 121 | q += 5; | |
1687 | } | ||
1688 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 3997 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
3997 | if (pes_extension && st->codecpar->codec_id == AV_CODEC_ID_DIRAC) { |
1689 | ✗ | flags = 0x01; /* set PES_extension_flag_2 */ | |
1690 | ✗ | *q++ = flags; | |
1691 | ✗ | *q++ = 0x80 | 0x01; /* marker bit + extension length */ | |
1692 | /* Set the stream ID extension flag bit to 0 and | ||
1693 | * write the extended stream ID. */ | ||
1694 | ✗ | *q++ = 0x00 | 0x60; | |
1695 | } | ||
1696 | /* For Blu-ray AC3 Audio Setting extended flags */ | ||
1697 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 3997 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
3997 | if (ts->m2ts_mode && |
1698 | ✗ | pes_extension && | |
1699 | ✗ | st->codecpar->codec_id == AV_CODEC_ID_AC3) { | |
1700 | ✗ | flags = 0x01; /* set PES_extension_flag_2 */ | |
1701 | ✗ | *q++ = flags; | |
1702 | ✗ | *q++ = 0x80 | 0x01; /* marker bit + extension length */ | |
1703 | ✗ | *q++ = 0x00 | 0x71; /* for AC3 Audio (specifically on blue-rays) */ | |
1704 | } | ||
1705 | |||
1706 | |||
1707 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3997 times.
|
3997 | if (is_dvb_subtitle) { |
1708 | /* First two fields of DVB subtitles PES data: | ||
1709 | * data_identifier: for DVB subtitle streams shall be coded with the value 0x20 | ||
1710 | * subtitle_stream_id: for DVB subtitle stream shall be identified by the value 0x00 */ | ||
1711 | ✗ | *q++ = 0x20; | |
1712 | ✗ | *q++ = 0x00; | |
1713 | } | ||
1714 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3997 times.
|
3997 | if (is_dvb_teletext) { |
1715 | ✗ | memset(q, 0xff, pes_header_stuffing_bytes); | |
1716 | ✗ | q += pes_header_stuffing_bytes; | |
1717 | } | ||
1718 | } else { | ||
1719 | ✗ | len = payload_size; | |
1720 | ✗ | *q++ = len >> 8; | |
1721 | ✗ | *q++ = len; | |
1722 | } | ||
1723 | 3997 | is_start = 0; | |
1724 | } | ||
1725 | /* header size */ | ||
1726 | 64443 | header_len = q - buf; | |
1727 | /* data len */ | ||
1728 | 64443 | len = TS_PACKET_SIZE - header_len; | |
1729 |
2/2✓ Branch 0 taken 3996 times.
✓ Branch 1 taken 60447 times.
|
64443 | if (len > payload_size) |
1730 | 3996 | len = payload_size; | |
1731 | 64443 | stuffing_len = TS_PACKET_SIZE - header_len - len; | |
1732 |
2/2✓ Branch 0 taken 3996 times.
✓ Branch 1 taken 60447 times.
|
64443 | if (stuffing_len > 0) { |
1733 | /* add stuffing with AFC */ | ||
1734 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 3994 times.
|
3996 | if (buf[3] & 0x20) { |
1735 | /* stuffing already present: increase its size */ | ||
1736 | 2 | afc_len = buf[4] + 1; | |
1737 | 2 | memmove(buf + 4 + afc_len + stuffing_len, | |
1738 | 2 | buf + 4 + afc_len, | |
1739 | 2 | header_len - (4 + afc_len)); | |
1740 | 2 | buf[4] += stuffing_len; | |
1741 | 2 | memset(buf + 4 + afc_len, 0xff, stuffing_len); | |
1742 | } else { | ||
1743 | /* add stuffing */ | ||
1744 | 3994 | memmove(buf + 4 + stuffing_len, buf + 4, header_len - 4); | |
1745 | 3994 | buf[3] |= 0x20; | |
1746 | 3994 | buf[4] = stuffing_len - 1; | |
1747 |
2/2✓ Branch 0 taken 3992 times.
✓ Branch 1 taken 2 times.
|
3994 | if (stuffing_len >= 2) { |
1748 | 3992 | buf[5] = 0x00; | |
1749 | 3992 | memset(buf + 6, 0xff, stuffing_len - 2); | |
1750 | } | ||
1751 | } | ||
1752 | } | ||
1753 | |||
1754 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 64443 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
64443 | if (is_dvb_subtitle && payload_size == len) { |
1755 | ✗ | memcpy(buf + TS_PACKET_SIZE - len, payload, len - 1); | |
1756 | ✗ | buf[TS_PACKET_SIZE - 1] = 0xff; /* end_of_PES_data_field_marker: an 8-bit field with fixed contents 0xff for DVB subtitle */ | |
1757 | } else { | ||
1758 | 64443 | memcpy(buf + TS_PACKET_SIZE - len, payload, len); | |
1759 | } | ||
1760 | |||
1761 | 64443 | payload += len; | |
1762 | 64443 | payload_size -= len; | |
1763 | 64443 | write_packet(s, buf); | |
1764 | } | ||
1765 | 3997 | ts_st->prev_payload_key = key; | |
1766 | 3997 | } | |
1767 | |||
1768 | 205 | static int check_h26x_startcode(AVFormatContext *s, const AVStream *st, const AVPacket *pkt, const char *codec) | |
1769 | { | ||
1770 |
2/6✓ Branch 0 taken 205 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 205 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
205 | if (pkt->size < 5 || AV_RB32(pkt->data) != 0x0000001 && AV_RB24(pkt->data) != 0x000001) { |
1771 | ✗ | if (!st->nb_frames) { | |
1772 | ✗ | av_log(s, AV_LOG_ERROR, "%s bitstream malformed, " | |
1773 | "no startcode found, use the video bitstream filter '%s_mp4toannexb' to fix it " | ||
1774 | "('-bsf:v %s_mp4toannexb' option with ffmpeg)\n", codec, codec, codec); | ||
1775 | ✗ | return AVERROR_INVALIDDATA; | |
1776 | } | ||
1777 | ✗ | av_log(s, AV_LOG_WARNING, "%s bitstream error, startcode missing, size %d", codec, pkt->size); | |
1778 | ✗ | if (pkt->size) | |
1779 | ✗ | av_log(s, AV_LOG_WARNING, " data %08"PRIX32, AV_RB32(pkt->data)); | |
1780 | ✗ | av_log(s, AV_LOG_WARNING, "\n"); | |
1781 | } | ||
1782 | 205 | return 0; | |
1783 | } | ||
1784 | |||
1785 | 205 | int ff_check_h264_startcode(AVFormatContext *s, const AVStream *st, const AVPacket *pkt) | |
1786 | { | ||
1787 | 205 | return check_h26x_startcode(s, st, pkt, "h264"); | |
1788 | } | ||
1789 | |||
1790 | /* Based on GStreamer's gst-plugins-base/ext/ogg/gstoggstream.c | ||
1791 | * Released under the LGPL v2.1+, written by | ||
1792 | * Vincent Penquerc'h <vincent.penquerch@collabora.co.uk> | ||
1793 | */ | ||
1794 | ✗ | static int opus_get_packet_samples(AVFormatContext *s, AVPacket *pkt) | |
1795 | { | ||
1796 | static const int durations[32] = { | ||
1797 | 480, 960, 1920, 2880, /* Silk NB */ | ||
1798 | 480, 960, 1920, 2880, /* Silk MB */ | ||
1799 | 480, 960, 1920, 2880, /* Silk WB */ | ||
1800 | 480, 960, /* Hybrid SWB */ | ||
1801 | 480, 960, /* Hybrid FB */ | ||
1802 | 120, 240, 480, 960, /* CELT NB */ | ||
1803 | 120, 240, 480, 960, /* CELT NB */ | ||
1804 | 120, 240, 480, 960, /* CELT NB */ | ||
1805 | 120, 240, 480, 960, /* CELT NB */ | ||
1806 | }; | ||
1807 | int toc, frame_duration, nframes, duration; | ||
1808 | |||
1809 | ✗ | if (pkt->size < 1) | |
1810 | ✗ | return 0; | |
1811 | |||
1812 | ✗ | toc = pkt->data[0]; | |
1813 | |||
1814 | ✗ | frame_duration = durations[toc >> 3]; | |
1815 | ✗ | switch (toc & 3) { | |
1816 | ✗ | case 0: | |
1817 | ✗ | nframes = 1; | |
1818 | ✗ | break; | |
1819 | ✗ | case 1: | |
1820 | ✗ | nframes = 2; | |
1821 | ✗ | break; | |
1822 | ✗ | case 2: | |
1823 | ✗ | nframes = 2; | |
1824 | ✗ | break; | |
1825 | ✗ | case 3: | |
1826 | ✗ | if (pkt->size < 2) | |
1827 | ✗ | return 0; | |
1828 | ✗ | nframes = pkt->data[1] & 63; | |
1829 | ✗ | break; | |
1830 | } | ||
1831 | |||
1832 | ✗ | duration = nframes * frame_duration; | |
1833 | ✗ | if (duration > 5760) { | |
1834 | ✗ | av_log(s, AV_LOG_WARNING, | |
1835 | "Opus packet duration > 120 ms, invalid"); | ||
1836 | ✗ | return 0; | |
1837 | } | ||
1838 | |||
1839 | ✗ | return duration; | |
1840 | } | ||
1841 | |||
1842 | ✗ | static uint8_t *h26x_prefix_aud(const uint8_t *aud, const int aud_size, | |
1843 | const uint8_t *extra_data, const int extra_size, AVPacket *pkt, int *size) | ||
1844 | { | ||
1845 | ✗ | const int sz = 4; //start code size | |
1846 | ✗ | uint8_t *data = av_malloc(pkt->size + sz + aud_size + extra_size); | |
1847 | ✗ | if (!data) | |
1848 | ✗ | return NULL; | |
1849 | ✗ | AV_WB32(data, 0x00000001); | |
1850 | ✗ | memcpy(data + sz, aud, aud_size); | |
1851 | ✗ | memcpy(data + sz + aud_size, extra_data, extra_size); | |
1852 | ✗ | memcpy(data + sz + aud_size + extra_size, pkt->data, pkt->size); | |
1853 | ✗ | *size = pkt->size + sz + aud_size + extra_size; | |
1854 | ✗ | return data; | |
1855 | } | ||
1856 | |||
1857 | #define H264_NAL_TYPE(state) (state & 0x1f) | ||
1858 | #define HEVC_NAL_TYPE(state) ((state & 0x7e) >> 1) | ||
1859 | #define VVC_NAL_TYPE(state) ((state >> 11) & 0x1f) | ||
1860 | 7764 | static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) | |
1861 | { | ||
1862 | 7764 | AVStream *st = s->streams[pkt->stream_index]; | |
1863 | 7764 | int size = pkt->size; | |
1864 | 7764 | const uint8_t *buf = pkt->data; | |
1865 | 7764 | uint8_t *data = NULL; | |
1866 | 7764 | MpegTSWrite *ts = s->priv_data; | |
1867 | 7764 | MpegTSWriteStream *ts_st = st->priv_data; | |
1868 | 7764 | const int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE) * 2; | |
1869 | 7764 | const int64_t max_audio_delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE) / 2; | |
1870 | 7764 | int64_t dts = pkt->dts, pts = pkt->pts; | |
1871 | 7764 | int opus_samples = 0; | |
1872 | size_t side_data_size; | ||
1873 | 7764 | uint8_t *side_data = NULL; | |
1874 | 7764 | int stream_id = -1; | |
1875 | |||
1876 | 7764 | side_data = av_packet_get_side_data(pkt, | |
1877 | AV_PKT_DATA_MPEGTS_STREAM_ID, | ||
1878 | &side_data_size); | ||
1879 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7764 times.
|
7764 | if (side_data) |
1880 | ✗ | stream_id = side_data[0]; | |
1881 | |||
1882 |
3/4✓ Branch 0 taken 20 times.
✓ Branch 1 taken 7744 times.
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
|
7764 | if (!ts->first_dts_checked && dts != AV_NOPTS_VALUE) { |
1883 | 20 | ts->first_pcr += dts * 300; | |
1884 | 20 | ts->first_dts_checked = 1; | |
1885 | } | ||
1886 | |||
1887 |
1/2✓ Branch 0 taken 7764 times.
✗ Branch 1 not taken.
|
7764 | if (ts->copyts < 1) { |
1888 |
1/2✓ Branch 0 taken 7764 times.
✗ Branch 1 not taken.
|
7764 | if (pts != AV_NOPTS_VALUE) |
1889 | 7764 | pts += delay; | |
1890 |
1/2✓ Branch 0 taken 7764 times.
✗ Branch 1 not taken.
|
7764 | if (dts != AV_NOPTS_VALUE) |
1891 | 7764 | dts += delay; | |
1892 | } | ||
1893 | |||
1894 |
4/6✓ Branch 0 taken 21 times.
✓ Branch 1 taken 7743 times.
✓ Branch 2 taken 21 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 21 times.
|
7764 | if (!ts_st->first_timestamp_checked && (pts == AV_NOPTS_VALUE || dts == AV_NOPTS_VALUE)) { |
1895 | ✗ | av_log(s, AV_LOG_ERROR, "first pts and dts value must be set\n"); | |
1896 | ✗ | return AVERROR_INVALIDDATA; | |
1897 | } | ||
1898 | 7764 | ts_st->first_timestamp_checked = 1; | |
1899 | |||
1900 |
2/2✓ Branch 0 taken 126 times.
✓ Branch 1 taken 7638 times.
|
7764 | if (st->codecpar->codec_id == AV_CODEC_ID_H264) { |
1901 | 126 | const uint8_t *p = buf, *buf_end = p + size; | |
1902 | 126 | const uint8_t *found_aud = NULL, *found_aud_end = NULL; | |
1903 | int nal_type; | ||
1904 | 126 | uint32_t state = -1; | |
1905 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 120 times.
|
126 | int extradd = (pkt->flags & AV_PKT_FLAG_KEY) ? st->codecpar->extradata_size : 0; |
1906 | 126 | int ret = ff_check_h264_startcode(s, st, pkt); | |
1907 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 126 times.
|
126 | if (ret < 0) |
1908 | ✗ | return ret; | |
1909 | |||
1910 |
3/4✓ Branch 0 taken 6 times.
✓ Branch 1 taken 120 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
|
126 | if (extradd && AV_RB24(st->codecpar->extradata) > 1) |
1911 | 6 | extradd = 0; | |
1912 | |||
1913 | /* Ensure that all pictures are prefixed with an AUD, and that | ||
1914 | * IDR pictures are also prefixed with SPS and PPS. SPS and PPS | ||
1915 | * are assumed to be available in 'extradata' if not found in-band. */ | ||
1916 | do { | ||
1917 | 127 | p = avpriv_find_start_code(p, buf_end, &state); | |
1918 | 127 | nal_type = H264_NAL_TYPE(state); | |
1919 | 127 | av_log(s, AV_LOG_TRACE, "nal %"PRId32"\n", nal_type); | |
1920 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 127 times.
|
127 | if (nal_type == H264_NAL_SPS) |
1921 | ✗ | extradd = 0; | |
1922 |
2/2✓ Branch 0 taken 126 times.
✓ Branch 1 taken 1 times.
|
127 | if (nal_type == H264_NAL_AUD) { |
1923 | 126 | found_aud = p - 4; // start of the 0x000001 start code. | |
1924 | 126 | found_aud_end = p + 1; // first byte past the AUD. | |
1925 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 126 times.
|
126 | if (found_aud < buf) |
1926 | ✗ | found_aud = buf; | |
1927 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 126 times.
|
126 | if (buf_end < found_aud_end) |
1928 | ✗ | found_aud_end = buf_end; | |
1929 | } | ||
1930 | } while (p < buf_end | ||
1931 |
1/2✓ Branch 0 taken 127 times.
✗ Branch 1 not taken.
|
127 | && nal_type != H264_NAL_IDR_SLICE |
1932 |
1/2✓ Branch 0 taken 127 times.
✗ Branch 1 not taken.
|
127 | && nal_type != H264_NAL_SLICE |
1933 |
4/6✓ Branch 0 taken 127 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 127 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 126 times.
|
254 | && (extradd > 0 || !found_aud)); |
1934 |
1/2✓ Branch 0 taken 126 times.
✗ Branch 1 not taken.
|
126 | if (nal_type != H264_NAL_IDR_SLICE) |
1935 | 126 | extradd = 0; | |
1936 | |||
1937 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 126 times.
|
126 | if (!found_aud) { |
1938 | /* Prefix 'buf' with the missing AUD, and extradata if needed. */ | ||
1939 | ✗ | const uint8_t aud[] = { | |
1940 | H264_NAL_AUD, | ||
1941 | 0xf0, // any slice type (0xe) + rbsp stop one bit | ||
1942 | }; | ||
1943 | ✗ | buf = data = h26x_prefix_aud(aud, FF_ARRAY_ELEMS(aud), | |
1944 | ✗ | st->codecpar->extradata, extradd, pkt, &size); | |
1945 | ✗ | if (!data) | |
1946 | ✗ | return AVERROR(ENOMEM); | |
1947 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 126 times.
|
126 | } else if (extradd != 0) { |
1948 | /* Move the AUD up to the beginning of the frame, where the H.264 | ||
1949 | * spec requires it to appear. Emit the extradata after it. */ | ||
1950 | PutByteContext pb; | ||
1951 | ✗ | const int new_pkt_size = pkt->size + 1 + extradd; | |
1952 | ✗ | data = av_malloc(new_pkt_size); | |
1953 | ✗ | if (!data) | |
1954 | ✗ | return AVERROR(ENOMEM); | |
1955 | ✗ | bytestream2_init_writer(&pb, data, new_pkt_size); | |
1956 | ✗ | bytestream2_put_byte(&pb, 0x00); | |
1957 | ✗ | bytestream2_put_buffer(&pb, found_aud, found_aud_end - found_aud); | |
1958 | ✗ | bytestream2_put_buffer(&pb, st->codecpar->extradata, extradd); | |
1959 | ✗ | bytestream2_put_buffer(&pb, pkt->data, found_aud - pkt->data); | |
1960 | ✗ | bytestream2_put_buffer(&pb, found_aud_end, buf_end - found_aud_end); | |
1961 | ✗ | av_assert0(new_pkt_size == bytestream2_tell_p(&pb)); | |
1962 | ✗ | buf = data; | |
1963 | ✗ | size = new_pkt_size; | |
1964 | } | ||
1965 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7638 times.
|
7638 | } else if (st->codecpar->codec_id == AV_CODEC_ID_AAC) { |
1966 | ✗ | if (pkt->size < 2) { | |
1967 | ✗ | av_log(s, AV_LOG_ERROR, "AAC packet too short\n"); | |
1968 | ✗ | return AVERROR_INVALIDDATA; | |
1969 | } | ||
1970 | ✗ | if ((AV_RB16(pkt->data) & 0xfff0) != 0xfff0) { | |
1971 | int ret; | ||
1972 | ✗ | AVPacket *pkt2 = ts->pkt; | |
1973 | |||
1974 | ✗ | if (!ts_st->amux) { | |
1975 | ✗ | av_log(s, AV_LOG_ERROR, "AAC bitstream not in ADTS format " | |
1976 | "and extradata missing\n"); | ||
1977 | } else { | ||
1978 | ✗ | av_packet_unref(pkt2); | |
1979 | ✗ | pkt2->data = pkt->data; | |
1980 | ✗ | pkt2->size = pkt->size; | |
1981 | ✗ | av_assert0(pkt->dts != AV_NOPTS_VALUE); | |
1982 | ✗ | pkt2->dts = av_rescale_q(pkt->dts, st->time_base, ts_st->amux->streams[0]->time_base); | |
1983 | |||
1984 | ✗ | ret = avio_open_dyn_buf(&ts_st->amux->pb); | |
1985 | ✗ | if (ret < 0) | |
1986 | ✗ | return ret; | |
1987 | |||
1988 | ✗ | ret = av_write_frame(ts_st->amux, pkt2); | |
1989 | ✗ | if (ret < 0) { | |
1990 | ✗ | ffio_free_dyn_buf(&ts_st->amux->pb); | |
1991 | ✗ | return ret; | |
1992 | } | ||
1993 | ✗ | size = avio_close_dyn_buf(ts_st->amux->pb, &data); | |
1994 | ✗ | ts_st->amux->pb = NULL; | |
1995 | ✗ | buf = data; | |
1996 | } | ||
1997 | } | ||
1998 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7638 times.
|
7638 | } else if (st->codecpar->codec_id == AV_CODEC_ID_HEVC) { |
1999 | ✗ | const uint8_t *p = buf, *buf_end = p + size; | |
2000 | ✗ | uint32_t state = -1; | |
2001 | int nal_type; | ||
2002 | ✗ | int extradd = (pkt->flags & AV_PKT_FLAG_KEY) ? st->codecpar->extradata_size : 0; | |
2003 | ✗ | int ret = check_h26x_startcode(s, st, pkt, "hevc"); | |
2004 | ✗ | if (ret < 0) | |
2005 | ✗ | return ret; | |
2006 | |||
2007 | ✗ | if (extradd && AV_RB24(st->codecpar->extradata) > 1) | |
2008 | ✗ | extradd = 0; | |
2009 | |||
2010 | do { | ||
2011 | ✗ | p = avpriv_find_start_code(p, buf_end, &state); | |
2012 | ✗ | nal_type = HEVC_NAL_TYPE(state); | |
2013 | ✗ | av_log(s, AV_LOG_TRACE, "nal %"PRId32"\n", nal_type); | |
2014 | ✗ | if (nal_type == HEVC_NAL_VPS) | |
2015 | ✗ | extradd = 0; | |
2016 | ✗ | } while (p < buf_end && nal_type != HEVC_NAL_AUD && nal_type >= HEVC_NAL_VPS); | |
2017 | |||
2018 | ✗ | if (nal_type < HEVC_NAL_BLA_W_LP || nal_type >= HEVC_NAL_RSV_VCL24) | |
2019 | ✗ | extradd = 0; | |
2020 | ✗ | if (nal_type != HEVC_NAL_AUD) { // AUD NAL | |
2021 | ✗ | const uint8_t aud[] = { | |
2022 | (HEVC_NAL_AUD << 1), | ||
2023 | 0x01, | ||
2024 | 0x50, // any slice type (0x4) + rbsp stop one bit | ||
2025 | }; | ||
2026 | ✗ | buf = data = h26x_prefix_aud(aud, FF_ARRAY_ELEMS(aud), | |
2027 | ✗ | st->codecpar->extradata, extradd, pkt, &size); | |
2028 | ✗ | if (!data) | |
2029 | ✗ | return AVERROR(ENOMEM); | |
2030 | } | ||
2031 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7638 times.
|
7638 | } else if (st->codecpar->codec_id == AV_CODEC_ID_VVC) { |
2032 | ✗ | const uint8_t *p = buf, *buf_end = p + size; | |
2033 | ✗ | uint32_t state = -1; | |
2034 | ✗ | uint32_t nal_type = -1; | |
2035 | ✗ | int extradd = (pkt->flags & AV_PKT_FLAG_KEY) ? st->codecpar->extradata_size : 0; | |
2036 | ✗ | int ret = check_h26x_startcode(s, st, pkt, "vvc"); | |
2037 | ✗ | if (ret < 0) | |
2038 | ✗ | return ret; | |
2039 | |||
2040 | ✗ | if (extradd && AV_RB24(st->codecpar->extradata) > 1) | |
2041 | ✗ | extradd = 0; | |
2042 | |||
2043 | do { | ||
2044 | ✗ | p = avpriv_find_start_code(p, buf_end, &state); | |
2045 | // state contains byte behind start code, p points 2 bytes behind start code | ||
2046 | ✗ | nal_type = VVC_NAL_TYPE(state); | |
2047 | ✗ | av_log(s, AV_LOG_TRACE, "nal %"PRId32"\n", nal_type ); | |
2048 | ✗ | if (nal_type == VVC_VPS_NUT) | |
2049 | ✗ | extradd = 0; | |
2050 | ✗ | } while (p < buf_end && nal_type != VVC_AUD_NUT && nal_type >= VVC_OPI_NUT); | |
2051 | |||
2052 | ✗ | if (nal_type >= VVC_OPI_NUT) | |
2053 | ✗ | extradd = 0; | |
2054 | ✗ | if (nal_type != VVC_AUD_NUT) { // AUD NAL | |
2055 | ✗ | const uint8_t aud[] = { | |
2056 | 0, // forbidden_zero_bit, nuh_reserved_zero_bit, nuh_layer_id | ||
2057 | (VVC_AUD_NUT << 3) | 1, // nal_unit_type, nuh_temporal_id_plus1(1) | ||
2058 | ✗ | (pkt->flags & AV_PKT_FLAG_KEY) << 7 | 0x28, // aud_irap_or_gdr_flag, aud_pic_type(2), rbsp_stop_one_bit | |
2059 | }; | ||
2060 | ✗ | buf = data = h26x_prefix_aud(aud, FF_ARRAY_ELEMS(aud), st->codecpar->extradata, extradd, pkt, &size); | |
2061 | ✗ | if (!data) | |
2062 | ✗ | return AVERROR(ENOMEM); | |
2063 | } | ||
2064 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7638 times.
|
7638 | } else if (st->codecpar->codec_id == AV_CODEC_ID_OPUS) { |
2065 | ✗ | if (pkt->size < 2) { | |
2066 | ✗ | av_log(s, AV_LOG_ERROR, "Opus packet too short\n"); | |
2067 | ✗ | return AVERROR_INVALIDDATA; | |
2068 | } | ||
2069 | |||
2070 | /* Add Opus control header */ | ||
2071 | ✗ | if ((AV_RB16(pkt->data) >> 5) != 0x3ff) { | |
2072 | uint8_t *side_data; | ||
2073 | size_t side_data_size; | ||
2074 | int i, n; | ||
2075 | int ctrl_header_size; | ||
2076 | ✗ | int trim_start = 0, trim_end = 0; | |
2077 | |||
2078 | ✗ | opus_samples = opus_get_packet_samples(s, pkt); | |
2079 | |||
2080 | ✗ | side_data = av_packet_get_side_data(pkt, | |
2081 | AV_PKT_DATA_SKIP_SAMPLES, | ||
2082 | &side_data_size); | ||
2083 | |||
2084 | ✗ | if (side_data && side_data_size >= 10) { | |
2085 | ✗ | trim_end = AV_RL32(side_data + 4) * 48000 / st->codecpar->sample_rate; | |
2086 | } | ||
2087 | |||
2088 | ✗ | ctrl_header_size = pkt->size + 2 + pkt->size / 255 + 1; | |
2089 | ✗ | if (ts_st->opus_pending_trim_start) | |
2090 | ✗ | ctrl_header_size += 2; | |
2091 | ✗ | if (trim_end) | |
2092 | ✗ | ctrl_header_size += 2; | |
2093 | |||
2094 | ✗ | data = av_malloc(ctrl_header_size); | |
2095 | ✗ | if (!data) | |
2096 | ✗ | return AVERROR(ENOMEM); | |
2097 | |||
2098 | ✗ | data[0] = 0x7f; | |
2099 | ✗ | data[1] = 0xe0; | |
2100 | ✗ | if (ts_st->opus_pending_trim_start) | |
2101 | ✗ | data[1] |= 0x10; | |
2102 | ✗ | if (trim_end) | |
2103 | ✗ | data[1] |= 0x08; | |
2104 | |||
2105 | ✗ | n = pkt->size; | |
2106 | ✗ | i = 2; | |
2107 | do { | ||
2108 | ✗ | data[i] = FFMIN(n, 255); | |
2109 | ✗ | n -= 255; | |
2110 | ✗ | i++; | |
2111 | ✗ | } while (n >= 0); | |
2112 | |||
2113 | ✗ | av_assert0(2 + pkt->size / 255 + 1 == i); | |
2114 | |||
2115 | ✗ | if (ts_st->opus_pending_trim_start) { | |
2116 | ✗ | trim_start = FFMIN(ts_st->opus_pending_trim_start, opus_samples); | |
2117 | ✗ | AV_WB16(data + i, trim_start); | |
2118 | ✗ | i += 2; | |
2119 | ✗ | ts_st->opus_pending_trim_start -= trim_start; | |
2120 | } | ||
2121 | ✗ | if (trim_end) { | |
2122 | ✗ | trim_end = FFMIN(trim_end, opus_samples - trim_start); | |
2123 | ✗ | AV_WB16(data + i, trim_end); | |
2124 | ✗ | i += 2; | |
2125 | } | ||
2126 | |||
2127 | ✗ | memcpy(data + i, pkt->data, pkt->size); | |
2128 | ✗ | buf = data; | |
2129 | ✗ | size = ctrl_header_size; | |
2130 | } else { | ||
2131 | /* TODO: Can we get TS formatted data here? If so we will | ||
2132 | * need to count the samples of that too! */ | ||
2133 | ✗ | av_log(s, AV_LOG_WARNING, "Got MPEG-TS formatted Opus data, unhandled"); | |
2134 | } | ||
2135 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 7638 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
7638 | } else if (st->codecpar->codec_id == AV_CODEC_ID_AC3 && !ts_st->dvb_ac3_desc) { |
2136 | ✗ | AC3HeaderInfo *hdr = NULL; | |
2137 | |||
2138 | ✗ | if (avpriv_ac3_parse_header(&hdr, pkt->data, pkt->size) >= 0) { | |
2139 | uint8_t number_of_channels_flag; | ||
2140 | uint8_t service_type_flag; | ||
2141 | ✗ | uint8_t full_service_flag = 1; | |
2142 | DVBAC3Descriptor *dvb_ac3_desc; | ||
2143 | |||
2144 | ✗ | dvb_ac3_desc = av_mallocz(sizeof(*dvb_ac3_desc)); | |
2145 | ✗ | if (!dvb_ac3_desc) { | |
2146 | ✗ | av_free(hdr); | |
2147 | ✗ | return AVERROR(ENOMEM); | |
2148 | } | ||
2149 | |||
2150 | ✗ | service_type_flag = hdr->bitstream_mode; | |
2151 | ✗ | switch (hdr->channel_mode) { | |
2152 | ✗ | case AC3_CHMODE_DUALMONO: | |
2153 | ✗ | number_of_channels_flag = 1; | |
2154 | ✗ | break; | |
2155 | ✗ | case AC3_CHMODE_MONO: | |
2156 | ✗ | number_of_channels_flag = 0; | |
2157 | ✗ | break; | |
2158 | ✗ | case AC3_CHMODE_STEREO: | |
2159 | ✗ | if (hdr->dolby_surround_mode == AC3_DSURMOD_ON) | |
2160 | ✗ | number_of_channels_flag = 3; | |
2161 | else | ||
2162 | ✗ | number_of_channels_flag = 2; | |
2163 | ✗ | break; | |
2164 | ✗ | case AC3_CHMODE_3F: | |
2165 | case AC3_CHMODE_2F1R: | ||
2166 | case AC3_CHMODE_3F1R: | ||
2167 | case AC3_CHMODE_2F2R: | ||
2168 | case AC3_CHMODE_3F2R: | ||
2169 | ✗ | number_of_channels_flag = 4; | |
2170 | ✗ | break; | |
2171 | ✗ | default: /* reserved */ | |
2172 | ✗ | number_of_channels_flag = 7; | |
2173 | ✗ | break; | |
2174 | } | ||
2175 | |||
2176 | ✗ | if (service_type_flag == 1 || service_type_flag == 4 || | |
2177 | ✗ | (service_type_flag == 7 && !number_of_channels_flag)) | |
2178 | ✗ | full_service_flag = 0; | |
2179 | |||
2180 | ✗ | dvb_ac3_desc->component_type_flag = 1; | |
2181 | ✗ | dvb_ac3_desc->component_type = (full_service_flag << 6) | | |
2182 | ✗ | ((service_type_flag & 0x7) << 3) | | |
2183 | ✗ | (number_of_channels_flag & 0x7); | |
2184 | ✗ | dvb_ac3_desc->bsid_flag = 1; | |
2185 | ✗ | dvb_ac3_desc->bsid = hdr->bitstream_id; | |
2186 | ✗ | dvb_ac3_desc->mainid_flag = 0; | |
2187 | ✗ | dvb_ac3_desc->asvc_flag = 0; | |
2188 | |||
2189 | ✗ | ts_st->dvb_ac3_desc = dvb_ac3_desc; | |
2190 | } | ||
2191 | ✗ | av_free(hdr); | |
2192 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 7638 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
7638 | } else if (st->codecpar->codec_id == AV_CODEC_ID_PCM_BLURAY && ts->m2ts_mode) { |
2193 | ✗ | mpegts_write_pes(s, st, buf, size, pts, dts, | |
2194 | ✗ | pkt->flags & AV_PKT_FLAG_KEY, stream_id); | |
2195 | ✗ | return 0; | |
2196 | } | ||
2197 | |||
2198 |
5/6✓ Branch 0 taken 7481 times.
✓ Branch 1 taken 283 times.
✓ Branch 2 taken 3767 times.
✓ Branch 3 taken 3714 times.
✓ Branch 4 taken 3767 times.
✗ Branch 5 not taken.
|
7764 | if (ts_st->payload_size && (ts_st->payload_size + size > ts->pes_payload_size || |
2199 |
1/2✓ Branch 0 taken 3767 times.
✗ Branch 1 not taken.
|
3767 | (dts != AV_NOPTS_VALUE && ts_st->payload_dts != AV_NOPTS_VALUE && |
2200 |
1/2✓ Branch 0 taken 3767 times.
✗ Branch 1 not taken.
|
3767 | dts - ts_st->payload_dts >= max_audio_delay) || |
2201 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3767 times.
|
3767 | ts_st->opus_queued_samples + opus_samples >= 5760 /* 120ms */)) { |
2202 | 3714 | mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_size, | |
2203 | ts_st->payload_pts, ts_st->payload_dts, | ||
2204 | 3714 | ts_st->payload_flags & AV_PKT_FLAG_KEY, stream_id); | |
2205 | 3714 | ts_st->payload_size = 0; | |
2206 | 3714 | ts_st->opus_queued_samples = 0; | |
2207 | } | ||
2208 | |||
2209 |
4/4✓ Branch 0 taken 7613 times.
✓ Branch 1 taken 151 times.
✓ Branch 2 taken 65 times.
✓ Branch 3 taken 7548 times.
|
7764 | if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO || size > ts->pes_payload_size) { |
2210 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 216 times.
|
216 | av_assert0(!ts_st->payload_size); |
2211 | // for video and subtitle, write a single pes packet | ||
2212 | 216 | mpegts_write_pes(s, st, buf, size, pts, dts, | |
2213 | 216 | pkt->flags & AV_PKT_FLAG_KEY, stream_id); | |
2214 | 216 | ts_st->opus_queued_samples = 0; | |
2215 | 216 | av_free(data); | |
2216 | 216 | return 0; | |
2217 | } | ||
2218 | |||
2219 |
2/2✓ Branch 0 taken 3781 times.
✓ Branch 1 taken 3767 times.
|
7548 | if (!ts_st->payload_size) { |
2220 | 3781 | ts_st->payload_pts = pts; | |
2221 | 3781 | ts_st->payload_dts = dts; | |
2222 | 3781 | ts_st->payload_flags = pkt->flags; | |
2223 | } | ||
2224 | |||
2225 | 7548 | memcpy(ts_st->payload + ts_st->payload_size, buf, size); | |
2226 | 7548 | ts_st->payload_size += size; | |
2227 | 7548 | ts_st->opus_queued_samples += opus_samples; | |
2228 | |||
2229 | 7548 | av_free(data); | |
2230 | |||
2231 | 7548 | return 0; | |
2232 | } | ||
2233 | |||
2234 | 136 | static void mpegts_write_flush(AVFormatContext *s) | |
2235 | { | ||
2236 | 136 | MpegTSWrite *ts = s->priv_data; | |
2237 | int i; | ||
2238 | |||
2239 | /* flush current packets */ | ||
2240 |
2/2✓ Branch 0 taken 137 times.
✓ Branch 1 taken 136 times.
|
273 | for (i = 0; i < s->nb_streams; i++) { |
2241 | 137 | AVStream *st = s->streams[i]; | |
2242 | 137 | MpegTSWriteStream *ts_st = st->priv_data; | |
2243 |
2/2✓ Branch 0 taken 67 times.
✓ Branch 1 taken 70 times.
|
137 | if (ts_st->payload_size > 0) { |
2244 | 67 | mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_size, | |
2245 | ts_st->payload_pts, ts_st->payload_dts, | ||
2246 | 67 | ts_st->payload_flags & AV_PKT_FLAG_KEY, -1); | |
2247 | 67 | ts_st->payload_size = 0; | |
2248 | 67 | ts_st->opus_queued_samples = 0; | |
2249 | } | ||
2250 | } | ||
2251 | |||
2252 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 136 times.
|
136 | if (ts->m2ts_mode) { |
2253 | ✗ | int packets = (avio_tell(s->pb) / (TS_PACKET_SIZE + 4)) % 32; | |
2254 | ✗ | while (packets++ < 32) | |
2255 | ✗ | mpegts_insert_null_packet(s); | |
2256 | } | ||
2257 | 136 | } | |
2258 | |||
2259 | 7880 | static int mpegts_write_packet(AVFormatContext *s, AVPacket *pkt) | |
2260 | { | ||
2261 |
2/2✓ Branch 0 taken 116 times.
✓ Branch 1 taken 7764 times.
|
7880 | if (!pkt) { |
2262 | 116 | mpegts_write_flush(s); | |
2263 | 116 | return 1; | |
2264 | } else { | ||
2265 | 7764 | return mpegts_write_packet_internal(s, pkt); | |
2266 | } | ||
2267 | } | ||
2268 | |||
2269 | 20 | static int mpegts_write_end(AVFormatContext *s) | |
2270 | { | ||
2271 |
1/2✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
|
20 | if (s->pb) |
2272 | 20 | mpegts_write_flush(s); | |
2273 | |||
2274 | 20 | return 0; | |
2275 | } | ||
2276 | |||
2277 | 20 | static void mpegts_deinit(AVFormatContext *s) | |
2278 | { | ||
2279 | 20 | MpegTSWrite *ts = s->priv_data; | |
2280 | MpegTSService *service; | ||
2281 | int i; | ||
2282 | |||
2283 |
2/2✓ Branch 0 taken 21 times.
✓ Branch 1 taken 20 times.
|
41 | for (i = 0; i < s->nb_streams; i++) { |
2284 | 21 | AVStream *st = s->streams[i]; | |
2285 | 21 | MpegTSWriteStream *ts_st = st->priv_data; | |
2286 |
1/2✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
|
21 | if (ts_st) { |
2287 | 21 | av_freep(&ts_st->dvb_ac3_desc); | |
2288 | 21 | av_freep(&ts_st->payload); | |
2289 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
|
21 | if (ts_st->amux) { |
2290 | ✗ | avformat_free_context(ts_st->amux); | |
2291 | ✗ | ts_st->amux = NULL; | |
2292 | } | ||
2293 | } | ||
2294 | } | ||
2295 | |||
2296 |
2/2✓ Branch 0 taken 20 times.
✓ Branch 1 taken 20 times.
|
40 | for (i = 0; i < ts->nb_services; i++) { |
2297 | 20 | service = ts->services[i]; | |
2298 | 20 | av_freep(&service); | |
2299 | } | ||
2300 | 20 | av_freep(&ts->services); | |
2301 | 20 | } | |
2302 | |||
2303 | 15 | static int mpegts_check_bitstream(AVFormatContext *s, AVStream *st, | |
2304 | const AVPacket *pkt) | ||
2305 | { | ||
2306 | const struct Entry { | ||
2307 | enum AVCodecID id; | ||
2308 | const char *bsf_name; | ||
2309 | uint8_t mask; | ||
2310 | uint8_t value; | ||
2311 | 15 | } list[] = { | |
2312 | { AV_CODEC_ID_H264, "h264_mp4toannexb", 0xff, 0x01 /* configurationVersion in AVCDecoderConfigurationRecord */}, | ||
2313 | { AV_CODEC_ID_HEVC, "hevc_mp4toannexb", 0xff, 0x01 /* configurationVersion in HEVCDecoderConfigurationRecord */}, | ||
2314 | { AV_CODEC_ID_VVC, "vvc_mp4toannexb", 0xf8, 0xf8 /* reserved '11111'b in VVCDecoderConfigurationRecord */}, | ||
2315 | }; | ||
2316 | |||
2317 |
2/2✓ Branch 0 taken 43 times.
✓ Branch 1 taken 14 times.
|
57 | for (int i = 0; i < FF_ARRAY_ELEMS(list); i++) { |
2318 | 43 | const struct Entry *e = list + i; | |
2319 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 42 times.
|
43 | if (e->id == st->codecpar->codec_id && |
2320 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | pkt->size >= 5 && AV_RB32(pkt->data) != 0x0000001 && |
2321 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | (AV_RB24(pkt->data) != 0x000001 || |
2322 | ✗ | (st->codecpar->extradata_size > 0 && | |
2323 | ✗ | ((st->codecpar->extradata[0] & e->mask) == e->value)))) | |
2324 | 1 | return ff_stream_add_bitstream_filter(st, e->bsf_name, NULL); | |
2325 | } | ||
2326 | 14 | return 1; | |
2327 | } | ||
2328 | |||
2329 | #define OFFSET(x) offsetof(MpegTSWrite, x) | ||
2330 | #define ENC AV_OPT_FLAG_ENCODING_PARAM | ||
2331 | static const AVOption options[] = { | ||
2332 | { "mpegts_transport_stream_id", "Set transport_stream_id field.", | ||
2333 | OFFSET(transport_stream_id), AV_OPT_TYPE_INT, { .i64 = 0x0001 }, 0x0001, 0xffff, ENC }, | ||
2334 | { "mpegts_original_network_id", "Set original_network_id field.", | ||
2335 | OFFSET(original_network_id), AV_OPT_TYPE_INT, { .i64 = DVB_PRIVATE_NETWORK_START }, 0x0001, 0xffff, ENC }, | ||
2336 | { "mpegts_service_id", "Set service_id field.", | ||
2337 | OFFSET(service_id), AV_OPT_TYPE_INT, { .i64 = 0x0001 }, 0x0001, 0xffff, ENC }, | ||
2338 | { "mpegts_service_type", "Set service_type field.", | ||
2339 | OFFSET(service_type), AV_OPT_TYPE_INT, { .i64 = 0x01 }, 0x01, 0xff, ENC, .unit = "mpegts_service_type" }, | ||
2340 | { "digital_tv", "Digital Television.", | ||
2341 | 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_SERVICE_TYPE_DIGITAL_TV }, 0x01, 0xff, ENC, .unit = "mpegts_service_type" }, | ||
2342 | { "digital_radio", "Digital Radio.", | ||
2343 | 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_SERVICE_TYPE_DIGITAL_RADIO }, 0x01, 0xff, ENC, .unit = "mpegts_service_type" }, | ||
2344 | { "teletext", "Teletext.", | ||
2345 | 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_SERVICE_TYPE_TELETEXT }, 0x01, 0xff, ENC, .unit = "mpegts_service_type" }, | ||
2346 | { "advanced_codec_digital_radio", "Advanced Codec Digital Radio.", | ||
2347 | 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_SERVICE_TYPE_ADVANCED_CODEC_DIGITAL_RADIO }, 0x01, 0xff, ENC, .unit = "mpegts_service_type" }, | ||
2348 | { "mpeg2_digital_hdtv", "MPEG2 Digital HDTV.", | ||
2349 | 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_SERVICE_TYPE_MPEG2_DIGITAL_HDTV }, 0x01, 0xff, ENC, .unit = "mpegts_service_type" }, | ||
2350 | { "advanced_codec_digital_sdtv", "Advanced Codec Digital SDTV.", | ||
2351 | 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_SERVICE_TYPE_ADVANCED_CODEC_DIGITAL_SDTV }, 0x01, 0xff, ENC, .unit = "mpegts_service_type" }, | ||
2352 | { "advanced_codec_digital_hdtv", "Advanced Codec Digital HDTV.", | ||
2353 | 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_SERVICE_TYPE_ADVANCED_CODEC_DIGITAL_HDTV }, 0x01, 0xff, ENC, .unit = "mpegts_service_type" }, | ||
2354 | { "hevc_digital_hdtv", "HEVC Digital Television Service.", | ||
2355 | 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_SERVICE_TYPE_HEVC_DIGITAL_HDTV }, 0x01, 0xff, ENC, .unit = "mpegts_service_type" }, | ||
2356 | { "mpegts_pmt_start_pid", "Set the first pid of the PMT.", | ||
2357 | OFFSET(pmt_start_pid), AV_OPT_TYPE_INT, { .i64 = 0x1000 }, FIRST_OTHER_PID, LAST_OTHER_PID, ENC }, | ||
2358 | { "mpegts_start_pid", "Set the first pid.", | ||
2359 | OFFSET(start_pid), AV_OPT_TYPE_INT, { .i64 = 0x0100 }, FIRST_OTHER_PID, LAST_OTHER_PID, ENC }, | ||
2360 | { "mpegts_m2ts_mode", "Enable m2ts mode.", OFFSET(m2ts_mode), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, ENC }, | ||
2361 | { "muxrate", NULL, OFFSET(mux_rate), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, INT_MAX, ENC }, | ||
2362 | { "pes_payload_size", "Minimum PES packet payload in bytes", | ||
2363 | OFFSET(pes_payload_size), AV_OPT_TYPE_INT, { .i64 = DEFAULT_PES_PAYLOAD_SIZE }, 0, INT_MAX, ENC }, | ||
2364 | { "mpegts_flags", "MPEG-TS muxing flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, { .i64 = 0 }, 0, INT_MAX, ENC, .unit = "mpegts_flags" }, | ||
2365 | { "resend_headers", "Reemit PAT/PMT before writing the next packet", | ||
2366 | 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_FLAG_REEMIT_PAT_PMT }, 0, INT_MAX, ENC, .unit = "mpegts_flags" }, | ||
2367 | { "latm", "Use LATM packetization for AAC", | ||
2368 | 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_FLAG_AAC_LATM }, 0, INT_MAX, ENC, .unit = "mpegts_flags" }, | ||
2369 | { "pat_pmt_at_frames", "Reemit PAT and PMT at each video frame", | ||
2370 | 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_FLAG_PAT_PMT_AT_FRAMES}, 0, INT_MAX, ENC, .unit = "mpegts_flags" }, | ||
2371 | { "system_b", "Conform to System B (DVB) instead of System A (ATSC)", | ||
2372 | 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_FLAG_SYSTEM_B }, 0, INT_MAX, ENC, .unit = "mpegts_flags" }, | ||
2373 | { "initial_discontinuity", "Mark initial packets as discontinuous", | ||
2374 | 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_FLAG_DISCONT }, 0, INT_MAX, ENC, .unit = "mpegts_flags" }, | ||
2375 | { "nit", "Enable NIT transmission", | ||
2376 | 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_FLAG_NIT}, 0, INT_MAX, ENC, .unit = "mpegts_flags" }, | ||
2377 | { "omit_rai", "Disable writing of random access indicator", | ||
2378 | 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_FLAG_OMIT_RAI }, 0, INT_MAX, ENC, .unit = "mpegts_flags" }, | ||
2379 | { "mpegts_copyts", "don't offset dts/pts", OFFSET(copyts), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, ENC }, | ||
2380 | { "tables_version", "set PAT, PMT, SDT and NIT version", OFFSET(tables_version), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 31, ENC }, | ||
2381 | { "omit_video_pes_length", "Omit the PES packet length for video packets", | ||
2382 | OFFSET(omit_video_pes_length), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, ENC }, | ||
2383 | { "pcr_period", "PCR retransmission time in milliseconds", | ||
2384 | OFFSET(pcr_period_ms), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, ENC }, | ||
2385 | { "pat_period", "PAT/PMT retransmission time limit in seconds", | ||
2386 | OFFSET(pat_period_us), AV_OPT_TYPE_DURATION, { .i64 = PAT_RETRANS_TIME * 1000LL }, 0, INT64_MAX, ENC }, | ||
2387 | { "sdt_period", "SDT retransmission time limit in seconds", | ||
2388 | OFFSET(sdt_period_us), AV_OPT_TYPE_DURATION, { .i64 = SDT_RETRANS_TIME * 1000LL }, 0, INT64_MAX, ENC }, | ||
2389 | { "nit_period", "NIT retransmission time limit in seconds", | ||
2390 | OFFSET(nit_period_us), AV_OPT_TYPE_DURATION, { .i64 = NIT_RETRANS_TIME * 1000LL }, 0, INT64_MAX, ENC }, | ||
2391 | { NULL }, | ||
2392 | }; | ||
2393 | |||
2394 | static const AVClass mpegts_muxer_class = { | ||
2395 | .class_name = "MPEGTS muxer", | ||
2396 | .item_name = av_default_item_name, | ||
2397 | .option = options, | ||
2398 | .version = LIBAVUTIL_VERSION_INT, | ||
2399 | }; | ||
2400 | |||
2401 | const FFOutputFormat ff_mpegts_muxer = { | ||
2402 | .p.name = "mpegts", | ||
2403 | .p.long_name = NULL_IF_CONFIG_SMALL("MPEG-TS (MPEG-2 Transport Stream)"), | ||
2404 | .p.mime_type = "video/MP2T", | ||
2405 | .p.extensions = "ts,m2t,m2ts,mts", | ||
2406 | .priv_data_size = sizeof(MpegTSWrite), | ||
2407 | .p.audio_codec = AV_CODEC_ID_MP2, | ||
2408 | .p.video_codec = AV_CODEC_ID_MPEG2VIDEO, | ||
2409 | .init = mpegts_init, | ||
2410 | .write_packet = mpegts_write_packet, | ||
2411 | .write_trailer = mpegts_write_end, | ||
2412 | .deinit = mpegts_deinit, | ||
2413 | .check_bitstream = mpegts_check_bitstream, | ||
2414 | #if FF_API_ALLOW_FLUSH | ||
2415 | .p.flags = AVFMT_ALLOW_FLUSH | AVFMT_VARIABLE_FPS | AVFMT_NODIMENSIONS, | ||
2416 | #else | ||
2417 | .p.flags = AVFMT_VARIABLE_FPS | AVFMT_NODIMENSIONS, | ||
2418 | #endif | ||
2419 | .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH, | ||
2420 | .p.priv_class = &mpegts_muxer_class, | ||
2421 | }; | ||
2422 |