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
30
31 /*********************************************/
32 /* demux code */
33
34 #define MAX_SYNC_SIZE 100000
35
36 static int check_pes(
const uint8_t *p,
const uint8_t *end)
37 {
38 int pes1;
39 int pes2 = (p[3] & 0xC0) == 0x80 &&
40 (p[4] & 0xC0) != 0x40 &&
41 ((p[4] & 0xC0) == 0x00 ||
42 (p[4] & 0xC0) >> 2 == (p[6] & 0xF0));
43
44 for (p += 3; p < end && *p == 0xFF; p++) ;
45 if ((*p & 0xC0) == 0x40)
46 p += 2;
47
48 if ((*p & 0xF0) == 0x20)
49 pes1 = p[0] & p[2] & p[4] & 1;
50 else if ((*p & 0xF0) == 0x30)
51 pes1 = p[0] & p[2] & p[4] & p[5] & p[7] & p[9] & 1;
52 else
53 pes1 = *p == 0x0F;
54
55 return pes1 || pes2;
56 }
57
59 {
60 return (buf[1] & 0xC0) == 0x40 || (buf[1] & 0xF0) == 0x20;
61 }
62
64 {
67 int sys = 0, pspack = 0, priv1 = 0, vid = 0;
68 int audio = 0, invalid = 0, score = 0;
69 int endpes = 0;
70
73 if ((
code & 0xffffff00) == 0x100) {
77
78 if (
len > INT_MAX -
i)
79 break;
80
82 sys++;
84 pspack++;
87 vid++;
88 }
89 // skip pes payload to avoid start code emulation for private
90 // and audio streams
93 else if (
code == 0x1fd && pes) vid++;
//VC1
94
98 }
99 }
100
101 if (vid + audio > invalid + 1) /* invalid VDR files nd short PES streams */
103
104 // av_log(NULL, AV_LOG_ERROR, "vid:%d aud:%d sys:%d pspack:%d invalid:%d size:%d \n",
105 // vid, audio, sys, pspack, invalid, p->buf_size);
106
107 if (sys > invalid && sys * 9 <= pspack * 10)
110 if (pspack > invalid && (priv1 + vid + audio) * 10 >= pspack * 9)
113 if ((!!vid ^ !!audio) && (audio > 4 || vid > 1) && !sys &&
114 !pspack && p->
buf_size > 2048 && vid + audio > invalid)
/* PES stream */
117
118 // 02-Penguin.flac has sys:0 priv1:0 pspack:0 vid:0 audio:1
119 // mp3_misidentified_2.mp3 has sys:0 priv1:0 pspack:0 vid:0 audio:6
120 // Have\ Yourself\ a\ Merry\ Little\ Christmas.mp3 0 0 0 5 0 1 len:21618
121 return score;
122 }
123
132
134 {
138
141
143 if (!memcmp(
"IMKH",
buffer, 4)) {
145 }
else if (!memcmp(
"Sofdec",
buffer, 6)) {
147 } else
149
150 /* no need to do more */
151 return 0;
152 }
153
155 {
156 uint8_t buf[5];
158
163
165 }
166
169 {
170 unsigned int state, v;
172
173 state = *header_state;
174 n = *size_ptr;
175 while (n > 0) {
177 break;
179 n--;
180 if (
state == 0x000001) {
183 goto found;
184 }
186 }
188
189 found:
190 *header_state =
state;
191 *size_ptr = n;
193 }
194
195 /**
196 * Extract stream types from a program stream map
197 * According to ISO/IEC 13818-1 ('MPEG-2 Systems') table 2-35
198 *
199 * @return number of bytes occupied by PSM in the bitstream
200 */
202 {
203 int psm_length, ps_info_length, es_map_length;
204
209
210 /* skip program_stream_info */
213 /* Ignore es_map_length, trust psm_length */
214 es_map_length = psm_length - ps_info_length - 10;
215
216 /* at least one es available? */
217 while (es_map_length >= 4) {
219 unsigned char es_id =
avio_r8(pb);
221
222 /* remember mapping from stream id to stream type */
224 /* skip program_stream_info */
226 es_map_length -= 4 + es_info_length;
227 }
229 return 2 + psm_length;
230 }
231
232 /* read the next PES header. Return its position in ppos
233 * (if not NULL), and its start code, pts and dts.
234 */
236 int64_t *ppos,
int *pstart_code,
238 {
241 int pes_ext, ext2_len, id_ext,
skip;
244
245 error_redo:
247 redo:
248 /* next start code (should be immediately after) */
253 if (startcode < 0) {
256 // FIXME we should remember header_state
258 }
259
261 goto redo;
263 goto redo;
266 goto redo;
267 }
270 /* Need to detect whether this from a DVD or a 'Sofdec' stream */
272 int bytesread = 0;
274
275 if (ps2buf) {
277
278 if (bytesread !=
len) {
280 } else {
281 uint8_t *p = 0;
283 p = memchr(ps2buf,
'S',
len - 5);
284
285 if (p)
286 m->
sofdec = !memcmp(p+1,
"ofdec", 5);
287
289
291 if (
len == 980 && ps2buf[0] == 0) {
292 /* PCI structure? */
293 uint32_t startpts =
AV_RB32(ps2buf + 0x0d);
294 uint32_t endpts =
AV_RB32(ps2buf + 0x11);
295 uint8_t hours = ((ps2buf[0x19] >> 4) * 10) + (ps2buf[0x19] & 0x0f);
296 uint8_t mins = ((ps2buf[0x1a] >> 4) * 10) + (ps2buf[0x1a] & 0x0f);
297 uint8_t secs = ((ps2buf[0x1b] >> 4) * 10) + (ps2buf[0x1b] & 0x0f);
298
299 m->
dvd = (hours <= 23 &&
300 mins <= 59 &&
301 secs <= 59 &&
302 (ps2buf[0x19] & 0x0f) < 10 &&
303 (ps2buf[0x1a] & 0x0f) < 10 &&
304 (ps2buf[0x1b] & 0x0f) < 10 &&
305 endpts >= startpts);
306 }
else if (
len == 1018 && ps2buf[0] == 1) {
307 /* DSI structure? */
308 uint8_t hours = ((ps2buf[0x1d] >> 4) * 10) + (ps2buf[0x1d] & 0x0f);
309 uint8_t mins = ((ps2buf[0x1e] >> 4) * 10) + (ps2buf[0x1e] & 0x0f);
310 uint8_t secs = ((ps2buf[0x1f] >> 4) * 10) + (ps2buf[0x1f] & 0x0f);
311
312 m->
dvd = (hours <= 23 &&
313 mins <= 59 &&
314 secs <= 59 &&
315 (ps2buf[0x1d] & 0x0f) < 10 &&
316 (ps2buf[0x1e] & 0x0f) < 10 &&
317 (ps2buf[0x1f] & 0x0f) < 10);
318 }
319 }
320 }
321
323
324 /* If this isn't a DVD packet or no memory
325 * could be allocated, just ignore it.
326 * If we did, move back to the start of the
327 * packet (plus 'length' field) */
329 /* Skip back failed.
330 * This packet will be lost but that can't be helped
331 * if we can't skip back
332 */
333 goto redo;
334 }
335 } else {
336 /* No memory */
338 goto redo;
339 }
340 }
else if (!m->
dvd) {
343 goto redo;
344 }
345 }
348 goto redo;
349 }
350
351 /* find matching stream */
352 if (!((startcode >= 0x1c0 && startcode <= 0x1df) ||
353 (startcode >= 0x1e0 && startcode <= 0x1ef) ||
354 (startcode == 0x1bd) ||
356 (startcode == 0x1fd)))
357 goto redo;
358 if (ppos) {
360 }
365 {
366 /* stuffing */
367 for (;;) {
369 goto error_redo;
372 /* XXX: for MPEG-1, should test only bit 7 */
374 break;
375 }
376 if ((
c & 0xc0) == 0x40) {
377 /* buffer scale & size */
381 }
382 if ((
c & 0xe0) == 0x20) {
383 dts =
389 }
390 }
else if ((
c & 0xc0) == 0x80) {
391 /* mpeg 2 PES */
395 if (header_len >
len)
396 goto error_redo;
400 header_len -= 5;
403 header_len -= 5;
404 }
405 }
406 if (
flags & 0x3f && header_len == 0) {
409 }
410 if (
flags & 0x01) {
/* PES extension */
412 header_len--;
413 /* Skip PES private data, program packet sequence counter
414 * and P-STD buffer */
415 skip = (pes_ext >> 4) & 0xb;
417 if (pes_ext & 0x40 ||
skip > header_len) {
420 }
423
424 if (pes_ext & 0x01) { /* PES extension 2 */
426 header_len--;
427 if ((ext2_len & 0x7f) > 0) {
429 if ((id_ext & 0x80) == 0)
430 startcode = ((startcode & 0xff) << 8) | id_ext;
431 header_len--;
432 }
433 }
434 }
435 if (header_len < 0)
436 goto error_redo;
439 goto redo;
440 }
441
444
447
450 if (startcode == 0x0b) {
452 startcode = 0x80;
455 } else {
457 }
458 } else {
460 }
461 }
463 goto error_redo;
466 for (
i = 0;
i <
s->nb_streams;
i++) {
467 if (startcode ==
s->streams[
i]->id &&
472 }
473 }
474 }
475
476 *pstart_code = startcode;
478 *pdts = dts;
480 }
481
484 {
488 int len, startcode,
i, es_type,
ret;
489 int pcm_dvd = 0;
490 int request_probe= 0;
493 int64_t pts, dts, dummy_pos;
// dummy_pos is needed for the index building to work
494
495 redo:
499
500 if (startcode >= 0x80 && startcode <= 0xcf) {
503
505 /* audio: skip header */
508 if (startcode >= 0xb0 && startcode <= 0xbf) {
509 /* MLP/TrueHD audio has a 4-byte header */
512 } else if (startcode >= 0xa0 && startcode <= 0xaf) {
518 }
519 }
520 }
521
522 /* now find stream */
523 for (
i = 0;
i <
s->nb_streams;
i++) {
525 if (st->
id == startcode)
526 goto found;
527 }
528
558 } else if (es_type == 0x90) {
561 }
else if (m->
imkh_cctv && es_type == 0x91) {
564 } else if (startcode >= 0x1e0 && startcode <= 0x1ef) {
565 static const unsigned char avs_seqh[4] = { 0, 0, 1, 0xb0 };
566 unsigned char buf[8];
567
570 if (!memcmp(buf, avs_seqh, 4) && (buf[6] != 0 || buf[7] != 1))
572 else
573 request_probe= 1;
578 } else if (startcode >= 0x1c0 && startcode <= 0x1df) {
582 // Auto-detect AC-3
583 request_probe = 50;
584 }
else if (m->
imkh_cctv && startcode == 0x1c0 &&
len > 80) {
586 request_probe = 50;
587 } else {
590 request_probe = 25;
591 }
592 } else if (startcode >= 0x80 && startcode <= 0x87) {
595 } else if ((startcode >= 0x88 && startcode <= 0x8f) ||
596 (startcode >= 0x98 && startcode <= 0x9f)) {
597 /* 0x90 - 0x97 is reserved for SDDS in DVD specs */
600 } else if (startcode >= 0xa0 && startcode <= 0xaf) {
602 if (!pcm_dvd) {
604 } else {
606 }
607 } else if (startcode >= 0xb0 && startcode <= 0xbf) {
610 } else if (startcode >= 0xc0 && startcode <= 0xcf) {
611 /* Used for both AC-3 and E-AC-3 in EVOB files */
614 } else if (startcode >= 0x20 && startcode <= 0x3f) {
617 } else if (startcode >= 0xfd55 && startcode <= 0xfd5f) {
620 } else {
622 /* skip packet */
624 goto redo;
625 }
626 /* no stream found: add a new stream */
628 if (!st)
638 }
641
642 found:
645 if (startcode >= 0xa0 && startcode <= 0xaf) {
651 }
652 }
654
659
664
665 return (
ret < 0) ?
ret : 0;
666 }
667
670 {
673
677
678 for (;;) {
684 }
685 if (startcode ==
s->streams[stream_index]->id &&
687 break;
688 }
690 }
693 pos, dts, dts / 90000.0);
695 return dts;
696 }
697
707 };
708
709 #if CONFIG_VOBSUB_DEMUXER
710
715
716 #define REF_STRING "# VobSub index file,"
717 #define MAX_LINE_SIZE 2048
718
719 typedef struct VobSubDemuxContext {
723 char *sub_name;
724 } VobSubDemuxContext;
725
727 {
728 if (!strncmp(p->
buf, REF_STRING,
sizeof(REF_STRING) - 1))
730 return 0;
731 }
732
734 {
735 VobSubDemuxContext *vobsub =
s->priv_data;
737
738 for (
i = 0;
i <
s->nb_streams;
i++)
741 return 0;
742 }
743
745 {
746 int i,
ret = 0, header_parsed = 0, langidx = 0;
747 VobSubDemuxContext *vobsub =
s->priv_data;
749 size_t fname_len;
753 int stream_id = -1;
754 char id[64] = {0};
756
757 if (!vobsub->sub_name) {
758 char *ext;
760 if (!vobsub->sub_name) {
762 }
763
764 fname_len = strlen(vobsub->sub_name);
765 ext = vobsub->sub_name - 3 + fname_len;
766 if (fname_len < 4 || *(ext - 1) != '.') {
768 "to guess the associated .SUB file\n");
770 }
771 memcpy(ext, !strncmp(ext, "IDX", 3) ? "SUB" : "sub", 3);
773 }
774
777 }
778
780 if (!vobsub->sub_ctx) {
782 }
783
786
791 }
792
794
798
800 break;
801
803
804 if (!strncmp(
line,
"id:", 3)) {
805 if (sscanf(
line,
"id: %63[^,], index: %u",
id, &stream_id) != 2) {
807 "assuming 'id: und, index: 0'\n",
line);
808 strcpy(id, "und");
809 stream_id = 0;
810 }
811
815 goto end;
816 }
817
818 header_parsed = 1;
819 alt[0] = '0円';
820 /* We do not create the stream immediately to avoid adding empty
821 * streams. See the following timestamp entry. */
822
824
825 }
else if (!strncmp(
line,
"timestamp:", 10)) {
829 const char *p =
line + 10;
830
831 if (stream_id == -1) {
834 goto end;
835 }
836
837 if (!st || st->
id != stream_id) {
839 if (!st) {
841 goto end;
842 }
848 if (alt[0])
850 }
851
852 if (sscanf(p, "%02d:%02d:%02d:%03d, filepos: %"SCNx64,
853 &hh, &mm, &
ss, &ms, &
pos) != 5) {
855 "abort parsing\n",
line);
857 goto end;
858 }
859 timestamp = (hh*3600LL + mm*60LL +
ss) * 1000LL + ms + delay;
861
863 if (!sub) {
865 goto end;
866 }
868 sub->
pts = timestamp;
870
871 }
else if (!strncmp(
line,
"alt:", 4)) {
872 const char *p =
line + 4;
873
874 while (*p == ' ')
875 p++;
878 header_parsed = 1;
879
880 }
else if (!strncmp(
line,
"delay:", 6)) {
881 int sign = 1, hh = 0, mm = 0,
ss = 0, ms = 0;
882 const char *p =
line + 6;
883
884 while (*p == ' ')
885 p++;
886 if (*p == '-' || *p == '+') {
887 sign = *p == '-' ? -1 : 1;
888 p++;
889 }
890 sscanf(p,
"%d:%d:%d:%d", &hh, &mm, &
ss, &ms);
891 delay = ((hh*3600LL + mm*60LL +
ss) * 1000LL + ms) * sign;
892
893 }
else if (!strncmp(
line,
"langidx:", 8)) {
894 const char *p =
line + 8;
895
896 if (sscanf(p, "%d", &langidx) != 1)
898
899 } else if (!header_parsed) {
902 }
903 }
904
907
908 for (
i = 0;
i <
s->nb_streams;
i++) {
910 vobsub->q[
i].keep_duplicates = 1;
912 }
913
916 goto end;
917 }
918 for (
i = 0;
i <
s->nb_streams;
i++) {
922 goto end;
923 }
925 }
926 end:
929 }
930
932 {
933 VobSubDemuxContext *vobsub =
s->priv_data;
936 int ret, psize, total_read = 0,
i;
937
939 int sid = 0;
940 for (
i = 0;
i <
s->nb_streams;
i++) {
944
946 continue;
947
949 if (ts < min_ts) {
950 min_ts = ts;
952 }
953 }
954 q = &vobsub->q[sid];
955 /* The returned packet will have size zero,
956 * so that it can be directly used with av_grow_packet. */
960
961 /* compute maximum packet size using the next packet position. This is
962 * useful when the len in the header is non-sense */
965 } else {
968 }
969
971
972 do {
973 int n, to_read, startcode;
976 int pkt_size;
977
980 if (
pkt->
size)
// raise packet even if incomplete
981 break;
983 }
984 to_read =
ret & 0xffff;
986 pkt_size =
ret + (new_pos - old_pos);
987
988 /* this prevents reads above the current packet */
989 if (total_read + pkt_size > psize)
990 break;
991 total_read += pkt_size;
992
993 /* the current chunk doesn't match the stream index (unlikely) */
995 break;
996
1000
1002 if (n < to_read)
1004 } while (total_read < psize);
1005
1006 return 0;
1007 }
1008
1011 {
1012 VobSubDemuxContext *vobsub =
s->priv_data;
1013
1014 /* Rescale requested timestamps based on the first stream (timebase is the
1015 * same for all subtitles stream within a .idx/.sub). Rescaling is done just
1016 * like in avformat_seek_file(). */
1017 if (stream_index == -1 &&
s->nb_streams != 1) {
1027 for (
i = 0;
i <
s->nb_streams;
i++) {
1029 min_ts, ts, max_ts,
flags);
1032 }
1034 }
1035
1036 if (stream_index == -1) // only 1 stream
1037 stream_index = 0;
1039 min_ts, ts, max_ts,
flags);
1040 }
1041
1045 };
1046
1047 static const AVClass vobsub_demuxer_class = {
1052 };
1053
1058 .p.extensions = "idx",
1059 .p.priv_class = &vobsub_demuxer_class,
1060 .priv_data_size = sizeof(VobSubDemuxContext),
1065 .read_seek2 = vobsub_read_seek,
1067 };
1068 #endif