Mercurial > libavformat.hg
annotate apetag.c @ 5549:7fc464450d8c libavformat
Support decoding Avid 1:1x codec, (partially) fixes issue1684.
author | cehoyos |
---|---|
date | Fri, 15 Jan 2010 10:55:31 +0000 |
parents | ab9e31e90d3c |
children | 8e0b6203dfb5 |
rev | line source |
---|---|
2548 | 1 /* |
5134 | 2 * APE tag handling |
2548 | 3 * Copyright (c) 2007 Benjamin Zores <ben@geexbox.org> |
4 * based upon libdemac from Dave Chapman. | |
5 * | |
6 * This file is part of FFmpeg. | |
7 * | |
8 * FFmpeg is free software; you can redistribute it and/or | |
9 * modify it under the terms of the GNU Lesser General Public | |
10 * License as published by the Free Software Foundation; either | |
11 * version 2.1 of the License, or (at your option) any later version. | |
12 * | |
13 * FFmpeg is distributed in the hope that it will be useful, | |
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 * Lesser General Public License for more details. | |
17 * | |
18 * You should have received a copy of the GNU Lesser General Public | |
19 * License along with FFmpeg; if not, write to the Free Software | |
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
21 */ | |
22 | |
4201
7d2f3f1b68d8
Fix build: Add intreadwrite.h and bswap.h #includes where necessary.
diego
parents:
3908
diff
changeset
|
23 #include "libavutil/intreadwrite.h" |
2548 | 24 #include "avformat.h" |
25 | |
2556
cb131102b256
disable loads of debug messages to reduce object size
aurel
parents:
2554
diff
changeset
|
26 #define ENABLE_DEBUG 0 |
cb131102b256
disable loads of debug messages to reduce object size
aurel
parents:
2554
diff
changeset
|
27 |
2554 | 28 #define APE_TAG_VERSION 2000 |
29 #define APE_TAG_FOOTER_BYTES 32 | |
30 #define APE_TAG_FLAG_CONTAINS_HEADER (1 << 31) | |
31 #define APE_TAG_FLAG_IS_HEADER (1 << 29) | |
32 | |
5133
1df917933244
Do not use internals of ByteIOContext during APE tags parsing.
kostya
parents:
5132
diff
changeset
|
33 static int ape_tag_read_field(AVFormatContext *s) |
2554 | 34 { |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2568
diff
changeset
|
35 ByteIOContext *pb = s->pb; |
5446
4211f91f69b1
Use AV_METADATA_DONT_STRDUP* / use av_malloced metadata instead of strduped
michael
parents:
5301
diff
changeset
|
36 uint8_t key[1024], *value; |
5133
1df917933244
Do not use internals of ByteIOContext during APE tags parsing.
kostya
parents:
5132
diff
changeset
|
37 uint32_t size, flags; |
5464 | 38 int i, c; |
2554 | 39 |
40 size = get_le32(pb); /* field size */ | |
5133
1df917933244
Do not use internals of ByteIOContext during APE tags parsing.
kostya
parents:
5132
diff
changeset
|
41 flags = get_le32(pb); /* field flags */ |
1df917933244
Do not use internals of ByteIOContext during APE tags parsing.
kostya
parents:
5132
diff
changeset
|
42 for (i = 0; i < sizeof(key) - 1; i++) { |
1df917933244
Do not use internals of ByteIOContext during APE tags parsing.
kostya
parents:
5132
diff
changeset
|
43 c = get_byte(pb); |
1df917933244
Do not use internals of ByteIOContext during APE tags parsing.
kostya
parents:
5132
diff
changeset
|
44 if (c < 0x20 || c > 0x7E) |
1df917933244
Do not use internals of ByteIOContext during APE tags parsing.
kostya
parents:
5132
diff
changeset
|
45 break; |
1df917933244
Do not use internals of ByteIOContext during APE tags parsing.
kostya
parents:
5132
diff
changeset
|
46 else |
1df917933244
Do not use internals of ByteIOContext during APE tags parsing.
kostya
parents:
5132
diff
changeset
|
47 key[i] = c; |
1df917933244
Do not use internals of ByteIOContext during APE tags parsing.
kostya
parents:
5132
diff
changeset
|
48 } |
1df917933244
Do not use internals of ByteIOContext during APE tags parsing.
kostya
parents:
5132
diff
changeset
|
49 key[i] = 0; |
1df917933244
Do not use internals of ByteIOContext during APE tags parsing.
kostya
parents:
5132
diff
changeset
|
50 if (c != 0) { |
1df917933244
Do not use internals of ByteIOContext during APE tags parsing.
kostya
parents:
5132
diff
changeset
|
51 av_log(s, AV_LOG_WARNING, "Invalid APE tag key '%s'.\n", key); |
1df917933244
Do not use internals of ByteIOContext during APE tags parsing.
kostya
parents:
5132
diff
changeset
|
52 return -1; |
1df917933244
Do not use internals of ByteIOContext during APE tags parsing.
kostya
parents:
5132
diff
changeset
|
53 } |
5446
4211f91f69b1
Use AV_METADATA_DONT_STRDUP* / use av_malloced metadata instead of strduped
michael
parents:
5301
diff
changeset
|
54 if (size >= UINT_MAX) |
4211f91f69b1
Use AV_METADATA_DONT_STRDUP* / use av_malloced metadata instead of strduped
michael
parents:
5301
diff
changeset
|
55 return -1; |
4211f91f69b1
Use AV_METADATA_DONT_STRDUP* / use av_malloced metadata instead of strduped
michael
parents:
5301
diff
changeset
|
56 value = av_malloc(size+1); |
4211f91f69b1
Use AV_METADATA_DONT_STRDUP* / use av_malloced metadata instead of strduped
michael
parents:
5301
diff
changeset
|
57 if (!value) |
4211f91f69b1
Use AV_METADATA_DONT_STRDUP* / use av_malloced metadata instead of strduped
michael
parents:
5301
diff
changeset
|
58 return AVERROR_NOMEM; |
4211f91f69b1
Use AV_METADATA_DONT_STRDUP* / use av_malloced metadata instead of strduped
michael
parents:
5301
diff
changeset
|
59 get_buffer(pb, value, size); |
4211f91f69b1
Use AV_METADATA_DONT_STRDUP* / use av_malloced metadata instead of strduped
michael
parents:
5301
diff
changeset
|
60 value[size] = 0; |
4211f91f69b1
Use AV_METADATA_DONT_STRDUP* / use av_malloced metadata instead of strduped
michael
parents:
5301
diff
changeset
|
61 av_metadata_set2(&s->metadata, key, value, AV_METADATA_DONT_STRDUP_VAL); |
5133
1df917933244
Do not use internals of ByteIOContext during APE tags parsing.
kostya
parents:
5132
diff
changeset
|
62 return 0; |
2554 | 63 } |
64 | |
5134 | 65 void ff_ape_parse_tag(AVFormatContext *s) |
2554 | 66 { |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2568
diff
changeset
|
67 ByteIOContext *pb = s->pb; |
2554 | 68 int file_size = url_fsize(pb); |
69 uint32_t val, fields, tag_bytes; | |
70 uint8_t buf[8]; | |
71 int i; | |
72 | |
73 if (file_size < APE_TAG_FOOTER_BYTES) | |
74 return; | |
75 | |
76 url_fseek(pb, file_size - APE_TAG_FOOTER_BYTES, SEEK_SET); | |
77 | |
78 get_buffer(pb, buf, 8); /* APETAGEX */ | |
79 if (strncmp(buf, "APETAGEX", 8)) { | |
80 return; | |
81 } | |
82 | |
83 val = get_le32(pb); /* APE tag version */ | |
84 if (val > APE_TAG_VERSION) { | |
4506
dfb8f047b552
Add a context to av_log() calls and extend ape_dumpinfo prototype to do that.
benoit
parents:
4201
diff
changeset
|
85 av_log(s, AV_LOG_ERROR, "Unsupported tag version. (>=%d)\n", APE_TAG_VERSION); |
2554 | 86 return; |
87 } | |
88 | |
89 tag_bytes = get_le32(pb); /* tag size */ | |
90 if (tag_bytes - APE_TAG_FOOTER_BYTES > (1024 * 1024 * 16)) { | |
4506
dfb8f047b552
Add a context to av_log() calls and extend ape_dumpinfo prototype to do that.
benoit
parents:
4201
diff
changeset
|
91 av_log(s, AV_LOG_ERROR, "Tag size is way too big\n"); |
2554 | 92 return; |
93 } | |
94 | |
95 fields = get_le32(pb); /* number of fields */ | |
96 if (fields > 65536) { | |
4506
dfb8f047b552
Add a context to av_log() calls and extend ape_dumpinfo prototype to do that.
benoit
parents:
4201
diff
changeset
|
97 av_log(s, AV_LOG_ERROR, "Too many tag fields (%d)\n", fields); |
2554 | 98 return; |
99 } | |
100 | |
101 val = get_le32(pb); /* flags */ | |
102 if (val & APE_TAG_FLAG_IS_HEADER) { | |
4506
dfb8f047b552
Add a context to av_log() calls and extend ape_dumpinfo prototype to do that.
benoit
parents:
4201
diff
changeset
|
103 av_log(s, AV_LOG_ERROR, "APE Tag is a header\n"); |
2554 | 104 return; |
105 } | |
106 | |
107 url_fseek(pb, file_size - tag_bytes, SEEK_SET); | |
108 | |
109 for (i=0; i<fields; i++) | |
5133
1df917933244
Do not use internals of ByteIOContext during APE tags parsing.
kostya
parents:
5132
diff
changeset
|
110 if (ape_tag_read_field(s) < 0) break; |
2554 | 111 } |