Mercurial > libavformat.hg
annotate iff.c @ 4723:a2390c6a35e6 libavformat
Fix index generation in the way that it was supposed to be used. See the
discussion in the ML thread "[PATCH] rmdec.c: merge old/new packet reading
code".
Over time, this code broke somewhat, e.g. seq was never actually written
into (and was thus always 1, therefore the seq condition was always true),
whereas it was supposed to be set to the sequence number of the video slice
in case the video frame is divided over multiple RM packets (slices). The
problem of this is that packets other than those containing the beginning
of a video frame would be indexed as well.
Secondly, flags&2 is supposed to be true for video keyframes and for these
audio packets containing the start of a block. For some codecs (e.g. AAC),
that is every single packet, whereas for others (e.g. cook), that is the
packet containing the first of a series of scrambled packets that are to be
descrambled together. Indexing any of the following would lead to incomplete
and thus useless frames. Problem here is that flags would be reset to 2 to
indicate that the first packet is ready to be returned, and in addition if
no data was left to be returned (which is always true for the first packet),
then we wouldn't actually write the index entry anyway.
All in all, the idea was good and it probably worked at some point, but that
is long ago. This patch should at the very least make it likely for this code
to be executed again at the right times, i.e. the way it was originally
intended to be used.
author | rbultje |
---|---|
date | Sun, 15 Mar 2009 20:14:25 +0000 |
parents | 49c1d3b27727 |
children | c76c1e0c50a5 |
rev | line source |
---|---|
3189 | 1 /* |
3198 | 2 * IFF (.iff) file demuxer |
3189 | 3 * Copyright (c) 2008 Jaikrishnan Menon <realityman@gmx.net> |
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 /** | |
4331
49c1d3b27727
Use full internal pathname in doxygen @file directives.
diego
parents:
4201
diff
changeset
|
23 * @file libavformat/iff.c |
3198 | 24 * IFF file demuxer |
3189 | 25 * by Jaikrishnan Menon |
26 * for more information on the .iff file format, visit: | |
27 * http://wiki.multimedia.cx/index.php?title=IFF | |
28 */ | |
29 | |
4201
7d2f3f1b68d8
Fix build: Add intreadwrite.h and bswap.h #includes where necessary.
diego
parents:
4090
diff
changeset
|
30 #include "libavutil/intreadwrite.h" |
3189 | 31 #include "avformat.h" |
32 | |
33 #define ID_8SVX MKTAG('8','S','V','X') | |
34 #define ID_VHDR MKTAG('V','H','D','R') | |
35 #define ID_ATAK MKTAG('A','T','A','K') | |
36 #define ID_RLSE MKTAG('R','L','S','E') | |
37 #define ID_CHAN MKTAG('C','H','A','N') | |
38 | |
39 #define ID_FORM MKTAG('F','O','R','M') | |
40 #define ID_ANNO MKTAG('A','N','N','O') | |
41 #define ID_AUTH MKTAG('A','U','T','H') | |
42 #define ID_CHRS MKTAG('C','H','R','S') | |
43 #define ID_COPYRIGHT MKTAG('(','c',')',' ') | |
44 #define ID_CSET MKTAG('C','S','E','T') | |
45 #define ID_FVER MKTAG('F','V','E','R') | |
46 #define ID_NAME MKTAG('N','A','M','E') | |
47 #define ID_TEXT MKTAG('T','E','X','T') | |
48 #define ID_BODY MKTAG('B','O','D','Y') | |
49 | |
50 #define LEFT 2 | |
51 #define RIGHT 4 | |
52 #define STEREO 6 | |
53 | |
54 #define PACKET_SIZE 1024 | |
55 | |
4090
a209d26d63c2
Avoid _t in identifier names, _t is reserved by POSIX.
diego
parents:
3908
diff
changeset
|
56 typedef enum {COMP_NONE, COMP_FIB, COMP_EXP} svx8_compression_type; |
3189 | 57 |
58 typedef struct { | |
59 uint32_t body_size; | |
60 uint32_t sent_bytes; | |
61 uint32_t audio_frame_count; | |
62 } IffDemuxContext; | |
63 | |
3285 | 64 |
65 static void interleave_stereo(const uint8_t *src, uint8_t *dest, int size) | |
66 { | |
67 uint8_t *end = dest + size; | |
68 size = size>>1; | |
69 | |
70 while(dest < end) { | |
71 *dest++ = *src; | |
72 *dest++ = *(src+size); | |
73 src++; | |
74 } | |
75 } | |
76 | |
3189 | 77 static int iff_probe(AVProbeData *p) |
78 { | |
79 const uint8_t *d = p->buf; | |
80 | |
81 if ( AV_RL32(d) == ID_FORM && | |
82 AV_RL32(d+8) == ID_8SVX) | |
83 return AVPROBE_SCORE_MAX; | |
84 return 0; | |
85 } | |
86 | |
87 static int iff_read_header(AVFormatContext *s, | |
88 AVFormatParameters *ap) | |
89 { | |
90 IffDemuxContext *iff = s->priv_data; | |
91 ByteIOContext *pb = s->pb; | |
92 AVStream *st; | |
93 uint32_t chunk_id, data_size; | |
3200 | 94 int padding, done = 0; |
3189 | 95 |
96 st = av_new_stream(s, 0); | |
97 if (!st) | |
98 return AVERROR(ENOMEM); | |
99 | |
100 st->codec->channels = 1; | |
101 url_fskip(pb, 12); | |
102 | |
103 while(!done && !url_feof(pb)) { | |
104 chunk_id = get_le32(pb); | |
105 data_size = get_be32(pb); | |
106 padding = data_size & 1; | |
107 | |
108 switch(chunk_id) { | |
109 case ID_VHDR: | |
110 url_fskip(pb, 12); | |
111 st->codec->sample_rate = get_be16(pb); | |
112 url_fskip(pb, 1); | |
113 st->codec->codec_tag = get_byte(pb); | |
114 url_fskip(pb, 4); | |
115 break; | |
116 | |
117 case ID_BODY: | |
118 iff->body_size = data_size; | |
119 done = 1; | |
120 break; | |
121 | |
122 case ID_CHAN: | |
123 st->codec->channels = (get_be32(pb) < 6) ? 1 : 2; | |
124 break; | |
125 | |
126 default: | |
127 url_fseek(pb, data_size + padding, SEEK_CUR); | |
128 break; | |
129 } | |
130 } | |
131 | |
132 if(!st->codec->sample_rate) | |
133 return AVERROR_INVALIDDATA; | |
134 | |
135 av_set_pts_info(st, 32, 1, st->codec->sample_rate); | |
136 st->codec->codec_type = CODEC_TYPE_AUDIO; | |
137 | |
138 switch(st->codec->codec_tag) { | |
139 case COMP_NONE: | |
140 st->codec->codec_id = CODEC_ID_PCM_S8; | |
141 break; | |
142 case COMP_FIB: | |
143 st->codec->codec_id = CODEC_ID_8SVX_FIB; | |
144 break; | |
145 case COMP_EXP: | |
146 st->codec->codec_id = CODEC_ID_8SVX_EXP; | |
147 break; | |
148 default: | |
149 av_log(s, AV_LOG_ERROR, "iff: unknown compression method\n"); | |
150 return -1; | |
151 } | |
152 | |
3908
1d3d17de20ba
Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents:
3424
diff
changeset
|
153 st->codec->bits_per_coded_sample = 8; |
1d3d17de20ba
Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents:
3424
diff
changeset
|
154 st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * st->codec->bits_per_coded_sample; |
1d3d17de20ba
Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents:
3424
diff
changeset
|
155 st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample; |
3189 | 156 |
157 return 0; | |
158 } | |
159 | |
160 static int iff_read_packet(AVFormatContext *s, | |
161 AVPacket *pkt) | |
162 { | |
163 IffDemuxContext *iff = s->priv_data; | |
164 ByteIOContext *pb = s->pb; | |
165 int ret; | |
166 | |
167 if(iff->sent_bytes > iff->body_size) | |
168 return AVERROR(EIO); | |
3285 | 169 |
170 if(s->streams[0]->codec->channels == 2) { | |
171 uint8_t sample_buffer[PACKET_SIZE]; | |
172 | |
173 ret = get_buffer(pb, sample_buffer, PACKET_SIZE); | |
174 if(av_new_packet(pkt, PACKET_SIZE) < 0) { | |
175 av_log(s, AV_LOG_ERROR, "iff: cannot allocate packet \n"); | |
176 return AVERROR(ENOMEM); | |
177 } | |
178 interleave_stereo(sample_buffer, pkt->data, PACKET_SIZE); | |
179 } | |
180 else { | |
181 ret = av_get_packet(pb, pkt, PACKET_SIZE); | |
182 } | |
3189 | 183 |
184 if(iff->sent_bytes == 0) | |
185 pkt->flags |= PKT_FLAG_KEY; | |
186 | |
187 iff->sent_bytes += PACKET_SIZE; | |
188 pkt->stream_index = 0; | |
189 pkt->pts = iff->audio_frame_count; | |
190 iff->audio_frame_count += ret / s->streams[0]->codec->channels; | |
191 return ret; | |
192 } | |
193 | |
194 AVInputFormat iff_demuxer = { | |
195 "IFF", | |
3424
7a0230981402
Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents:
3285
diff
changeset
|
196 NULL_IF_CONFIG_SMALL("IFF format"), |
3189 | 197 sizeof(IffDemuxContext), |
198 iff_probe, | |
199 iff_read_header, | |
200 iff_read_packet, | |
201 }; |