Revision 04d2540c
libavformat/Makefile | ||
---|---|---|
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 |
libavformat/avi.c | ||
---|---|---|
1 |
/* |
|
2 |
* AVI common data |
|
3 |
* Copyright (c) 2010 Anton Khirnov |
|
4 |
* |
|
5 |
* This file is part of FFmpeg. |
|
6 |
* |
|
7 |
* FFmpeg is free software; you can redistribute it and/or |
|
8 |
* modify it under the terms of the GNU Lesser General Public |
|
9 |
* License as published by the Free Software Foundation; either |
|
10 |
* version 2.1 of the License, or (at your option) any later version. |
|
11 |
* |
|
12 |
* FFmpeg is distributed in the hope that it will be useful, |
|
13 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
14 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
15 |
* Lesser General Public License for more details. |
|
16 |
* |
|
17 |
* You should have received a copy of the GNU Lesser General Public |
|
18 |
* License along with FFmpeg; if not, write to the Free Software |
|
19 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
20 |
*/ |
|
21 |
|
|
22 |
#include "avi.h" |
|
23 |
|
|
24 |
const AVMetadataConv ff_avi_metadata_conv[] = { |
|
25 |
{ "IART", "artist" }, |
|
26 |
{ "ICMT", "comment" }, |
|
27 |
{ "ICOP", "copyright" }, |
|
28 |
{ "ICRD", "date" }, |
|
29 |
{ "IGNR", "genre" }, |
|
30 |
{ "ILNG", "language" }, |
|
31 |
{ "INAM", "title" }, |
|
32 |
{ "IPRD", "album" }, |
|
33 |
{ "IPRT", "track" }, |
|
34 |
{ "ISFT", "encoder" }, |
|
35 |
{ "ITCH", "encoded_by"}, |
|
36 |
{ "strn", "title" }, |
|
37 |
{ 0 }, |
|
38 |
}; |
|
39 |
|
|
40 |
const char ff_avi_tags[][5] = { |
|
41 |
"IARL", "IART", "ICMS", "ICMT", "ICOP", "ICRD", "ICRP", "IDIM", "IDPI", |
|
42 |
"IENG", "IGNR", "IKEY", "ILGT", "ILNG", "IMED", "INAM", "IPLT", "IPRD", |
|
43 |
"IPRT", "ISBJ",/*"ISFT"*/"ISHP", "ISRC", "ISRF", "ITCH", |
|
44 |
{0} |
|
45 |
}; |
libavformat/avi.h | ||
---|---|---|
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 | 36 |
/* index flags */ |
35 | 37 |
#define AVIIF_INDEX 0x10 |
36 | 38 |
|
39 |
extern const AVMetadataConv ff_avi_metadata_conv[]; |
|
40 |
|
|
41 |
/** |
|
42 |
* A list of AVI info tags. |
|
43 |
*/ |
|
44 |
extern const char ff_avi_tags[][5]; |
|
45 |
|
|
37 | 46 |
#endif /* AVFORMAT_AVI_H */ |
libavformat/avidec.c | ||
---|---|---|
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 | 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 | 252 |
AV_METADATA_DONT_STRDUP_VAL); |
251 | 253 |
} |
252 | 254 |
|
255 |
static void avi_read_info(AVFormatContext *s, uint64_t end) |
|
256 |
{ |
|
257 |
while (url_ftell(s->pb) < end) { |
|
258 |
uint32_t tag = get_le32(s->pb); |
|
259 |
uint32_t size = get_le32(s->pb); |
|
260 |
avi_read_tag(s, NULL, tag, size); |
|
261 |
} |
|
262 |
} |
|
263 |
|
|
253 | 264 |
static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) |
254 | 265 |
{ |
255 | 266 |
AVIContext *avi = s->priv_data; |
... | ... | |
301 | 312 |
dprintf(NULL, "movi end=%"PRIx64"\n", avi->movi_end); |
302 | 313 |
goto end_of_header; |
303 | 314 |
} |
315 |
else if (tag1 == MKTAG('I', 'N', 'F', 'O')) |
|
316 |
avi_read_info(s, list_end); |
|
317 |
|
|
304 | 318 |
break; |
305 | 319 |
case MKTAG('d', 'm', 'l', 'h'): |
306 | 320 |
avi->is_odml = 1; |
... | ... | |
606 | 620 |
} |
607 | 621 |
url_fseek(pb, size, SEEK_CUR); |
608 | 622 |
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 | 623 |
case MKTAG('s', 't', 'r', 'n'): |
631 | 624 |
if(s->nb_streams){ |
632 |
avi_read_tag(s, s->streams[s->nb_streams-1], "Title", size);
|
|
625 |
avi_read_tag(s, s->streams[s->nb_streams-1], tag, size);
|
|
633 | 626 |
break; |
634 | 627 |
} |
635 | 628 |
default: |
... | ... | |
1190 | 1183 |
avi_read_packet, |
1191 | 1184 |
avi_read_close, |
1192 | 1185 |
avi_read_seek, |
1186 |
.metadata_conv = ff_avi_metadata_conv, |
|
1193 | 1187 |
}; |
libavformat/avienc.c | ||
---|---|---|
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 | 115 |
} |
115 | 116 |
} |
116 | 117 |
|
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 | 118 |
static int avi_write_counters(AVFormatContext* s, int riff_id) |
134 | 119 |
{ |
135 | 120 |
ByteIOContext *pb = s->pb; |
... | ... | |
171 | 156 |
int bitrate, n, i, nb_frames, au_byterate, au_ssize, au_scale; |
172 | 157 |
AVCodecContext *stream, *video_enc; |
173 | 158 |
int64_t list1, list2, strh, strf; |
159 |
AVMetadataTag *t = NULL; |
|
174 | 160 |
|
175 | 161 |
for(n=0;n<s->nb_streams;n++) { |
176 | 162 |
s->streams[n]->priv_data= av_mallocz(sizeof(AVIStream)); |
... | ... | |
301 | 287 |
return -1; |
302 | 288 |
} |
303 | 289 |
ff_end_tag(pb, strf); |
304 |
avi_write_info_tag2(s, s->streams[i], "strn", "Title", "Description"); |
|
290 |
if ((t = av_metadata_get(s->streams[i]->metadata, "strn", NULL, 0))) { |
|
291 |
avi_write_info_tag(s->pb, t->key, t->value); |
|
292 |
t = NULL; |
|
293 |
} |
|
294 |
//FIXME a limitation of metadata conversion system |
|
295 |
else if ((t = av_metadata_get(s->streams[i]->metadata, "INAM", NULL, 0))) { |
|
296 |
avi_write_info_tag(s->pb, "strn", t->value); |
|
297 |
t = NULL; |
|
298 |
} |
|
305 | 299 |
} |
306 | 300 |
|
307 | 301 |
if (!url_is_streamed(pb)) { |
... | ... | |
378 | 372 |
|
379 | 373 |
list2 = ff_start_tag(pb, "LIST"); |
380 | 374 |
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); |
|
375 |
for (i = 0; *ff_avi_tags[i]; i++) { |
|
376 |
if ((t = av_metadata_get(s->metadata, ff_avi_tags[i], NULL, AV_METADATA_MATCH_CASE))) |
|
377 |
avi_write_info_tag(s->pb, t->key, t->value); |
|
378 |
} |
|
388 | 379 |
if(!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) |
389 | 380 |
avi_write_info_tag(pb, "ISFT", LIBAVFORMAT_IDENT); |
390 | 381 |
ff_end_tag(pb, list2); |
... | ... | |
655 | 646 |
avi_write_trailer, |
656 | 647 |
.codec_tag= (const AVCodecTag* const []){ff_codec_bmp_tags, ff_codec_wav_tags, 0}, |
657 | 648 |
.flags= AVFMT_VARIABLE_FPS, |
649 |
.metadata_conv = ff_avi_metadata_conv, |
|
658 | 650 |
}; |
Also available in: Unified diff