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