[FFmpeg-devel] [PATCH 3/3] mov: support timecode extraction.
Baptiste Coudurier
baptiste.coudurier at gmail.com
Thu Jan 5 08:07:27 CET 2012
On 1/3/12 12:28 AM, Clément Bœsch wrote:
> On Mon, Jan 02, 2012 at 09:36:19PM +0000, Baptiste Coudurier wrote:
>> On 1/2/12 4:23 PM, Clément Bœsch wrote:
>>> From: Clément Bœsch <clement.boesch at smartjog.com>
>>>
>>> ---
>>> I'm really not sure about this one. All the samples I have store the timecode
>>> in "frame number" format. But all of them have the Counter flag unset.
>>> Unfortunately, the specs[1] stats (p160+):
>>>
>>> If the Counter flag is set to 1 in the timecode sample description, the
>>> sample data is an unsigned 32-bit integer. The timecode counter value is
>>> determined by dividing this unsigned 32-bit integer by the number of frames
>>> field in the timecode sample description.
>>>
>>> If the Counter flag is set to 0 in the timecode sample description, the
>>> sample data format is a signed 32-bit integer and is used to calculate a
>>> timecode record, defined as follows.
>>>
>>> [...]
>>>
>>> So basically, I understand it as: cf=1 → frame number format, cf=0 → qt format.
>>>
>>> Also, I can't find a sample with a timecode stored in quicktime format (where
>>> counter flag should be set to 0).
>>
>> Just remove that code and display a message. It's not needed yet.
>>
>
> Mmh, OK. That is certainly a naive question, but any idea why the specs
> are just being violated in that case?
>
> Anyway, I dropped the QT format code, and assumed frame counter format all
> the time. I'm not so sure about printing a warning since it will likely
> warn for every single sample. OTOH, I think a comment on this might be
> appropriate for any future potential improvement.
>
> New patch attached.
>
>
>
> 0003-mov-support-timecode-extraction.patch
>
>
> From c816e8916c23f4d83c2d5ba0112ddc0df1513c1d Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= <clement.boesch at smartjog.com>
> Date: Mon, 2 Jan 2012 11:56:06 +0100
> Subject: [PATCH 3/3] mov: support timecode extraction.
>
> ---
> Changelog | 2 +-
> libavformat/mov.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++--
> 2 files changed, 50 insertions(+), 3 deletions(-)
>
> diff --git a/Changelog b/Changelog
> index 7b5d277..2dcc423 100644
> --- a/Changelog
> +++ b/Changelog
> @@ -6,7 +6,7 @@ version next:
> - v410 Quicktime Uncompressed 4:4:4 10-bit encoder and decoder
> - SBaGen (SBG) binaural beats script demuxer
> - OpenMG Audio muxer
> -- dv: add timecode to metadata
> +- Timecode extraction in DV and MOV
> - thumbnail video filter
> - XML output in ffprobe
> - asplit audio filter
> diff --git a/libavformat/mov.c b/libavformat/mov.c
> index ee67a9f..57e7949 100644
> --- a/libavformat/mov.c
> +++ b/libavformat/mov.c
> @@ -36,6 +36,7 @@
> #include "riff.h"
> #include "isom.h"
> #include "libavcodec/get_bits.h"
> +#include "libavcodec/timecode.h"
> #include "id3v1.h"
> #include "mov_chan.h"
>
> @@ -2615,6 +2616,46 @@ finish:
> avio_seek(sc->pb, cur_pos, SEEK_SET);
> }
>
> +static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
> + uint32_t value)
> +{
> + char buf[16];
> + struct ff_timecode tc = {
> + .drop = st->codec->flags2 & CODEC_FLAG2_DROP_FRAME_TIMECODE,
> + .rate = (AVRational){st->codec->time_base.den,
> + st->codec->time_base.num},
> + };
> +
> + if (avpriv_check_timecode_rate(s, tc.rate, tc.drop) < 0)
> + return AVERROR(EINVAL);
> + av_dict_set(&st->metadata, "timecode",
> + avpriv_timecode_to_string(buf, &tc, value), 0);
Overall the API is pretty ugly.
Why 2 params for check_timecode_rate when passing a struct tcblah would
be sufficient.
Why timecode_to_string when it's obviously a frame number instead of a timecode ?
Why a struct tcblah + value instead of one struct tc ?
> + return 0;
> +}
> +
> +static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
> +{
> + MOVStreamContext *sc = st->priv_data;
> + int64_t cur_pos = avio_tell(sc->pb);
> + uint32_t value;
> +
> + if (!st->nb_index_entries)
> + return -1;
> +
> + avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
> + value = avio_rb32(s->pb);
> +
> + /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
> + * not the case) and thus assume "frame number format" instead of QT one.
> + * No sample with tmcd track can be found with a QT timecode at the moment,
> + * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
> + * format). */
> + parse_timecode_in_framenum_format(s, st, value);
> +
> + avio_seek(sc->pb, cur_pos, SEEK_SET);
> + return 0;
> +}
> +
> static int mov_read_header(AVFormatContext *s, AVFormatParameters *ap)
> {
> MOVContext *mov = s->priv_data;
> @@ -2640,8 +2681,14 @@ static int mov_read_header(AVFormatContext *s, AVFormatParameters *ap)
> }
> av_dlog(mov->fc, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
>
> - if (pb->seekable && mov->chapter_track > 0)
> - mov_read_chapters(s);
> + if (pb->seekable) {
> + int i;
> + if (mov->chapter_track > 0)
> + mov_read_chapters(s);
> + for (i = 0; i < s->nb_streams; i++)
> + if (s->streams[i]->codec->codec_tag == MKTAG('t','m','c','d'))
AV_RL32("tmcd")
--
Baptiste COUDURIER
Key fingerprint 8D77134D20CC9220201FC5DB0AC9325C5C1ABAAA
FFmpeg maintainer http://www.ffmpeg.org
More information about the ffmpeg-devel
mailing list