Add a list of generic tags and change demuxers to follow it.
authorAnton Khirnov <wyskas@gmail.com>
Mon, 1 Feb 2010 11:39:10 +0000 (11:39 +0000)
committerPeter Ross <pross@xvid.org>
Mon, 1 Feb 2010 11:39:10 +0000 (11:39 +0000)
Patch by Anton Khirnov, wyskas at gmail dot com

Originally committed as revision 21587 to svn://svn.ffmpeg.org/ffmpeg/trunk

12 files changed:
doc/APIchanges
libavformat/asf.c
libavformat/avformat.h
libavformat/id3v1.c
libavformat/id3v2.c
libavformat/matroska.c
libavformat/matroskadec.c
libavformat/metadata_compat.c
libavformat/mov.c
libavformat/movenc.c
libavformat/mp3.c
libavformat/oggparsevorbis.c

index cf601d8..339f14f 100644 (file)
@@ -12,6 +12,10 @@ libavutil:   2009-03-08
 
 API changes, most recent first:
 
+2010-02-01 - r21587 - lavf 52.50.0 - metadata API
+  Add a list of generic tag names, change 'author' -> 'artist',
+  'year' -> 'date'.
+
 2010-01-30 - r21545 - lavu 50.8.0 - av_get_pix_fmt()
   Add av_get_pix_fmt().
 
index cf01e07..e8b37d4 100644 (file)
@@ -129,12 +129,10 @@ const ff_asf_guid ff_asf_digital_signature = {
 };
 
 const AVMetadataConv ff_asf_metadata_conv[] = {
-    { "AlbumArtist", "artist"    },
+    { "AlbumArtist", "album_artist"},
     { "AlbumTitle" , "album"     },
-    { "Author"     , "author"    },
-    { "Genre"      , "genre"     },
-    { "Copyright"  , "copyright" },
+    { "Author"     , "artist"    },
     { "TrackNumber", "track"     },
-    { "Year"       , "year"      },
+//  { "Year"       , "date"      }, TODO: conversion year<->date
     { 0 }
 };
index fd38573..e404fd1 100644 (file)
@@ -22,7 +22,7 @@
 #define AVFORMAT_AVFORMAT_H
 
 #define LIBAVFORMAT_VERSION_MAJOR 52
-#define LIBAVFORMAT_VERSION_MINOR 49
+#define LIBAVFORMAT_VERSION_MINOR 50
 #define LIBAVFORMAT_VERSION_MICRO  0
 
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
@@ -73,11 +73,44 @@ struct AVFormatContext;
  * 2. Metadata is flat, not hierarchical; there are no subtags. If you
  *    want to store, e.g., the email address of the child of producer Alice
  *    and actor Bob, that could have key=alice_and_bobs_childs_email_address.
- * 3. A tag whose value is localized for a particular language is appended
- *    with a dash character ('-') and the ISO 639-2/B 3-letter language code.
- *    For example: Author-ger=Michael, Author-eng=Mike
- *    The original/default language is in the unqualified "Author" tag.
- *    A demuxer should set a default if it sets any translated tag.
+ * 3. Several modifiers can be applied to the tag name. This is done by
+ *    appending a dash character ('-') and the modifier name in the order
+ *    they appear in the list below -- e.g. foo-eng-sort, not foo-sort-eng.
+ *    a) language -- a tag whose value is localized for a particular language
+ *       is appended with the ISO 639-2/B 3-letter language code.
+ *       For example: Author-ger=Michael, Author-eng=Mike
+ *       The original/default language is in the unqualified "Author" tag.
+ *       A demuxer should set a default if it sets any translated tag.
+ *    b) sorting  -- a modified version of a tag that should be used for
+ *       sorting will have '-sort' appended. E.g. artist="The Beatles",
+ *       artist-sort="Beatles, The".
+ *
+ * 4. Tag names are normally exported exactly as stored in the container to
+ *    allow lossless remuxing to the same format. For container-independent
+ *    handling of metadata, av_metadata_conv() can convert it to ffmpeg generic
+ *    format. Follows a list of generic tag names:
+ *
+ * album        -- name of the set this work belongs to
+ * album_artist -- main creator of the set/album, if different from artist.
+ *                 e.g. "Various Artists" for compilation albums.
+ * artist       -- main creator of the work
+ * comment      -- any additional description of the file.
+ * composer     -- who composed the work, if different from artist.
+ * copyright    -- name of copyright holder.
+ * date         -- date when the work was created, preferably in ISO 8601.
+ * disc         -- number of a subset, e.g. disc in a multi-disc collection.
+ * encoder      -- name/settings of the software/hardware that produced the file.
+ * encoded_by   -- person/group who created the file.
+ * filename     -- original name of the file.
+ * genre        -- <self-evident>.
+ * language     -- main language in which the work is performed, preferably
+ *                 in ISO 639-2 format.
+ * performer    -- artist who performed the work, if different from artist.
+ *                 E.g for "Also sprach Zarathustra", artist would be "Richard
+ *                 Strauss" and performer "London Philharmonic Orchestra".
+ * publisher    -- name of the label/publisher.
+ * title        -- name of the work.
+ * track        -- number of this work in the set, can be in form current/total.
  */
 
 #define AV_METADATA_MATCH_CASE      1
