matroska : Add support for reading/writing creation_time metadata.
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
parent
c7048036db
commit
2e061130f4
@ -235,6 +235,7 @@ typedef struct {
|
|||||||
uint64_t time_scale;
|
uint64_t time_scale;
|
||||||
double duration;
|
double duration;
|
||||||
char *title;
|
char *title;
|
||||||
|
EbmlBin date_utc;
|
||||||
EbmlList tracks;
|
EbmlList tracks;
|
||||||
EbmlList attachments;
|
EbmlList attachments;
|
||||||
EbmlList chapters;
|
EbmlList chapters;
|
||||||
@ -294,7 +295,7 @@ static EbmlSyntax matroska_info[] = {
|
|||||||
{ MATROSKA_ID_TITLE, EBML_UTF8, 0, offsetof(MatroskaDemuxContext,title) },
|
{ MATROSKA_ID_TITLE, EBML_UTF8, 0, offsetof(MatroskaDemuxContext,title) },
|
||||||
{ MATROSKA_ID_WRITINGAPP, EBML_NONE },
|
{ MATROSKA_ID_WRITINGAPP, EBML_NONE },
|
||||||
{ MATROSKA_ID_MUXINGAPP, 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 },
|
{ MATROSKA_ID_SEGMENTUID, EBML_NONE },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
@ -1346,6 +1347,17 @@ static int matroska_aac_sri(int samplerate)
|
|||||||
return sri;
|
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)
|
static int matroska_read_header(AVFormatContext *s)
|
||||||
{
|
{
|
||||||
MatroskaDemuxContext *matroska = s->priv_data;
|
MatroskaDemuxContext *matroska = s->priv_data;
|
||||||
@ -1406,6 +1418,9 @@ static int matroska_read_header(AVFormatContext *s)
|
|||||||
* 1000 / AV_TIME_BASE;
|
* 1000 / AV_TIME_BASE;
|
||||||
av_dict_set(&s->metadata, "title", matroska->title, 0);
|
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;
|
tracks = matroska->tracks.elem;
|
||||||
for (i=0; i < matroska->tracks.nb_elem; i++) {
|
for (i=0; i < matroska->tracks.nb_elem; i++) {
|
||||||
MatroskaTrack *track = &tracks[i];
|
MatroskaTrack *track = &tracks[i];
|
||||||
|
@ -940,6 +940,14 @@ static int mkv_write_header(AVFormatContext *s)
|
|||||||
put_ebml_binary(pb, MATROSKA_ID_SEGMENTUID, segment_uid, 16);
|
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
|
// reserve space for the duration
|
||||||
mkv->duration = 0;
|
mkv->duration = 0;
|
||||||
mkv->duration_offset = avio_tell(pb);
|
mkv->duration_offset = avio_tell(pb);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user