[FFmpeg-devel] [PATCH 1/5] avformat/mov: export edit list as stream side data
Clément Bœsch
u at pkh.me
Tue Jan 6 18:09:57 CET 2015
From: Clément Bœsch <clement at stupeflix.com>
Add a AV_PKT_DATA_MOV_TIMELINE stream side data which will be used by
the MOV/MP4 demuxer when "ignore_editlist" option is set to "export"
(or -1, not the default).
Note: exporting the timeline as side data inhibits current demuxer
heuristics.
TODO: bump micro
---
libavcodec/avcodec.h | 7 +++++++
libavformat/dump.c | 3 +++
libavformat/mov.c | 46 ++++++++++++++++++++++++++++++++++++++++++++--
3 files changed, 54 insertions(+), 2 deletions(-)
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 99467bb..0b761b4 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -1094,6 +1094,13 @@ enum AVPacketSideDataType {
* side data includes updated metadata which appeared in the stream.
*/
AV_PKT_DATA_METADATA_UPDATE,
+
+ /**
+ * MOV/MP4 elst atom, with additionnal 4 bytes at the beginning containing
+ * the presentation time scale to be used as a unit for the values in the
+ * table.
+ */
+ AV_PKT_DATA_MOV_TIMELINE,
};
typedef struct AVPacketSideData {
diff --git a/libavformat/dump.c b/libavformat/dump.c
index 56b37ff..6436521 100644
--- a/libavformat/dump.c
+++ b/libavformat/dump.c
@@ -328,6 +328,9 @@ static void dump_sidedata(void *ctx, AVStream *st, const char *indent)
av_log(ctx, AV_LOG_INFO, "stereo3d: ");
dump_stereo3d(ctx, &sd);
break;
+ case AV_PKT_DATA_MOV_TIMELINE:
+ av_log(ctx, AV_LOG_INFO, "mov edit list");
+ break;
default:
av_log(ctx, AV_LOG_WARNING,
"unknown side data type %d (%d bytes)", sd.type, sd.size);
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 248faf7..27e0232 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -3209,14 +3209,54 @@ free_and_return:
#endif
}
+static int export_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+ int n;
+ uint8_t *buf;
+ AVPacketSideData *sd, *tmp;
+ AVStream *st = c->fc->streams[c->fc->nb_streams-1];
+ int64_t start = avio_tell(pb);
+
+ buf = av_malloc(atom.size + 4);
+ if (!buf)
+ return AVERROR(ENOMEM);
+
+ AV_WB32(buf, c->time_scale);
+
+ n = avio_read(pb, buf + 4, atom.size);
+ if (n != atom.size) {
+ av_log(c->fc, AV_LOG_ERROR, "Unexpected read error in ELST\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ tmp = av_realloc_array(st->side_data, st->nb_side_data + 1, sizeof(*tmp));
+ if (!tmp) {
+ av_freep(&buf);
+ return AVERROR(ENOMEM);
+ }
+ st->side_data = tmp;
+ st->nb_side_data++;
+
+ sd = &st->side_data[st->nb_side_data - 1];
+ sd->type = AV_PKT_DATA_MOV_TIMELINE;
+ sd->data = buf;
+ sd->size = atom.size + 4;
+
+ return avio_seek(pb, start, SEEK_SET);
+}
+
/* edit list atom */
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
MOVStreamContext *sc;
int i, edit_count, version;
- if (c->fc->nb_streams < 1 || c->ignore_editlist)
+ if (c->fc->nb_streams < 1 || c->ignore_editlist == 1)
return 0;
+
+ if (c->ignore_editlist == -1)
+ return export_elst(c, pb, atom);
+
sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
version = avio_r8(pb); /* version */
@@ -4261,7 +4301,9 @@ static const AVOption mov_options[] = {
OFFSET(use_absolute_path), FF_OPT_TYPE_INT, {.i64 = 0},
0, 1, FLAGS},
{"ignore_editlist", "", OFFSET(ignore_editlist), FF_OPT_TYPE_INT, {.i64 = 0},
- 0, 1, FLAGS},
+ -1, 1, FLAGS, "editlist_mode"},
+ {"export", "ignore edit list and export is as side data",
+ 0, AV_OPT_TYPE_CONST, {.i64 = -1}, 0, 0, FLAGS, "editlist_mode" },
{"use_mfra_for",
"use mfra for fragment timestamps",
OFFSET(use_mfra_for), FF_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
--
2.2.1
More information about the ffmpeg-devel
mailing list