Commit d75542c7 authored by aurel's avatar aurel

matroskadec: add basic tags support (metadata)

git-svn-id: file:///var/local/repositories/ffmpeg/trunk@14672 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b
parent c800cb13
...@@ -133,7 +133,13 @@ ...@@ -133,7 +133,13 @@
#define MATROSKA_ID_CUECLUSTERPOSITION 0xF1 #define MATROSKA_ID_CUECLUSTERPOSITION 0xF1
/* IDs in the tags master */ /* IDs in the tags master */
/* TODO */ #define MATROSKA_ID_TAG 0x7373
#define MATROSKA_ID_SIMPLETAG 0x67C8
#define MATROSKA_ID_TAGNAME 0x45A3
#define MATROSKA_ID_TAGSTRING 0x4487
#define MATROSKA_ID_TAGLANG 0x447A
#define MATROSKA_ID_TAGDEFAULT 0x44B4
#define MATROSKA_ID_TAGTARGETS 0x63C0
/* IDs in the seekhead master */ /* IDs in the seekhead master */
#define MATROSKA_ID_SEEKENTRY 0x4DBB #define MATROSKA_ID_SEEKENTRY 0x4DBB
......
...@@ -163,6 +163,12 @@ typedef struct { ...@@ -163,6 +163,12 @@ typedef struct {
EbmlList pos; EbmlList pos;
} MatroskaIndex; } MatroskaIndex;
typedef struct {
char *name;
char *string;
EbmlList sub;
} MatroskaTag;
typedef struct { typedef struct {
uint64_t id; uint64_t id;
uint64_t pos; uint64_t pos;
...@@ -188,6 +194,7 @@ typedef struct { ...@@ -188,6 +194,7 @@ typedef struct {
EbmlList attachments; EbmlList attachments;
EbmlList chapters; EbmlList chapters;
EbmlList index; EbmlList index;
EbmlList tags;
EbmlList seekhead; EbmlList seekhead;
/* byte position of the segment inside the stream */ /* byte position of the segment inside the stream */
...@@ -390,7 +397,25 @@ static EbmlSyntax matroska_index[] = { ...@@ -390,7 +397,25 @@ static EbmlSyntax matroska_index[] = {
{ 0 } { 0 }
}; };
static EbmlSyntax matroska_simpletag[] = {
{ MATROSKA_ID_TAGNAME, EBML_UTF8, 0, offsetof(MatroskaTag,name) },
{ MATROSKA_ID_TAGSTRING, EBML_UTF8, 0, offsetof(MatroskaTag,string) },
{ MATROSKA_ID_SIMPLETAG, EBML_NEST, sizeof(MatroskaTag), offsetof(MatroskaTag,sub), {.n=matroska_simpletag} },
{ MATROSKA_ID_TAGLANG, EBML_NONE },
{ MATROSKA_ID_TAGDEFAULT, EBML_NONE },
{ EBML_ID_VOID, EBML_NONE },
{ 0 }
};
static EbmlSyntax matroska_tag[] = {
{ MATROSKA_ID_SIMPLETAG, EBML_NEST, sizeof(MatroskaTag), 0, {.n=matroska_simpletag} },
{ MATROSKA_ID_TAGTARGETS, EBML_NONE },
{ EBML_ID_VOID, EBML_NONE },
{ 0 }
};
static EbmlSyntax matroska_tags[] = { static EbmlSyntax matroska_tags[] = {
{ MATROSKA_ID_TAG, EBML_NEST, 0, offsetof(MatroskaDemuxContext,tags), {.n=matroska_tag} },
{ EBML_ID_VOID, EBML_NONE }, { EBML_ID_VOID, EBML_NONE },
{ 0 } { 0 }
}; };
...@@ -448,6 +473,25 @@ static EbmlSyntax matroska_clusters[] = { ...@@ -448,6 +473,25 @@ static EbmlSyntax matroska_clusters[] = {
{ 0 } { 0 }
}; };
#define SIZE_OFF(x) sizeof(((AVFormatContext*)0)->x),offsetof(AVFormatContext,x)
const struct {
const char name[16];
int size;
int offset;
} metadata[] = {
{ "TITLE", SIZE_OFF(title) },
{ "ARTIST", SIZE_OFF(author) },
{ "WRITTEN_BY", SIZE_OFF(author) },
{ "LEAD_PERFORMER", SIZE_OFF(author) },
{ "COPYRIGHT", SIZE_OFF(copyright) },
{ "COMMENT", SIZE_OFF(comment) },
{ "ALBUM", SIZE_OFF(album) },
{ "DATE_WRITTEN", SIZE_OFF(year) },
{ "DATE_RELEASED", SIZE_OFF(year) },
{ "PART_NUMBER", SIZE_OFF(track) },
{ "GENRE", SIZE_OFF(genre) },
};
/* /*
* Return: Whether we reached the end of a level in the hierarchy or not. * Return: Whether we reached the end of a level in the hierarchy or not.
*/ */
...@@ -891,6 +935,27 @@ static int matroska_decode_buffer(uint8_t** buf, int* buf_size, ...@@ -891,6 +935,27 @@ static int matroska_decode_buffer(uint8_t** buf, int* buf_size,
return -1; return -1;
} }
static void matroska_convert_tags(AVFormatContext *s, EbmlList *list)
{
MatroskaTag *tags = list->elem;
int i, j;
for (i=0; i < list->nb_elem; i++) {
for (j=0; j < ARRAY_SIZE(metadata); j++){
if (!strcmp(tags[i].name, metadata[j].name)) {
int *ptr = (int *)((char *)s + metadata[j].offset);
if (*ptr) continue;
if (metadata[j].size > sizeof(int))
av_strlcpy((char *)ptr, tags[i].string, metadata[j].size);
else
*ptr = atoi(tags[i].string);
}
}
if (tags[i].sub.nb_elem)
matroska_convert_tags(s, &tags[i].sub);
}
}
static void matroska_execute_seekhead(MatroskaDemuxContext *matroska) static void matroska_execute_seekhead(MatroskaDemuxContext *matroska)
{ {
EbmlList *seekhead_list = &matroska->seekhead; EbmlList *seekhead_list = &matroska->seekhead;
...@@ -1002,6 +1067,7 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap) ...@@ -1002,6 +1067,7 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
if (matroska->title) if (matroska->title)
strncpy(matroska->ctx->title, matroska->title, strncpy(matroska->ctx->title, matroska->title,
sizeof(matroska->ctx->title)-1); sizeof(matroska->ctx->title)-1);
matroska_convert_tags(s, &matroska->tags);
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++) {
......
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