[FFmpeg-devel] [PATCH] Keep track of stream duration and nb_frames when muxing
Aurelien Jacobs
aurel
Wed Jan 20 17:40:35 CET 2010
On Tue, Jan 19, 2010 at 12:18:35AM -0500, David Conrad wrote:
> Hi,
>
> This has av_(interleaved)_write_frame() keep track of duration and number of frames for each stream. This is generally useful for calculating an average frame rate after muxing is complete, as I intend to write for mkv.
>
> [...]
>
> commit 980dec0261bb25a47c8a0b65f85288ca70a3e2da
> Author: David Conrad <lessen42 at gmail.com>
> Date: Tue Jan 19 00:12:33 2010 -0500
>
> Write average frame rate in the matroska header
>
> diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
> index c119518..162467a 100644
> --- a/libavformat/matroskaenc.c
> +++ b/libavformat/matroskaenc.c
> @@ -580,6 +581,11 @@ static int mkv_write_tracks(AVFormatContext *s)
> put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYWIDTH , d_width);
> put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYHEIGHT, codec->height);
> }
> + mkv->fps_offset[i] = url_ftell(pb);
> + if (st->avg_frame_rate.num && st->avg_frame_rate.den)
> + put_ebml_float(pb, MATROSKA_ID_VIDEOFRAMERATE, av_q2d(st->avg_frame_rate));
> + else
> + put_ebml_float(pb, MATROSKA_ID_VIDEOFRAMERATE, 1/av_q2d(codec->time_base));
IMHO it would be nicer to extract the put_ebml_float() call out of the if(),
IOW use a temporary fps variable.
But maybe that's just my cosmetical preference, so fell free to ignore this
comment if you don't like it.
> @@ -908,6 +914,17 @@ static int mkv_write_trailer(AVFormatContext *s)
> url_fseek(pb, mkv->duration_offset, SEEK_SET);
> put_ebml_float(pb, MATROSKA_ID_DURATION, mkv->duration);
>
> + // update the fps
> + for (i = 0; i < s->nb_streams; i++) {
> + AVStream *st = s->streams[i];
> + int64_t duration = st->duration - st->start_time;
> + if (duration && st->nb_frames) {
> + double fps = st->nb_frames / (duration * av_q2d(st->time_base));
> + url_fseek(pb, mkv->fps_offset[i], SEEK_SET);
> + put_ebml_float(pb, MATROSKA_ID_VIDEOFRAMERATE, fps);
> + }
> + }
MATROSKA_ID_VIDEOFRAMERATE is only valid for video tracks. Here you
try to write it for every tracks, including the non-video ones (for
which mkv->fps_offset[i] was not initialized).
Aurel
More information about the ffmpeg-devel
mailing list