mirror of https://git.ffmpeg.org/ffmpeg.git
Add AVI metadata conversion table.
Patch by Anton Khirnov (gmail{wyskas}). Originally committed as revision 21653 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
86a4f011e6
commit
04d2540c4b
|
@ -35,8 +35,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 raw.o
|
OBJS-$(CONFIG_AU_DEMUXER) += au.o raw.o
|
||||||
OBJS-$(CONFIG_AU_MUXER) += au.o
|
OBJS-$(CONFIG_AU_MUXER) += au.o
|
||||||
OBJS-$(CONFIG_AVI_DEMUXER) += avidec.o riff.o
|
OBJS-$(CONFIG_AVI_DEMUXER) += avidec.o riff.o avi.o
|
||||||
OBJS-$(CONFIG_AVI_MUXER) += avienc.o riff.o
|
OBJS-$(CONFIG_AVI_MUXER) += avienc.o riff.o avi.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
|
||||||
|
|
|
@ -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}
|
||||||
|
};
|
|
@ -21,6 +21,8 @@
|
||||||
#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
|
||||||
|
@ -34,4 +36,11 @@
|
||||||
/* 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 */
|
||||||
|
|
|
@ -227,10 +227,10 @@ static void clean_index(AVFormatContext *s){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
ByteIOContext *pb = s->pb;
|
||||||
char *value;
|
char key[5] = {0}, *value;
|
||||||
|
|
||||||
size += (size & 1);
|
size += (size & 1);
|
||||||
|
|
||||||
|
@ -242,6 +242,8 @@ static int avi_read_tag(AVFormatContext *s, AVStream *st, const char *key, unsig
|
||||||
get_buffer(pb, value, size);
|
get_buffer(pb, value, size);
|
||||||
value[size]=0;
|
value[size]=0;
|
||||||
|
|
||||||
|
AV_WL32(key, tag);
|
||||||
|
|
||||||
if(st)
|
if(st)
|
||||||
return av_metadata_set2(&st->metadata, key, value,
|
return av_metadata_set2(&st->metadata, key, value,
|
||||||
AV_METADATA_DONT_STRDUP_VAL);
|
AV_METADATA_DONT_STRDUP_VAL);
|
||||||
|
@ -250,6 +252,15 @@ static int avi_read_tag(AVFormatContext *s, AVStream *st, const char *key, unsig
|
||||||
AV_METADATA_DONT_STRDUP_VAL);
|
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)
|
static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
|
||||||
{
|
{
|
||||||
AVIContext *avi = s->priv_data;
|
AVIContext *avi = s->priv_data;
|
||||||
|
@ -301,6 +312,9 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
|
||||||
dprintf(NULL, "movi end=%"PRIx64"\n", avi->movi_end);
|
dprintf(NULL, "movi end=%"PRIx64"\n", avi->movi_end);
|
||||||
goto end_of_header;
|
goto end_of_header;
|
||||||
}
|
}
|
||||||
|
else if (tag1 == MKTAG('I', 'N', 'F', 'O'))
|
||||||
|
avi_read_info(s, list_end);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case MKTAG('d', 'm', 'l', 'h'):
|
case MKTAG('d', 'm', 'l', 'h'):
|
||||||
avi->is_odml = 1;
|
avi->is_odml = 1;
|
||||||
|
@ -606,30 +620,9 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
|
||||||
}
|
}
|
||||||
url_fseek(pb, size, SEEK_CUR);
|
url_fseek(pb, size, SEEK_CUR);
|
||||||
break;
|
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'):
|
case MKTAG('s', 't', 'r', 'n'):
|
||||||
if(s->nb_streams){
|
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;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -1190,4 +1183,5 @@ AVInputFormat avi_demuxer = {
|
||||||
avi_read_packet,
|
avi_read_packet,
|
||||||
avi_read_close,
|
avi_read_close,
|
||||||
avi_read_seek,
|
avi_read_seek,
|
||||||
|
.metadata_conv = ff_avi_metadata_conv,
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "avformat.h"
|
#include "avformat.h"
|
||||||
#include "avi.h"
|
#include "avi.h"
|
||||||
#include "riff.h"
|
#include "riff.h"
|
||||||
|
#include "libavutil/intreadwrite.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO:
|
* TODO:
|
||||||
|
@ -114,22 +115,6 @@ static void avi_write_info_tag(ByteIOContext *pb, const char *tag, const char *s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
static int avi_write_counters(AVFormatContext* s, int riff_id)
|
||||||
{
|
{
|
||||||
ByteIOContext *pb = s->pb;
|
ByteIOContext *pb = s->pb;
|
||||||
|
@ -171,6 +156,7 @@ static int avi_write_header(AVFormatContext *s)
|
||||||
int bitrate, n, i, nb_frames, au_byterate, au_ssize, au_scale;
|
int bitrate, n, i, nb_frames, au_byterate, au_ssize, au_scale;
|
||||||
AVCodecContext *stream, *video_enc;
|
AVCodecContext *stream, *video_enc;
|
||||||
int64_t list1, list2, strh, strf;
|
int64_t list1, list2, strh, strf;
|
||||||
|
AVMetadataTag *t = NULL;
|
||||||
|
|
||||||
for(n=0;n<s->nb_streams;n++) {
|
for(n=0;n<s->nb_streams;n++) {
|
||||||
s->streams[n]->priv_data= av_mallocz(sizeof(AVIStream));
|
s->streams[n]->priv_data= av_mallocz(sizeof(AVIStream));
|
||||||
|
@ -301,7 +287,15 @@ static int avi_write_header(AVFormatContext *s)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ff_end_tag(pb, strf);
|
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)) {
|
if (!url_is_streamed(pb)) {
|
||||||
|
@ -378,13 +372,10 @@ static int avi_write_header(AVFormatContext *s)
|
||||||
|
|
||||||
list2 = ff_start_tag(pb, "LIST");
|
list2 = ff_start_tag(pb, "LIST");
|
||||||
put_tag(pb, "INFO");
|
put_tag(pb, "INFO");
|
||||||
avi_write_info_tag2(s, NULL, "INAM", "Title", NULL);
|
for (i = 0; *ff_avi_tags[i]; i++) {
|
||||||
avi_write_info_tag2(s, NULL, "IART", "Artist", "Author");
|
if ((t = av_metadata_get(s->metadata, ff_avi_tags[i], NULL, AV_METADATA_MATCH_CASE)))
|
||||||
avi_write_info_tag2(s, NULL, "ICOP", "Copyright", NULL);
|
avi_write_info_tag(s->pb, t->key, t->value);
|
||||||
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);
|
|
||||||
if(!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT))
|
if(!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT))
|
||||||
avi_write_info_tag(pb, "ISFT", LIBAVFORMAT_IDENT);
|
avi_write_info_tag(pb, "ISFT", LIBAVFORMAT_IDENT);
|
||||||
ff_end_tag(pb, list2);
|
ff_end_tag(pb, list2);
|
||||||
|
@ -655,4 +646,5 @@ AVOutputFormat avi_muxer = {
|
||||||
avi_write_trailer,
|
avi_write_trailer,
|
||||||
.codec_tag= (const AVCodecTag* const []){ff_codec_bmp_tags, ff_codec_wav_tags, 0},
|
.codec_tag= (const AVCodecTag* const []){ff_codec_bmp_tags, ff_codec_wav_tags, 0},
|
||||||
.flags= AVFMT_VARIABLE_FPS,
|
.flags= AVFMT_VARIABLE_FPS,
|
||||||
|
.metadata_conv = ff_avi_metadata_conv,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue