FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/mpeg.c
Date: 2024-04-25 15:36:26
Exec Total Coverage
Lines: 436 621 70.2%
Functions: 14 15 93.3%
Branches: 336 524 64.1%

Line Branch Exec Source
1 /*
2 * MPEG-1/2 demuxer
3 * Copyright (c) 2000, 2001, 2002 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 "config_components.h"
23
24 #include "libavutil/channel_layout.h"
25 #include "libavutil/mem.h"
26 #include "avformat.h"
27 #include "avio_internal.h"
28 #include "demux.h"
29 #include "internal.h"
30 #include "mpeg.h"
31
32 /*********************************************/
33 /* demux code */
34
35 #define MAX_SYNC_SIZE 100000
36
37 48025 static int check_pes(const uint8_t *p, const uint8_t *end)
38 {
39 int pes1;
40 99449 int pes2 = (p[3] & 0xC0) == 0x80 &&
41
4/4
✓ Branch 0 taken 3399 times.
✓ Branch 1 taken 44626 times.
✓ Branch 2 taken 2839 times.
✓ Branch 3 taken 560 times.
50864 (p[4] & 0xC0) != 0x40 &&
42
2/2
✓ Branch 0 taken 1221 times.
✓ Branch 1 taken 1618 times.
2839 ((p[4] & 0xC0) == 0x00 ||
43
2/2
✓ Branch 0 taken 121 times.
✓ Branch 1 taken 1100 times.
1221 (p[4] & 0xC0) >> 2 == (p[6] & 0xF0));
44
45
4/4
✓ Branch 0 taken 50201 times.
✓ Branch 1 taken 67 times.
✓ Branch 2 taken 2243 times.
✓ Branch 3 taken 47958 times.
50268 for (p += 3; p < end && *p == 0xFF; p++) ;
46
2/2
✓ Branch 0 taken 4441 times.
✓ Branch 1 taken 43584 times.
48025 if ((*p & 0xC0) == 0x40)
47 4441 p += 2;
48
49
2/2
✓ Branch 0 taken 1477 times.
✓ Branch 1 taken 46548 times.
48025 if ((*p & 0xF0) == 0x20)
50 1477 pes1 = p[0] & p[2] & p[4] & 1;
51
2/2
✓ Branch 0 taken 1180 times.
✓ Branch 1 taken 45368 times.
46548 else if ((*p & 0xF0) == 0x30)
52 1180 pes1 = p[0] & p[2] & p[4] & p[5] & p[7] & p[9] & 1;
53 else
54 45368 pes1 = *p == 0x0F;
55
56
4/4
✓ Branch 0 taken 47696 times.
✓ Branch 1 taken 329 times.
✓ Branch 2 taken 1739 times.
✓ Branch 3 taken 45957 times.
48025 return pes1 || pes2;
57 }
58
59 48344 static int check_pack_header(const uint8_t *buf)
60 {
61
4/4
✓ Branch 0 taken 41437 times.
✓ Branch 1 taken 6907 times.
✓ Branch 2 taken 2739 times.
✓ Branch 3 taken 38698 times.
48344 return (buf[1] & 0xC0) == 0x40 || (buf[1] & 0xF0) == 0x20;
62 }
63
64 7128 static int mpegps_probe(const AVProbeData *p)
65 {
66 7128 uint32_t code = -1;
67 int i;
68 7128 int sys = 0, pspack = 0, priv1 = 0, vid = 0;
69 7128 int audio = 0, invalid = 0, score = 0;
70 7128 int endpes = 0;
71
72
2/2
✓ Branch 0 taken 367019742 times.
✓ Branch 1 taken 7128 times.
367026870 for (i = 0; i < p->buf_size; i++) {
73 367019742 code = (code << 8) + p->buf[i];
74
2/2
✓ Branch 0 taken 48344 times.
✓ Branch 1 taken 366971398 times.
367019742 if ((code & 0xffffff00) == 0x100) {
75 48344 int len = p->buf[i + 1] << 8 | p->buf[i + 2];
76
4/4
✓ Branch 0 taken 48025 times.
✓ Branch 1 taken 319 times.
✓ Branch 3 taken 2068 times.
✓ Branch 4 taken 45957 times.
48344 int pes = endpes <= i && check_pes(p->buf + i, p->buf + p->buf_size);
77 48344 int pack = check_pack_header(p->buf + i);
78
79
2/2
✓ Branch 0 taken 43 times.
✓ Branch 1 taken 48301 times.
48344 if (code == SYSTEM_HEADER_START_CODE)
80 43 sys++;
81
4/4
✓ Branch 0 taken 77 times.
✓ Branch 1 taken 48224 times.
✓ Branch 2 taken 72 times.
✓ Branch 3 taken 5 times.
48301 else if (code == PACK_START_CODE && pack)
82 72 pspack++;
83
4/4
✓ Branch 0 taken 913 times.
✓ Branch 1 taken 47316 times.
✓ Branch 2 taken 82 times.
✓ Branch 3 taken 831 times.
48229 else if ((code & 0xf0) == VIDEO_ID && pes) {
84 82 endpes = i + len;
85 82 vid++;
86 }
87 // skip pes payload to avoid start code emulation for private
88 // and audio streams
89
4/4
✓ Branch 0 taken 1199 times.
✓ Branch 1 taken 46948 times.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 1161 times.
48147 else if ((code & 0xe0) == AUDIO_ID && pes) {audio++; i+=len;}
90
4/4
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 48043 times.
✓ Branch 2 taken 55 times.
✓ Branch 3 taken 11 times.
48109 else if (code == PRIVATE_STREAM_1 && pes) {priv1++; i+=len;}
91
3/4
✓ Branch 0 taken 113 times.
✓ Branch 1 taken 47941 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 113 times.
48054 else if (code == 0x1fd && pes) vid++; //VC1
92
93
3/4
✓ Branch 0 taken 831 times.
✓ Branch 1 taken 47223 times.
✓ Branch 2 taken 831 times.
✗ Branch 3 not taken.
48054 else if ((code & 0xf0) == VIDEO_ID && !pes) invalid++;
94
3/4
✓ Branch 0 taken 1161 times.
✓ Branch 1 taken 46062 times.
✓ Branch 2 taken 1161 times.
✗ Branch 3 not taken.
47223 else if ((code & 0xe0) == AUDIO_ID && !pes) invalid++;
95
3/4
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 46051 times.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
46062 else if (code == PRIVATE_STREAM_1 && !pes) invalid++;
96 }
97 }
98
99
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 7107 times.
7128 if (vid + audio > invalid + 1) /* invalid VDR files nd short PES streams */
100 21 score = AVPROBE_SCORE_EXTENSION / 2;
101
102 // av_log(NULL, AV_LOG_ERROR, "vid:%d aud:%d sys:%d pspack:%d invalid:%d size:%d \n",
103 // vid, audio, sys, pspack, invalid, p->buf_size);
104
105
4/4
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 7094 times.
✓ Branch 2 taken 33 times.
✓ Branch 3 taken 1 times.
7128 if (sys > invalid && sys * 9 <= pspack * 10)
106
3/4
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
✓ Branch 3 taken 1 times.
33 return (audio > 12 || vid > 3 || pspack > 2) ? AVPROBE_SCORE_EXTENSION + 2
107
3/4
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
✓ Branch 3 taken 15 times.
66 : AVPROBE_SCORE_EXTENSION / 2 + (audio + vid + pspack > 1); // 1 more than mp3
108
4/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 7082 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 3 times.
7095 if (pspack > invalid && (priv1 + vid + audio) * 10 >= pspack * 9)
109 return pspack > 2 ? AVPROBE_SCORE_EXTENSION + 2
110
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 7 times.
10 : AVPROBE_SCORE_EXTENSION / 2; // 1 more than .mpg
111
7/10
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 7034 times.
✓ Branch 2 taken 51 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12 times.
✓ Branch 5 taken 39 times.
✓ Branch 6 taken 12 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 12 times.
✗ Branch 9 not taken.
7085 if ((!!vid ^ !!audio) && (audio > 4 || vid > 1) && !sys &&
112
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 !pspack && p->buf_size > 2048 && vid + audio > invalid) /* PES stream */
113 return (audio > 12 || vid > 6 + 2 * invalid) ? AVPROBE_SCORE_EXTENSION + 2
114 : AVPROBE_SCORE_EXTENSION / 2;
115
116 // 02-Penguin.flac has sys:0 priv1:0 pspack:0 vid:0 audio:1
117 // mp3_misidentified_2.mp3 has sys:0 priv1:0 pspack:0 vid:0 audio:6
118 // Have\ Yourself\ a\ Merry\ Little\ Christmas.mp3 0 0 0 5 0 1 len:21618
119 7085 return score;
120 }
121
122 typedef struct MpegDemuxContext {
123 int32_t header_state;
124 unsigned char psm_es_type[256];
125 int sofdec;
126 int dvd;
127 int imkh_cctv;
128 int raw_ac3;
129 } MpegDemuxContext;
130
131 28 static int mpegps_read_header(AVFormatContext *s)
132 {
133 28 MpegDemuxContext *m = s->priv_data;
134 28 char buffer[7] = { 0 };
135 28 int64_t last_pos = avio_tell(s->pb);
136
137 28 m->header_state = 0xff;
138 28 s->ctx_flags |= AVFMTCTX_NOHEADER;
139
140 28 avio_get_str(s->pb, 6, buffer, sizeof(buffer));
141
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
28 if (!memcmp("IMKH", buffer, 4)) {
142 m->imkh_cctv = 1;
143
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
28 } else if (!memcmp("Sofdec", buffer, 6)) {
144 m->sofdec = 1;
145 } else
146 28 avio_seek(s->pb, last_pos, SEEK_SET);
147
148 /* no need to do more */
149 28 return 0;
150 }
151
152 6966 static int64_t get_pts(AVIOContext *pb, int c)
153 {
154 uint8_t buf[5];
155 int ret;
156
157
2/2
✓ Branch 0 taken 6044 times.
✓ Branch 1 taken 922 times.
6966 buf[0] = c < 0 ? avio_r8(pb) : c;
158 6966 ret = avio_read(pb, buf + 1, 4);
159
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6966 times.
6966 if (ret < 4)
160 return AV_NOPTS_VALUE;
161
162 6966 return ff_parse_pes_pts(buf);
163 }
164
165 24688 static int find_next_start_code(AVIOContext *pb, int *size_ptr,
166 int32_t *header_state)
167 {
168 unsigned int state, v;
169 int val, n;
170
171 24688 state = *header_state;
172 24688 n = *size_ptr;
173
1/2
✓ Branch 0 taken 313937 times.
✗ Branch 1 not taken.
313937 while (n > 0) {
174
2/2
✓ Branch 1 taken 129 times.
✓ Branch 2 taken 313808 times.
313937 if (avio_feof(pb))
175 129 break;
176 313808 v = avio_r8(pb);
177 313808 n--;
178
2/2
✓ Branch 0 taken 24559 times.
✓ Branch 1 taken 289249 times.
313808 if (state == 0x000001) {
179 24559 state = ((state << 8) | v) & 0xffffff;
180 24559 val = state;
181 24559 goto found;
182 }
183 289249 state = ((state << 8) | v) & 0xffffff;
184 }
185 129 val = -1;
186
187 24688 found:
188 24688 *header_state = state;
189 24688 *size_ptr = n;
190 24688 return val;
191 }
192
193 /**
194 * Extract stream types from a program stream map
195 * According to ISO/IEC 13818-1 ('MPEG-2 Systems') table 2-35
196 *
197 * @return number of bytes occupied by PSM in the bitstream
198 */
199 static long mpegps_psm_parse(MpegDemuxContext *m, AVIOContext *pb)
200 {
201 int psm_length, ps_info_length, es_map_length;
202
203 psm_length = avio_rb16(pb);
204 avio_r8(pb);
205 avio_r8(pb);
206 ps_info_length = avio_rb16(pb);
207
208 /* skip program_stream_info */
209 avio_skip(pb, ps_info_length);
210 /*es_map_length = */avio_rb16(pb);
211 /* Ignore es_map_length, trust psm_length */
212 es_map_length = psm_length - ps_info_length - 10;
213
214 /* at least one es available? */
215 while (es_map_length >= 4) {
216 unsigned char type = avio_r8(pb);
217 unsigned char es_id = avio_r8(pb);
218 uint16_t es_info_length = avio_rb16(pb);
219
220 /* remember mapping from stream id to stream type */
221 m->psm_es_type[es_id] = type;
222 /* skip program_stream_info */
223 avio_skip(pb, es_info_length);
224 es_map_length -= 4 + es_info_length;
225 }
226 avio_rb32(pb); /* crc32 */
227 return 2 + psm_length;
228 }
229
230 /* read the next PES header. Return its position in ppos
231 * (if not NULL), and its start code, pts and dts.
232 */
233 13385 static int mpegps_read_pes_header(AVFormatContext *s,
234 int64_t *ppos, int *pstart_code,
235 int64_t *ppts, int64_t *pdts)
236 {
237 13385 MpegDemuxContext *m = s->priv_data;
238 int len, size, startcode, c, flags, header_len;
239 int pes_ext, ext2_len, id_ext, skip;
240 int64_t pts, dts;
241 13385 int64_t last_sync = avio_tell(s->pb);
242
243 error_redo:
244 13385 avio_seek(s->pb, last_sync, SEEK_SET);
245 11303 redo:
246 /* next start code (should be immediately after) */
247 24688 m->header_state = 0xff;
248 24688 size = MAX_SYNC_SIZE;
249 24688 startcode = find_next_start_code(s->pb, &size, &m->header_state);
250 24688 last_sync = avio_tell(s->pb);
251
2/2
✓ Branch 0 taken 129 times.
✓ Branch 1 taken 24559 times.
24688 if (startcode < 0) {
252
1/2
✓ Branch 1 taken 129 times.
✗ Branch 2 not taken.
129 if (avio_feof(s->pb))
253 129 return AVERROR_EOF;
254 // FIXME we should remember header_state
255 return FFERROR_REDO;
256 }
257
258
2/2
✓ Branch 0 taken 10260 times.
✓ Branch 1 taken 14299 times.
24559 if (startcode == PACK_START_CODE)
259 10260 goto redo;
260
2/2
✓ Branch 0 taken 192 times.
✓ Branch 1 taken 14107 times.
14299 if (startcode == SYSTEM_HEADER_START_CODE)
261 192 goto redo;
262
2/2
✓ Branch 0 taken 796 times.
✓ Branch 1 taken 13311 times.
14107 if (startcode == PADDING_STREAM) {
263 796 avio_skip(s->pb, avio_rb16(s->pb));
264 796 goto redo;
265 }
266
2/2
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 13267 times.
13311 if (startcode == PRIVATE_STREAM_2) {
267
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 41 times.
44 if (!m->sofdec) {
268 /* Need to detect whether this from a DVD or a 'Sofdec' stream */
269 3 int len = avio_rb16(s->pb);
270 3 int bytesread = 0;
271 3 uint8_t *ps2buf = av_malloc(len);
272
273
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (ps2buf) {
274 3 bytesread = avio_read(s->pb, ps2buf, len);
275
276
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (bytesread != len) {
277 avio_skip(s->pb, len - bytesread);
278 } else {
279 3 uint8_t *p = 0;
280
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (len >= 6)
281 3 p = memchr(ps2buf, 'S', len - 5);
282
283
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (p)
284 m->sofdec = !memcmp(p+1, "ofdec", 5);
285
286 3 m->sofdec -= !m->sofdec;
287
288
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (m->sofdec < 0) {
289
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 if (len == 980 && ps2buf[0] == 0) {
290 /* PCI structure? */
291 3 uint32_t startpts = AV_RB32(ps2buf + 0x0d);
292 3 uint32_t endpts = AV_RB32(ps2buf + 0x11);
293 3 uint8_t hours = ((ps2buf[0x19] >> 4) * 10) + (ps2buf[0x19] & 0x0f);
294 3 uint8_t mins = ((ps2buf[0x1a] >> 4) * 10) + (ps2buf[0x1a] & 0x0f);
295 3 uint8_t secs = ((ps2buf[0x1b] >> 4) * 10) + (ps2buf[0x1b] & 0x0f);
296
297
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
6 m->dvd = (hours <= 23 &&
298
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 mins <= 59 &&
299 3 secs <= 59 &&
300
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 (ps2buf[0x19] & 0x0f) < 10 &&
301
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 (ps2buf[0x1a] & 0x0f) < 10 &&
302
3/6
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
6 (ps2buf[0x1b] & 0x0f) < 10 &&
303 endpts >= startpts);
304 } else if (len == 1018 && ps2buf[0] == 1) {
305 /* DSI structure? */
306 uint8_t hours = ((ps2buf[0x1d] >> 4) * 10) + (ps2buf[0x1d] & 0x0f);
307 uint8_t mins = ((ps2buf[0x1e] >> 4) * 10) + (ps2buf[0x1e] & 0x0f);
308 uint8_t secs = ((ps2buf[0x1f] >> 4) * 10) + (ps2buf[0x1f] & 0x0f);
309
310 m->dvd = (hours <= 23 &&
311 mins <= 59 &&
312 secs <= 59 &&
313 (ps2buf[0x1d] & 0x0f) < 10 &&
314 (ps2buf[0x1e] & 0x0f) < 10 &&
315 (ps2buf[0x1f] & 0x0f) < 10);
316 }
317 }
318 }
319
320 3 av_free(ps2buf);
321
322 /* If this isn't a DVD packet or no memory
323 * could be allocated, just ignore it.
324 * If we did, move back to the start of the
325 * packet (plus 'length' field) */
326
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
3 if (!m->dvd || avio_skip(s->pb, -(len + 2)) < 0) {
327 /* Skip back failed.
328 * This packet will be lost but that can't be helped
329 * if we can't skip back
330 */
331 goto redo;
332 }
333 } else {
334 /* No memory */
335 avio_skip(s->pb, len);
336 goto redo;
337 }
338
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
41 } else if (!m->dvd) {
339 int len = avio_rb16(s->pb);
340 avio_skip(s->pb, len);
341 goto redo;
342 }
343 }
344
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13311 times.
13311 if (startcode == PROGRAM_STREAM_MAP) {
345 mpegps_psm_parse(m, s->pb);
346 goto redo;
347 }
348
349 /* find matching stream */
350
7/8
✓ Branch 0 taken 7456 times.
✓ Branch 1 taken 5855 times.
✓ Branch 2 taken 7103 times.
✓ Branch 3 taken 353 times.
✓ Branch 4 taken 7103 times.
✓ Branch 5 taken 5855 times.
✓ Branch 6 taken 55 times.
✗ Branch 7 not taken.
13366 if (!((startcode >= 0x1c0 && startcode <= 0x1df) ||
351
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7103 times.
✓ Branch 2 taken 99 times.
✓ Branch 3 taken 5756 times.
12958 (startcode >= 0x1e0 && startcode <= 0x1ef) ||
352
2/2
✓ Branch 0 taken 55 times.
✓ Branch 1 taken 44 times.
99 (startcode == 0x1bd) ||
353 (startcode == PRIVATE_STREAM_2) ||
354 (startcode == 0x1fd)))
355 55 goto redo;
356
2/2
✓ Branch 0 taken 12869 times.
✓ Branch 1 taken 387 times.
13256 if (ppos) {
357 12869 *ppos = avio_tell(s->pb) - 4;
358 }
359 13256 len = avio_rb16(s->pb);
360 13256 pts =
361 13256 dts = AV_NOPTS_VALUE;
362
2/2
✓ Branch 0 taken 13212 times.
✓ Branch 1 taken 44 times.
13256 if (startcode != PRIVATE_STREAM_2)
363 {
364 /* stuffing */
365 for (;;) {
366
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13218 times.
13218 if (len < 1)
367 goto error_redo;
368 13218 c = avio_r8(s->pb);
369 13218 len--;
370 /* XXX: for MPEG-1, should test only bit 7 */
371
2/2
✓ Branch 0 taken 13212 times.
✓ Branch 1 taken 6 times.
13218 if (c != 0xff)
372 13212 break;
373 }
374
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13212 times.
13212 if ((c & 0xc0) == 0x40) {
375 /* buffer scale & size */
376 avio_r8(s->pb);
377 c = avio_r8(s->pb);
378 len -= 2;
379 }
380
2/2
✓ Branch 0 taken 922 times.
✓ Branch 1 taken 12290 times.
13212 if ((c & 0xe0) == 0x20) {
381 922 dts =
382 922 pts = get_pts(s->pb, c);
383 922 len -= 4;
384
2/2
✓ Branch 0 taken 438 times.
✓ Branch 1 taken 484 times.
922 if (c & 0x10) {
385 438 dts = get_pts(s->pb, -1);
386 438 len -= 5;
387 }
388
2/2
✓ Branch 0 taken 9742 times.
✓ Branch 1 taken 2548 times.
12290 } else if ((c & 0xc0) == 0x80) {
389 /* mpeg 2 PES */
390 9742 flags = avio_r8(s->pb);
391 9742 header_len = avio_r8(s->pb);
392 9742 len -= 2;
393
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9742 times.
9742 if (header_len > len)
394 goto error_redo;
395 9742 len -= header_len;
396
2/2
✓ Branch 0 taken 5575 times.
✓ Branch 1 taken 4167 times.
9742 if (flags & 0x80) {
397 5575 dts = pts = get_pts(s->pb, -1);
398 5575 header_len -= 5;
399
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 5544 times.
5575 if (flags & 0x40) {
400 31 dts = get_pts(s->pb, -1);
401 31 header_len -= 5;
402 }
403 }
404
3/4
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 9700 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 42 times.
9742 if (flags & 0x3f && header_len == 0) {
405 flags &= 0xC0;
406 av_log(s, AV_LOG_WARNING, "Further flags set but no bytes left\n");
407 }
408
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 9700 times.
9742 if (flags & 0x01) { /* PES extension */
409 42 pes_ext = avio_r8(s->pb);
410 42 header_len--;
411 /* Skip PES private data, program packet sequence counter
412 * and P-STD buffer */
413 42 skip = (pes_ext >> 4) & 0xb;
414 42 skip += skip & 0x9;
415
2/4
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 42 times.
42 if (pes_ext & 0x40 || skip > header_len) {
416 av_log(s, AV_LOG_WARNING, "pes_ext %X is invalid\n", pes_ext);
417 pes_ext = skip = 0;
418 }
419 42 avio_skip(s->pb, skip);
420 42 header_len -= skip;
421
422
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
42 if (pes_ext & 0x01) { /* PES extension 2 */
423 ext2_len = avio_r8(s->pb);
424 header_len--;
425 if ((ext2_len & 0x7f) > 0) {
426 id_ext = avio_r8(s->pb);
427 if ((id_ext & 0x80) == 0)
428 startcode = ((startcode & 0xff) << 8) | id_ext;
429 header_len--;
430 }
431 }
432 }
433
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9742 times.
9742 if (header_len < 0)
434 goto error_redo;
435 9742 avio_skip(s->pb, header_len);
436
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2548 times.
2548 } else if (c != 0xf)
437 goto redo;
438 }
439
440
2/2
✓ Branch 0 taken 5756 times.
✓ Branch 1 taken 7500 times.
13256 if (startcode == PRIVATE_STREAM_1) {
441 5756 int ret = ffio_ensure_seekback(s->pb, 2);
442
443
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5756 times.
5756 if (ret < 0)
444 return ret;
445
446 5756 startcode = avio_r8(s->pb);
447 5756 m->raw_ac3 = 0;
448
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5756 times.
5756 if (startcode == 0x0b) {
449 if (avio_r8(s->pb) == 0x77) {
450 startcode = 0x80;
451 m->raw_ac3 = 1;
452 avio_skip(s->pb, -2);
453 } else {
454 avio_skip(s->pb, -1);
455 }
456 } else {
457 5756 len--;
458 }
459 }
460
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13256 times.
13256 if (len < 0)
461 goto error_redo;
462
4/4
✓ Branch 0 taken 6497 times.
✓ Branch 1 taken 6759 times.
✓ Branch 2 taken 6233 times.
✓ Branch 3 taken 264 times.
13256 if (dts != AV_NOPTS_VALUE && ppos) {
463 int i;
464
2/2
✓ Branch 0 taken 7613 times.
✓ Branch 1 taken 6233 times.
13846 for (i = 0; i < s->nb_streams; i++) {
465
2/2
✓ Branch 0 taken 6199 times.
✓ Branch 1 taken 1414 times.
7613 if (startcode == s->streams[i]->id &&
466
1/2
✓ Branch 0 taken 6199 times.
✗ Branch 1 not taken.
6199 (s->pb->seekable & AVIO_SEEKABLE_NORMAL) /* index useless on streams anyway */) {
467 6199 ff_reduce_index(s, i);
468 6199 av_add_index_entry(s->streams[i], *ppos, dts, 0, 0,
469 AVINDEX_KEYFRAME /* FIXME keyframe? */);
470 }
471 }
472 }
473
474 13256 *pstart_code = startcode;
475 13256 *ppts = pts;
476 13256 *pdts = dts;
477 13256 return len;
478 }
479
480 12060 static int mpegps_read_packet(AVFormatContext *s,
481 AVPacket *pkt)
482 {
483 12060 MpegDemuxContext *m = s->priv_data;
484 AVStream *st;
485 FFStream *sti;
486 int len, startcode, i, es_type, ret;
487 12060 int pcm_dvd = 0;
488 12060 int request_probe= 0;
489 12060 enum AVCodecID codec_id = AV_CODEC_ID_NONE;
490 enum AVMediaType type;
491 int64_t pts, dts, dummy_pos; // dummy_pos is needed for the index building to work
492
493 12541 redo:
494 12541 len = mpegps_read_pes_header(s, &dummy_pos, &startcode, &pts, &dts);
495
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 12463 times.
12541 if (len < 0)
496 78 return len;
497
498
4/4
✓ Branch 0 taken 12433 times.
✓ Branch 1 taken 30 times.
✓ Branch 2 taken 5339 times.
✓ Branch 3 taken 7094 times.
12463 if (startcode >= 0x80 && startcode <= 0xcf) {
499
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5339 times.
5339 if (len < 4)
500 goto skip;
501
502
1/2
✓ Branch 0 taken 5339 times.
✗ Branch 1 not taken.
5339 if (!m->raw_ac3) {
503 /* audio: skip header */
504 5339 avio_skip(s->pb, 3);
505 5339 len -= 3;
506
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5339 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
5339 if (startcode >= 0xb0 && startcode <= 0xbf) {
507 /* MLP/TrueHD audio has a 4-byte header */
508 avio_r8(s->pb);
509 len--;
510
3/4
✓ Branch 0 taken 5333 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 5333 times.
✗ Branch 3 not taken.
5339 } else if (startcode >= 0xa0 && startcode <= 0xaf) {
511 5333 ret = ffio_ensure_seekback(s->pb, 3);
512
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5333 times.
5333 if (ret < 0)
513 return ret;
514 5333 pcm_dvd = (avio_rb24(s->pb) & 0xFF) == 0x80;
515 5333 avio_skip(s->pb, -3);
516 }
517 }
518 }
519
520 /* now find stream */
521
2/2
✓ Branch 0 taken 16025 times.
✓ Branch 1 taken 39 times.
16064 for (i = 0; i < s->nb_streams; i++) {
522 16025 st = s->streams[i];
523
2/2
✓ Branch 0 taken 12424 times.
✓ Branch 1 taken 3601 times.
16025 if (st->id == startcode)
524 12424 goto found;
525 }
526
527 39 es_type = m->psm_es_type[startcode & 0xff];
528
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 if (es_type == STREAM_TYPE_VIDEO_MPEG1) {
529 codec_id = AV_CODEC_ID_MPEG2VIDEO;
530 type = AVMEDIA_TYPE_VIDEO;
531
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 } else if (es_type == STREAM_TYPE_VIDEO_MPEG2) {
532 codec_id = AV_CODEC_ID_MPEG2VIDEO;
533 type = AVMEDIA_TYPE_VIDEO;
534
2/4
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 39 times.
39 } else if (es_type == STREAM_TYPE_AUDIO_MPEG1 ||
535 es_type == STREAM_TYPE_AUDIO_MPEG2) {
536 codec_id = AV_CODEC_ID_MP3;
537 type = AVMEDIA_TYPE_AUDIO;
538
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 } else if (es_type == STREAM_TYPE_AUDIO_AAC) {
539 codec_id = AV_CODEC_ID_AAC;
540 type = AVMEDIA_TYPE_AUDIO;
541
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 } else if (es_type == STREAM_TYPE_VIDEO_MPEG4) {
542 codec_id = AV_CODEC_ID_MPEG4;
543 type = AVMEDIA_TYPE_VIDEO;
544
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 } else if (es_type == STREAM_TYPE_VIDEO_H264) {
545 codec_id = AV_CODEC_ID_H264;
546 type = AVMEDIA_TYPE_VIDEO;
547
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 } else if (es_type == STREAM_TYPE_VIDEO_HEVC) {
548 codec_id = AV_CODEC_ID_HEVC;
549 type = AVMEDIA_TYPE_VIDEO;
550
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 } else if (es_type == STREAM_TYPE_VIDEO_VVC) {
551 codec_id = AV_CODEC_ID_VVC;
552 type = AVMEDIA_TYPE_VIDEO;
553
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 } else if (es_type == STREAM_TYPE_AUDIO_AC3) {
554 codec_id = AV_CODEC_ID_AC3;
555 type = AVMEDIA_TYPE_AUDIO;
556
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 } else if (es_type == 0x90) {
557 codec_id = AV_CODEC_ID_PCM_ALAW;
558 type = AVMEDIA_TYPE_AUDIO;
559
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
39 } else if (m->imkh_cctv && es_type == 0x91) {
560 codec_id = AV_CODEC_ID_PCM_MULAW;
561 type = AVMEDIA_TYPE_AUDIO;
562
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 26 times.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
39 } else if (startcode >= 0x1e0 && startcode <= 0x1ef) {
563 static const unsigned char avs_seqh[4] = { 0, 0, 1, 0xb0 };
564 unsigned char buf[8];
565
566 13 avio_read(s->pb, buf, 8);
567 13 avio_seek(s->pb, -8, SEEK_CUR);
568
3/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
13 if (!memcmp(buf, avs_seqh, 4) && (buf[6] != 0 || buf[7] != 1))
569 2 codec_id = AV_CODEC_ID_CAVS;
570 else
571 11 request_probe= 1;
572 13 type = AVMEDIA_TYPE_VIDEO;
573
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 23 times.
26 } else if (startcode == PRIVATE_STREAM_2) {
574 3 type = AVMEDIA_TYPE_DATA;
575 3 codec_id = AV_CODEC_ID_DVD_NAV;
576
3/4
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
23 } else if (startcode >= 0x1c0 && startcode <= 0x1df) {
577 7 type = AVMEDIA_TYPE_AUDIO;
578
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (m->sofdec > 0) {
579 codec_id = AV_CODEC_ID_ADPCM_ADX;
580 // Auto-detect AC-3
581 request_probe = 50;
582
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
7 } else if (m->imkh_cctv && startcode == 0x1c0 && len > 80) {
583 codec_id = AV_CODEC_ID_PCM_ALAW;
584 request_probe = 50;
585 } else {
586 7 codec_id = AV_CODEC_ID_MP2;
587
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (m->imkh_cctv)
588 request_probe = 25;
589 }
590
4/4
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 13 times.
16 } else if (startcode >= 0x80 && startcode <= 0x87) {
591 1 type = AVMEDIA_TYPE_AUDIO;
592 1 codec_id = AV_CODEC_ID_AC3;
593
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
15 } else if ((startcode >= 0x88 && startcode <= 0x8f) ||
594
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
15 (startcode >= 0x98 && startcode <= 0x9f)) {
595 /* 0x90 - 0x97 is reserved for SDDS in DVD specs */
596 type = AVMEDIA_TYPE_AUDIO;
597 codec_id = AV_CODEC_ID_DTS;
598
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
15 } else if (startcode >= 0xa0 && startcode <= 0xaf) {
599 13 type = AVMEDIA_TYPE_AUDIO;
600
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if (!pcm_dvd) {
601 codec_id = AV_CODEC_ID_MLP;
602 } else {
603 13 codec_id = AV_CODEC_ID_PCM_DVD;
604 }
605
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 } else if (startcode >= 0xb0 && startcode <= 0xbf) {
606 type = AVMEDIA_TYPE_AUDIO;
607 codec_id = AV_CODEC_ID_TRUEHD;
608
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 } else if (startcode >= 0xc0 && startcode <= 0xcf) {
609 /* Used for both AC-3 and E-AC-3 in EVOB files */
610 type = AVMEDIA_TYPE_AUDIO;
611 codec_id = AV_CODEC_ID_AC3;
612
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 } else if (startcode >= 0x20 && startcode <= 0x3f) {
613 2 type = AVMEDIA_TYPE_SUBTITLE;
614 2 codec_id = AV_CODEC_ID_DVD_SUBTITLE;
615 } else if (startcode >= 0xfd55 && startcode <= 0xfd5f) {
616 type = AVMEDIA_TYPE_VIDEO;
617 codec_id = AV_CODEC_ID_VC1;
618 } else {
619 skip:
620 /* skip packet */
621 481 avio_skip(s->pb, len);
622 481 goto redo;
623 }
624 /* no stream found: add a new stream */
625 39 st = avformat_new_stream(s, NULL);
626
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 if (!st)
627 goto skip;
628 39 sti = ffstream(st);
629 39 st->id = startcode;
630 39 st->codecpar->codec_type = type;
631 39 st->codecpar->codec_id = codec_id;
632
1/2
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
39 if ( st->codecpar->codec_id == AV_CODEC_ID_PCM_MULAW
633
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 || st->codecpar->codec_id == AV_CODEC_ID_PCM_ALAW) {
634 st->codecpar->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO;
635 st->codecpar->sample_rate = 8000;
636 }
637 39 sti->request_probe = request_probe;
638 39 sti->need_parsing = AVSTREAM_PARSE_FULL;
639
640 12463 found:
641
2/2
✓ Branch 0 taken 481 times.
✓ Branch 1 taken 11982 times.
12463 if (st->discard >= AVDISCARD_ALL)
642 481 goto skip;
643
4/4
✓ Branch 0 taken 11956 times.
✓ Branch 1 taken 26 times.
✓ Branch 2 taken 5333 times.
✓ Branch 3 taken 6623 times.
11982 if (startcode >= 0xa0 && startcode <= 0xaf) {
644
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5333 times.
5333 if (st->codecpar->codec_id == AV_CODEC_ID_MLP) {
645 if (len < 6)
646 goto skip;
647 avio_skip(s->pb, 6);
648 len -=6;
649 }
650 }
651 11982 ret = av_get_packet(s->pb, pkt, len);
652
653 11982 pkt->pts = pts;
654 11982 pkt->dts = dts;
655 11982 pkt->pos = dummy_pos;
656 11982 pkt->stream_index = st->index;
657
658
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11982 times.
11982 if (s->debug & FF_FDEBUG_TS)
659 av_log(s, AV_LOG_DEBUG, "%d: pts=%0.3f dts=%0.3f size=%d\n",
660 pkt->stream_index, pkt->pts / 90000.0, pkt->dts / 90000.0,
661 pkt->size);
662
663 11982 return (ret < 0) ? ret : 0;
664 }
665
666 91 static int64_t mpegps_read_dts(AVFormatContext *s, int stream_index,
667 int64_t *ppos, int64_t pos_limit)
668 {
669 int len, startcode;
670 int64_t pos, pts, dts;
671
672 91 pos = *ppos;
673
1/2
✓ Branch 1 taken 91 times.
✗ Branch 2 not taken.
91 if (avio_seek(s->pb, pos, SEEK_SET) < 0)
674 return AV_NOPTS_VALUE;
675
676 for (;;) {
677 451 len = mpegps_read_pes_header(s, &pos, &startcode, &pts, &dts);
678
2/2
✓ Branch 0 taken 45 times.
✓ Branch 1 taken 406 times.
451 if (len < 0) {
679
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
45 if (s->debug & FF_FDEBUG_TS)
680 av_log(s, AV_LOG_DEBUG, "none (ret=%d)\n", len);
681 45 return AV_NOPTS_VALUE;
682 }
683
2/2
✓ Branch 0 taken 323 times.
✓ Branch 1 taken 83 times.
406 if (startcode == s->streams[stream_index]->id &&
684
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 277 times.
323 dts != AV_NOPTS_VALUE) {
685 46 break;
686 }
687 360 avio_skip(s->pb, len);
688 }
689
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
46 if (s->debug & FF_FDEBUG_TS)
690 av_log(s, AV_LOG_DEBUG, "pos=0x%"PRIx64" dts=0x%"PRIx64" %0.3f\n",
691 pos, dts, dts / 90000.0);
692 46 *ppos = pos;
693 46 return dts;
694 }
695
696 const FFInputFormat ff_mpegps_demuxer = {
697 .p.name = "mpeg",
698 .p.long_name = NULL_IF_CONFIG_SMALL("MPEG-PS (MPEG-2 Program Stream)"),
699 .p.flags = AVFMT_SHOW_IDS | AVFMT_TS_DISCONT,
700 .priv_data_size = sizeof(MpegDemuxContext),
701 .read_probe = mpegps_probe,
702 .read_header = mpegps_read_header,
703 .read_packet = mpegps_read_packet,
704 .read_timestamp = mpegps_read_dts,
705 };
706
707 #if CONFIG_VOBSUB_DEMUXER
708
709 #include "subtitles.h"
710 #include "libavutil/avassert.h"
711 #include "libavutil/bprint.h"
712 #include "libavutil/opt.h"
713
714 #define REF_STRING "# VobSub index file,"
715 #define MAX_LINE_SIZE 2048
716
717 typedef struct VobSubDemuxContext {
718 const AVClass *class;
719 AVFormatContext *sub_ctx;
720 FFDemuxSubtitlesQueue q[32];
721 char *sub_name;
722 } VobSubDemuxContext;
723
724 7128 static int vobsub_probe(const AVProbeData *p)
725 {
726
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 7126 times.
7128 if (!strncmp(p->buf, REF_STRING, sizeof(REF_STRING) - 1))
727 2 return AVPROBE_SCORE_MAX;
728 7126 return 0;
729 }
730
731 3 static int vobsub_read_close(AVFormatContext *s)
732 {
733 3 VobSubDemuxContext *vobsub = s->priv_data;
734 int i;
735
736
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 for (i = 0; i < s->nb_streams; i++)
737 3 ff_subtitles_queue_clean(&vobsub->q[i]);
738 3 avformat_close_input(&vobsub->sub_ctx);
739 3 return 0;
740 }
741
742 3 static int vobsub_read_header(AVFormatContext *s)
743 {
744 3 int i, ret = 0, header_parsed = 0, langidx = 0;
745 3 VobSubDemuxContext *vobsub = s->priv_data;
746 const AVInputFormat *iformat;
747 size_t fname_len;
748 AVBPrint header;
749 3 int64_t delay = 0;
750 3 AVStream *st = NULL;
751 3 int stream_id = -1;
752 3 char id[64] = {0};
753 3 char alt[MAX_LINE_SIZE] = {0};
754
755
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (!vobsub->sub_name) {
756 char *ext;
757 3 vobsub->sub_name = av_strdup(s->url);
758
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!vobsub->sub_name) {
759 return AVERROR(ENOMEM);
760 }
761
762 3 fname_len = strlen(vobsub->sub_name);
763 3 ext = vobsub->sub_name - 3 + fname_len;
764
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
3 if (fname_len < 4 || *(ext - 1) != '.') {
765 av_log(s, AV_LOG_ERROR, "The input index filename is too short "
766 "to guess the associated .SUB file\n");
767 return AVERROR_INVALIDDATA;
768 }
769
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 memcpy(ext, !strncmp(ext, "IDX", 3) ? "SUB" : "sub", 3);
770 3 av_log(s, AV_LOG_VERBOSE, "IDX/SUB: %s -> %s\n", s->url, vobsub->sub_name);
771 }
772
773
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if (!(iformat = av_find_input_format("mpeg"))) {
774 return AVERROR_DEMUXER_NOT_FOUND;
775 }
776
777 3 vobsub->sub_ctx = avformat_alloc_context();
778
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!vobsub->sub_ctx) {
779 return AVERROR(ENOMEM);
780 }
781
782
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if ((ret = ff_copy_whiteblacklists(vobsub->sub_ctx, s)) < 0)
783 return ret;
784
785 3 ret = avformat_open_input(&vobsub->sub_ctx, vobsub->sub_name, iformat, NULL);
786
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (ret < 0) {
787 av_log(s, AV_LOG_ERROR, "Unable to open %s as MPEG subtitles\n", vobsub->sub_name);
788 return ret;
789 }
790
791 3 av_bprint_init(&header, 0, INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE);
792
793
1/2
✓ Branch 1 taken 189 times.
✗ Branch 2 not taken.
189 while (!avio_feof(s->pb)) {
794 char line[MAX_LINE_SIZE];
795 189 int len = ff_get_line(s->pb, line, sizeof(line));
796
797
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 186 times.
189 if (!len)
798 3 break;
799
800 186 line[strcspn(line, "\r\n")] = 0;
801
802
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 183 times.
186 if (!strncmp(line, "id:", 3)) {
803
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (sscanf(line, "id: %63[^,], index: %u", id, &stream_id) != 2) {
804 av_log(s, AV_LOG_WARNING, "Unable to parse index line '%s', "
805 "assuming 'id: und, index: 0'\n", line);
806 strcpy(id, "und");
807 stream_id = 0;
808 }
809
810
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (stream_id >= FF_ARRAY_ELEMS(vobsub->q)) {
811 av_log(s, AV_LOG_ERROR, "Maximum number of subtitles streams reached\n");
812 ret = AVERROR(EINVAL);
813 goto end;
814 }
815
816 3 header_parsed = 1;
817 3 alt[0] = '\0';
818 /* We do not create the stream immediately to avoid adding empty
819 * streams. See the following timestamp entry. */
820
821 3 av_log(s, AV_LOG_DEBUG, "IDX stream[%d] id=%s\n", stream_id, id);
822
823
2/2
✓ Branch 0 taken 141 times.
✓ Branch 1 taken 42 times.
183 } else if (!strncmp(line, "timestamp:", 10)) {
824 AVPacket *sub;
825 int hh, mm, ss, ms;
826 int64_t pos, timestamp;
827 141 const char *p = line + 10;
828
829
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 141 times.
141 if (stream_id == -1) {
830 av_log(s, AV_LOG_ERROR, "Timestamp declared before any stream\n");
831 ret = AVERROR_INVALIDDATA;
832 goto end;
833 }
834
835
3/4
✓ Branch 0 taken 138 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 138 times.
141 if (!st || st->id != stream_id) {
836 3 st = avformat_new_stream(s, NULL);
837
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!st) {
838 ret = AVERROR(ENOMEM);
839 goto end;
840 }
841 3 st->id = stream_id;
842 3 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
843 3 st->codecpar->codec_id = AV_CODEC_ID_DVD_SUBTITLE;
844 3 avpriv_set_pts_info(st, 64, 1, 1000);
845 3 av_dict_set(&st->metadata, "language", id, 0);
846
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (alt[0])
847 av_dict_set(&st->metadata, "title", alt, 0);
848 }
849
850
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 141 times.
141 if (sscanf(p, "%02d:%02d:%02d:%03d, filepos: %"SCNx64,
851 &hh, &mm, &ss, &ms, &pos) != 5) {
852 av_log(s, AV_LOG_ERROR, "Unable to parse timestamp line '%s', "
853 "abort parsing\n", line);
854 ret = AVERROR_INVALIDDATA;
855 goto end;
856 }
857 141 timestamp = (hh*3600LL + mm*60LL + ss) * 1000LL + ms + delay;
858 141 timestamp = av_rescale_q(timestamp, av_make_q(1, 1000), st->time_base);
859
860 141 sub = ff_subtitles_queue_insert(&vobsub->q[s->nb_streams - 1], "", 0, 0);
861
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 141 times.
141 if (!sub) {
862 ret = AVERROR(ENOMEM);
863 goto end;
864 }
865 141 sub->pos = pos;
866 141 sub->pts = timestamp;
867 141 sub->stream_index = s->nb_streams - 1;
868
869
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
42 } else if (!strncmp(line, "alt:", 4)) {
870 const char *p = line + 4;
871
872 while (*p == ' ')
873 p++;
874 av_log(s, AV_LOG_DEBUG, "IDX stream[%d] name=%s\n", stream_id, p);
875 av_strlcpy(alt, p, sizeof(alt));
876 header_parsed = 1;
877
878
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
42 } else if (!strncmp(line, "delay:", 6)) {
879 int sign = 1, hh = 0, mm = 0, ss = 0, ms = 0;
880 const char *p = line + 6;
881
882 while (*p == ' ')
883 p++;
884 if (*p == '-' || *p == '+') {
885 sign = *p == '-' ? -1 : 1;
886 p++;
887 }
888 sscanf(p, "%d:%d:%d:%d", &hh, &mm, &ss, &ms);
889 delay = ((hh*3600LL + mm*60LL + ss) * 1000LL + ms) * sign;
890
891
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 39 times.
42 } else if (!strncmp(line, "langidx:", 8)) {
892 3 const char *p = line + 8;
893
894
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (sscanf(p, "%d", &langidx) != 1)
895 av_log(s, AV_LOG_ERROR, "Invalid langidx specified\n");
896
897
1/2
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
39 } else if (!header_parsed) {
898
4/4
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 24 times.
39 if (line[0] && line[0] != '#')
899 9 av_bprintf(&header, "%s\n", line);
900 }
901 }
902
903
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (langidx < s->nb_streams)
904 3 s->streams[langidx]->disposition |= AV_DISPOSITION_DEFAULT;
905
906
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 for (i = 0; i < s->nb_streams; i++) {
907 3 vobsub->q[i].sort = SUB_SORT_POS_TS;
908 3 vobsub->q[i].keep_duplicates = 1;
909 3 ff_subtitles_queue_finalize(s, &vobsub->q[i]);
910 }
911
912
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if (!av_bprint_is_complete(&header)) {
913 ret = AVERROR(ENOMEM);
914 goto end;
915 }
916
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 for (i = 0; i < s->nb_streams; i++) {
917 3 AVCodecParameters *par = s->streams[i]->codecpar;
918 3 ret = ff_alloc_extradata(par, header.len);
919
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (ret < 0) {
920 goto end;
921 }
922 3 memcpy(par->extradata, header.str, header.len);
923 }
924 3 end:
925 3 av_bprint_finalize(&header, NULL);
926 3 return ret;
927 }
928
929 141 static int vobsub_read_packet(AVFormatContext *s, AVPacket *pkt)
930 {
931 141 VobSubDemuxContext *vobsub = s->priv_data;
932 FFDemuxSubtitlesQueue *q;
933 141 AVIOContext *pb = vobsub->sub_ctx->pb;
934 141 int ret, psize, total_read = 0, i;
935
936 141 int64_t min_ts = INT64_MAX;
937 141 int sid = 0;
938
2/2
✓ Branch 0 taken 141 times.
✓ Branch 1 taken 141 times.
282 for (i = 0; i < s->nb_streams; i++) {
939 141 FFDemuxSubtitlesQueue *tmpq = &vobsub->q[i];
940 int64_t ts;
941
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 141 times.
141 av_assert0(tmpq->nb_subs);
942
943
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 141 times.
141 if (tmpq->current_sub_idx >= tmpq->nb_subs)
944 continue;
945
946 141 ts = tmpq->subs[tmpq->current_sub_idx]->pts;
947
1/2
✓ Branch 0 taken 141 times.
✗ Branch 1 not taken.
141 if (ts < min_ts) {
948 141 min_ts = ts;
949 141 sid = i;
950 }
951 }
952 141 q = &vobsub->q[sid];
953 /* The returned packet will have size zero,
954 * so that it can be directly used with av_grow_packet. */
955 141 ret = ff_subtitles_queue_read_packet(q, pkt);
956
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 141 times.
141 if (ret < 0)
957 return ret;
958
959 /* compute maximum packet size using the next packet position. This is
960 * useful when the len in the header is non-sense */
961
2/2
✓ Branch 0 taken 138 times.
✓ Branch 1 taken 3 times.
141 if (q->current_sub_idx < q->nb_subs) {
962 138 psize = q->subs[q->current_sub_idx]->pos - pkt->pos;
963 } else {
964 3 int64_t fsize = avio_size(pb);
965
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 psize = fsize < 0 ? 0xffff : fsize - pkt->pos;
966 }
967
968 141 avio_seek(pb, pkt->pos, SEEK_SET);
969
970 do {
971 int n, to_read, startcode;
972 int64_t pts, dts;
973 393 int64_t old_pos = avio_tell(pb), new_pos;
974 int pkt_size;
975
976 393 ret = mpegps_read_pes_header(vobsub->sub_ctx, NULL, &startcode, &pts, &dts);
977
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 387 times.
393 if (ret < 0) {
978
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (pkt->size) // raise packet even if incomplete
979 129 break;
980 3 return ret;
981 }
982 387 to_read = ret & 0xffff;
983 387 new_pos = avio_tell(pb);
984 387 pkt_size = ret + (new_pos - old_pos);
985
986 /* this prevents reads above the current packet */
987
2/2
✓ Branch 0 taken 126 times.
✓ Branch 1 taken 261 times.
387 if (total_read + pkt_size > psize)
988 126 break;
989 261 total_read += pkt_size;
990
991 /* the current chunk doesn't match the stream index (unlikely) */
992
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 261 times.
261 if ((startcode & 0x1f) != s->streams[pkt->stream_index]->id)
993 break;
994
995 261 ret = av_grow_packet(pkt, to_read);
996
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 261 times.
261 if (ret < 0)
997 return ret;
998
999 261 n = avio_read(pb, pkt->data + (pkt->size - to_read), to_read);
1000
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 261 times.
261 if (n < to_read)
1001 pkt->size -= to_read - n;
1002
2/2
✓ Branch 0 taken 252 times.
✓ Branch 1 taken 9 times.
261 } while (total_read < psize);
1003
1004 138 return 0;
1005 }
1006
1007 1 static int vobsub_read_seek(AVFormatContext *s, int stream_index,
1008 int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
1009 {
1010 1 VobSubDemuxContext *vobsub = s->priv_data;
1011
1012 /* Rescale requested timestamps based on the first stream (timebase is the
1013 * same for all subtitles stream within a .idx/.sub). Rescaling is done just
1014 * like in avformat_seek_file(). */
1015
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 if (stream_index == -1 && s->nb_streams != 1) {
1016 int i, ret = 0;
1017 AVRational time_base = s->streams[0]->time_base;
1018 ts = av_rescale_q(ts, AV_TIME_BASE_Q, time_base);
1019 min_ts = av_rescale_rnd(min_ts, time_base.den,
1020 time_base.num * (int64_t)AV_TIME_BASE,
1021 AV_ROUND_UP | AV_ROUND_PASS_MINMAX);
1022 max_ts = av_rescale_rnd(max_ts, time_base.den,
1023 time_base.num * (int64_t)AV_TIME_BASE,
1024 AV_ROUND_DOWN | AV_ROUND_PASS_MINMAX);
1025 for (i = 0; i < s->nb_streams; i++) {
1026 int r = ff_subtitles_queue_seek(&vobsub->q[i], s, stream_index,
1027 min_ts, ts, max_ts, flags);
1028 if (r < 0)
1029 ret = r;
1030 }
1031 return ret;
1032 }
1033
1034
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (stream_index == -1) // only 1 stream
1035 stream_index = 0;
1036 1 return ff_subtitles_queue_seek(&vobsub->q[stream_index], s, stream_index,
1037 min_ts, ts, max_ts, flags);
1038 }
1039
1040 static const AVOption options[] = {
1041 { "sub_name", "URI for .sub file", offsetof(VobSubDemuxContext, sub_name), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, AV_OPT_FLAG_DECODING_PARAM },
1042 { NULL }
1043 };
1044
1045 static const AVClass vobsub_demuxer_class = {
1046 .class_name = "vobsub",
1047 .item_name = av_default_item_name,
1048 .option = options,
1049 .version = LIBAVUTIL_VERSION_INT,
1050 };
1051
1052 const FFInputFormat ff_vobsub_demuxer = {
1053 .p.name = "vobsub",
1054 .p.long_name = NULL_IF_CONFIG_SMALL("VobSub subtitle format"),
1055 .p.flags = AVFMT_SHOW_IDS,
1056 .p.extensions = "idx",
1057 .p.priv_class = &vobsub_demuxer_class,
1058 .priv_data_size = sizeof(VobSubDemuxContext),
1059 .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
1060 .read_probe = vobsub_probe,
1061 .read_header = vobsub_read_header,
1062 .read_packet = vobsub_read_packet,
1063 .read_seek2 = vobsub_read_seek,
1064 .read_close = vobsub_read_close,
1065 };
1066 #endif
1067