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