@@ -122,7 +155,8 @@ int av_metadata_set2(AVMetadata **pm, const char *key, const char *value, int fl
 
 /**
  * Converts all the metadata sets from ctx according to the source and
- * destination conversion tables.
+ * destination conversion tables. If one of the tables is NULL, then
+ * tags are converted to/from ffmpeg generic tag names.
  * @param d_conv destination tags format conversion table
  * @param s_conv source tags format conversion table
  */
index 845697f..b1e3dc3 100644 (file)
@@ -211,7 +211,7 @@ static int parse_tag(AVFormatContext *s, const uint8_t *buf)
     get_string(s, "title",   buf +  3, 30);
     get_string(s, "artist",  buf + 33, 30);
     get_string(s, "album",   buf + 63, 30);
-    get_string(s, "year",    buf + 93,  4);
+    get_string(s, "date",    buf + 93,  4);
     get_string(s, "comment", buf + 97, 30);
     if (buf[125] == 0 && buf[126] != 0)
         av_metadata_set2(&s->metadata, "track", av_d2str(buf[126]), AV_METADATA_DONT_STRDUP_VAL);
index 7cf3b22..f007a3c 100644 (file)
@@ -240,20 +240,26 @@ const AVMetadataConv ff_id3v2_metadata_conv[] = {
     { "TCO",  "genre"},
     { "TCOP", "copyright"},
     { "TDRL", "date"},
-    { "TENC", "encoder"},
-    { "TEN",  "encoder"},
+    { "TDRC", "date"},
+    { "TENC", "encoded_by"},
+    { "TEN",  "encoded_by"},
     { "TIT2", "title"},
     { "TT2",  "title"},
     { "TLAN", "language"},
     { "TPE1", "artist"},
     { "TP1",  "artist"},
+    { "TPE2", "album_artist"},
+    { "TP2",  "album_artist"},
+    { "TPE3", "performer"},
+    { "TP3",  "performer"},
     { "TPOS", "disc"},
     { "TPUB", "publisher"},
     { "TRCK", "track"},
     { "TRK",  "track"},
-    { "TSOA", "albumsort"},
-    { "TSOP", "authorsort"},
-    { "TSOT", "titlesort"},
+    { "TSOA", "album-sort"},
+    { "TSOP", "artist-sort"},
+    { "TSOT", "title-sort"},
+    { "TSSE", "encoder"},
     { 0 }
 };
 
index f208e32..1e74d2b 100644 (file)
@@ -93,8 +93,7 @@ const CodecMime ff_mkv_mime_tags[] = {
 };
 
 const AVMetadataConv ff_mkv_metadata_conv[] = {
-    { "ARTIST"        , "artist" },
-    { "LEAD_PERFORMER", "artist" },
+    { "LEAD_PERFORMER", "performer" },
     { "PART_NUMBER"   , "track"  },
     { 0 }
 };
index 59dc166..de896d7 100644 (file)
@@ -1342,7 +1342,7 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
         st->start_time = 0;
         if (strcmp(track->language, "und"))
             av_metadata_set(&st->metadata, "language", track->language);
-        av_metadata_set(&st->metadata, "description", track->name);
+        av_metadata_set(&st->metadata, "title", track->name);
 
         if (track->flag_default)
             st->disposition |= AV_DISPOSITION_DEFAULT;
index b05fb04..9869a17 100644 (file)
@@ -45,8 +45,11 @@ static const struct {
     { "creator",         SIZE_OFFSET(author)    },
     { "written_by",      SIZE_OFFSET(author)    },
     { "lead_performer",  SIZE_OFFSET(author)    },
+    { "composer",        SIZE_OFFSET(author)    },
+    { "performer",       SIZE_OFFSET(author)    },
     { "description",     SIZE_OFFSET(comment)   },
     { "albumtitle",      SIZE_OFFSET(album)     },
+    { "date",            SIZE_OFFSET(year)      },
     { "date_written",    SIZE_OFFSET(year)      },
     { "date_released",   SIZE_OFFSET(year)      },
     { "tracknumber",     SIZE_OFFSET(track)     },
index 4765f18..c5e3ec0 100644 (file)
@@ -113,7 +113,7 @@ static int mov_read_udta_string(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
     case MKTAG(0xa9,'c','m','t'):
     case MKTAG(0xa9,'i','n','f'): key = "comment";   break;
     case MKTAG(0xa9,'a','l','b'): key = "album";     break;
-    case MKTAG(0xa9,'d','a','y'): key = "year";      break;
+    case MKTAG(0xa9,'d','a','y'): key = "date";      break;
     case MKTAG(0xa9,'g','e','n'): key = "genre";     break;
     case MKTAG(0xa9,'t','o','o'):
     case MKTAG(0xa9,'e','n','c'): key = "encoder";   break;
index 9273458..ecabd8e 100644 (file)
@@ -1437,7 +1437,7 @@ static int mov_write_ilst_tag(ByteIOContext *pb, MOVMuxContext *mov,
     mov_write_string_metadata(s, pb, "aART", "album_artist", 1);
     mov_write_string_metadata(s, pb, "\251wrt", "composer" , 1);
     mov_write_string_metadata(s, pb, "\251alb", "album"    , 1);
-    mov_write_string_metadata(s, pb, "\251day", "year"     , 1);
+    mov_write_string_metadata(s, pb, "\251day", "date"     , 1);
     mov_write_string_tag(pb, "\251too", LIBAVFORMAT_IDENT, 0, 1);
     mov_write_string_metadata(s, pb, "\251cmt", "comment"  , 1);
     mov_write_string_metadata(s, pb, "\251gen", "genre"    , 1);
@@ -1511,7 +1511,7 @@ static int mov_write_3gp_udta_tag(ByteIOContext *pb, AVFormatContext *s,
         put_be16(pb, language_code("eng")); /* language */
         put_buffer(pb, t->value, strlen(t->value)+1); /* UTF8 string value */
         if (!strcmp(tag, "albm") &&
-            (t = av_metadata_get(s->metadata, "year", NULL, 0)))
+            (t = av_metadata_get(s->metadata, "date", NULL, 0)))
             put_byte(pb, atoi(t->value));
     }
     return updateSize(pb, pos);
@@ -1540,12 +1540,12 @@ static int mov_write_udta_tag(ByteIOContext *pb, MOVMuxContext *mov,
             mov_write_3gp_udta_tag(pb_buf, s, "dscp", "comment");
             mov_write_3gp_udta_tag(pb_buf, s, "albm", "album");
             mov_write_3gp_udta_tag(pb_buf, s, "cprt", "copyright");
-            mov_write_3gp_udta_tag(pb_buf, s, "yrrc", "year");
+            mov_write_3gp_udta_tag(pb_buf, s, "yrrc", "date");
         } else if (mov->mode == MODE_MOV) { // the title field breaks gtkpod with mp4 and my suspicion is that stuff is not valid in mp4
             mov_write_string_metadata(s, pb_buf, "\251nam", "title"      , 0);
             mov_write_string_metadata(s, pb_buf, "\251aut", "author"     , 0);
             mov_write_string_metadata(s, pb_buf, "\251alb", "album"      , 0);
-            mov_write_string_metadata(s, pb_buf, "\251day", "year"       , 0);
+            mov_write_string_metadata(s, pb_buf, "\251day", "date"       , 0);
             mov_write_string_tag(pb_buf, "\251enc", LIBAVFORMAT_IDENT, 0, 0);
             mov_write_string_metadata(s, pb_buf, "\251des", "comment"    , 0);
             mov_write_string_metadata(s, pb_buf, "\251gen", "genre"      , 0);
index 7d3458c..d8742b5 100644 (file)
@@ -214,7 +214,7 @@ static int id3v1_create_tag(AVFormatContext *s, uint8_t *buf)
     count += id3v1_set_string(s, "title",   buf +  3, 30);
     count += id3v1_set_string(s, "author",  buf + 33, 30);
     count += id3v1_set_string(s, "album",   buf + 63, 30);
-    count += id3v1_set_string(s, "year",    buf + 93,  4);
+    count += id3v1_set_string(s, "date",    buf + 93,  4);
     count += id3v1_set_string(s, "comment", buf + 97, 30);
     if ((tag = av_metadata_get(s->metadata, "track", NULL, 0))) {
         buf[125] = 0;
index 6222962..2e8ea72 100644 (file)
@@ -36,8 +36,7 @@
  * http://xiph.org/vorbis/doc/v-comment.html
  */
 const AVMetadataConv ff_vorbiscomment_metadata_conv[] = {
-    { "ARTIST"     , "author" },
-    { "DATE"       , "year"   },
+    { "ALBUMARTIST", "album_artist"},
     { "TRACKNUMBER", "track"  },
     { 0 }
 };