LCOV - code coverage report
Current view: top level - libavformat - mpeg.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 440 619 71.1 %
Date: 2018-05-20 11:54:08 Functions: 14 15 93.3 %

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

Generated by: LCOV version 1.13