Signed-off-by: Ronald S. Bultje <rsbultje@gmail.com>tags/n0.9
| @@ -39,8 +39,8 @@ OBJS-$(CONFIG_ASS_DEMUXER) += assdec.o | |||||
| OBJS-$(CONFIG_ASS_MUXER) += assenc.o | OBJS-$(CONFIG_ASS_MUXER) += assenc.o | ||||
| OBJS-$(CONFIG_AU_DEMUXER) += au.o pcm.o | OBJS-$(CONFIG_AU_DEMUXER) += au.o pcm.o | ||||
| OBJS-$(CONFIG_AU_MUXER) += au.o | OBJS-$(CONFIG_AU_MUXER) += au.o | ||||
| OBJS-$(CONFIG_AVI_DEMUXER) += avidec.o riff.o avi.o | |||||
| OBJS-$(CONFIG_AVI_MUXER) += avienc.o riff.o avi.o | |||||
| OBJS-$(CONFIG_AVI_DEMUXER) += avidec.o riff.o | |||||
| OBJS-$(CONFIG_AVI_MUXER) += avienc.o riff.o | |||||
| OBJS-$(CONFIG_AVISYNTH) += avisynth.o | OBJS-$(CONFIG_AVISYNTH) += avisynth.o | ||||
| OBJS-$(CONFIG_AVM2_MUXER) += swfenc.o | OBJS-$(CONFIG_AVM2_MUXER) += swfenc.o | ||||
| OBJS-$(CONFIG_AVS_DEMUXER) += avs.o vocdec.o voc.o | OBJS-$(CONFIG_AVS_DEMUXER) += avs.o vocdec.o voc.o | ||||
| @@ -1,45 +0,0 @@ | |||||
| /* | |||||
| * AVI common data | |||||
| * Copyright (c) 2010 Anton Khirnov | |||||
| * | |||||
| * This file is part of Libav. | |||||
| * | |||||
| * Libav 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. | |||||
| * | |||||
| * Libav 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 Libav; 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} | |||||
| }; | |||||
| @@ -21,8 +21,6 @@ | |||||
| #ifndef AVFORMAT_AVI_H | #ifndef AVFORMAT_AVI_H | ||||
| #define AVFORMAT_AVI_H | #define AVFORMAT_AVI_H | ||||
| #include "metadata.h" | |||||
| #define AVIF_HASINDEX 0x00000010 // Index at end of file? | #define AVIF_HASINDEX 0x00000010 // Index at end of file? | ||||
| #define AVIF_MUSTUSEINDEX 0x00000020 | #define AVIF_MUSTUSEINDEX 0x00000020 | ||||
| #define AVIF_ISINTERLEAVED 0x00000100 | #define AVIF_ISINTERLEAVED 0x00000100 | ||||
| @@ -37,11 +35,4 @@ | |||||
| /* index flags */ | /* index flags */ | ||||
| #define AVIIF_INDEX 0x10 | #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 */ | #endif /* AVFORMAT_AVI_H */ | ||||
| @@ -79,6 +79,11 @@ static const char avi_headers[][8] = { | |||||
| { 0 } | { 0 } | ||||
| }; | }; | ||||
| static const AVMetadataConv avi_metadata_conv[] = { | |||||
| { "strn", "title" }, | |||||
| { 0 }, | |||||
| }; | |||||
| static int avi_load_index(AVFormatContext *s); | static int avi_load_index(AVFormatContext *s); | ||||
| static int guess_ni_flag(AVFormatContext *s); | static int guess_ni_flag(AVFormatContext *s); | ||||
| @@ -261,15 +266,6 @@ static int avi_read_tag(AVFormatContext *s, AVStream *st, uint32_t tag, uint32_t | |||||
| AV_DICT_DONT_STRDUP_VAL); | AV_DICT_DONT_STRDUP_VAL); | ||||
| } | } | ||||
| static void avi_read_info(AVFormatContext *s, uint64_t end) | |||||
| { | |||||
| while (avio_tell(s->pb) < end) { | |||||
| uint32_t tag = avio_rl32(s->pb); | |||||
| uint32_t size = avio_rl32(s->pb); | |||||
| avi_read_tag(s, NULL, tag, size); | |||||
| } | |||||
| } | |||||
| static const char months[12][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", | static const char months[12][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", | ||||
| "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; | "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; | ||||
| @@ -380,7 +376,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||||
| goto end_of_header; | goto end_of_header; | ||||
| } | } | ||||
| else if (tag1 == MKTAG('I', 'N', 'F', 'O')) | else if (tag1 == MKTAG('I', 'N', 'F', 'O')) | ||||
| avi_read_info(s, list_end); | |||||
| ff_read_riff_info(s, size - 4); | |||||
| else if (tag1 == MKTAG('n', 'c', 'd', 't')) | else if (tag1 == MKTAG('n', 'c', 'd', 't')) | ||||
| avi_read_nikon(s, list_end); | avi_read_nikon(s, list_end); | ||||
| @@ -745,7 +741,8 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||||
| clean_index(s); | clean_index(s); | ||||
| } | } | ||||
| ff_metadata_conv_ctx(s, NULL, ff_avi_metadata_conv); | |||||
| ff_metadata_conv_ctx(s, NULL, avi_metadata_conv); | |||||
| ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv); | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -378,9 +378,9 @@ static int avi_write_header(AVFormatContext *s) | |||||
| list2 = ff_start_tag(pb, "LIST"); | list2 = ff_start_tag(pb, "LIST"); | ||||
| ffio_wfourcc(pb, "INFO"); | ffio_wfourcc(pb, "INFO"); | ||||
| ff_metadata_conv(&s->metadata, ff_avi_metadata_conv, NULL); | |||||
| for (i = 0; *ff_avi_tags[i]; i++) { | |||||
| if ((t = av_dict_get(s->metadata, ff_avi_tags[i], NULL, AV_DICT_MATCH_CASE))) | |||||
| ff_metadata_conv(&s->metadata, ff_riff_info_conv, NULL); | |||||
| for (i = 0; *ff_riff_tags[i]; i++) { | |||||
| if ((t = av_dict_get(s->metadata, ff_riff_tags[i], NULL, AV_DICT_MATCH_CASE))) | |||||
| avi_write_info_tag(s->pb, t->key, t->value); | avi_write_info_tag(s->pb, t->key, t->value); | ||||
| } | } | ||||
| ff_end_tag(pb, list2); | ff_end_tag(pb, list2); | ||||
| @@ -342,6 +342,28 @@ const AVCodecTag ff_codec_wav_tags[] = { | |||||
| { CODEC_ID_NONE, 0 }, | { CODEC_ID_NONE, 0 }, | ||||
| }; | }; | ||||
| const AVMetadataConv ff_riff_info_conv[] = { | |||||
| { "IART", "artist" }, | |||||
| { "ICMT", "comment" }, | |||||
| { "ICOP", "copyright" }, | |||||
| { "ICRD", "date" }, | |||||
| { "IGNR", "genre" }, | |||||
| { "ILNG", "language" }, | |||||
| { "INAM", "title" }, | |||||
| { "IPRD", "album" }, | |||||
| { "IPRT", "track" }, | |||||
| { "ISFT", "encoder" }, | |||||
| { "ITCH", "encoded_by"}, | |||||
| { 0 }, | |||||
| }; | |||||
| const char ff_riff_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} | |||||
| }; | |||||
| #if CONFIG_MUXERS | #if CONFIG_MUXERS | ||||
| int64_t ff_start_tag(AVIOContext *pb, const char *tag) | int64_t ff_start_tag(AVIOContext *pb, const char *tag) | ||||
| { | { | ||||
| @@ -613,3 +635,49 @@ void ff_parse_specific_params(AVCodecContext *stream, int *au_rate, int *au_ssiz | |||||
| *au_scale /= gcd; | *au_scale /= gcd; | ||||
| *au_rate /= gcd; | *au_rate /= gcd; | ||||
| } | } | ||||
| int ff_read_riff_info(AVFormatContext *s, int64_t size) | |||||
| { | |||||
| int64_t start, end, cur; | |||||
| AVIOContext *pb = s->pb; | |||||
| start = avio_tell(pb); | |||||
| end = start + size; | |||||
| while ((cur = avio_tell(pb)) >= 0 && cur <= end - 8 /* = tag + size */) { | |||||
| uint32_t chunk_code; | |||||
| int64_t chunk_size; | |||||
| char key[5] = {0}; | |||||
| char *value; | |||||
| chunk_code = avio_rl32(pb); | |||||
| chunk_size = avio_rl32(pb); | |||||
| if (chunk_size > end || end - chunk_size < cur || chunk_size == UINT_MAX) { | |||||
| av_log(s, AV_LOG_ERROR, "too big INFO subchunk\n"); | |||||
| return AVERROR_INVALIDDATA; | |||||
| } | |||||
| chunk_size += (chunk_size & 1); | |||||
| value = av_malloc(chunk_size + 1); | |||||
| if (!value) { | |||||
| av_log(s, AV_LOG_ERROR, "out of memory, unable to read INFO tag\n"); | |||||
| return AVERROR(ENOMEM); | |||||
| } | |||||
| AV_WL32(key, chunk_code); | |||||
| if (avio_read(pb, value, chunk_size) != chunk_size) { | |||||
| av_freep(key); | |||||
| av_freep(value); | |||||
| av_log(s, AV_LOG_ERROR, "premature end of file while reading INFO tag\n"); | |||||
| return AVERROR_INVALIDDATA; | |||||
| } | |||||
| value[chunk_size] = 0; | |||||
| av_dict_set(&s->metadata, key, value, AV_DICT_DONT_STRDUP_VAL); | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| @@ -31,6 +31,10 @@ | |||||
| #include "libavcodec/avcodec.h" | #include "libavcodec/avcodec.h" | ||||
| #include "avio.h" | #include "avio.h" | ||||
| #include "internal.h" | #include "internal.h" | ||||
| #include "metadata.h" | |||||
| extern const AVMetadataConv ff_riff_info_conv[]; | |||||
| extern const char ff_riff_tags[][5]; | |||||
| int64_t ff_start_tag(AVIOContext *pb, const char *tag); | int64_t ff_start_tag(AVIOContext *pb, const char *tag); | ||||
| void ff_end_tag(AVIOContext *pb, int64_t start); | void ff_end_tag(AVIOContext *pb, int64_t start); | ||||
| @@ -54,4 +58,6 @@ unsigned int ff_codec_get_tag(const AVCodecTag *tags, enum CodecID id); | |||||
| enum CodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag); | enum CodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag); | ||||
| void ff_parse_specific_params(AVCodecContext *stream, int *au_rate, int *au_ssize, int *au_scale); | void ff_parse_specific_params(AVCodecContext *stream, int *au_rate, int *au_ssize, int *au_scale); | ||||
| int ff_read_riff_info(AVFormatContext *s, int64_t size); | |||||
| #endif /* AVFORMAT_RIFF_H */ | #endif /* AVFORMAT_RIFF_H */ | ||||
| @@ -33,7 +33,6 @@ | |||||
| #include "pcm.h" | #include "pcm.h" | ||||
| #include "riff.h" | #include "riff.h" | ||||
| #include "avio.h" | #include "avio.h" | ||||
| #include "avio_internal.h" | |||||
| #include "metadata.h" | #include "metadata.h" | ||||
| typedef struct { | typedef struct { | ||||
| @@ -224,7 +223,7 @@ AVOutputFormat ff_wav_muxer = { | |||||
| #if CONFIG_WAV_DEMUXER | #if CONFIG_WAV_DEMUXER | ||||
| static int64_t next_tag(AVIOContext *pb, unsigned int *tag) | |||||
| static int64_t next_tag(AVIOContext *pb, uint32_t *tag) | |||||
| { | { | ||||
| *tag = avio_rl32(pb); | *tag = avio_rl32(pb); | ||||
| return avio_rl32(pb); | return avio_rl32(pb); | ||||
| @@ -385,7 +384,7 @@ static int wav_read_header(AVFormatContext *s, | |||||
| int64_t size, av_uninit(data_size); | int64_t size, av_uninit(data_size); | ||||
| int64_t sample_count=0; | int64_t sample_count=0; | ||||
| int rf64; | int rf64; | ||||
| unsigned int tag; | |||||
| uint32_t tag, list_type; | |||||
| AVIOContext *pb = s->pb; | AVIOContext *pb = s->pb; | ||||
| AVStream *st; | AVStream *st; | ||||
| WAVContext *wav = s->priv_data; | WAVContext *wav = s->priv_data; | ||||
| @@ -467,6 +466,18 @@ static int wav_read_header(AVFormatContext *s, | |||||
| if ((ret = wav_parse_bext_tag(s, size)) < 0) | if ((ret = wav_parse_bext_tag(s, size)) < 0) | ||||
| return ret; | return ret; | ||||
| break; | break; | ||||
| case MKTAG('L', 'I', 'S', 'T'): | |||||
| list_type = avio_rl32(pb); | |||||
| if (size <= 4) { | |||||
| av_log(s, AV_LOG_ERROR, "too short LIST"); | |||||
| return AVERROR_INVALIDDATA; | |||||
| } | |||||
| switch (list_type) { | |||||
| case MKTAG('I', 'N', 'F', 'O'): | |||||
| if ((ret = ff_read_riff_info(s, size - 4)) < 0) | |||||
| return ret; | |||||
| } | |||||
| break; | |||||
| } | } | ||||
| /* seek to next tag unless we know that we'll run into EOF */ | /* seek to next tag unless we know that we'll run into EOF */ | ||||
| @@ -489,6 +500,7 @@ break_loop: | |||||
| st->duration = sample_count; | st->duration = sample_count; | ||||
| ff_metadata_conv_ctx(s, NULL, wav_metadata_conv); | ff_metadata_conv_ctx(s, NULL, wav_metadata_conv); | ||||
| ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv); | |||||
| return 0; | return 0; | ||||
| } | } | ||||