Commit 35da8556 authored by Clément Bœsch's avatar Clément Bœsch Committed by Clément Bœsch

mov: support timecode extraction.

parent adc27878
......@@ -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
......
......@@ -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)
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 == AV_RL32("tmcd"))
mov_read_timecode_track(s, s->streams[i]);
}
return 0;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment