[FFmpeg-devel] [PATCH 3/3] mov: support timecode extraction.

Clément Bœsch ubitux at gmail.com
Tue Jan 3 09:28:07 CET 2012


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.

-- 
Clément B.
-------------- next part --------------
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);
+    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'))
+                mov_read_timecode_track(s, s->streams[i]);
+    }
 
     return 0;
 }
-- 
1.7.7.3

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 490 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20120103/90ecfa06/attachment.asc>


More information about the ffmpeg-devel mailing list