Browse code

mov: support timecode extraction.

Clément Bœsch authored on 2012/01/02 19:56:06
Showing 2 changed files
... ...
@@ -6,7 +6,7 @@ version next:
6 6
 - v410 Quicktime Uncompressed 4:4:4 10-bit encoder and decoder
7 7
 - SBaGen (SBG) binaural beats script demuxer
8 8
 - OpenMG Audio muxer
9
-- dv: add timecode to metadata
9
+- Timecode extraction in DV and MOV
10 10
 - thumbnail video filter
11 11
 - XML output in ffprobe
12 12
 - asplit audio filter
... ...
@@ -36,6 +36,7 @@
36 36
 #include "riff.h"
37 37
 #include "isom.h"
38 38
 #include "libavcodec/get_bits.h"
39
+#include "libavcodec/timecode.h"
39 40
 #include "id3v1.h"
40 41
 #include "mov_chan.h"
41 42
 
... ...
@@ -2615,6 +2616,46 @@ finish:
2615 2615
     avio_seek(sc->pb, cur_pos, SEEK_SET);
2616 2616
 }
2617 2617
 
2618
+static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
2619
+                                             uint32_t value)
2620
+{
2621
+    char buf[16];
2622
+    struct ff_timecode tc = {
2623
+        .drop  = st->codec->flags2 & CODEC_FLAG2_DROP_FRAME_TIMECODE,
2624
+        .rate  = (AVRational){st->codec->time_base.den,
2625
+                              st->codec->time_base.num},
2626
+    };
2627
+
2628
+    if (avpriv_check_timecode_rate(s, tc.rate, tc.drop) < 0)
2629
+        return AVERROR(EINVAL);
2630
+    av_dict_set(&st->metadata, "timecode",
2631
+                avpriv_timecode_to_string(buf, &tc, value), 0);
2632
+    return 0;
2633
+}
2634
+
2635
+static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
2636
+{
2637
+    MOVStreamContext *sc = st->priv_data;
2638
+    int64_t cur_pos = avio_tell(sc->pb);
2639
+    uint32_t value;
2640
+
2641
+    if (!st->nb_index_entries)
2642
+        return -1;
2643
+
2644
+    avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
2645
+    value = avio_rb32(s->pb);
2646
+
2647
+    /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
2648
+     * not the case) and thus assume "frame number format" instead of QT one.
2649
+     * No sample with tmcd track can be found with a QT timecode at the moment,
2650
+     * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
2651
+     * format). */
2652
+    parse_timecode_in_framenum_format(s, st, value);
2653
+
2654
+    avio_seek(sc->pb, cur_pos, SEEK_SET);
2655
+    return 0;
2656
+}
2657
+
2618 2658
 static int mov_read_header(AVFormatContext *s, AVFormatParameters *ap)
2619 2659
 {
2620 2660
     MOVContext *mov = s->priv_data;
... ...
@@ -2640,8 +2681,14 @@ static int mov_read_header(AVFormatContext *s, AVFormatParameters *ap)
2640 2640
     }
2641 2641
     av_dlog(mov->fc, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
2642 2642
 
2643
-    if (pb->seekable && mov->chapter_track > 0)
2644
-        mov_read_chapters(s);
2643
+    if (pb->seekable) {
2644
+        int i;
2645
+        if (mov->chapter_track > 0)
2646
+            mov_read_chapters(s);
2647
+        for (i = 0; i < s->nb_streams; i++)
2648
+            if (s->streams[i]->codec->codec_tag == AV_RL32("tmcd"))
2649
+                mov_read_timecode_track(s, s->streams[i]);
2650
+    }
2645 2651
 
2646 2652
     return 0;
2647 2653
 }