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.
> + }
> +
> + if (cues_end < cuespos + mkv->reserve_cues_space)
> + put_ebml_void(pb, mkv->reserve_cues_space - (cues_end -
> cuespos));
> +
> + avio_seek(pb, currentpos, SEEK_SET);
You could make a static function out of the block above for additional
clarity.
> + } else {
> + cuespos = mkv_write_cues(pb, mkv->cues, s->nb_streams);
> + }
The rest looks good.
lu
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel