Browse code

Add AVI metadata conversion table.

Patch by Anton Khirnov (gmail{wyskas}).

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

Anton Khirnov authored on 2010/02/06 21:32:44
Showing 5 changed files
... ...
@@ -35,8 +35,8 @@ OBJS-$(CONFIG_ASS_DEMUXER)               += assdec.o
35 35
 OBJS-$(CONFIG_ASS_MUXER)                 += assenc.o
36 36
 OBJS-$(CONFIG_AU_DEMUXER)                += au.o raw.o
37 37
 OBJS-$(CONFIG_AU_MUXER)                  += au.o
38
-OBJS-$(CONFIG_AVI_DEMUXER)               += avidec.o riff.o
39
-OBJS-$(CONFIG_AVI_MUXER)                 += avienc.o riff.o
38
+OBJS-$(CONFIG_AVI_DEMUXER)               += avidec.o riff.o avi.o
39
+OBJS-$(CONFIG_AVI_MUXER)                 += avienc.o riff.o avi.o
40 40
 OBJS-$(CONFIG_AVISYNTH)                  += avisynth.o
41 41
 OBJS-$(CONFIG_AVM2_MUXER)                += swfenc.o
42 42
 OBJS-$(CONFIG_AVS_DEMUXER)               += avs.o vocdec.o voc.o
43 43
new file mode 100644
... ...
@@ -0,0 +1,45 @@
0
+/*
1
+ * AVI common data
2
+ * Copyright (c) 2010 Anton Khirnov
3
+ *
4
+ * This file is part of FFmpeg.
5
+ *
6
+ * FFmpeg is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU Lesser General Public
8
+ * License as published by the Free Software Foundation; either
9
+ * version 2.1 of the License, or (at your option) any later version.
10
+ *
11
+ * FFmpeg is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
+ * Lesser General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public
17
+ * License along with FFmpeg; if not, write to the Free Software
18
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ */
20
+
21
+#include "avi.h"
22
+
23
+const AVMetadataConv ff_avi_metadata_conv[] = {
24
+    { "IART", "artist"    },
25
+    { "ICMT", "comment"   },
26
+    { "ICOP", "copyright" },
27
+    { "ICRD", "date"      },
28
+    { "IGNR", "genre"     },
29
+    { "ILNG", "language"  },
30
+    { "INAM", "title"     },
31
+    { "IPRD", "album"     },
32
+    { "IPRT", "track"     },
33
+    { "ISFT", "encoder"   },
34
+    { "ITCH", "encoded_by"},
35
+    { "strn", "title"     },
36
+    { 0 },
37
+};
38
+
39
+const char ff_avi_tags[][5] = {
40
+    "IARL", "IART", "ICMS", "ICMT", "ICOP", "ICRD", "ICRP", "IDIM", "IDPI",
41
+    "IENG", "IGNR", "IKEY", "ILGT", "ILNG", "IMED", "INAM", "IPLT", "IPRD",
42
+    "IPRT", "ISBJ",/*"ISFT"*/"ISHP", "ISRC", "ISRF", "ITCH",
43
+    {0}
44
+};
... ...
@@ -21,6 +21,8 @@
21 21
 #ifndef AVFORMAT_AVI_H
22 22
 #define AVFORMAT_AVI_H
23 23
 
24
+#include "metadata.h"
25
+
24 26
 #define AVIF_HASINDEX           0x00000010        // Index at end of file?
25 27
 #define AVIF_MUSTUSEINDEX       0x00000020
26 28
 #define AVIF_ISINTERLEAVED      0x00000100
... ...
@@ -34,4 +36,11 @@
34 34
 /* index flags */
35 35
 #define AVIIF_INDEX             0x10
36 36
 
37
+extern const AVMetadataConv ff_avi_metadata_conv[];
38
+
39
+/**
40
+ * A list of AVI info tags.
41
+ */
42
+extern const char ff_avi_tags[][5];
43
+
37 44
 #endif /* AVFORMAT_AVI_H */
... ...
@@ -227,10 +227,10 @@ static void clean_index(AVFormatContext *s){
227 227
     }
228 228
 }
229 229
 
230
-static int avi_read_tag(AVFormatContext *s, AVStream *st, const char *key, unsigned int size)
230
+static int avi_read_tag(AVFormatContext *s, AVStream *st, uint32_t tag, uint32_t size)
231 231
 {
232 232
     ByteIOContext *pb = s->pb;
233
-    char *value;
233
+    char key[5] = {0}, *value;
234 234
 
235 235
     size += (size & 1);
236 236
 
... ...
@@ -242,6 +242,8 @@ static int avi_read_tag(AVFormatContext *s, AVStream *st, const char *key, unsig
242 242
     get_buffer(pb, value, size);
243 243
     value[size]=0;
244 244
 
245
+    AV_WL32(key, tag);
246
+
245 247
     if(st)
246 248
         return av_metadata_set2(&st->metadata, key, value,
247 249
                                     AV_METADATA_DONT_STRDUP_VAL);
... ...
@@ -250,6 +252,15 @@ static int avi_read_tag(AVFormatContext *s, AVStream *st, const char *key, unsig
250 250
                                   AV_METADATA_DONT_STRDUP_VAL);
251 251
 }
252 252
 
253
+static void avi_read_info(AVFormatContext *s, uint64_t end)
254
+{
255
+    while (url_ftell(s->pb) < end) {
256
+        uint32_t tag  = get_le32(s->pb);
257
+        uint32_t size = get_le32(s->pb);
258
+        avi_read_tag(s, NULL, tag, size);
259
+    }
260
+}
261
+
253 262
 static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
254 263
 {
255 264
     AVIContext *avi = s->priv_data;
... ...
@@ -301,6 +312,9 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
301 301
                 dprintf(NULL, "movi end=%"PRIx64"\n", avi->movi_end);
302 302
                 goto end_of_header;
303 303
             }
304
+            else if (tag1 == MKTAG('I', 'N', 'F', 'O'))
305
+                avi_read_info(s, list_end);
306
+
304 307
             break;
305 308
         case MKTAG('d', 'm', 'l', 'h'):
306 309
             avi->is_odml = 1;
... ...
@@ -606,30 +620,9 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
606 606
             }
607 607
             url_fseek(pb, size, SEEK_CUR);
608 608
             break;
609
-        case MKTAG('I', 'N', 'A', 'M'):
610
-            avi_read_tag(s, NULL, "Title", size);
611
-            break;
612
-        case MKTAG('I', 'A', 'R', 'T'):
613
-            avi_read_tag(s, NULL, "Artist", size);
614
-            break;
615
-        case MKTAG('I', 'C', 'O', 'P'):
616
-            avi_read_tag(s, NULL, "Copyright", size);
617
-            break;
618
-        case MKTAG('I', 'C', 'M', 'T'):
619
-            avi_read_tag(s, NULL, "Comment", size);
620
-            break;
621
-        case MKTAG('I', 'G', 'N', 'R'):
622
-            avi_read_tag(s, NULL, "Genre", size);
623
-            break;
624
-        case MKTAG('I', 'P', 'R', 'D'):
625
-            avi_read_tag(s, NULL, "Album", size);
626
-            break;
627
-        case MKTAG('I', 'P', 'R', 'T'):
628
-            avi_read_tag(s, NULL, "Track", size);
629
-            break;
630 609
         case MKTAG('s', 't', 'r', 'n'):
631 610
             if(s->nb_streams){
632
-                avi_read_tag(s, s->streams[s->nb_streams-1], "Title", size);
611
+                avi_read_tag(s, s->streams[s->nb_streams-1], tag, size);
633 612
                 break;
634 613
             }
635 614
         default:
... ...
@@ -1190,4 +1183,5 @@ AVInputFormat avi_demuxer = {
1190 1190
     avi_read_packet,
1191 1191
     avi_read_close,
1192 1192
     avi_read_seek,
1193
+    .metadata_conv = ff_avi_metadata_conv,
1193 1194
 };
... ...
@@ -21,6 +21,7 @@
21 21
 #include "avformat.h"
22 22
 #include "avi.h"
23 23
 #include "riff.h"
24
+#include "libavutil/intreadwrite.h"
24 25
 
