1. 16 Jul, 2019 5 commits
    • Andreas Rheinhardt's avatar
      avformat/matroskadec: Introduce a "last known good" position · a3db9f62
      Andreas Rheinhardt authored
      Currently, resyncing during reading packets works as follows:
      The current position is recorded, then a call to matroska_parse_cluster
      is made and if said call fails, the demuxer tries to resync from the
      earlier position. If the call doesn't fail, but also doesn't deliver a
      packet, then this is looped.
      
      There are two problems with this approach:
      1. The Matroska file format aims to be forward-compatible; to achieve
      this, a demuxer should simply ignore and skip elements it doesn't
      know about. But it is not possible to reliably distinguish unknown
      elements from junk. If matroska_parse_cluster encounters an unknown
      element, it can therefore not simply error out; instead it returns zero
      and the loop is iterated which includes an update of the position that
      is intended to be used in case of errors, i.e. the element that is
      skipped is not searched for level 1 element ids to resync to at all if
      later calls to matroska_parse_cluster return an error.
      Notice that in case that sync has been lost there can be a chain of
      several unknown/possibly junk elements before an error is detected.
      
      2. Even if a call to matroska_parse_cluster delivers a packet, this does
      not mean that everything is fine. E.g. it might be that some of the
      block's data is missing and that the data that was presumed to be from
      the block just read actually contains the beginning of the next element.
      This will only be apparent at the next call of matroska_read_packet,
      which uses the (false) end of the earlier block as resync position so
      that in the (not unlikely) case that the call to matroska_parse_cluster
      fails, the data believed to be part of the earlier block is not searched
      for a level 1 element to resync to.
      
      To counter this, a "last known good" position is introduced. When an
      element id that is known to be allowed at this position in the hierarchy
      (according to the syntax currently in use for parsing) is read and some
      further checks (regarding the length of the element and its containing
      master element) are passed, then the beginning of the current element is
      treated as a "good" position and recorded as such in the
      MatroskaDemuxContext. Because of 2., only the start of the element is
      treated as a "good" position, not the whole element. If an error occurs
      later during parsing of clusters, the resync process starts at the last
      known good position.
      
      Given that when the header is damaged the subsequent resync never skips over
      data and is therefore unaffected by both issues, the "last known good"
      concept is not used there.
      Signed-off-by: 's avatarAndreas Rheinhardt <andreas.rheinhardt@gmail.com>
      a3db9f62
    • Andreas Rheinhardt's avatar
      avformat/matroskadec: Refactor some functions · 559e3422
      Andreas Rheinhardt authored
      Since the changes to the parsing of SimpleBlocks, both ebml_parse_id and
      ebml_parse_elem are only called from one place, so that it is possible
      to inline these two function calls. This is done, but not completely:
      ebml_parse_id still exists in a modified form. This is done in
      preparation for a further patch regarding the handling of
      unknown-length elements.
      Signed-off-by: 's avatarAndreas Rheinhardt <andreas.rheinhardt@gmail.com>
      559e3422
    • Andreas Rheinhardt's avatar
      avformat/matroskadec: Use proper levels after discontínuity · 8a286e74
      Andreas Rheinhardt authored
      The earlier code set the level to zero upon seeking and after a
      discontinuity although in both cases parsing (re)starts at a level 1
      element.
      
      Also set the segment's length to unkown if an error occured in order not
      to drop any valid data that happens to be beyond the designated end of
      the segment.
      Signed-off-by: 's avatarAndreas Rheinhardt <andreas.rheinhardt@gmail.com>
      8a286e74
    • Andreas Rheinhardt's avatar
      avformat/matroskadec: Add function to reset status · 310f326b
      Andreas Rheinhardt authored
      This function will be useful later to reset the status (e.g. current
      level and the already parsed id).
      Signed-off-by: 's avatarAndreas Rheinhardt <andreas.rheinhardt@gmail.com>
      310f326b
    • Andreas Rheinhardt's avatar
      avformat/matroskadec: Don't abort resyncing upon seek failure · 27f40b1d
      Andreas Rheinhardt authored
      When an error happens, the Matroska demuxer tries to resync to level 1
      elements from an earlier position onwards. If the seek to said earlier
      position fails, the demuxer currently treats this as an unrecoverable
      error. And that behaviour is suboptimal as said failure is nothing
      unrecoverable or unexpected (when the input isn't seekable).
      It is preferable to simply resync from the earliest position available
      (i.e. the start of the AVIOContext's buffer) onwards if the seek failed.
      
      Here are some scenarios that might be treated as unrecoverable errors
      by the current code if the input isn't seekable. They all have in
      common that the current position is so far away from the desired
      position that the seek can't be fulfilled from the AVIOContext's buffer:
      
      1. Blocks (both SimpleBlocks as well as a Block in a BlockGroup) for
      which reading them as binary EBML elements succeeds, but whose parsing
      triggers an error (e.g. an invalid TrackNumber). In this case the
      earlier position from which resyncing begins is at the start of the block
      (or even earlier).
      2. BlockGroups, whose parsing fails in one of the latter elements. Just
      as in 1., the start of the BlockGroup (the target of the seek) might be
      so far away from the current position that it is no longer in the
      buffer.
      3. At the beginning of parsing a cluster, the cluster is parsed until a
      SimpleBlock or a BlockGroup is encountered. So if the input is damaged
      between the beginning of the cluster and the first occurrence of a
      SimpleBlock/BlockGroup and if said damage makes the demuxer read/skip so
      much data that the beginning of the cluster is no longer in the buffer,
      demuxing will currently fail completely.
      Signed-off-by: 's avatarAndreas Rheinhardt <andreas.rheinhardt@gmail.com>
      27f40b1d
  2. 15 Jul, 2019 4 commits
  3. 14 Jul, 2019 15 commits
  4. 13 Jul, 2019 9 commits
  5. 12 Jul, 2019 4 commits
    • Marton Balint's avatar
      avformat/mpegts: respect program number when merging streams · 81d3d7dd
      Marton Balint authored
      merge_pmt_versions was not usable if multiple programs were present because
      when it was searching for candidate streams it did not make sure that the PMT was
      of the same program. This caused the streams of all programs to get merged into
      a single (garbled) program.
      
      This patch makes sure that the program number (service ID) is also matching
      with the old streams when parsing the PMT making the feature useful for multi
      program streams.
      
      This change might cause issues for single program streams if the program number
      changes, but I think it is acceptable because the goal of the option is to make
      the parsing resilient to PID changes, and that is still working as expected.
      Signed-off-by: 's avatarMarton Balint <cus@passwd.hu>
      81d3d7dd
    • Marton Balint's avatar
      avformat/movenc: use unspecified language by default · 397abca0
      Marton Balint authored
      English was used before.
      Signed-off-by: 's avatarMarton Balint <cus@passwd.hu>
      397abca0
    • Andreas Rheinhardt's avatar
      lavf/webm_chunk: Correct duration if start time > 0 · 24a64e04
      Andreas Rheinhardt authored
      Up until now, it was simply presumed that the first packet had a pts of
      zero; otherwise the duration of the first chunk was wrong.
      Signed-off-by: 's avatarAndreas Rheinhardt <andreas.rheinhardt@gmail.com>
      24a64e04
    • Andreas Rheinhardt's avatar
      lavf/webm_chunk: Fix NULL dereference · 8c6ee762
      Andreas Rheinhardt authored
      The earlier version of the webm_chunk muxer had several bugs:
      
      1. If the first packet of an audio stream didn't have a PTS of zero,
      then no chunk will be started before a packet is delivered to the
      underlying Matroska/WebM muxer, i.e. the AVFormatContext used to write
      these packets had a NULL as AVIOContext for output. This is behind the
      crash in ticket #5752.
      
      2. If an error happens during writing a packet, the underlyimg
      Matroska/WebM muxer context is freed. This leads to a use-after-free
      coupled with a double-free in webm_chunk_write_trailer (which supposes
      that the underlying AVFormatContext is still valid).
      
      3. Even when no error occurs at all, webm_chunk_write_trailer is still
      buggy: After the underlying Matroska/WebM muxer has written its trailer,
      ending the chunk implicitly flushes it again which is illegal at this
      point.
      
      These bugs have been fixed.
      
      Fixes #5752.
      Signed-off-by: 's avatarAndreas Rheinhardt <andreas.rheinhardt@gmail.com>
      8c6ee762
  6. 11 Jul, 2019 3 commits