Mercurial > libavformat.hg
changeset 5633:5d3ac5652047 libavformat
Add AVI metadata conversion table.
Patch by Anton Khirnov (gmail{wyskas}).
author | jai_menon |
---|---|
date | Sat, 06 Feb 2010 12:32:44 +0000 |
parents | 4c2b20d0233c |
children | b280788e1936 |
files | Makefile avi.c avi.h avidec.c avienc.c |
diffstat | 5 files changed, 90 insertions(+), 50 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile Fri Feb 05 23:03:32 2010 +0000 +++ b/Makefile Sat Feb 06 12:32:44 2010 +0000 @@ -35,8 +35,8 @@ OBJS-$(CONFIG_ASS_MUXER) += assenc.o OBJS-$(CONFIG_AU_DEMUXER) += au.o raw.o OBJS-$(CONFIG_AU_MUXER) += au.o -OBJS-$(CONFIG_AVI_DEMUXER) += avidec.o riff.o -OBJS-$(CONFIG_AVI_MUXER) += avienc.o riff.o +OBJS-$(CONFIG_AVI_DEMUXER) += avidec.o riff.o avi.o +OBJS-$(CONFIG_AVI_MUXER) += avienc.o riff.o avi.o OBJS-$(CONFIG_AVISYNTH) += avisynth.o OBJS-$(CONFIG_AVM2_MUXER) += swfenc.o OBJS-$(CONFIG_AVS_DEMUXER) += avs.o vocdec.o voc.o
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/avi.c Sat Feb 06 12:32:44 2010 +0000 @@ -0,0 +1,45 @@ +/* + * AVI common data + * Copyright (c) 2010 Anton Khirnov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "avi.h" + +const AVMetadataConv ff_avi_metadata_conv[] = { + { "IART", "artist" }, + { "ICMT", "comment" }, + { "ICOP", "copyright" }, + { "ICRD", "date" }, + { "IGNR", "genre" }, + { "ILNG", "language" }, + { "INAM", "title" }, + { "IPRD", "album" }, + { "IPRT", "track" }, + { "ISFT", "encoder" }, + { "ITCH", "encoded_by"}, + { "strn", "title" }, + { 0 }, +}; + +const char ff_avi_tags[][5] = { + "IARL", "IART", "ICMS", "ICMT", "ICOP", "ICRD", "ICRP", "IDIM", "IDPI", + "IENG", "IGNR", "IKEY", "ILGT", "ILNG", "IMED", "INAM", "IPLT", "IPRD", + "IPRT", "ISBJ",/*"ISFT"*/"ISHP", "ISRC", "ISRF", "ITCH", + {0} +};
--- a/avi.h Fri Feb 05 23:03:32 2010 +0000 +++ b/avi.h Sat Feb 06 12:32:44 2010 +0000 @@ -21,6 +21,8 @@ #ifndef AVFORMAT_AVI_H #define AVFORMAT_AVI_H +#include "metadata.h" + #define AVIF_HASINDEX 0x00000010 // Index at end of file? #define AVIF_MUSTUSEINDEX 0x00000020 #define AVIF_ISINTERLEAVED 0x00000100 @@ -34,4 +36,11 @@ /* index flags */ #define AVIIF_INDEX 0x10 +extern const AVMetadataConv ff_avi_metadata_conv[]; + +/** + * A list of AVI info tags. + */ +extern const char ff_avi_tags[][5]; + #endif /* AVFORMAT_AVI_H */
--- a/avidec.c Fri Feb 05 23:03:32 2010 +0000 +++ b/avidec.c Sat Feb 06 12:32:44 2010 +0000 @@ -227,10 +227,10 @@ } } -static int avi_read_tag(AVFormatContext *s, AVStream *st, const char *key, unsigned int size) +static int avi_read_tag(AVFormatContext *s, AVStream *st, uint32_t tag, uint32_t size) { ByteIOContext *pb = s->pb; - char *value; + char key[5] = {0}, *value; size += (size & 1); @@ -242,6 +242,8 @@ get_buffer(pb, value, size); value[size]=0; + AV_WL32(key, tag); + if(st) return av_metadata_set2(&st->metadata, key, value, AV_METADATA_DONT_STRDUP_VAL); @@ -250,6 +252,15 @@ AV_METADATA_DONT_STRDUP_VAL); } +static void avi_read_info(AVFormatContext *s, uint64_t end) +{ + while (url_ftell(s->pb) < end) { + uint32_t tag = get_le32(s->pb); + uint32_t size = get_le32(s->pb); + avi_read_tag(s, NULL, tag, size); + } +} + static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) { AVIContext *avi = s->priv_data; @@ -301,6 +312,9 @@ dprintf(NULL, "movi end=%"PRIx64"\n", avi->movi_end); goto end_of_header; } + else if (tag1 == MKTAG('I', 'N', 'F', 'O')) + avi_read_info(s, list_end); + break; case MKTAG('d', 'm', 'l', 'h'): avi->is_odml = 1; @@ -606,30 +620,9 @@ } url_fseek(pb, size, SEEK_CUR); break; - case MKTAG('I', 'N', 'A', 'M'): - avi_read_tag(s, NULL, "Title", size); - break; - case MKTAG('I', 'A', 'R', 'T'): - avi_read_tag(s, NULL, "Artist", size); - break; - case MKTAG('I', 'C', 'O', 'P'): - avi_read_tag(s, NULL, "Copyright", size); - break; - case MKTAG('I', 'C', 'M', 'T'): - avi_read_tag(s, NULL, "Comment", size); - break; - case MKTAG('I', 'G', 'N', 'R'): - avi_read_tag(s, NULL, "Genre", size); - break; - case MKTAG('I', 'P', 'R', 'D'): - avi_read_tag(s, NULL, "Album", size); - break; - case MKTAG('I', 'P', 'R', 'T'): - avi_read_tag(s, NULL, "Track", size); - break; case MKTAG('s', 't', 'r', 'n'): if(s->nb_streams){ - avi_read_tag(s, s->streams[s->nb_streams-1], "Title", size); + avi_read_tag(s, s->streams[s->nb_streams-1], tag, size); break; } default: @@ -1190,4 +1183,5 @@ avi_read_packet, avi_read_close, avi_read_seek, + .metadata_conv = ff_avi_metadata_conv, };
--- a/avienc.c Fri Feb 05 23:03:32 2010 +0000 +++ b/avienc.c Sat Feb 06 12:32:44 2010 +0000 @@ -21,6 +21,7 @@ #include "avformat.h" #include "avi.h" #include "riff.h" +#include "libavutil/intreadwrite.h" /* * TODO: @@ -114,22 +115,6 @@ } } -static void avi_write_info_tag2(AVFormatContext *s, AVStream *st, const char *fourcc, const char *key1, const char *key2) -{ - AVMetadataTag *tag; - if(st){ - tag= av_metadata_get(st->metadata, key1, NULL, 0); - if(!tag && key2) - tag= av_metadata_get(st->metadata, key2, NULL, 0); - }else{ - tag= av_metadata_get(s->metadata, key1, NULL, 0); - if(!tag && key2) - tag= av_metadata_get(s->metadata, key2, NULL, 0); - } - if(tag) - avi_write_info_tag(s->pb, fourcc, tag->value); -} - static int avi_write_counters(AVFormatContext* s, int riff_id) { ByteIOContext *pb = s->pb; @@ -171,6 +156,7 @@ int bitrate, n, i, nb_frames, au_byterate, au_ssize, au_scale; AVCodecContext *stream, *video_enc; int64_t list1, list2, strh, strf; + AVMetadataTag *t = NULL; for(n=0;n<s->nb_streams;n++) { s->streams[n]->priv_data= av_mallocz(sizeof(AVIStream)); @@ -301,7 +287,15 @@ return -1; } ff_end_tag(pb, strf); - avi_write_info_tag2(s, s->streams[i], "strn", "Title", "Description"); + if ((t = av_metadata_get(s->streams[i]->metadata, "strn", NULL, 0))) { + avi_write_info_tag(s->pb, t->key, t->value); + t = NULL; + } + //FIXME a limitation of metadata conversion system + else if ((t = av_metadata_get(s->streams[i]->metadata, "INAM", NULL, 0))) { + avi_write_info_tag(s->pb, "strn", t->value); + t = NULL; + } } if (!url_is_streamed(pb)) { @@ -378,13 +372,10 @@ list2 = ff_start_tag(pb, "LIST"); put_tag(pb, "INFO"); - avi_write_info_tag2(s, NULL, "INAM", "Title", NULL); - avi_write_info_tag2(s, NULL, "IART", "Artist", "Author"); - avi_write_info_tag2(s, NULL, "ICOP", "Copyright", NULL); - avi_write_info_tag2(s, NULL, "ICMT", "Comment", NULL); - avi_write_info_tag2(s, NULL, "IPRD", "Album", NULL); - avi_write_info_tag2(s, NULL, "IGNR", "Genre", NULL); - avi_write_info_tag2(s, NULL, "IPRT", "Track", NULL); + for (i = 0; *ff_avi_tags[i]; i++) { + if ((t = av_metadata_get(s->metadata, ff_avi_tags[i], NULL, AV_METADATA_MATCH_CASE))) + avi_write_info_tag(s->pb, t->key, t->value); + } if(!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) avi_write_info_tag(pb, "ISFT", LIBAVFORMAT_IDENT); ff_end_tag(pb, list2); @@ -655,4 +646,5 @@ avi_write_trailer, .codec_tag= (const AVCodecTag* const []){ff_codec_bmp_tags, ff_codec_wav_tags, 0}, .flags= AVFMT_VARIABLE_FPS, + .metadata_conv = ff_avi_metadata_conv, };