25 26
 /*
26 27
  * TODO:
... ...
@@ -114,22 +115,6 @@ static void avi_write_info_tag(ByteIOContext *pb, const char *tag, const char *s
114 114
     }
115 115
 }
116 116
 
117
-static void avi_write_info_tag2(AVFormatContext *s, AVStream *st, const char *fourcc, const char *key1, const char *key2)
118
-{
119
-    AVMetadataTag *tag;
120
-    if(st){
121
-        tag= av_metadata_get(st->metadata, key1, NULL, 0);
122
-        if(!tag && key2)
123
-            tag= av_metadata_get(st->metadata, key2, NULL, 0);
124
-    }else{
125
-        tag= av_metadata_get(s->metadata, key1, NULL, 0);
126
-    if(!tag && key2)
127
-        tag= av_metadata_get(s->metadata, key2, NULL, 0);
128
-    }
129
-    if(tag)
130
-        avi_write_info_tag(s->pb, fourcc, tag->value);
131
-}
132
-
133 117
 static int avi_write_counters(AVFormatContext* s, int riff_id)
134 118
 {
135 119
     ByteIOContext *pb = s->pb;
... ...
@@ -171,6 +156,7 @@ static int avi_write_header(AVFormatContext *s)
171 171
     int bitrate, n, i, nb_frames, au_byterate, au_ssize, au_scale;
172 172
     AVCodecContext *stream, *video_enc;
173 173
     int64_t list1, list2, strh, strf;
174
+    AVMetadataTag *t = NULL;
174 175
 
175 176
     for(n=0;n<s->nb_streams;n++) {
176 177
         s->streams[n]->priv_data= av_mallocz(sizeof(AVIStream));
... ...
@@ -301,7 +287,15 @@ static int avi_write_header(AVFormatContext *s)
301 301
             return -1;
302 302
         }
303 303
         ff_end_tag(pb, strf);
304
-        avi_write_info_tag2(s, s->streams[i], "strn", "Title", "Description");
304
+        if ((t = av_metadata_get(s->streams[i]->metadata, "strn", NULL, 0))) {
305
+            avi_write_info_tag(s->pb, t->key, t->value);
306
+            t = NULL;
307
+        }
308
+        //FIXME a limitation of metadata conversion system
309
+        else if ((t = av_metadata_get(s->streams[i]->metadata, "INAM", NULL, 0))) {
310
+            avi_write_info_tag(s->pb, "strn", t->value);
311
+            t = NULL;
312
+        }
305 313
       }
306 314
 
307 315
         if (!url_is_streamed(pb)) {
... ...
@@ -378,13 +372,10 @@ static int avi_write_header(AVFormatContext *s)
378 378
 
379 379
     list2 = ff_start_tag(pb, "LIST");
380 380
     put_tag(pb, "INFO");
381
-    avi_write_info_tag2(s, NULL, "INAM", "Title", NULL);
382
-    avi_write_info_tag2(s, NULL, "IART", "Artist", "Author");
383
-    avi_write_info_tag2(s, NULL, "ICOP", "Copyright", NULL);
384
-    avi_write_info_tag2(s, NULL, "ICMT", "Comment", NULL);
385
-    avi_write_info_tag2(s, NULL, "IPRD", "Album", NULL);
386
-    avi_write_info_tag2(s, NULL, "IGNR", "Genre", NULL);
387
-    avi_write_info_tag2(s, NULL, "IPRT", "Track", NULL);
381
+    for (i = 0; *ff_avi_tags[i]; i++) {
382
+        if ((t = av_metadata_get(s->metadata, ff_avi_tags[i], NULL, AV_METADATA_MATCH_CASE)))
383
+            avi_write_info_tag(s->pb, t->key, t->value);
384
+    }
388 385
     if(!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT))
389 386
         avi_write_info_tag(pb, "ISFT", LIBAVFORMAT_IDENT);
390 387
     ff_end_tag(pb, list2);
... ...
@@ -655,4 +646,5 @@ AVOutputFormat avi_muxer = {
655 655
     avi_write_trailer,
656 656
     .codec_tag= (const AVCodecTag* const []){ff_codec_bmp_tags, ff_codec_wav_tags, 0},
657 657
     .flags= AVFMT_VARIABLE_FPS,
658
+    .metadata_conv = ff_avi_metadata_conv,
658 659
 };