1. 21 May, 2020 9 commits
  2. 20 May, 2020 8 commits
  3. 19 May, 2020 17 commits
  4. 18 May, 2020 6 commits
    • Andreas Rheinhardt's avatar
      avformat/matroskaenc: Don't assert when writing huge files · 575557ce
      Andreas Rheinhardt authored
      EBML numbers are variable length numbers: Only seven bits of every byte
      are available to encode the number, the other bits encode the length of
      the number itself. So an eight byte EBML number can only encode numbers
      in the range 0..(2^56 - 1). And when using EBML numbers to encode the
      length of an EBML element, the EBML number corresponding to 2^56 - 1 is
      actually reserved to mean that the length of the corresponding element
      is unknown.
      
      And therefore put_ebml_length() asserted that the length it should
      represent is < 2^56 - 1. Yet there was nothing that actually guaranteed
      this to be true for the Segment (the main/root EBML element of a
      Matroska file that encompasses nearly the whole file). This commit
      changes this by checking in advance how big the length is and only
      updating the number if it is representable at all; if not, the unknown
      length element is not touched.
      Signed-off-by: 's avatarAndreas Rheinhardt <andreas.rheinhardt@gmail.com>
      575557ce
    • Andreas Rheinhardt's avatar
      avformat/matroskaenc: Avoid unnecessary seek · efeb3a53
      Andreas Rheinhardt authored
      The Matroska muxer has a pair of functions designed to write master
      elements whose exact length is not known in advance: start_ebml_master()
      and end_ebml_master(). The first one of these would write the EBML ID of
      the master element that is about to be started, reserve some bytes for
      the length field and record the current position as well as how many
      bytes were used for the length field. When writing the master's contents
      is finished, end_ebml_master() gets the current position (at the end of
      the master element), seeks to the length field using the recorded
      position, writes the length field and seeks back to the end of the
      master element so that one can continue writing other elements.
      
      But if one wants to modify the content of the master element itself,
      then the seek back is superfluous. This is the scenario that presents
      itself when writing the trailer: One wants to update several elements
      contained in the Segment master element (this is the main/root master
      element of a Matroska file) that were already written when writing the
      header. The current approach is to seek to the beginning of the file
      to update the elements, then seek to the end, call end_ebml_master()
      which immediately seeks to the beginning to write the length and seeks
      back. The seek to the end (which has only been performed because
      end_ebml_master() uses the initial position to determine the length
      of the master element) and the seek back are of course superfluous.
      
      This commit avoids these seeks by no longer using start/end_ebml_master()
      to write the segment's length field. Instead, it is now written
      manually. The new approach is: Seek to the beginning to write the length
      field, then update the elements (in the order they appear in the file)
      and seek back to the end.
      
      This reduces the ordinary amount of seeks of the Matroska muxer to two
      (ordinary excludes scenarios where one has big Chapters or Attachments
      or where one writes the Cues at the front).
      Signed-off-by: 's avatarAndreas Rheinhardt <andreas.rheinhardt@gmail.com>
      efeb3a53
    • Andreas Rheinhardt's avatar
      avformat/matroskaenc: Only write Cues at the front if space has been reserved · a54c94d9
      Andreas Rheinhardt authored
      If the AVIOContext for output was unseekable when writing the header,
      no space for Cues would be reserved even if the reserve_index_space
      option was used (because it is reasonable to expect that one can't seek
      back to the beginning to write the Cues anyway). But if the AVIOContext
      was seekable when writing the trailer, it was presumed that space for
      the Cues had been reserved when the reserve_index_space option indicated
      so even when it was not. As a result, the beginning of the file would be
      overwritten.
      
      This commit fixes this: If the reserve_index_space option had been used
      and no space has been reserved in advance because of unseekability when
      writing the header, then no attempt to write Cues will be performed
      when writing the trailer; after all, writing them at the front is
      impossible and writing them at the end is probably undesired.
      Signed-off-by: 's avatarAndreas Rheinhardt <andreas.rheinhardt@gmail.com>
      a54c94d9
    • Andreas Rheinhardt's avatar
      avformat/matroskaenc: Don't reserve space for duration when unseekable · 81e39cf4
      Andreas Rheinhardt authored
      We won't be able to seek back to write the actual duration anyway.
      
      FATE-tests using the md5pipe command had to be updated due to this change.
      Signed-off-by: 's avatarAndreas Rheinhardt <andreas.rheinhardt@gmail.com>
      81e39cf4
    • Andreas Rheinhardt's avatar
      avformat/matroskaenc: Remove inconsistencies wrt seekability handling · 1779f0b1
      Andreas Rheinhardt authored
      The Matroska muxer behaves differently in several ways when it thinks
      that it is in unseekable/livestreaming mode: It does not add Cue entries
      because they won't be written anyway for a livestream and it writes some
      elements only preliminarily (with the intention to overwrite them with
      an updated version at the end) when non-livestreaming etc.
      
      There are two ways to set the Matroska muxer into livestreaming mode:
      Setting an option or by providing an unseekable AVIOContext. Yet the
      actual checks were not consistent:
      
      If the AVIOContext was unseekable and no AAC extradata was available
      when writing the header, writing the header failed; but if the AVIOContext
      was seekable, it didn't, because the muxer expected to get the extradata
      via packet side-data. Here the livestreaming option has not been checked,
      although one can't use the updated extradata in case it is a livestream.
      
      If the reserve_index_space option was used, space for writing Cues would
      be reserved when writing the header unless the AVIOContext was
      unseekable. Yet Cues were only written if the livestreaming option was
      not set and the AVIOContext was seekable (when writing the trailer), so
      if the AVIOContext was seekable and the livestreaming option set, the
      reserved space would never be used at all.
      
      If the AVIOContext was unseekable and the livestreaming option was not
      set, it would be attempted to update the main length field at the end.
      After all, it might be possible that the file is so short that it fits
      into the AVIOContext's buffer in which case the seek back would work.
      Yet this is dangerous: It might be that we are not dealing with a
      simple output file, but that our output gets split into chunks and that
      each of these chunks is actually seekable. In this case some part of the
      last chunk (namely the eight bytes that have the same offset as the
      length field had in the header) will be overwritten with what the muxer
      wrongly believes to be the filesize.
      (The livestreaming option has been added to deal with this scenario,
      yet its documentation ("Write files assuming it is a live stream.")
      doesn't make this clear at all. At least the segment muxer does not
      set the option for live and given that the chances of successfully
      seeking when the output is actually unseekable are slim, it is best to
      not attempt to update the length field in the unseekable case at all.)
      
      All these inconsistencies were fixed by treating the output as seekable
      if the livestreaming option is not set and if the AVIOContext is
      seekable. A macro has been used to enforce consistency and improve code
      readability.
      Signed-off-by: 's avatarAndreas Rheinhardt <andreas.rheinhardt@gmail.com>
      1779f0b1
    • Andreas Rheinhardt's avatar
      avformat/matroskaenc: Don't segfault when seekability changes · 8aabcf6c
      Andreas Rheinhardt authored
      If the Matroska muxer's AVIOContext was unseekable when writing the
      header, but is seekable when writing the trailer, the code for writing
      the trailer presumes that a dynamic buffer exists and tries to update
      its content in order to overwrite data that has already been
      preliminarily written when writing the header, yet said buffer doesn't
      exist as it has been written finally and not preliminarily when writing
      the header (because of the unseekability it was presumed that one won't
      be able to update the data anyway).
      
      This commit adds a check for this and also for a similar situation
      involving updating extradata with new data from packet side-data.
      Signed-off-by: 's avatarAndreas Rheinhardt <andreas.rheinhardt@gmail.com>
      8aabcf6c