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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3189
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
1 /*
3198
814a32de9ec7 minor typo fixes
diego
parents: 3189
diff changeset
2 * IFF (.iff) file demuxer
3189
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
3 * Copyright (c) 2008 Jaikrishnan Menon <realityman@gmx.net>
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
4 *
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
5 * This file is part of FFmpeg.
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
6 *
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
11 *
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
15 * Lesser General Public License for more details.
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
16 *
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
20 */
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
21
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
22 /**
4331
49c1d3b27727 Use full internal pathname in doxygen @file directives.
diego
parents: 4201
diff changeset
23 * @file libavformat/iff.c
3198
814a32de9ec7 minor typo fixes
diego
parents: 3189
diff changeset
24 * IFF file demuxer
3189
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
25 * by Jaikrishnan Menon
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
26 * for more information on the .iff file format, visit:
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
27 * http://wiki.multimedia.cx/index.php?title=IFF
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
28 */
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
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
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
31 #include "avformat.h"
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
32
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
33 #define ID_8SVX MKTAG('8','S','V','X')
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
34 #define ID_VHDR MKTAG('V','H','D','R')
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
35 #define ID_ATAK MKTAG('A','T','A','K')
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
36 #define ID_RLSE MKTAG('R','L','S','E')
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
37 #define ID_CHAN MKTAG('C','H','A','N')
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
38
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
39 #define ID_FORM MKTAG('F','O','R','M')
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
40 #define ID_ANNO MKTAG('A','N','N','O')
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
41 #define ID_AUTH MKTAG('A','U','T','H')
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
42 #define ID_CHRS MKTAG('C','H','R','S')
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
43 #define ID_COPYRIGHT MKTAG('(','c',')',' ')
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
44 #define ID_CSET MKTAG('C','S','E','T')
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
45 #define ID_FVER MKTAG('F','V','E','R')
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
46 #define ID_NAME MKTAG('N','A','M','E')
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
47 #define ID_TEXT MKTAG('T','E','X','T')
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
48 #define ID_BODY MKTAG('B','O','D','Y')
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
49
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
50 #define LEFT 2
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
51 #define RIGHT 4
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
52 #define STEREO 6
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
53
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
54 #define PACKET_SIZE 1024
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
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
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
57
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
58 typedef struct {
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
59 uint32_t body_size;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
60 uint32_t sent_bytes;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
61 uint32_t audio_frame_count;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
62 } IffDemuxContext;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
63
3285
ccfd981fe0fa IFF stereo support
superdump
parents: 3200
diff changeset
64
ccfd981fe0fa IFF stereo support
superdump
parents: 3200
diff changeset
65 static void interleave_stereo(const uint8_t *src, uint8_t *dest, int size)
ccfd981fe0fa IFF stereo support
superdump
parents: 3200
diff changeset
66 {
ccfd981fe0fa IFF stereo support
superdump
parents: 3200
diff changeset
67 uint8_t *end = dest + size;
ccfd981fe0fa IFF stereo support
superdump
parents: 3200
diff changeset
68 size = size>>1;
ccfd981fe0fa IFF stereo support
superdump
parents: 3200
diff changeset
69
ccfd981fe0fa IFF stereo support
superdump
parents: 3200
diff changeset
70 while(dest < end) {
ccfd981fe0fa IFF stereo support
superdump
parents: 3200
diff changeset
71 *dest++ = *src;
ccfd981fe0fa IFF stereo support
superdump
parents: 3200
diff changeset
72 *dest++ = *(src+size);
ccfd981fe0fa IFF stereo support
superdump
parents: 3200
diff changeset
73 src++;
ccfd981fe0fa IFF stereo support
superdump
parents: 3200
diff changeset
74 }
ccfd981fe0fa IFF stereo support
superdump
parents: 3200
diff changeset
75 }
ccfd981fe0fa IFF stereo support
superdump
parents: 3200
diff changeset
76
3189
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
77 static int iff_probe(AVProbeData *p)
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
78 {
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
79 const uint8_t *d = p->buf;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
80
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
81 if ( AV_RL32(d) == ID_FORM &&
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
82 AV_RL32(d+8) == ID_8SVX)
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
83 return AVPROBE_SCORE_MAX;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
84 return 0;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
85 }
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
86
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
87 static int iff_read_header(AVFormatContext *s,
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
88 AVFormatParameters *ap)
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
89 {
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
90 IffDemuxContext *iff = s->priv_data;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
91 ByteIOContext *pb = s->pb;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
92 AVStream *st;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
93 uint32_t chunk_id, data_size;
3200
a437fb5ca080 Remove unused variable.
diego
parents: 3198
diff changeset
94 int padding, done = 0;
3189
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
95
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
96 st = av_new_stream(s, 0);
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
97 if (!st)
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
98 return AVERROR(ENOMEM);
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
99
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
100 st->codec->channels = 1;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
101 url_fskip(pb, 12);
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
102
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
103 while(!done && !url_feof(pb)) {
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
104 chunk_id = get_le32(pb);
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
105 data_size = get_be32(pb);
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
106 padding = data_size & 1;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
107
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
108 switch(chunk_id) {
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
109 case ID_VHDR:
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
110 url_fskip(pb, 12);
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
111 st->codec->sample_rate = get_be16(pb);
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
112 url_fskip(pb, 1);
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
113 st->codec->codec_tag = get_byte(pb);
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
114 url_fskip(pb, 4);
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
115 break;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
116
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
117 case ID_BODY:
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
118 iff->body_size = data_size;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
119 done = 1;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
120 break;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
121
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
122 case ID_CHAN:
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
123 st->codec->channels = (get_be32(pb) < 6) ? 1 : 2;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
124 break;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
125
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
126 default:
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
127 url_fseek(pb, data_size + padding, SEEK_CUR);
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
128 break;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
129 }
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
130 }
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
131
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
132 if(!st->codec->sample_rate)
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
133 return AVERROR_INVALIDDATA;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
134
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
135 av_set_pts_info(st, 32, 1, st->codec->sample_rate);
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
136 st->codec->codec_type = CODEC_TYPE_AUDIO;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
137
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
138 switch(st->codec->codec_tag) {
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
139 case COMP_NONE:
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
140 st->codec->codec_id = CODEC_ID_PCM_S8;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
141 break;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
142 case COMP_FIB:
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
143 st->codec->codec_id = CODEC_ID_8SVX_FIB;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
144 break;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
145 case COMP_EXP:
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
146 st->codec->codec_id = CODEC_ID_8SVX_EXP;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
147 break;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
148 default:
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
149 av_log(s, AV_LOG_ERROR, "iff: unknown compression method\n");
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
150 return -1;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
151 }
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
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
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
156
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
157 return 0;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
158 }
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
159
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
160 static int iff_read_packet(AVFormatContext *s,
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
161 AVPacket *pkt)
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
162 {
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
163 IffDemuxContext *iff = s->priv_data;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
164 ByteIOContext *pb = s->pb;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
165 int ret;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
166
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
167 if(iff->sent_bytes > iff->body_size)
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
168 return AVERROR(EIO);
3285
ccfd981fe0fa IFF stereo support
superdump
parents: 3200
diff changeset
169
ccfd981fe0fa IFF stereo support
superdump
parents: 3200
diff changeset
170 if(s->streams[0]->codec->channels == 2) {
ccfd981fe0fa IFF stereo support
superdump
parents: 3200
diff changeset
171 uint8_t sample_buffer[PACKET_SIZE];
ccfd981fe0fa IFF stereo support
superdump
parents: 3200
diff changeset
172
ccfd981fe0fa IFF stereo support
superdump
parents: 3200
diff changeset
173 ret = get_buffer(pb, sample_buffer, PACKET_SIZE);
ccfd981fe0fa IFF stereo support
superdump
parents: 3200
diff changeset
174 if(av_new_packet(pkt, PACKET_SIZE) < 0) {
ccfd981fe0fa IFF stereo support
superdump
parents: 3200
diff changeset
175 av_log(s, AV_LOG_ERROR, "iff: cannot allocate packet \n");
ccfd981fe0fa IFF stereo support
superdump
parents: 3200
diff changeset
176 return AVERROR(ENOMEM);
ccfd981fe0fa IFF stereo support
superdump
parents: 3200
diff changeset
177 }
ccfd981fe0fa IFF stereo support
superdump
parents: 3200
diff changeset
178 interleave_stereo(sample_buffer, pkt->data, PACKET_SIZE);
ccfd981fe0fa IFF stereo support
superdump
parents: 3200
diff changeset
179 }
ccfd981fe0fa IFF stereo support
superdump
parents: 3200
diff changeset
180 else {
ccfd981fe0fa IFF stereo support
superdump
parents: 3200
diff changeset
181 ret = av_get_packet(pb, pkt, PACKET_SIZE);
ccfd981fe0fa IFF stereo support
superdump
parents: 3200
diff changeset
182 }
3189
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
183
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
184 if(iff->sent_bytes == 0)
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
185 pkt->flags |= PKT_FLAG_KEY;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
186
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
187 iff->sent_bytes += PACKET_SIZE;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
188 pkt->stream_index = 0;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
189 pkt->pts = iff->audio_frame_count;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
190 iff->audio_frame_count += ret / s->streams[0]->codec->channels;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
191 return ret;
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
192 }
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
193
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
194 AVInputFormat iff_demuxer = {
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
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
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
197 sizeof(IffDemuxContext),
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
198 iff_probe,
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
199 iff_read_header,
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
200 iff_read_packet,
f016d69a28b6 IFF demuxer
vitor
parents:
diff changeset
201 };