On Tue, 30 Apr 2013 09:18:31 +0200, Luca Barbato <[email protected]> wrote:
> On 04/30/2013 08:37 AM, Anton Khirnov wrote:
> > ---
> >  Changelog                 |    1 +
> >  doc/muxers.texi           |   21 +++++++++++++++
> >  libavformat/matroskaenc.c |   64 
> > ++++++++++++++++++++++++++++++++++++++++++++-
> >  libavformat/version.h     |    2 +-
> >  4 files changed, 86 insertions(+), 2 deletions(-)
> > 
> > diff --git a/Changelog b/Changelog
> > index 24f0791..e9e0a9f 100644
> > --- a/Changelog
> > +++ b/Changelog
> > @@ -16,6 +16,7 @@ version 9_beta3:
> >  - multi-channel ALAC encoding up to 7.1
> >  - TAK demuxer, parser, and decoder
> >  - adaptive frame-level multithreading for H.264
> > +- an option in matroska muxer to put the index at the beginning of the file
> >  
> >  
> >  version 9_beta2:
> > diff --git a/doc/muxers.texi b/doc/muxers.texi
> > index e368e68..19a5806 100644
> > --- a/doc/muxers.texi
> > +++ b/doc/muxers.texi
> > @@ -367,6 +367,27 @@ For example a 3D WebM clip can be created using the 
> > following command line:
> >  avconv -i sample_left_right_clip.mpg -an -c:v libvpx -metadata 
> > STEREO_MODE=left_right -y stereo_clip.webm
> >  @end example
> >  
> > +This muxer supports the following options:
> > +
> > +@table @option
> > +
> > +@item reserve_index_space
> > +By default, this muxer writes the index for seeking (called cues in 
> > matroska
> > +terms) at the end of the file, because it cannot know in advance how much 
> > space
> > +to leave for it at the beginning of the file. However for some use cases 
> > -- e.g.
> > +streaming where seeking is possible but slow -- it is useful to put the 
> > index at
> > +the beginning of the file.
> > +
> > +If this option is set to a non-zero value, the muxer will reserve a given 
> > amount
> > +of space in the file header and then try to write the cues there when the 
> > muxing
> > +finishes. If there is not enough space, muxing will fail. A safe size for 
> > most
> > +use cases should be about 50kB per hour of video.
> > +
> > +Note that cues are only written if the output is seekable and this option 
> > will
> > +have no effect if it is not.
> > +
> > +@end table
> > +
> >  @section segment
> >  
> >  Basic stream segmenter.
> > diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
> > index b0998d4..c521ed3 100644
> > --- a/libavformat/matroskaenc.c
> > +++ b/libavformat/matroskaenc.c
> > @@ -34,6 +34,7 @@
> >  #include "libavutil/intreadwrite.h"
> >  #include "libavutil/lfg.h"
> >  #include "libavutil/mathematics.h"
> > +#include "libavutil/opt.h"
> >  #include "libavutil/random_seed.h"
> >  #include "libavutil/samplefmt.h"
> >  
> > @@ -79,6 +80,7 @@ typedef struct {
> >  #define MODE_WEBM       0x02
> >  
> >  typedef struct MatroskaMuxContext {
> > +    const AVClass  *class;
> >      int             mode;
> >      AVIOContext   *dyn_bc;
> >      ebml_master     segment;
> > @@ -95,6 +97,9 @@ typedef struct MatroskaMuxContext {
> >      AVPacket        cur_audio_pkt;
> >  
> >      int have_attachments;
> > +
> > +    int reserve_cues_space;
> > +    int64_t cues_pos;
> >  } MatroskaMuxContext;
> >  
> >  
> > @@ -968,6 +973,11 @@ static int mkv_write_header(AVFormatContext *s)
> >      if (mkv->cues == NULL)
> >          return AVERROR(ENOMEM);
> >  
> > +    if (pb->seekable && mkv->reserve_cues_space) {
> > +        mkv->cues_pos = avio_tell(pb);
> > +        put_ebml_void(pb, mkv->reserve_cues_space);
> > +    }
> > +
> >      av_init_packet(&mkv->cur_audio_pkt);
> >      mkv->cur_audio_pkt.size = 0;
> >  
> > @@ -1250,7 +1260,28 @@ static int mkv_write_trailer(AVFormatContext *s)
> >  
> >      if (pb->seekable) {
> >          if (mkv->cues->num_entries) {
> > -            cuespos = mkv_write_cues(pb, mkv->cues, s->nb_streams);
> > +            if (mkv->reserve_cues_space) {
> > +                int64_t cues_end;
> > +
> > +                currentpos = avio_tell(pb);
> > +                avio_seek(pb, mkv->cues_pos, SEEK_SET);
> > +
> > +                cuespos = mkv_write_cues(pb, mkv->cues, s->nb_streams);
> > +                cues_end = avio_tell(pb);
> > +                if (cues_end > cuespos + mkv->reserve_cues_space) {
> > +                    av_log(s, AV_LOG_ERROR, "Insufficient space reserved 
> > for cues: %d "
> > +                           "(needed: %"PRId64").\n", 
> > mkv->reserve_cues_space,
> > +                           cues_end - cuespos);
> > +                    return AVERROR(EINVAL);
> 
> In that case might be better wipe the index and fallback to the normal
> situation.
> 

I don't think it's better.

If the caller bothered to set this option, the he probably cares about it being
used. So IMO it's better to fail if we cannot do what was requested.

Also at this point we have probably irretrievably overwritten some other data.
This could be handled of course, but I really think it's better to fail.

-- 
Anton Khirnov
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to