Mercurial > libavformat.hg
comparison matroskadec.c @ 3702:b4f34511ccd3 libavformat
matroskadec: add basic tags support (metadata)
author | aurel |
---|---|
date | Fri, 08 Aug 2008 23:50:38 +0000 |
parents | 4aef467adb6b |
children | b337fe64a31f |
comparison
equal
deleted
inserted
replaced
3701:5cf9918994ed | 3702:b4f34511ccd3 |
---|---|
162 uint64_t time; | 162 uint64_t time; |
163 EbmlList pos; | 163 EbmlList pos; |
164 } MatroskaIndex; | 164 } MatroskaIndex; |
165 | 165 |
166 typedef struct { | 166 typedef struct { |
167 char *name; | |
168 char *string; | |
169 EbmlList sub; | |
170 } MatroskaTag; | |
171 | |
172 typedef struct { | |
167 uint64_t id; | 173 uint64_t id; |
168 uint64_t pos; | 174 uint64_t pos; |
169 } MatroskaSeekhead; | 175 } MatroskaSeekhead; |
170 | 176 |
171 typedef struct { | 177 typedef struct { |
186 char *title; | 192 char *title; |
187 EbmlList tracks; | 193 EbmlList tracks; |
188 EbmlList attachments; | 194 EbmlList attachments; |
189 EbmlList chapters; | 195 EbmlList chapters; |
190 EbmlList index; | 196 EbmlList index; |
197 EbmlList tags; | |
191 EbmlList seekhead; | 198 EbmlList seekhead; |
192 | 199 |
193 /* byte position of the segment inside the stream */ | 200 /* byte position of the segment inside the stream */ |
194 offset_t segment_start; | 201 offset_t segment_start; |
195 | 202 |
388 { MATROSKA_ID_POINTENTRY, EBML_NEST, sizeof(MatroskaIndex), offsetof(MatroskaDemuxContext,index), {.n=matroska_index_entry} }, | 395 { MATROSKA_ID_POINTENTRY, EBML_NEST, sizeof(MatroskaIndex), offsetof(MatroskaDemuxContext,index), {.n=matroska_index_entry} }, |
389 { EBML_ID_VOID, EBML_NONE }, | 396 { EBML_ID_VOID, EBML_NONE }, |
390 { 0 } | 397 { 0 } |
391 }; | 398 }; |
392 | 399 |
400 static EbmlSyntax matroska_simpletag[] = { | |
401 { MATROSKA_ID_TAGNAME, EBML_UTF8, 0, offsetof(MatroskaTag,name) }, | |
402 { MATROSKA_ID_TAGSTRING, EBML_UTF8, 0, offsetof(MatroskaTag,string) }, | |
403 { MATROSKA_ID_SIMPLETAG, EBML_NEST, sizeof(MatroskaTag), offsetof(MatroskaTag,sub), {.n=matroska_simpletag} }, | |
404 { MATROSKA_ID_TAGLANG, EBML_NONE }, | |
405 { MATROSKA_ID_TAGDEFAULT, EBML_NONE }, | |
406 { EBML_ID_VOID, EBML_NONE }, | |
407 { 0 } | |
408 }; | |
409 | |
410 static EbmlSyntax matroska_tag[] = { | |
411 { MATROSKA_ID_SIMPLETAG, EBML_NEST, sizeof(MatroskaTag), 0, {.n=matroska_simpletag} }, | |
412 { MATROSKA_ID_TAGTARGETS, EBML_NONE }, | |
413 { EBML_ID_VOID, EBML_NONE }, | |
414 { 0 } | |
415 }; | |
416 | |
393 static EbmlSyntax matroska_tags[] = { | 417 static EbmlSyntax matroska_tags[] = { |
418 { MATROSKA_ID_TAG, EBML_NEST, 0, offsetof(MatroskaDemuxContext,tags), {.n=matroska_tag} }, | |
394 { EBML_ID_VOID, EBML_NONE }, | 419 { EBML_ID_VOID, EBML_NONE }, |
395 { 0 } | 420 { 0 } |
396 }; | 421 }; |
397 | 422 |
398 static EbmlSyntax matroska_seekhead_entry[] = { | 423 static EbmlSyntax matroska_seekhead_entry[] = { |
444 }; | 469 }; |
445 | 470 |
446 static EbmlSyntax matroska_clusters[] = { | 471 static EbmlSyntax matroska_clusters[] = { |
447 { MATROSKA_ID_CLUSTER, EBML_NEST, 0, 0, {.n=matroska_cluster} }, | 472 { MATROSKA_ID_CLUSTER, EBML_NEST, 0, 0, {.n=matroska_cluster} }, |
448 { 0 } | 473 { 0 } |
474 }; | |
475 | |
476 #define SIZE_OFF(x) sizeof(((AVFormatContext*)0)->x),offsetof(AVFormatContext,x) | |
477 const struct { | |
478 const char name[16]; | |
479 int size; | |
480 int offset; | |
481 } metadata[] = { | |
482 { "TITLE", SIZE_OFF(title) }, | |
483 { "ARTIST", SIZE_OFF(author) }, | |
484 { "WRITTEN_BY", SIZE_OFF(author) }, | |
485 { "LEAD_PERFORMER", SIZE_OFF(author) }, | |
486 { "COPYRIGHT", SIZE_OFF(copyright) }, | |
487 { "COMMENT", SIZE_OFF(comment) }, | |
488 { "ALBUM", SIZE_OFF(album) }, | |
489 { "DATE_WRITTEN", SIZE_OFF(year) }, | |
490 { "DATE_RELEASED", SIZE_OFF(year) }, | |
491 { "PART_NUMBER", SIZE_OFF(track) }, | |
492 { "GENRE", SIZE_OFF(genre) }, | |
449 }; | 493 }; |
450 | 494 |
451 /* | 495 /* |
452 * Return: Whether we reached the end of a level in the hierarchy or not. | 496 * Return: Whether we reached the end of a level in the hierarchy or not. |
453 */ | 497 */ |
889 failed: | 933 failed: |
890 av_free(pkt_data); | 934 av_free(pkt_data); |
891 return -1; | 935 return -1; |
892 } | 936 } |
893 | 937 |
938 static void matroska_convert_tags(AVFormatContext *s, EbmlList *list) | |
939 { | |
940 MatroskaTag *tags = list->elem; | |
941 int i, j; | |
942 | |
943 for (i=0; i < list->nb_elem; i++) { | |
944 for (j=0; j < ARRAY_SIZE(metadata); j++){ | |
945 if (!strcmp(tags[i].name, metadata[j].name)) { | |
946 int *ptr = (int *)((char *)s + metadata[j].offset); | |
947 if (*ptr) continue; | |
948 if (metadata[j].size > sizeof(int)) | |
949 av_strlcpy((char *)ptr, tags[i].string, metadata[j].size); | |
950 else | |
951 *ptr = atoi(tags[i].string); | |
952 } | |
953 } | |
954 if (tags[i].sub.nb_elem) | |
955 matroska_convert_tags(s, &tags[i].sub); | |
956 } | |
957 } | |
958 | |
894 static void matroska_execute_seekhead(MatroskaDemuxContext *matroska) | 959 static void matroska_execute_seekhead(MatroskaDemuxContext *matroska) |
895 { | 960 { |
896 EbmlList *seekhead_list = &matroska->seekhead; | 961 EbmlList *seekhead_list = &matroska->seekhead; |
897 MatroskaSeekhead *seekhead = seekhead_list->elem; | 962 MatroskaSeekhead *seekhead = seekhead_list->elem; |
898 uint32_t level_up = matroska->level_up; | 963 uint32_t level_up = matroska->level_up; |
1000 matroska->ctx->duration = matroska->duration * matroska->time_scale | 1065 matroska->ctx->duration = matroska->duration * matroska->time_scale |
1001 * 1000 / AV_TIME_BASE; | 1066 * 1000 / AV_TIME_BASE; |
1002 if (matroska->title) | 1067 if (matroska->title) |
1003 strncpy(matroska->ctx->title, matroska->title, | 1068 strncpy(matroska->ctx->title, matroska->title, |
1004 sizeof(matroska->ctx->title)-1); | 1069 sizeof(matroska->ctx->title)-1); |
1070 matroska_convert_tags(s, &matroska->tags); | |
1005 | 1071 |
1006 tracks = matroska->tracks.elem; | 1072 tracks = matroska->tracks.elem; |
1007 for (i=0; i < matroska->tracks.nb_elem; i++) { | 1073 for (i=0; i < matroska->tracks.nb_elem; i++) { |
1008 MatroskaTrack *track = &tracks[i]; | 1074 MatroskaTrack *track = &tracks[i]; |
1009 enum CodecID codec_id = CODEC_ID_NONE; | 1075 enum CodecID codec_id = CODEC_ID_NONE; |