From 03700d399bcc749ad7916f2d39a99527f37c8b6e Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Fri, 15 Oct 2010 19:04:25 +0000 Subject: Export metadata in the generic format. Deprecate old conversion API. patch by Anton Khirnov anton _at_ khirnov _dot_ net Originally committed as revision 25493 to svn://svn.ffmpeg.org/ffmpeg/trunk --- doc/APIchanges | 5 +++++ libavformat/asfdec.c | 3 ++- libavformat/asfenc.c | 4 ++-- libavformat/avformat.h | 28 +++++++++++++++------------- libavformat/avidec.c | 3 ++- libavformat/avienc.c | 9 ++------- libavformat/flacdec.c | 1 - libavformat/flacenc.c | 1 - libavformat/id3v2.c | 2 ++ libavformat/matroskadec.c | 2 +- libavformat/matroskaenc.c | 4 ++-- libavformat/metadata.c | 10 ++++++++-- libavformat/metadata.h | 5 +++++ libavformat/mp3.c | 4 +--- libavformat/nutdec.c | 3 ++- libavformat/nutenc.c | 3 ++- libavformat/oggdec.c | 1 - libavformat/oggenc.c | 1 - libavformat/oggparsevorbis.c | 3 +++ libavformat/oma.c | 1 - libavformat/vorbiscomment.c | 1 + 21 files changed, 55 insertions(+), 39 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index 4155d32df9..d126c13edd 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,11 @@ libavutil: 2009-03-08 API changes, most recent first: +2010-10-15 - r25493 - lavf 52.83.0 - metadata API + Change demuxers to export metadata in generic format and + muxers to accept generic format. Deprecate the public + conversion API. + 2010-10-10 - r25441 - lavfi 1.49.0 - AVFilterLink.time_base Add time_base field to AVFilterLink. diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c index 6741f8ce17..519c15a090 100644 --- a/libavformat/asfdec.c +++ b/libavformat/asfdec.c @@ -659,6 +659,8 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) } } + metadata_conv(&s->metadata, NULL, ff_asf_metadata_conv); + return 0; } @@ -1235,5 +1237,4 @@ AVInputFormat asf_demuxer = { asf_read_close, asf_read_seek, asf_read_pts, - .metadata_conv = ff_asf_metadata_conv, }; diff --git a/libavformat/asfenc.c b/libavformat/asfenc.c index 9f8d69ac5c..863709b2ca 100644 --- a/libavformat/asfenc.c +++ b/libavformat/asfenc.c @@ -279,6 +279,8 @@ static int asf_write_header1(AVFormatContext *s, int64_t file_size, int64_t data int bit_rate; int64_t duration; + metadata_conv(&s->metadata, ff_asf_metadata_conv, NULL); + tags[0] = av_metadata_get(s->metadata, "title" , NULL, 0); tags[1] = av_metadata_get(s->metadata, "author" , NULL, 0); tags[2] = av_metadata_get(s->metadata, "copyright", NULL, 0); @@ -870,7 +872,6 @@ AVOutputFormat asf_muxer = { asf_write_trailer, .flags = AVFMT_GLOBALHEADER, .codec_tag= (const AVCodecTag* const []){codec_asf_bmp_tags, ff_codec_bmp_tags, ff_codec_wav_tags, 0}, - .metadata_conv = ff_asf_metadata_conv, }; #endif @@ -892,6 +893,5 @@ AVOutputFormat asf_stream_muxer = { asf_write_trailer, .flags = AVFMT_GLOBALHEADER, .codec_tag= (const AVCodecTag* const []){codec_asf_bmp_tags, ff_codec_bmp_tags, ff_codec_wav_tags, 0}, - .metadata_conv = ff_asf_metadata_conv, }; #endif //CONFIG_ASF_STREAM_MUXER diff --git a/libavformat/avformat.h b/libavformat/avformat.h index ab308c87d3..62bf42b968 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -22,7 +22,7 @@ #define AVFORMAT_AVFORMAT_H #define LIBAVFORMAT_VERSION_MAJOR 52 -#define LIBAVFORMAT_VERSION_MINOR 82 +#define LIBAVFORMAT_VERSION_MINOR 83 #define LIBAVFORMAT_VERSION_MICRO 0 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ @@ -137,10 +137,9 @@ struct AVFormatContext; * 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: + * 4. Demuxers attempt to export metadata in a generic format, however tags + * with no generic equivalents are left as they are stored in the container. + * 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. @@ -177,7 +176,9 @@ typedef struct { }AVMetadataTag; typedef struct AVMetadata AVMetadata; +#if FF_API_OLD_METADATA typedef struct AVMetadataConv AVMetadataConv; +#endif /** * Get a metadata element with matching key. @@ -216,16 +217,13 @@ attribute_deprecated int av_metadata_set(AVMetadata **pm, const char *key, const */ int av_metadata_set2(AVMetadata **pm, const char *key, const char *value, int flags); +#if FF_API_OLD_METADATA /** - * Convert all the metadata sets from ctx according to the source and - * 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 + * This function is provided for compatibility reason and currently does nothing. */ -void av_metadata_conv(struct AVFormatContext *ctx, const AVMetadataConv *d_conv, - const AVMetadataConv *s_conv); +attribute_deprecated void av_metadata_conv(struct AVFormatContext *ctx, const AVMetadataConv *d_conv, + const AVMetadataConv *s_conv); +#endif /** * Free all the memory allocated for an AVMetadata struct. @@ -349,7 +347,9 @@ typedef struct AVOutputFormat { enum CodecID subtitle_codec; /**< default subtitle codec */ +#if FF_API_OLD_METADATA const AVMetadataConv *metadata_conv; +#endif /* private fields */ struct AVOutputFormat *next; @@ -465,7 +465,9 @@ typedef struct AVInputFormat { */ int (*read_seek2)(struct AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags); +#if FF_API_OLD_METADATA const AVMetadataConv *metadata_conv; +#endif /* private fields */ struct AVInputFormat *next; diff --git a/libavformat/avidec.c b/libavformat/avidec.c index 84ccaec5e3..2d38191726 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -693,6 +693,8 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) clean_index(s); } + ff_metadata_conv_ctx(s, NULL, ff_avi_metadata_conv); + return 0; } @@ -1332,5 +1334,4 @@ AVInputFormat avi_demuxer = { avi_read_packet, avi_read_close, avi_read_seek, - .metadata_conv = ff_avi_metadata_conv, }; diff --git a/libavformat/avienc.c b/libavformat/avienc.c index 161fb1bfc7..744e0a63c0 100644 --- a/libavformat/avienc.c +++ b/libavformat/avienc.c @@ -290,12 +290,7 @@ static int avi_write_header(AVFormatContext *s) return -1; } ff_end_tag(pb, strf); - 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))) { + if ((t = av_metadata_get(s->streams[i]->metadata, "title", NULL, 0))) { avi_write_info_tag(s->pb, "strn", t->value); t = NULL; } @@ -375,6 +370,7 @@ static int avi_write_header(AVFormatContext *s) list2 = ff_start_tag(pb, "LIST"); put_tag(pb, "INFO"); + metadata_conv(&s->metadata, ff_avi_metadata_conv, 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); @@ -647,5 +643,4 @@ AVOutputFormat avi_muxer = { 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, }; diff --git a/libavformat/flacdec.c b/libavformat/flacdec.c index 6922b6ce3f..d73486f4f4 100644 --- a/libavformat/flacdec.c +++ b/libavformat/flacdec.c @@ -133,5 +133,4 @@ AVInputFormat flac_demuxer = { .flags= AVFMT_GENERIC_INDEX, .extensions = "flac", .value = CODEC_ID_FLAC, - .metadata_conv = ff_vorbiscomment_metadata_conv, }; diff --git a/libavformat/flacenc.c b/libavformat/flacenc.c index ccf83294ec..996d9f43e0 100644 --- a/libavformat/flacenc.c +++ b/libavformat/flacenc.c @@ -128,5 +128,4 @@ AVOutputFormat flac_muxer = { flac_write_packet, flac_write_trailer, .flags= AVFMT_NOTIMESTAMPS, - .metadata_conv = ff_vorbiscomment_metadata_conv, }; diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c index 364720f380..fbcb8f86ba 100644 --- a/libavformat/id3v2.c +++ b/libavformat/id3v2.c @@ -23,6 +23,7 @@ #include "id3v1.h" #include "libavutil/avstring.h" #include "libavutil/intreadwrite.h" +#include "metadata.h" int ff_id3v2_match(const uint8_t *buf, const char * magic) { @@ -249,6 +250,7 @@ void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t flags) /* Skip to end of tag */ url_fseek(s->pb, next, SEEK_SET); } + metadata_conv(&s->metadata, NULL, ff_id3v2_metadata_conv); if (len > 0) { /* Skip padding */ diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 0d0285e6c0..b8a6711778 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -1048,6 +1048,7 @@ static void matroska_convert_tag(AVFormatContext *s, EbmlList *list, matroska_convert_tag(s, &tags[i].sub, metadata, key); } } + metadata_conv(metadata, NULL, ff_mkv_metadata_conv); } static void matroska_convert_tags(AVFormatContext *s) @@ -1923,5 +1924,4 @@ AVInputFormat matroska_demuxer = { matroska_read_packet, matroska_read_close, matroska_read_seek, - .metadata_conv = ff_mkv_metadata_conv, }; diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 29fddce50c..80bb08ef4f 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -752,6 +752,8 @@ static int mkv_write_tags(AVFormatContext *s) ebml_master tags = {0}; int i, ret; + ff_metadata_conv_ctx(s, ff_mkv_metadata_conv, NULL); + if (av_metadata_get(s->metadata, "", NULL, AV_METADATA_IGNORE_SUFFIX)) { ret = mkv_write_tag(s, s->metadata, 0, 0, &tags); if (ret < 0) return ret; @@ -1186,7 +1188,6 @@ AVOutputFormat matroska_muxer = { .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS, .codec_tag = (const AVCodecTag* const []){ff_codec_bmp_tags, ff_codec_wav_tags, 0}, .subtitle_codec = CODEC_ID_TEXT, - .metadata_conv = ff_mkv_metadata_conv, }; #endif @@ -1220,6 +1221,5 @@ AVOutputFormat matroska_audio_muxer = { mkv_write_trailer, .flags = AVFMT_GLOBALHEADER, .codec_tag = (const AVCodecTag* const []){ff_codec_wav_tags, 0}, - .metadata_conv = ff_mkv_metadata_conv, }; #endif diff --git a/libavformat/metadata.c b/libavformat/metadata.c index 8fc1771956..b4d9c5ef08 100644 --- a/libavformat/metadata.c +++ b/libavformat/metadata.c @@ -91,6 +91,12 @@ int av_metadata_set(AVMetadata **pm, const char *key, const char *value) { return av_metadata_set2(pm, key, value, 0); } + +void av_metadata_conv(AVFormatContext *ctx, const AVMetadataConv *d_conv, + const AVMetadataConv *s_conv) +{ + return; +} #endif void av_metadata_free(AVMetadata **pm) @@ -140,8 +146,8 @@ void metadata_conv(AVMetadata **pm, const AVMetadataConv *d_conv, *pm = dst; } -void av_metadata_conv(AVFormatContext *ctx, const AVMetadataConv *d_conv, - const AVMetadataConv *s_conv) +void ff_metadata_conv_ctx(AVFormatContext *ctx, const AVMetadataConv *d_conv, + const AVMetadataConv *s_conv) { int i; metadata_conv(&ctx->metadata, d_conv, s_conv); diff --git a/libavformat/metadata.h b/libavformat/metadata.h index 3706bc409d..197ca515e6 100644 --- a/libavformat/metadata.h +++ b/libavformat/metadata.h @@ -39,6 +39,9 @@ struct AVMetadataConv{ const char *native; const char *generic; }; +#if !FF_API_OLD_METADATA +typedef struct AVMetadataConv AVMetadataConv; +#endif #if FF_API_OLD_METADATA void ff_metadata_demux_compat(AVFormatContext *s); @@ -47,5 +50,7 @@ void ff_metadata_mux_compat(AVFormatContext *s); void metadata_conv(AVMetadata **pm, const AVMetadataConv *d_conv, const AVMetadataConv *s_conv); +void ff_metadata_conv_ctx(AVFormatContext *ctx, const AVMetadataConv *d_conv, + const AVMetadataConv *s_conv); #endif /* AVFORMAT_METADATA_H */ diff --git a/libavformat/mp3.c b/libavformat/mp3.c index 4dfffec6de..77b131d5d5 100644 --- a/libavformat/mp3.c +++ b/libavformat/mp3.c @@ -195,7 +195,6 @@ AVInputFormat mp3_demuxer = { mp3_read_packet, .flags= AVFMT_GENERIC_INDEX, .extensions = "mp2,mp3,m2a", /* XXX: use probe */ - .metadata_conv = ff_id3v2_metadata_conv, }; #endif @@ -294,7 +293,6 @@ AVOutputFormat mp2_muxer = { NULL, mp3_write_packet, mp3_write_trailer, - .metadata_conv = ff_id3v2_metadata_conv, }; #endif @@ -317,6 +315,7 @@ static int mp3_write_header(struct AVFormatContext *s) size_pos = url_ftell(s->pb); put_be32(s->pb, 0); + metadata_conv(&s->metadata, ff_id3v2_metadata_conv, NULL); while ((t = av_metadata_get(s->metadata, "", t, AV_METADATA_IGNORE_SUFFIX))) { uint32_t tag = 0; @@ -366,6 +365,5 @@ AVOutputFormat mp3_muxer = { mp3_write_packet, mp3_write_trailer, AVFMT_NOTIMESTAMPS, - .metadata_conv = ff_id3v2_metadata_conv, }; #endif diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c index fa1cb188d7..f8eda4f660 100644 --- a/libavformat/nutdec.c +++ b/libavformat/nutdec.c @@ -656,6 +656,8 @@ static int nut_read_header(AVFormatContext *s, AVFormatParameters *ap) } assert(nut->next_startcode == SYNCPOINT_STARTCODE); + ff_metadata_conv_ctx(s, NULL, ff_nut_metadata_conv); + return 0; } @@ -931,7 +933,6 @@ AVInputFormat nut_demuxer = { nut_read_close, read_seek, .extensions = "nut", - .metadata_conv = ff_nut_metadata_conv, .codec_tag = (const AVCodecTag * const []) { ff_codec_bmp_tags, ff_nut_video_tags, ff_codec_wav_tags, ff_nut_subtitle_tags, 0 }, }; #endif diff --git a/libavformat/nutenc.c b/libavformat/nutenc.c index 8cbc7d4cc3..a030fee55c 100644 --- a/libavformat/nutenc.c +++ b/libavformat/nutenc.c @@ -491,6 +491,8 @@ static int write_headers(AVFormatContext *avctx, ByteIOContext *bc){ ByteIOContext *dyn_bc; int i, ret; + ff_metadata_conv_ctx(avctx, ff_nut_metadata_conv, NULL); + ret = url_open_dyn_buf(&dyn_bc); if(ret < 0) return ret; @@ -810,5 +812,4 @@ AVOutputFormat nut_muxer = { write_trailer, .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS, .codec_tag = (const AVCodecTag * const []){ ff_codec_bmp_tags, ff_nut_video_tags, ff_codec_wav_tags, ff_nut_subtitle_tags, 0 }, - .metadata_conv = ff_nut_metadata_conv, }; diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c index 4c9a43a1cf..5e52bb3c97 100644 --- a/libavformat/oggdec.c +++ b/libavformat/oggdec.c @@ -641,6 +641,5 @@ AVInputFormat ogg_demuxer = { ogg_read_seek, ogg_read_timestamp, .extensions = "ogg", - .metadata_conv = ff_vorbiscomment_metadata_conv, .flags = AVFMT_GENERIC_INDEX, }; diff --git a/libavformat/oggenc.c b/libavformat/oggenc.c index b71e96a9d7..7ec1b3ee05 100644 --- a/libavformat/oggenc.c +++ b/libavformat/oggenc.c @@ -495,5 +495,4 @@ AVOutputFormat ogg_muxer = { ogg_write_header, ogg_write_packet, ogg_write_trailer, - .metadata_conv = ff_vorbiscomment_metadata_conv, }; diff --git a/libavformat/oggparsevorbis.c b/libavformat/oggparsevorbis.c index c7f8149a23..9f873934c4 100644 --- a/libavformat/oggparsevorbis.c +++ b/libavformat/oggparsevorbis.c @@ -29,6 +29,7 @@ #include "libavcodec/bytestream.h" #include "avformat.h" #include "oggdec.h" +#include "vorbiscomment.c" static int ogm_chapter(AVFormatContext *as, uint8_t *key, uint8_t *val) { @@ -137,6 +138,8 @@ ff_vorbis_comment(AVFormatContext * as, AVMetadata **m, const uint8_t *buf, int av_log(as, AV_LOG_INFO, "truncated comment header, %i comments not found\n", n); + metadata_conv(m, NULL, ff_vorbiscomment_metadata_conv); + return 0; } diff --git a/libavformat/oma.c b/libavformat/oma.c index cdf11067e7..0f471dd91f 100644 --- a/libavformat/oma.c +++ b/libavformat/oma.c @@ -201,6 +201,5 @@ AVInputFormat oma_demuxer = { .flags= AVFMT_GENERIC_INDEX, .extensions = "oma,aa3", .codec_tag= (const AVCodecTag* const []){codec_oma_tags, 0}, - .metadata_conv = ff_id3v2_metadata_conv, }; diff --git a/libavformat/vorbiscomment.c b/libavformat/vorbiscomment.c index 59a403f209..c84144e4c4 100644 --- a/libavformat/vorbiscomment.c +++ b/libavformat/vorbiscomment.c @@ -55,6 +55,7 @@ int ff_vorbiscomment_length(AVMetadata *m, const char *vendor_string, int ff_vorbiscomment_write(uint8_t **p, AVMetadata **m, const char *vendor_string, const unsigned count) { + metadata_conv(m, ff_vorbiscomment_metadata_conv, NULL); bytestream_put_le32(p, strlen(vendor_string)); bytestream_put_buffer(p, vendor_string, strlen(vendor_string)); if (*m) { -- cgit v1.2.3