mov: support timecode extraction.
This commit is contained in:
parent
adc278788b
commit
35da85562d
@ -6,7 +6,7 @@ version next:
|
|||||||
- v410 Quicktime Uncompressed 4:4:4 10-bit encoder and decoder
|
- v410 Quicktime Uncompressed 4:4:4 10-bit encoder and decoder
|
||||||
- SBaGen (SBG) binaural beats script demuxer
|
- SBaGen (SBG) binaural beats script demuxer
|
||||||
- OpenMG Audio muxer
|
- OpenMG Audio muxer
|
||||||
- dv: add timecode to metadata
|
- Timecode extraction in DV and MOV
|
||||||
- thumbnail video filter
|
- thumbnail video filter
|
||||||
- XML output in ffprobe
|
- XML output in ffprobe
|
||||||
- asplit audio filter
|
- asplit audio filter
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include "riff.h"
|
#include "riff.h"
|
||||||
#include "isom.h"
|
#include "isom.h"
|
||||||
#include "libavcodec/get_bits.h"
|
#include "libavcodec/get_bits.h"
|
||||||
|
#include "libavcodec/timecode.h"
|
||||||
#include "id3v1.h"
|
#include "id3v1.h"
|
||||||
#include "mov_chan.h"
|
#include "mov_chan.h"
|
||||||
|
|
||||||
@ -2615,6 +2616,46 @@ finish:
|
|||||||
avio_seek(sc->pb, cur_pos, SEEK_SET);
|
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)
|
static int mov_read_header(AVFormatContext *s, AVFormatParameters *ap)
|
||||||
{
|
{
|
||||||
MOVContext *mov = s->priv_data;
|
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));
|
av_dlog(mov->fc, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
|
||||||
|
|
||||||
if (pb->seekable && mov->chapter_track > 0)
|
if (pb->seekable) {
|
||||||
mov_read_chapters(s);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user