Merge commit '86ba2327e1cf35c6f77d5fb516a1a7a8dce0b98a'
authorMichael Niedermayer <michaelni@gmx.at>
Tue, 18 Mar 2014 12:16:56 +0000 (13:16 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Tue, 18 Mar 2014 12:19:24 +0000 (13:19 +0100)
* commit '86ba2327e1cf35c6f77d5fb516a1a7a8dce0b98a':
  mpegts: K&R formatting cosmetics

Conflicts:
libavformat/mpegts.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavformat/mpegts.c

@@@ -59,7 -58,8 +59,8 @@@ enum MpegTSFilterType 
  
  typedef struct MpegTSFilter MpegTSFilter;
  
- typedef int PESCallback(MpegTSFilter *f, const uint8_t *buf, int len, int is_start, int64_t pos, int64_t cur_pcr);
+ typedef int PESCallback (MpegTSFilter *f, const uint8_t *buf, int len,
 -                         int is_start, int64_t pos);
++                         int is_start, int64_t pos, int64_t cur_pcr);
  
  typedef struct MpegTSPESFilter {
      PESCallback *pes_cb;
@@@ -93,45 -93,37 +94,45 @@@ struct MpegTSFilter 
  
  #define MAX_PIDS_PER_PROGRAM 64
  struct Program {
-     unsigned int id; //program id/service id
+     unsigned int id; // program id/service id
      unsigned int nb_pids;
      unsigned int pids[MAX_PIDS_PER_PROGRAM];
 +
 +    /** have we found pmt for this program */
 +    int pmt_found;
  };
  
  struct MpegTSContext {
      const AVClass *class;
      /* user data */
      AVFormatContext *stream;
-     /** raw packet size, including FEC if present            */
+     /** raw packet size, including FEC if present */
      int raw_packet_size;
  
 -    int pos47;
 -    /** position corresponding to pos47, or 0 if pos47 invalid */
 -    int64_t pos;
 +    int size_stat[3];
 +    int size_stat_count;
 +#define SIZE_STAT_THRESHOLD 10
 +
 +    int64_t pos47_full;
  
-     /** if true, all pids are analyzed to find streams       */
+     /** if true, all pids are analyzed to find streams */
      int auto_guess;
  
-     /** compute exact PCR for each transport stream packet   */
+     /** compute exact PCR for each transport stream packet */
      int mpeg2ts_compute_pcr;
  
-     int64_t cur_pcr;    /**< used to estimate the exact PCR  */
-     int pcr_incr;       /**< used to estimate the exact PCR  */
 +    /** fix dvb teletext pts                                 */
 +    int fix_teletext_pts;
 +
+     int64_t cur_pcr;    /**< used to estimate the exact PCR */
+     int pcr_incr;       /**< used to estimate the exact PCR */
  
      /* data needed to handle file based ts */
-     /** stop parsing loop                                    */
+     /** stop parsing loop */
      int stop_parse;
-     /** packet containing Audio/Video data                   */
+     /** packet containing Audio/Video data */
      AVPacket *pkt;
-     /** to detect seek                                       */
+     /** to detect seek */
      int64_t last_pos;
  
      /******************************************/
      unsigned int nb_prg;
      struct Program *prg;
  
 +    int8_t crc_validity[NB_PID_MAX];
      /** filters for various streams specified by PMT + for the PAT and PMT */
      MpegTSFilter *pids[NB_PID_MAX];
 +    int current_pid;
  };
  
 -static const AVOption options[] = {
 +static const AVOption mpegtsraw_options[] = {
-     {"compute_pcr", "Compute exact PCR for each transport stream packet.", offsetof(MpegTSContext, mpeg2ts_compute_pcr), AV_OPT_TYPE_INT,
-      {.i64 = 0}, 0, 1, AV_OPT_FLAG_DECODING_PARAM },
-     {"ts_packetsize", "Output option carrying the raw packet size.", offsetof(MpegTSContext, raw_packet_size), AV_OPT_TYPE_INT,
-      {.i64 = 0}, 0, 0, AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_EXPORT | AV_OPT_FLAG_READONLY },
+     { "compute_pcr",   "Compute exact PCR for each transport stream packet.",
+           offsetof(MpegTSContext, mpeg2ts_compute_pcr), AV_OPT_TYPE_INT,
+           { .i64 = 0 }, 0, 1,  AV_OPT_FLAG_DECODING_PARAM },
+     { "ts_packetsize", "Output option carrying the raw packet size.",
+       offsetof(MpegTSContext, raw_packet_size), AV_OPT_TYPE_INT,
+       { .i64 = 0 }, 0, 0,
+       AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_EXPORT | AV_OPT_FLAG_READONLY },
      { NULL },
  };
  
@@@ -218,41 -194,13 +221,41 @@@ typedef struct PESContext 
  
  extern AVInputFormat ff_mpegts_demuxer;
  
-     for(i=0; i<ts->nb_prg; i++) {
-         if(ts->prg[i].id == programid) {
 +static struct Program * get_program(MpegTSContext *ts, unsigned int programid)
 +{
 +    int i;
-     for(i=0; i<ts->stream->nb_programs; i++)
-         if(ts->stream->programs[i]->id == programid){
++    for (i = 0; i < ts->nb_prg; i++) {
++        if (ts->prg[i].id == programid) {
 +            return &ts->prg[i];
 +        }
 +    }
 +    return NULL;
 +}
 +
 +static void clear_avprogram(MpegTSContext *ts, unsigned int programid)
 +{
 +    AVProgram *prg = NULL;
 +    int i;
++    for (i = 0; i < ts->stream->nb_programs; i++)
++        if (ts->stream->programs[i]->id == programid) {
 +            prg = ts->stream->programs[i];
 +            break;
 +        }
 +    if (!prg)
 +        return;
 +    prg->nb_stream_indexes = 0;
 +}
 +
  static void clear_program(MpegTSContext *ts, unsigned int programid)
  {
      int i;
  
-     for(i=0; i<ts->nb_prg; i++)
-         if(ts->prg[i].id == programid) {
 +    clear_avprogram(ts, programid);
 -        if (ts->prg[i].id == programid)
+     for (i = 0; i < ts->nb_prg; i++)
++        if (ts->prg[i].id == programid) {
              ts->prg[i].nb_pids = 0;
 +            ts->prg[i].pmt_found = 0;
 +        }
  }
  
  static void clear_programs(MpegTSContext *ts)
@@@ -275,37 -222,25 +278,38 @@@ static void add_pat_entry(MpegTSContex
      ts->nb_prg++;
  }
  
- static void add_pid_to_pmt(MpegTSContext *ts, unsigned int programid, unsigned int pid)
+ static void add_pid_to_pmt(MpegTSContext *ts, unsigned int programid,
+                            unsigned int pid)
  {
 -    int i;
 -    struct Program *p = NULL;
 -    for (i = 0; i < ts->nb_prg; i++) {
 -        if (ts->prg[i].id == programid) {
 -            p = &ts->prg[i];
 -            break;
 -        }
 -    }
 +    struct Program *p = get_program(ts, programid);
-     if(!p)
+     if (!p)
          return;
  
-     if(p->nb_pids >= MAX_PIDS_PER_PROGRAM)
+     if (p->nb_pids >= MAX_PIDS_PER_PROGRAM)
          return;
      p->pids[p->nb_pids++] = pid;
  }
  
-     if(!p)
 +static void set_pmt_found(MpegTSContext *ts, unsigned int programid)
 +{
 +    struct Program *p = get_program(ts, programid);
-     for(i=0; i<s->nb_programs; i++) {
-         if(s->programs[i]->id == programid) {
++    if (!p)
 +        return;
 +
 +    p->pmt_found = 1;
 +}
 +
 +static void set_pcr_pid(AVFormatContext *s, unsigned int programid, unsigned int pid)
 +{
 +    int i;
++    for (i = 0; i < s->nb_programs; i++) {
++        if (s->programs[i]->id == programid) {
 +            s->programs[i]->pcr_pid = pid;
 +            break;
 +        }
 +    }
 +}
 +
  /**
   * @brief discard_pid() decides if the pid is to be discarded according
   *                      to caller's programs selection
@@@ -384,20 -316,12 +386,21 @@@ static void write_section_data(AVFormat
          tss->section_h_size = len;
      }
  
-     if (tss->section_h_size != -1 && tss->section_index >= tss->section_h_size) {
+     if (tss->section_h_size != -1 &&
+         tss->section_index >= tss->section_h_size) {
 +        int crc_valid = 1;
          tss->end_of_section_reached = 1;
 -        if (!tss->check_crc ||
 -            av_crc(av_crc_get_table(AV_CRC_32_IEEE), -1,
 -                   tss->section_buf, tss->section_h_size) == 0)
 +
-         if (tss->check_crc){
++        if (tss->check_crc) {
 +            crc_valid = !av_crc(av_crc_get_table(AV_CRC_32_IEEE), -1, tss->section_buf, tss->section_h_size);
-             if (crc_valid){
++            if (crc_valid) {
 +                ts->crc_validity[ tss1->pid ] = 100;
-             }else if(ts->crc_validity[ tss1->pid ] > -10){
++            }else if (ts->crc_validity[ tss1->pid ] > -10) {
 +                ts->crc_validity[ tss1->pid ]--;
 +            }else
 +                crc_valid = 2;
 +        }
 +        if (crc_valid)
              tss->section_cb(tss1, tss->section_buf, tss->section_h_size);
      }
  }
@@@ -478,22 -407,28 +486,24 @@@ static void mpegts_close_filter(MpegTSC
      ts->pids[pid] = NULL;
  }
  
- static int analyze(const uint8_t *buf, int size, int packet_size, int *index){
+ static int analyze(const uint8_t *buf, int size, int packet_size, int *index)
+ {
      int stat[TS_MAX_PACKET_SIZE];
      int i;
-     int best_score=0;
 -    int x = 0;
+     int best_score = 0;
  
-     memset(stat, 0, packet_size*sizeof(*stat));
 -    memset(stat, 0, packet_size * sizeof(int));
++    memset(stat, 0, packet_size * sizeof(*stat));
  
-     for(i=0; i<size-3; i++){
-         if(buf[i] == 0x47 && !(buf[i+1] & 0x80) && buf[i+3] != 0x47){
 -    for (x = i = 0; i < size - 3; i++) {
 -        if (buf[i] == 0x47 && !(buf[i + 1] & 0x80) && (buf[i + 3] & 0x30)) {
++    for (i = 0; i < size - 3; i++) {
++        if (buf[i] == 0x47 && !(buf[i + 1] & 0x80) && buf[i + 3] != 0x47) {
 +            int x = i % packet_size;
              stat[x]++;
-             if(stat[x] > best_score){
-                 best_score= stat[x];
-                 if(index) *index= x;
+             if (stat[x] > best_score) {
+                 best_score = stat[x];
+                 if (index)
+                     *index = x;
              }
          }
 -
 -        x++;
 -        if (x == packet_size)
 -            x = 0;
      }
  
      return best_score;
@@@ -615,33 -554,27 +629,33 @@@ typedef struct 
  static const StreamType ISO_types[] = {
      { 0x01, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_MPEG2VIDEO },
      { 0x02, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_MPEG2VIDEO },
-     { 0x03, AVMEDIA_TYPE_AUDIO,        AV_CODEC_ID_MP3 },
-     { 0x04, AVMEDIA_TYPE_AUDIO,        AV_CODEC_ID_MP3 },
-     { 0x0f, AVMEDIA_TYPE_AUDIO,        AV_CODEC_ID_AAC },
-     { 0x10, AVMEDIA_TYPE_VIDEO,      AV_CODEC_ID_MPEG4 },
+     { 0x03, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_MP3        },
+     { 0x04, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_MP3        },
+     { 0x0f, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AAC        },
+     { 0x10, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_MPEG4      },
 +    /* Makito encoder sets stream type 0x11 for AAC,
 +     * so auto-detect LOAS/LATM instead of hardcoding it. */
 +#if !CONFIG_LOAS_DEMUXER
-     { 0x11, AVMEDIA_TYPE_AUDIO,   AV_CODEC_ID_AAC_LATM }, /* LATM syntax */
+     { 0x11, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AAC_LATM   }, /* LATM syntax */
 +#endif
-     { 0x1b, AVMEDIA_TYPE_VIDEO,       AV_CODEC_ID_H264 },
-     { 0x24, AVMEDIA_TYPE_VIDEO,       AV_CODEC_ID_HEVC },
-     { 0x42, AVMEDIA_TYPE_VIDEO,       AV_CODEC_ID_CAVS },
-     { 0xd1, AVMEDIA_TYPE_VIDEO,      AV_CODEC_ID_DIRAC },
-     { 0xea, AVMEDIA_TYPE_VIDEO,        AV_CODEC_ID_VC1 },
+     { 0x1b, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_H264       },
+     { 0x24, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_HEVC       },
+     { 0x42, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_CAVS       },
+     { 0xd1, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_DIRAC      },
+     { 0xea, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_VC1        },
      { 0 },
  };
  
  static const StreamType HDMV_types[] = {
-     { 0x80, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_PCM_BLURAY },
-     { 0x81, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AC3 },
-     { 0x82, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS },
-     { 0x83, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_TRUEHD },
-     { 0x84, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_EAC3 },
-     { 0x85, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS }, /* DTS HD */
-     { 0x86, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS }, /* DTS HD MASTER*/
-     { 0xa1, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_EAC3 }, /* E-AC3 Secondary Audio */
-     { 0xa2, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS },  /* DTS Express Secondary Audio */
+     { 0x80, AVMEDIA_TYPE_AUDIO,    AV_CODEC_ID_PCM_BLURAY        },
+     { 0x81, AVMEDIA_TYPE_AUDIO,    AV_CODEC_ID_AC3               },
+     { 0x82, AVMEDIA_TYPE_AUDIO,    AV_CODEC_ID_DTS               },
+     { 0x83, AVMEDIA_TYPE_AUDIO,    AV_CODEC_ID_TRUEHD            },
+     { 0x84, AVMEDIA_TYPE_AUDIO,    AV_CODEC_ID_EAC3              },
+     { 0x85, AVMEDIA_TYPE_AUDIO,    AV_CODEC_ID_DTS               }, /* DTS HD */
+     { 0x86, AVMEDIA_TYPE_AUDIO,    AV_CODEC_ID_DTS               }, /* DTS HD MASTER*/
++    { 0xa1, AVMEDIA_TYPE_AUDIO,    AV_CODEC_ID_EAC3              }, /* E-AC3 Secondary Audio */
++    { 0xa2, AVMEDIA_TYPE_AUDIO,    AV_CODEC_ID_DTS               }, /* DTS Express Secondary Audio */
      { 0x90, AVMEDIA_TYPE_SUBTITLE, AV_CODEC_ID_HDMV_PGS_SUBTITLE },
      { 0 },
  };
@@@ -654,69 -587,48 +668,69 @@@ static const StreamType MISC_types[] = 
  };
  
  static const StreamType REGD_types[] = {
-     { MKTAG('d','r','a','c'), AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_DIRAC },
-     { MKTAG('A','C','-','3'), AVMEDIA_TYPE_AUDIO,   AV_CODEC_ID_AC3 },
-     { MKTAG('B','S','S','D'), AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_S302M },
-     { MKTAG('D','T','S','1'), AVMEDIA_TYPE_AUDIO,   AV_CODEC_ID_DTS },
-     { MKTAG('D','T','S','2'), AVMEDIA_TYPE_AUDIO,   AV_CODEC_ID_DTS },
-     { MKTAG('D','T','S','3'), AVMEDIA_TYPE_AUDIO,   AV_CODEC_ID_DTS },
-     { MKTAG('H','E','V','C'), AVMEDIA_TYPE_VIDEO,  AV_CODEC_ID_HEVC },
-     { MKTAG('K','L','V','A'), AVMEDIA_TYPE_DATA,    AV_CODEC_ID_SMPTE_KLV },
-     { MKTAG('V','C','-','1'), AVMEDIA_TYPE_VIDEO,   AV_CODEC_ID_VC1 },
+     { MKTAG('d', 'r', 'a', 'c'), AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_DIRAC },
+     { MKTAG('A', 'C', '-', '3'), AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AC3   },
+     { MKTAG('B', 'S', 'S', 'D'), AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_S302M },
+     { MKTAG('D', 'T', 'S', '1'), AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS   },
+     { MKTAG('D', 'T', 'S', '2'), AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS   },
+     { MKTAG('D', 'T', 'S', '3'), AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS   },
+     { MKTAG('H', 'E', 'V', 'C'), AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_HEVC  },
++    { MKTAG('K', 'L', 'V', 'A'), AVMEDIA_TYPE_DATA,  AV_CODEC_ID_SMPTE_KLV },
+     { MKTAG('V', 'C', '-', '1'), AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_VC1   },
      { 0 },
  };
  
 +static const StreamType METADATA_types[] = {
 +    { MKTAG('K','L','V','A'), AVMEDIA_TYPE_DATA, AV_CODEC_ID_SMPTE_KLV },
 +    { MKTAG('I','D','3',' '), AVMEDIA_TYPE_DATA, AV_CODEC_ID_TIMED_ID3 },
 +    { 0 },
 +};
 +
  /* descriptor present */
  static const StreamType DESC_types[] = {
-     { 0x6a, AVMEDIA_TYPE_AUDIO,             AV_CODEC_ID_AC3 }, /* AC-3 descriptor */
-     { 0x7a, AVMEDIA_TYPE_AUDIO,            AV_CODEC_ID_EAC3 }, /* E-AC-3 descriptor */
-     { 0x7b, AVMEDIA_TYPE_AUDIO,             AV_CODEC_ID_DTS },
+     { 0x6a, AVMEDIA_TYPE_AUDIO,    AV_CODEC_ID_AC3          }, /* AC-3 descriptor */
+     { 0x7a, AVMEDIA_TYPE_AUDIO,    AV_CODEC_ID_EAC3         }, /* E-AC-3 descriptor */
+     { 0x7b, AVMEDIA_TYPE_AUDIO,    AV_CODEC_ID_DTS          },
      { 0x56, AVMEDIA_TYPE_SUBTITLE, AV_CODEC_ID_DVB_TELETEXT },
      { 0x59, AVMEDIA_TYPE_SUBTITLE, AV_CODEC_ID_DVB_SUBTITLE }, /* subtitling descriptor */
      { 0 },
  };
  
  static void mpegts_find_stream_type(AVStream *st,
-                                     uint32_t stream_type, const StreamType *types)
+                                     uint32_t stream_type,
+                                     const StreamType *types)
  {
-     for (; types->stream_type; types++) {
 +    if (avcodec_is_open(st->codec)) {
 +        av_log(NULL, AV_LOG_DEBUG, "cannot set stream info, codec is open\n");
 +        return;
 +    }
 +
+     for (; types->stream_type; types++)
          if (stream_type == types->stream_type) {
              st->codec->codec_type = types->codec_type;
              st->codec->codec_id   = types->codec_id;
 +            st->request_probe     = 0;
              return;
          }
-     }
  }
  
  static int mpegts_set_stream_info(AVStream *st, PESContext *pes,
                                    uint32_t stream_type, uint32_t prog_reg_desc)
  {
-     int old_codec_type= st->codec->codec_type;
++    int old_codec_type = st->codec->codec_type;
 +    int old_codec_id  = st->codec->codec_id;
 +
 +    if (avcodec_is_open(st->codec)) {
 +        av_log(pes->stream, AV_LOG_DEBUG, "cannot set stream info, codec is open\n");
 +        return 0;
 +    }
 +
      avpriv_set_pts_info(st, 33, 1, 90000);
-     st->priv_data = pes;
+     st->priv_data         = pes;
      st->codec->codec_type = AVMEDIA_TYPE_DATA;
      st->codec->codec_id   = AV_CODEC_ID_NONE;
-     st->need_parsing = AVSTREAM_PARSE_FULL;
-     pes->st = st;
+     st->need_parsing      = AVSTREAM_PARSE_FULL;
+     pes->st          = st;
      pes->stream_type = stream_type;
  
      av_log(pes->stream, AV_LOG_DEBUG,
      }
      if (st->codec->codec_id == AV_CODEC_ID_NONE)
          mpegts_find_stream_type(st, pes->stream_type, MISC_types);
-     if (st->codec->codec_id == AV_CODEC_ID_NONE){
++    if (st->codec->codec_id == AV_CODEC_ID_NONE) {
 +        st->codec->codec_id  = old_codec_id;
-         st->codec->codec_type= old_codec_type;
++        st->codec->codec_type = old_codec_type;
 +    }
  
      return 0;
  }
@@@ -792,29 -700,22 +807,30 @@@ static void new_pes_packet(PESContext *
      pkt->flags = pes->flags;
  
      /* reset pts values */
-     pes->pts = AV_NOPTS_VALUE;
-     pes->dts = AV_NOPTS_VALUE;
-     pes->buffer = NULL;
+     pes->pts        = AV_NOPTS_VALUE;
+     pes->dts        = AV_NOPTS_VALUE;
+     pes->buffer     = NULL;
      pes->data_index = 0;
-     pes->flags = 0;
+     pes->flags      = 0;
  }
  
- static int read_sl_header(PESContext *pes, SLConfigDescr *sl, const uint8_t *buf, int buf_size)
 +static uint64_t get_ts64(GetBitContext *gb, int bits)
 +{
 +    if (get_bits_left(gb) < bits)
 +        return AV_NOPTS_VALUE;
 +    return get_bits64(gb, bits);
 +}
 +
+ static int read_sl_header(PESContext *pes, SLConfigDescr *sl,
+                           const uint8_t *buf, int buf_size)
  {
      GetBitContext gb;
      int au_start_flag = 0, au_end_flag = 0, ocr_flag = 0, idle_flag = 0;
      int padding_flag = 0, padding_bits = 0, inst_bitrate_flag = 0;
      int dts_flag = -1, cts_flag = -1;
      int64_t dts = AV_NOPTS_VALUE, cts = AV_NOPTS_VALUE;
-     init_get_bits(&gb, buf, buf_size*8);
 +
+     init_get_bits(&gb, buf, buf_size * 8);
  
      if (sl->use_au_start)
          au_start_flag = get_bits1(&gb);
  /* return non zero if a packet could be constructed */
  static int mpegts_push_data(MpegTSFilter *filter,
                              const uint8_t *buf, int buf_size, int is_start,
 -                            int64_t pos)
 +                            int64_t pos, int64_t pcr)
  {
-     PESContext *pes = filter->u.pes_filter.opaque;
+     PESContext *pes   = filter->u.pes_filter.opaque;
      MpegTSContext *ts = pes->ts;
      const uint8_t *p;
      int len, code;
  
-     if(!ts->pkt)
+     if (!ts->pkt)
          return 0;
  
 +    if (pcr != -1)
 +        pes->last_pcr = pcr;
 +
      if (is_start) {
          if (pes->state == MPEGTS_PAYLOAD && pes->data_index > 0) {
              new_pes_packet(pes, ts->pkt);
                          code != 0x1ff && code != 0x1f2 && /* program_stream_directory, DSMCC_stream */
                          code != 0x1f8) {                  /* ITU-T Rec. H.222.1 type E stream */
                          pes->state = MPEGTS_PESHEADER;
 -                        if (pes->st->codec->codec_id == AV_CODEC_ID_NONE) {
 +                        if (pes->st->codec->codec_id == AV_CODEC_ID_NONE && !pes->st->request_probe) {
-                             av_dlog(pes->stream, "pid=%x stream_type=%x probing\n",
-                                     pes->pid, pes->stream_type);
-                             pes->st->request_probe= 1;
+                             av_dlog(pes->stream,
+                                     "pid=%x stream_type=%x probing\n",
+                                     pes->pid,
+                                     pes->stream_type);
 -                            pes->st->codec->codec_id = AV_CODEC_ID_PROBE;
++                            pes->st->request_probe = 1;
                          }
                      } else {
-                         pes->state = MPEGTS_PAYLOAD;
+                         pes->state      = MPEGTS_PAYLOAD;
                          pes->data_index = 0;
                      }
                  } else {
@@@ -1115,15 -989,14 +1139,15 @@@ static PESContext *add_pes_stream(MpegT
      pes = av_mallocz(sizeof(PESContext));
      if (!pes)
          return 0;
-     pes->ts = ts;
-     pes->stream = ts->stream;
-     pes->pid = pid;
+     pes->ts      = ts;
+     pes->stream  = ts->stream;
+     pes->pid     = pid;
      pes->pcr_pid = pcr_pid;
-     pes->state = MPEGTS_SKIP;
-     pes->pts = AV_NOPTS_VALUE;
-     pes->dts = AV_NOPTS_VALUE;
-     pes->last_pcr = -1;
-     tss = mpegts_open_pes_filter(ts, pid, mpegts_push_data, pes);
+     pes->state   = MPEGTS_SKIP;
+     pes->pts     = AV_NOPTS_VALUE;
+     pes->dts     = AV_NOPTS_VALUE;
++    pes->last_pcr= -1;
+     tss          = mpegts_open_pes_filter(ts, pid, mpegts_push_data, pes);
      if (!tss) {
          av_free(pes);
          return 0;
@@@ -1251,20 -1126,15 +1277,20 @@@ static int parse_MP4SLDescrTag(MP4Descr
      if (!predefined) {
          int lengths;
          int flags = avio_r8(&d->pb);
-         descr->sl.use_au_start       = !!(flags & 0x80);
-         descr->sl.use_au_end         = !!(flags & 0x40);
-         descr->sl.use_rand_acc_pt    = !!(flags & 0x20);
-         descr->sl.use_padding        = !!(flags & 0x08);
-         descr->sl.use_timestamps     = !!(flags & 0x04);
-         descr->sl.use_idle           = !!(flags & 0x02);
-         descr->sl.timestamp_res      = avio_rb32(&d->pb);
-                                        avio_rb32(&d->pb);
+         descr->sl.use_au_start    = !!(flags & 0x80);
+         descr->sl.use_au_end      = !!(flags & 0x40);
+         descr->sl.use_rand_acc_pt = !!(flags & 0x20);
+         descr->sl.use_padding     = !!(flags & 0x08);
+         descr->sl.use_timestamps  = !!(flags & 0x04);
+         descr->sl.use_idle        = !!(flags & 0x02);
+         descr->sl.timestamp_res   = avio_rb32(&d->pb);
+         avio_rb32(&d->pb);
          descr->sl.timestamp_len      = avio_r8(&d->pb);
 +        if (descr->sl.timestamp_len > 64) {
 +            avpriv_request_sample(NULL, "timestamp_len > 64");
 +            descr->sl.timestamp_len = 64;
 +            return AVERROR_PATCHWELCOME;
 +        }
          descr->sl.ocr_len            = avio_r8(&d->pb);
          descr->sl.au_len             = avio_r8(&d->pb);
          descr->sl.inst_bitrate_len   = avio_r8(&d->pb);
@@@ -1459,125 -1336,55 +1492,127 @@@ int ff_parse_mpeg2_descriptor(AVFormatC
          break;
      case 0x1F: /* FMC descriptor */
          get16(pp, desc_end);
-         if (mp4_descr_count > 0 && (st->codec->codec_id == AV_CODEC_ID_AAC_LATM || st->request_probe>0) &&
+         if (mp4_descr_count > 0 &&
 -            st->codec->codec_id == AV_CODEC_ID_AAC_LATM &&
++            (st->codec->codec_id == AV_CODEC_ID_AAC_LATM || st->request_probe > 0) &&
              mp4_descr->dec_config_descr_len && mp4_descr->es_id == pid) {
              AVIOContext pb;
              ffio_init_context(&pb, mp4_descr->dec_config_descr,
-                           mp4_descr->dec_config_descr_len, 0, NULL, NULL, NULL, NULL);
+                               mp4_descr->dec_config_descr_len, 0,
+                               NULL, NULL, NULL, NULL);
              ff_mp4_read_dec_config_descr(fc, st, &pb);
              if (st->codec->codec_id == AV_CODEC_ID_AAC &&
-                 st->codec->extradata_size > 0){
-                 st->request_probe= st->need_parsing = 0;
-                 st->codec->codec_type= AVMEDIA_TYPE_AUDIO;
 -                st->codec->extradata_size > 0)
 -                st->need_parsing = 0;
++                st->codec->extradata_size > 0) {
++                st->request_probe = st->need_parsing = 0;
++                st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
 +            }
          }
          break;
      case 0x56: /* DVB teletext descriptor */
 -        language[0] = get8(pp, desc_end);
 -        language[1] = get8(pp, desc_end);
 -        language[2] = get8(pp, desc_end);
 -        language[3] = 0;
 -        av_dict_set(&st->metadata, "language", language, 0);
 +        {
 +            uint8_t *extradata = NULL;
 +            int language_count = desc_len / 5;
 +
 +            if (desc_len > 0 && desc_len % 5 != 0)
 +                return AVERROR_INVALIDDATA;
 +
 +            if (language_count > 0) {
 +                /* 4 bytes per language code (3 bytes) with comma or NUL byte should fit language buffer */
 +                if (language_count > sizeof(language) / 4) {
 +                    language_count = sizeof(language) / 4;
 +                }
 +
 +                if (st->codec->extradata == NULL) {
 +                    if (ff_alloc_extradata(st->codec, language_count * 2)) {
 +                        return AVERROR(ENOMEM);
 +                    }
 +                }
 +
 +               if (st->codec->extradata_size < language_count * 2)
 +                   return AVERROR_INVALIDDATA;
 +
 +               extradata = st->codec->extradata;
 +
 +                for (i = 0; i < language_count; i++) {
 +                    language[i * 4 + 0] = get8(pp, desc_end);
 +                    language[i * 4 + 1] = get8(pp, desc_end);
 +                    language[i * 4 + 2] = get8(pp, desc_end);
 +                    language[i * 4 + 3] = ',';
 +
 +                    memcpy(extradata, *pp, 2);
 +                    extradata += 2;
 +
 +                    *pp += 2;
 +                }
 +
 +                language[i * 4 - 1] = 0;
 +                av_dict_set(&st->metadata, "language", language, 0);
 +            }
 +        }
          break;
      case 0x59: /* subtitling descriptor */
 -        language[0] = get8(pp, desc_end);
 -        language[1] = get8(pp, desc_end);
 -        language[2] = get8(pp, desc_end);
 -        language[3] = 0;
 -        /* hearing impaired subtitles detection */
 -        switch (get8(pp, desc_end)) {
 -        case 0x20: /* DVB subtitles (for the hard of hearing) with no monitor aspect ratio criticality */
 -        case 0x21: /* DVB subtitles (for the hard of hearing) for display on 4:3 aspect ratio monitor */
 -        case 0x22: /* DVB subtitles (for the hard of hearing) for display on 16:9 aspect ratio monitor */
 -        case 0x23: /* DVB subtitles (for the hard of hearing) for display on 2.21:1 aspect ratio monitor */
 -        case 0x24: /* DVB subtitles (for the hard of hearing) for display on a high definition monitor */
 -        case 0x25: /* DVB subtitles (for the hard of hearing) with plano-stereoscopic disparity for display on a high definition monitor */
 -            st->disposition |= AV_DISPOSITION_HEARING_IMPAIRED;
 -            break;
 -        }
 -        if (st->codec->extradata) {
 -            if (st->codec->extradata_size == 4 &&
 -                memcmp(st->codec->extradata, *pp, 4))
 -                avpriv_request_sample(fc, "DVB sub with multiple IDs");
 -        } else {
 -            st->codec->extradata = av_malloc(4 + FF_INPUT_BUFFER_PADDING_SIZE);
 -            if (st->codec->extradata) {
 -                st->codec->extradata_size = 4;
 -                memcpy(st->codec->extradata, *pp, 4);
 +        {
 +            /* 8 bytes per DVB subtitle substream data:
 +             * ISO_639_language_code (3 bytes),
 +             * subtitling_type (1 byte),
 +             * composition_page_id (2 bytes),
 +             * ancillary_page_id (2 bytes) */
 +            int language_count = desc_len / 8;
 +
 +            if (desc_len > 0 && desc_len % 8 != 0)
 +                return AVERROR_INVALIDDATA;
 +
 +            if (language_count > 1) {
 +                avpriv_request_sample(fc, "DVB subtitles with multiple languages");
 +            }
 +
 +            if (language_count > 0) {
 +                uint8_t *extradata;
 +
 +                /* 4 bytes per language code (3 bytes) with comma or NUL byte should fit language buffer */
 +                if (language_count > sizeof(language) / 4) {
 +                    language_count = sizeof(language) / 4;
 +                }
 +
 +                if (st->codec->extradata == NULL) {
 +                    if (ff_alloc_extradata(st->codec, language_count * 5)) {
 +                        return AVERROR(ENOMEM);
 +                    }
 +                }
 +
 +                if (st->codec->extradata_size < language_count * 5)
 +                    return AVERROR_INVALIDDATA;
 +
 +                extradata = st->codec->extradata;
 +
 +                for (i = 0; i < language_count; i++) {
 +                    language[i * 4 + 0] = get8(pp, desc_end);
 +                    language[i * 4 + 1] = get8(pp, desc_end);
 +                    language[i * 4 + 2] = get8(pp, desc_end);
 +                    language[i * 4 + 3] = ',';
 +
 +                    /* hearing impaired subtitles detection using subtitling_type */
-                     switch(*pp[0]) {
++                    switch (*pp[0]) {
 +                    case 0x20: /* DVB subtitles (for the hard of hearing) with no monitor aspect ratio criticality */
 +                    case 0x21: /* DVB subtitles (for the hard of hearing) for display on 4:3 aspect ratio monitor */
 +                    case 0x22: /* DVB subtitles (for the hard of hearing) for display on 16:9 aspect ratio monitor */
 +                    case 0x23: /* DVB subtitles (for the hard of hearing) for display on 2.21:1 aspect ratio monitor */
 +                    case 0x24: /* DVB subtitles (for the hard of hearing) for display on a high definition monitor */
 +                    case 0x25: /* DVB subtitles (for the hard of hearing) with plano-stereoscopic disparity for display on a high definition monitor */
 +                        st->disposition |= AV_DISPOSITION_HEARING_IMPAIRED;
 +                        break;
 +                    }
 +
 +                    extradata[4] = get8(pp, desc_end); /* subtitling_type */
 +                    memcpy(extradata, *pp, 4); /* composition_page_id and ancillary_page_id */
 +                    extradata += 5;
 +
 +                    *pp += 4;
 +                }
 +
 +                language[i * 4 - 1] = 0;
 +                av_dict_set(&st->metadata, "language", language, 0);
              }
          }
 -        *pp += 4;
 -        av_dict_set(&st->metadata, "language", language, 0);
          break;
      case 0x0a: /* ISO 639 language descriptor */
          for (i = 0; i + 4 <= desc_len; i += 4) {
@@@ -1693,11 -1493,10 +1734,12 @@@ static void pmt_cb(MpegTSFilter *filter
  
      // stop parsing after pmt, we found header
      if (!ts->stream->nb_streams)
 -        ts->stop_parse = 1;
 +        ts->stop_parse = 2;
 +
 +    set_pmt_found(ts, h->id);
  
-     for(;;) {
+     for (;;) {
          st = 0;
          pes = NULL;
          stream_type = get8(&p, p_end);
          if (ts->pids[pid] && ts->pids[pid]->type == MPEGTS_PES) {
              pes = ts->pids[pid]->u.pes_filter.opaque;
              if (!pes->st) {
-                 pes->st = avformat_new_stream(pes->stream, NULL);
+                 pes->st     = avformat_new_stream(pes->stream, NULL);
 +                if (!pes->st)
 +                    goto out;
                  pes->st->id = pes->pid;
              }
              st = pes->st;
  
          desc_list_len = get16(&p, p_end);
          if (desc_list_len < 0)
 -            break;
 +            goto out;
          desc_list_len &= 0xfff;
-         desc_list_end = p + desc_list_len;
+         desc_list_end  = p + desc_list_len;
          if (desc_list_end > p_end)
 -            break;
 +            goto out;
-         for(;;) {
-             if (ff_parse_mpeg2_descriptor(ts->stream, st, stream_type, &p, desc_list_end,
-                 mp4_descr, mp4_descr_count, pid, ts) < 0)
+         for (;;) {
+             if (ff_parse_mpeg2_descriptor(ts->stream, st, stream_type, &p,
+                                           desc_list_end, mp4_descr,
+                                           mp4_descr_count, pid, ts) < 0)
                  break;
  
-             if (pes && prog_reg_desc == AV_RL32("HDMV") && stream_type == 0x83 && pes->sub_st) {
-                 ff_program_add_stream_index(ts->stream, h->id, pes->sub_st->index);
+             if (pes && prog_reg_desc == AV_RL32("HDMV") &&
+                 stream_type == 0x83 && pes->sub_st) {
+                 ff_program_add_stream_index(ts->stream, h->id,
+                                             pes->sub_st->index);
                  pes->sub_st->codec->codec_tag = st->codec->codec_tag;
              }
          }
@@@ -1795,10 -1589,8 +1841,10 @@@ static void pat_cb(MpegTSFilter *filter
      if (h->tid != PAT_TID)
          return;
  
 +    ts->stream->ts_id = h->id;
 +
      clear_programs(ts);
-     for(;;) {
+     for (;;) {
          sid = get16(&p, p_end);
          if (sid < 0)
              break;
          if (sid == 0x0000) {
              /* NIT info */
          } else {
 -            av_new_program(ts->stream, sid);
 -            if (ts->pids[pmt_pid])
 -                mpegts_close_filter(ts, ts->pids[pmt_pid]);
 -            mpegts_open_section_filter(ts, pmt_pid, pmt_cb, ts, 1);
 +            MpegTSFilter *fil = ts->pids[pmt_pid];
 +            program = av_new_program(ts->stream, sid);
 +            program->program_num = sid;
 +            program->pmt_pid = pmt_pid;
 +            if (fil)
 +                if (   fil->type != MPEGTS_SECTION
 +                    || fil->pid != pmt_pid
 +                    || fil->u.section_filter.section_cb != pmt_cb)
 +                    mpegts_close_filter(ts, ts->pids[pmt_pid]);
 +
 +            if (!ts->pids[pmt_pid])
 +                mpegts_open_section_filter(ts, pmt_pid, pmt_cb, ts, 1);
              add_pat_entry(ts, sid);
-             add_pid_to_pmt(ts, sid, 0); //add pat pid to program
+             add_pid_to_pmt(ts, sid, 0); // add pat pid to program
              add_pid_to_pmt(ts, sid, pmt_pid);
          }
      }
-             for (i=0; i<ts->nb_prg; i++)
 +
 +    if (sid < 0) {
 +        int i,j;
 +        for (j=0; j<ts->stream->nb_programs; j++) {
++            for (i = 0; i < ts->nb_prg; i++)
 +                if (ts->prg[i].id == ts->stream->programs[j]->id)
 +                    break;
 +            if (i==ts->nb_prg)
 +                clear_avprogram(ts, ts->stream->programs[j]->id);
 +        }
 +    }
  }
  
  static void sdt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len)
@@@ -1967,10 -1734,10 +2014,10 @@@ static int handle_packet(MpegTSContext 
  
      tss->last_cc = cc;
      if (!cc_ok) {
 -        av_log(ts->stream, AV_LOG_WARNING,
 +        av_log(ts->stream, AV_LOG_DEBUG,
                 "Continuity check failed for pid %d expected %d got %d\n",
                 pid, expected_cc, cc);
-         if(tss->type == MPEGTS_PES) {
+         if (tss->type == MPEGTS_PES) {
              PESContext *pc = tss->u.pes_filter.opaque;
              pc->flags |= AV_PKT_FLAG_CORRUPT;
          }
                                     p, p_end - p, 0);
              }
          }
-         if(ts->stream->ctx_flags & AVFMTCTX_NOHEADER) {
 +
 +        // stop find_stream_info from waiting for more streams
 +        // when all programs have received a PMT
-             for(i=0; i<ts->nb_prg; i++) {
++        if (ts->stream->ctx_flags & AVFMTCTX_NOHEADER) {
 +            int i;
++            for (i = 0; i < ts->nb_prg; i++) {
 +                if (!ts->prg[i].pmt_found)
 +                    break;
 +            }
 +            if (i == ts->nb_prg && ts->nb_prg > 0) {
 +                if (ts->stream->nb_streams > 1 || pos > 100000) {
 +                    av_log(ts->stream, AV_LOG_DEBUG, "All programs have pmt, headers found\n");
 +                    ts->stream->ctx_flags &= ~AVFMTCTX_NOHEADER;
 +                }
 +            }
 +        }
 +
      } else {
          int ret;
 +        int64_t pcr = -1;
 +        int64_t pcr_h;
 +        int pcr_l;
 +        if (parse_pcr(&pcr_h, &pcr_l, packet) == 0)
 +            pcr = pcr_h * 300 + pcr_l;
          // Note: The position here points actually behind the current packet.
          if ((ret = tss->u.pes_filter.pes_cb(tss, p, p_end - p, is_start,
 -                                            pos - ts->raw_packet_size)) < 0)
 +                                            pos - ts->raw_packet_size, pcr)) < 0)
              return ret;
      }
  
      return 0;
  }
  
-     if(pos < 0)
 +static void reanalyze(MpegTSContext *ts) {
 +    AVIOContext *pb = ts->stream->pb;
 +    int64_t pos = avio_tell(pb);
-     if(ts->size_stat_count > SIZE_STAT_THRESHOLD) {
++    if (pos < 0)
 +        return;
 +    pos -= ts->pos47_full;
 +    if (pos == TS_PACKET_SIZE) {
 +        ts->size_stat[0] ++;
 +    } else if (pos == TS_DVHS_PACKET_SIZE) {
 +        ts->size_stat[1] ++;
 +    } else if (pos == TS_FEC_PACKET_SIZE) {
 +        ts->size_stat[2] ++;
 +    }
 +
 +    ts->size_stat_count ++;
++    if (ts->size_stat_count > SIZE_STAT_THRESHOLD) {
 +        int newsize = 0;
 +        if (ts->size_stat[0] > SIZE_STAT_THRESHOLD) {
 +            newsize = TS_PACKET_SIZE;
 +        } else if (ts->size_stat[1] > SIZE_STAT_THRESHOLD) {
 +            newsize = TS_DVHS_PACKET_SIZE;
 +        } else if (ts->size_stat[2] > SIZE_STAT_THRESHOLD) {
 +            newsize = TS_FEC_PACKET_SIZE;
 +        }
 +        if (newsize && newsize != ts->raw_packet_size) {
 +            av_log(ts->stream, AV_LOG_WARNING, "changing packet size to %d\n", newsize);
 +            ts->raw_packet_size = newsize;
 +        }
 +        ts->size_stat_count = 0;
 +        memset(ts->size_stat, 0, sizeof(ts->size_stat));
 +    }
 +}
 +
  /* XXX: try to find a better synchro over several packets (use
-    get_packet_size() ?) */
+  * get_packet_size() ?) */
  static int mpegts_resync(AVFormatContext *s)
  {
      AVIOContext *pb = s->pb;
      int c, i;
  
-     for(i = 0;i < MAX_RESYNC_SIZE; i++) {
+     for (i = 0; i < MAX_RESYNC_SIZE; i++) {
          c = avio_r8(pb);
 -        if (pb->eof_reached)
 +        if (url_feof(pb))
              return -1;
          if (c == 0x47) {
              avio_seek(pb, -1, SEEK_CUR);
@@@ -2156,11 -1864,10 +2205,11 @@@ static int handle_packets(MpegTSContex
          for (i = 0; i < NB_PID_MAX; i++) {
              if (ts->pids[i]) {
                  if (ts->pids[i]->type == MPEGTS_PES) {
-                    PESContext *pes = ts->pids[i]->u.pes_filter.opaque;
-                    av_buffer_unref(&pes->buffer);
-                    pes->data_index = 0;
-                    pes->state = MPEGTS_SKIP; /* skip until pes header */
-                    pes->last_pcr = -1;
+                     PESContext *pes = ts->pids[i]->u.pes_filter.opaque;
+                     av_buffer_unref(&pes->buffer);
+                     pes->data_index = 0;
+                     pes->state = MPEGTS_SKIP; /* skip until pes header */
++                    pes->last_pcr = -1;
                  }
                  ts->pids[i]->last_cc = -1;
              }
      ts->stop_parse = 0;
      packet_num = 0;
      memset(packet + TS_PACKET_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);
-     for(;;) {
+     for (;;) {
 -        if (ts->stop_parse > 0)
 -            break;
          packet_num++;
 -        if (nb_packets != 0 && packet_num >= nb_packets)
 +        if (nb_packets != 0 && packet_num >= nb_packets ||
 +            ts->stop_parse > 1) {
 +            ret = AVERROR(EAGAIN);
 +            break;
 +        }
 +        if (ts->stop_parse > 0)
              break;
 +
          ret = read_packet(s, packet, ts->raw_packet_size, &data);
          if (ret != 0)
              break;
  
  static int mpegts_probe(AVProbeData *p)
  {
-     const int size= p->buf_size;
-     int maxscore=0;
-     int sumscore=0;
+     const int size = p->buf_size;
 -    int score, fec_score, dvhs_score;
++    int maxscore = 0;
++    int sumscore = 0;
 +    int i;
-     int check_count= size / TS_FEC_PACKET_SIZE;
+     int check_count = size / TS_FEC_PACKET_SIZE;
  #define CHECK_COUNT 10
 +#define CHECK_BLOCK 100
  
      if (check_count < CHECK_COUNT)
          return -1;
  
-     for (i=0; i<check_count; i+=CHECK_BLOCK){
 -    score = analyze(p->buf, TS_PACKET_SIZE * check_count,
 -                    TS_PACKET_SIZE, NULL) * CHECK_COUNT / check_count;
 -    dvhs_score = analyze(p->buf, TS_DVHS_PACKET_SIZE * check_count,
 -                         TS_DVHS_PACKET_SIZE, NULL) * CHECK_COUNT / check_count;
 -    fec_score = analyze(p->buf, TS_FEC_PACKET_SIZE * check_count,
 -                        TS_FEC_PACKET_SIZE, NULL) * CHECK_COUNT / check_count;
 -    av_dlog(NULL, "score: %d, dvhs_score: %d, fec_score: %d \n",
 -            score, dvhs_score, fec_score);
++    for (i = 0; i<check_count; i+=CHECK_BLOCK) {
 +        int left = FFMIN(check_count - i, CHECK_BLOCK);
-         int score     = analyze(p->buf + TS_PACKET_SIZE     *i, TS_PACKET_SIZE     *left, TS_PACKET_SIZE     , NULL);
-         int dvhs_score= analyze(p->buf + TS_DVHS_PACKET_SIZE*i, TS_DVHS_PACKET_SIZE*left, TS_DVHS_PACKET_SIZE, NULL);
-         int fec_score = analyze(p->buf + TS_FEC_PACKET_SIZE *i, TS_FEC_PACKET_SIZE *left, TS_FEC_PACKET_SIZE , NULL);
++        int score      = analyze(p->buf + TS_PACKET_SIZE     *i, TS_PACKET_SIZE     *left, TS_PACKET_SIZE     , NULL);
++        int dvhs_score = analyze(p->buf + TS_DVHS_PACKET_SIZE*i, TS_DVHS_PACKET_SIZE*left, TS_DVHS_PACKET_SIZE, NULL);
++        int fec_score  = analyze(p->buf + TS_FEC_PACKET_SIZE *i, TS_FEC_PACKET_SIZE *left, TS_FEC_PACKET_SIZE , NULL);
 +        score = FFMAX3(score, dvhs_score, fec_score);
 +        sumscore += score;
 +        maxscore = FFMAX(maxscore, score);
 +    }
 +
-     sumscore = sumscore*CHECK_COUNT/check_count;
-     maxscore = maxscore*CHECK_COUNT/CHECK_BLOCK;
++    sumscore = sumscore * CHECK_COUNT / check_count;
++    maxscore = maxscore * CHECK_COUNT / CHECK_BLOCK;
 +
 +    av_dlog(0, "TS score: %d %d\n", sumscore, maxscore);
  
-     if (sumscore > 6)           return AVPROBE_SCORE_MAX + sumscore - CHECK_COUNT;
-     else if (maxscore > 6)      return AVPROBE_SCORE_MAX/2 + sumscore - CHECK_COUNT;
-     else                        return -1;
 -    /* we need a clear definition for the returned score otherwise
 -     * things will become messy sooner or later */
 -    if (score > fec_score && score > dvhs_score && score > 6)
 -        return AVPROBE_SCORE_MAX + score - CHECK_COUNT;
 -    else if (dvhs_score > score && dvhs_score > fec_score && dvhs_score > 6)
 -        return AVPROBE_SCORE_MAX + dvhs_score - CHECK_COUNT;
 -    else if (fec_score > 6)
 -        return AVPROBE_SCORE_MAX + fec_score - CHECK_COUNT;
++    if      (sumscore > 6) return AVPROBE_SCORE_MAX   + sumscore - CHECK_COUNT;
++    else if (maxscore > 6) return AVPROBE_SCORE_MAX/2 + sumscore - CHECK_COUNT;
+     else
+         return -1;
  }
  
  /* return the 90kHz PCR and the extension for the 27MHz PCR. return
@@@ -2266,22 -1957,20 +2315,22 @@@ static void seek_back(AVFormatContext *
  static int mpegts_read_header(AVFormatContext *s)
  {
      MpegTSContext *ts = s->priv_data;
-     AVIOContext *pb = s->pb;
-     uint8_t buf[8*1024]={0};
+     AVIOContext *pb   = s->pb;
 -    uint8_t buf[5 * 1024];
++    uint8_t buf[8 * 1024] = {0};
      int len;
      int64_t pos;
  
 -    /* read the first 1024 bytes to get packet size */
 +    ffio_ensure_seekback(pb, s->probesize);
 +
 +    /* read the first 8192 bytes to get packet size */
      pos = avio_tell(pb);
      len = avio_read(pb, buf, sizeof(buf));
 -    if (len != sizeof(buf))
 -        goto fail;
 -    ts->raw_packet_size = get_packet_size(buf, sizeof(buf));
 -    if (ts->raw_packet_size <= 0)
 -        goto fail;
 +    ts->raw_packet_size = get_packet_size(buf, len);
 +    if (ts->raw_packet_size <= 0) {
 +        av_log(s, AV_LOG_WARNING, "Could not detect TS packet size, defaulting to non-FEC/DVHS\n");
 +        ts->raw_packet_size = TS_PACKET_SIZE;
 +    }
-     ts->stream = s;
+     ts->stream     = s;
      ts->auto_guess = 0;
  
      if (s->iformat == &ff_mpegts_demuxer) {
              goto fail;
          avpriv_set_pts_info(st, 60, 1, 27000000);
          st->codec->codec_type = AVMEDIA_TYPE_DATA;
-         st->codec->codec_id = AV_CODEC_ID_MPEG2TS;
+         st->codec->codec_id   = AV_CODEC_ID_MPEG2TS;
  
          /* we iterate until we find two PCRs to estimate the bitrate */
-         pcr_pid = -1;
-         nb_pcrs = 0;
+         pcr_pid    = -1;
+         nb_pcrs    = 0;
          nb_packets = 0;
-         for(;;) {
+         for (;;) {
              ret = read_packet(s, packet, ts->raw_packet_size, &data);
              if (ret < 0)
 -                return -1;
 +                goto fail;
              pid = AV_RB16(data + 1) & 0x1fff;
              if ((pcr_pid == -1 || pcr_pid == pid) &&
                  parse_pcr(&pcr_h, &pcr_l, data) == 0) {
                  st->start_time / 1000000.0, pcrs[0] / 27e6, ts->pcr_incr);
      }
  
 -    avio_seek(pb, pos, SEEK_SET);
 +    seek_back(s, pb, pos);
      return 0;
 fail:
+ fail:
      return -1;
  }
  
@@@ -2420,9 -2109,8 +2468,9 @@@ static int mpegts_read_packet(AVFormatC
      ts->pkt = pkt;
      ret = handle_packets(ts, 0);
      if (ret < 0) {
 +        av_free_packet(ts->pkt);
          /* flush pes data left */
-         for (i = 0; i < NB_PID_MAX; i++) {
+         for (i = 0; i < NB_PID_MAX; i++)
              if (ts->pids[i] && ts->pids[i]->type == MPEGTS_PES) {
                  PESContext *pes = ts->pids[i]->u.pes_filter.opaque;
                  if (pes->state == MPEGTS_PAYLOAD && pes->data_index > 0) {
@@@ -2463,62 -2151,65 +2511,65 @@@ static av_unused int64_t mpegts_get_pcr
      MpegTSContext *ts = s->priv_data;
      int64_t pos, timestamp;
      uint8_t buf[TS_PACKET_SIZE];
-     int pcr_l, pcr_pid = ((PESContext*)s->streams[stream_index]->priv_data)->pcr_pid;
+     int pcr_l, pcr_pid =
+         ((PESContext *)s->streams[stream_index]->priv_data)->pcr_pid;
 -    const int find_next = 1;
 +    int pos47 = ts->pos47_full % ts->raw_packet_size;
-     pos = ((*ppos  + ts->raw_packet_size - 1 - pos47) / ts->raw_packet_size) * ts->raw_packet_size + pos47;
+     pos =
 -        ((*ppos + ts->raw_packet_size - 1 - ts->pos47) / ts->raw_packet_size) *
 -        ts->raw_packet_size + ts->pos47;
 -    if (find_next) {
 -        for (;;) {
 -            avio_seek(s->pb, pos, SEEK_SET);
 -            if (avio_read(s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE)
++        ((*ppos + ts->raw_packet_size - 1 - pos47) / ts->raw_packet_size) *
++        ts->raw_packet_size + pos47;
 +    while(pos < pos_limit) {
 +        if (avio_seek(s->pb, pos, SEEK_SET) < 0)
 +            return AV_NOPTS_VALUE;
 +        if (avio_read(s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE)
 +            return AV_NOPTS_VALUE;
 +        if (buf[0] != 0x47) {
 +            avio_seek(s->pb, -TS_PACKET_SIZE, SEEK_CUR);
 +            if (mpegts_resync(s) < 0)
                  return AV_NOPTS_VALUE;
 -            if ((pcr_pid < 0 || (AV_RB16(buf + 1) & 0x1fff) == pcr_pid) &&
 -                parse_pcr(&timestamp, &pcr_l, buf) == 0) {
 -                break;
 -            }
 -            pos += ts->raw_packet_size;
 +            pos = avio_tell(s->pb);
 +            continue;
          }
 -    } else {
 -        for (;;) {
 -            pos -= ts->raw_packet_size;
 -            if (pos < 0)
 -                return AV_NOPTS_VALUE;
 -            avio_seek(s->pb, pos, SEEK_SET);
 -            if (avio_read(s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE)
 -                return AV_NOPTS_VALUE;
 -            if ((pcr_pid < 0 || (AV_RB16(buf + 1) & 0x1fff) == pcr_pid) &&
 -                parse_pcr(&timestamp, &pcr_l, buf) == 0) {
 -                break;
 -            }
 +        if ((pcr_pid < 0 || (AV_RB16(buf + 1) & 0x1fff) == pcr_pid) &&
 +            parse_pcr(&timestamp, &pcr_l, buf) == 0) {
 +            *ppos = pos;
 +            return timestamp;
          }
 +        pos += ts->raw_packet_size;
      }
 -    *ppos = pos;
  
 -    return timestamp;
 +    return AV_NOPTS_VALUE;
  }
  
 -static int read_seek(AVFormatContext *s, int stream_index, int64_t target_ts, int flags)
 +static int64_t mpegts_get_dts(AVFormatContext *s, int stream_index,
 +                              int64_t *ppos, int64_t pos_limit)
  {
      MpegTSContext *ts = s->priv_data;
 -    uint8_t buf[TS_PACKET_SIZE];
      int64_t pos;
 -
 -    if (ff_seek_frame_binary(s, stream_index, target_ts, flags) < 0)
 -        return -1;
 -
 -    pos = avio_tell(s->pb);
 -
 -    for (;;) {
 -        avio_seek(s->pb, pos, SEEK_SET);
 -        if (avio_read(s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE)
 -            return -1;
 -        // pid = AV_RB16(buf + 1) & 0x1fff;
 -        if (buf[1] & 0x40)
 -            break;
 -        pos += ts->raw_packet_size;
 +    int pos47 = ts->pos47_full % ts->raw_packet_size;
 +    pos = ((*ppos  + ts->raw_packet_size - 1 - pos47) / ts->raw_packet_size) * ts->raw_packet_size + pos47;
 +    ff_read_frame_flush(s);
 +    if (avio_seek(s->pb, pos, SEEK_SET) < 0)
 +        return AV_NOPTS_VALUE;
 +    while(pos < pos_limit) {
 +        int ret;
 +        AVPacket pkt;
 +        av_init_packet(&pkt);
-         ret= av_read_frame(s, &pkt);
-         if(ret < 0)
++        ret = av_read_frame(s, &pkt);
++        if (ret < 0)
 +            return AV_NOPTS_VALUE;
 +        av_free_packet(&pkt);
-         if(pkt.dts != AV_NOPTS_VALUE && pkt.pos >= 0){
++        if (pkt.dts != AV_NOPTS_VALUE && pkt.pos >= 0) {
 +            ff_reduce_index(s, pkt.stream_index);
 +            av_add_index_entry(s->streams[pkt.stream_index], pkt.pos, pkt.dts, 0, 0, AVINDEX_KEYFRAME /* FIXME keyframe? */);
-             if(pkt.stream_index == stream_index && pkt.pos >= *ppos){
-                 *ppos= pkt.pos;
++            if (pkt.stream_index == stream_index && pkt.pos >= *ppos) {
++                *ppos = pkt.pos;
 +                return pkt.dts;
 +            }
 +        }
 +        pos = pkt.pos;
      }
 -    avio_seek(s->pb, pos, SEEK_SET);
  
 -    return 0;
 +    return AV_NOPTS_VALUE;
  }
  
  /**************************************************************/
@@@ -2550,8 -2238,10 +2601,8 @@@ int ff_mpegts_parse_packet(MpegTSContex
  
      len1 = len;
      ts->pkt = pkt;
-     for(;;) {
 -    ts->stop_parse = 0;
+     for (;;) {
 -        if (ts->stop_parse > 0)
 -            break;
 +        ts->stop_parse = 0;
          if (len < TS_PACKET_SIZE)
              return -1;
          if (buf[0] != 0x47) {