[FFmpeg-devel] [PATCH] matroska : Add support for reading/writing creation_time metadata.

Aaron Colwell acolwell at chromium.org
Sun Feb 26 01:49:42 CET 2012


---
 libavformat/matroskadec.c |   17 ++++++++++++++++-
 libavformat/matroskaenc.c |    8 ++++++++
 2 files changed, 24 insertions(+), 1 deletions(-)

diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index 26db823..fd91b43 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -235,6 +235,7 @@ typedef struct {
     uint64_t time_scale;
     double   duration;
     char    *title;
+    EbmlBin date_utc;
     EbmlList tracks;
     EbmlList attachments;
     EbmlList chapters;
@@ -294,7 +295,7 @@ static EbmlSyntax matroska_info[] = {
     { MATROSKA_ID_TITLE,              EBML_UTF8,  0,
offsetof(MatroskaDemuxContext,title) },
     { MATROSKA_ID_WRITINGAPP,         EBML_NONE },
     { MATROSKA_ID_MUXINGAPP,          EBML_NONE },
-    { MATROSKA_ID_DATEUTC,            EBML_NONE },
+    { MATROSKA_ID_DATEUTC,            EBML_BIN,  0,
offsetof(MatroskaDemuxContext,date_utc) },
     { MATROSKA_ID_SEGMENTUID,         EBML_NONE },
     { 0 }
 };
@@ -1343,6 +1344,17 @@ static int matroska_aac_sri(int samplerate)
     return sri;
 }

+static void matroska_metadata_creation_time(AVDictionary **metadata,
int64_t date_utc)
+{
+    char buffer[32];
+    /* Convert to seconds and adjust by number of seconds between
2001-01-01 and Epoch */
+    time_t creation_time = date_utc / 1000000000 + 978307200;
+    struct tm *ptm = gmtime(&creation_time);
+    if (!ptm) return;
+    strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", ptm);
+    av_dict_set(metadata, "creation_time", buffer, 0);
+}
+
 static int matroska_read_header(AVFormatContext *s)
 {
     MatroskaDemuxContext *matroska = s->priv_data;
@@ -1403,6 +1415,9 @@ static int matroska_read_header(AVFormatContext *s)
                                   * 1000 / AV_TIME_BASE;
     av_dict_set(&s->metadata, "title", matroska->title, 0);

+    if (matroska->date_utc.size == 8)
+        matroska_metadata_creation_time(&s->metadata,
AV_RB64(matroska->date_utc.data));
+
     tracks = matroska->tracks.elem;
     for (i=0; i < matroska->tracks.nb_elem; i++) {
         MatroskaTrack *track = &tracks[i];
diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index 0ee8348..0b36725 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -940,6 +940,14 @@ static int mkv_write_header(AVFormatContext *s)
         put_ebml_binary(pb, MATROSKA_ID_SEGMENTUID, segment_uid, 16);
     }

+    if (tag = av_dict_get(s->metadata, "creation_time", NULL, 0)) {
+        // Adjust time so it's relative to 2001-01-01 and convert to
nanoseconds.
+        int64_t date_utc = (ff_iso8601_to_unix_time(tag->value) -
978307200) * 1000000000;
+        uint8_t date_utc_buf[8];
+        AV_WB64(date_utc_buf, date_utc);
+        put_ebml_binary(pb, MATROSKA_ID_DATEUTC, date_utc_buf, 8);
+    }
+
     // reserve space for the duration
     mkv->duration = 0;
     mkv->duration_offset = avio_tell(pb);
-- 
1.7.0.4


More information about the ffmpeg-devel mailing list