Mercurial > libavformat.hg
annotate siff.c @ 5061:5ff6a72c9686 libavformat
In mov_read_packet remember the AVStream we want to demux next instead of the
MOVStreamContext. We need the AVStream anyway and it is easier to get the
MOVStreamContext from the AVStream than the other way around.
author | reimar |
---|---|
date | Wed, 24 Jun 2009 08:23:40 +0000 |
parents | 77e0c7511d41 |
children | 0d44bd284a96 |
rev | line source |
---|---|
2659 | 1 /* |
2 * Beam Software SIFF demuxer | |
4251
77e0c7511d41
cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents:
4201
diff
changeset
|
3 * Copyright (c) 2007 Konstantin Shishkov |
2659 | 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 | |
4201
7d2f3f1b68d8
Fix build: Add intreadwrite.h and bswap.h #includes where necessary.
diego
parents:
3908
diff
changeset
|
22 #include "libavutil/intreadwrite.h" |
2659 | 23 #include "avformat.h" |
24 | |
25 enum SIFFTags{ | |
26 TAG_SIFF = MKTAG('S', 'I', 'F', 'F'), | |
27 TAG_BODY = MKTAG('B', 'O', 'D', 'Y'), | |
28 TAG_VBHD = MKTAG('V', 'B', 'H', 'D'), | |
29 TAG_SHDR = MKTAG('S', 'H', 'D', 'R'), | |
30 TAG_VBV1 = MKTAG('V', 'B', 'V', '1'), | |
31 TAG_SOUN = MKTAG('S', 'O', 'U', 'N'), | |
32 }; | |
33 | |
34 enum VBFlags{ | |
35 VB_HAS_GMC = 0x01, | |
36 VB_HAS_AUDIO = 0x04, | |
37 VB_HAS_VIDEO = 0x08, | |
38 VB_HAS_PALETTE = 0x10, | |
39 VB_HAS_LENGTH = 0x20 | |
40 }; | |
41 | |
42 typedef struct SIFFContext{ | |
43 int frames; | |
44 int cur_frame; | |
45 int rate; | |
46 int bits; | |
47 int block_align; | |
48 | |
49 int has_video; | |
50 int has_audio; | |
51 | |
52 int curstrm; | |
53 int pktsize; | |
54 int gmcsize; | |
55 int sndsize; | |
56 | |
57 int flags; | |
58 uint8_t gmc[4]; | |
59 }SIFFContext; | |
60 | |
61 static int siff_probe(AVProbeData *p) | |
62 { | |
63 /* check file header */ | |
64 if (AV_RL32(p->buf) == TAG_SIFF) | |
65 return AVPROBE_SCORE_MAX; | |
66 else | |
67 return 0; | |
68 } | |
69 | |
70 static int create_audio_stream(AVFormatContext *s, SIFFContext *c) | |
71 { | |
72 AVStream *ast; | |
73 ast = av_new_stream(s, 0); | |
74 if (!ast) | |
75 return -1; | |
76 ast->codec->codec_type = CODEC_TYPE_AUDIO; | |
77 ast->codec->codec_id = CODEC_ID_PCM_U8; | |
78 ast->codec->channels = 1; | |
3908
1d3d17de20ba
Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents:
3424
diff
changeset
|
79 ast->codec->bits_per_coded_sample = c->bits; |
2659 | 80 ast->codec->sample_rate = c->rate; |
81 ast->codec->frame_size = c->block_align; | |
82 av_set_pts_info(ast, 16, 1, c->rate); | |
83 return 0; | |
84 } | |
85 | |
86 static int siff_parse_vbv1(AVFormatContext *s, SIFFContext *c, ByteIOContext *pb) | |
87 { | |
88 AVStream *st; | |
89 int width, height; | |
90 | |
91 if (get_le32(pb) != TAG_VBHD){ | |
92 av_log(s, AV_LOG_ERROR, "Header chunk is missing\n"); | |
93 return -1; | |
94 } | |
95 if(get_be32(pb) != 32){ | |
96 av_log(s, AV_LOG_ERROR, "Header chunk size is incorrect\n"); | |
97 return -1; | |
98 } | |
99 if(get_le16(pb) != 1){ | |
100 av_log(s, AV_LOG_ERROR, "Incorrect header version\n"); | |
101 return -1; | |
102 } | |
103 width = get_le16(pb); | |
104 height = get_le16(pb); | |
105 url_fskip(pb, 4); | |
106 c->frames = get_le16(pb); | |
107 if(!c->frames){ | |
108 av_log(s, AV_LOG_ERROR, "File contains no frames ???\n"); | |
109 return -1; | |
110 } | |
111 c->bits = get_le16(pb); | |
112 c->rate = get_le16(pb); | |
113 c->block_align = c->rate * (c->bits >> 3); | |
114 | |
115 url_fskip(pb, 16); //zeroes | |
116 | |
117 st = av_new_stream(s, 0); | |
118 if (!st) | |
119 return -1; | |
120 st->codec->codec_type = CODEC_TYPE_VIDEO; | |
121 st->codec->codec_id = CODEC_ID_VB; | |
122 st->codec->codec_tag = MKTAG('V', 'B', 'V', '1'); | |
123 st->codec->width = width; | |
124 st->codec->height = height; | |
125 st->codec->pix_fmt = PIX_FMT_PAL8; | |
126 av_set_pts_info(st, 16, 1, 12); | |
127 | |
128 c->cur_frame = 0; | |
129 c->has_video = 1; | |
130 c->has_audio = !!c->rate; | |
131 c->curstrm = -1; | |
132 if (c->has_audio && create_audio_stream(s, c) < 0) | |
133 return -1; | |
134 return 0; | |
135 } | |
136 | |
137 static int siff_parse_soun(AVFormatContext *s, SIFFContext *c, ByteIOContext *pb) | |
138 { | |
139 if (get_le32(pb) != TAG_SHDR){ | |
140 av_log(s, AV_LOG_ERROR, "Header chunk is missing\n"); | |
141 return -1; | |
142 } | |
143 if(get_be32(pb) != 8){ | |
144 av_log(s, AV_LOG_ERROR, "Header chunk size is incorrect\n"); | |
145 return -1; | |
146 } | |
147 url_fskip(pb, 4); //unknown value | |
148 c->rate = get_le16(pb); | |
149 c->bits = get_le16(pb); | |
150 c->block_align = c->rate * (c->bits >> 3); | |
151 return create_audio_stream(s, c); | |
152 } | |
153 | |
154 static int siff_read_header(AVFormatContext *s, AVFormatParameters *ap) | |
155 { | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2690
diff
changeset
|
156 ByteIOContext *pb = s->pb; |
2659 | 157 SIFFContext *c = s->priv_data; |
158 uint32_t tag; | |
159 | |
160 if (get_le32(pb) != TAG_SIFF) | |
161 return -1; | |
162 url_fskip(pb, 4); //ignore size | |
163 tag = get_le32(pb); | |
164 | |
165 if (tag != TAG_VBV1 && tag != TAG_SOUN){ | |
166 av_log(s, AV_LOG_ERROR, "Not a VBV file\n"); | |
167 return -1; | |
168 } | |
169 | |
170 if (tag == TAG_VBV1 && siff_parse_vbv1(s, c, pb) < 0) | |
171 return -1; | |
172 if (tag == TAG_SOUN && siff_parse_soun(s, c, pb) < 0) | |
173 return -1; | |
174 if (get_le32(pb) != MKTAG('B', 'O', 'D', 'Y')){ | |
175 av_log(s, AV_LOG_ERROR, "'BODY' chunk is missing\n"); | |
176 return -1; | |
177 } | |
178 url_fskip(pb, 4); //ignore size | |
179 | |
180 return 0; | |
181 } | |
182 | |
183 static int siff_read_packet(AVFormatContext *s, AVPacket *pkt) | |
184 { | |
185 SIFFContext *c = s->priv_data; | |
2690
0a8f2dc62d01
Remove unused variables, fixes the following warnings:
diego
parents:
2659
diff
changeset
|
186 int size; |
2659 | 187 |
188 if (c->has_video){ | |
189 if (c->cur_frame >= c->frames) | |
190 return AVERROR(EIO); | |
191 if (c->curstrm == -1){ | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2690
diff
changeset
|
192 c->pktsize = get_le32(s->pb) - 4; |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2690
diff
changeset
|
193 c->flags = get_le16(s->pb); |
2659 | 194 c->gmcsize = (c->flags & VB_HAS_GMC) ? 4 : 0; |
195 if (c->gmcsize) | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2690
diff
changeset
|
196 get_buffer(s->pb, c->gmc, c->gmcsize); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2690
diff
changeset
|
197 c->sndsize = (c->flags & VB_HAS_AUDIO) ? get_le32(s->pb): 0; |
2659 | 198 c->curstrm = !!(c->flags & VB_HAS_AUDIO); |
199 } | |
200 | |
201 if (!c->curstrm){ | |
202 size = c->pktsize - c->sndsize; | |
203 if (av_new_packet(pkt, size) < 0) | |
204 return AVERROR(ENOMEM); | |
205 AV_WL16(pkt->data, c->flags); | |
206 if (c->gmcsize) | |
207 memcpy(pkt->data + 2, c->gmc, c->gmcsize); | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2690
diff
changeset
|
208 get_buffer(s->pb, pkt->data + 2 + c->gmcsize, size - c->gmcsize - 2); |
2659 | 209 pkt->stream_index = 0; |
210 c->curstrm = -1; | |
211 }else{ | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2690
diff
changeset
|
212 if (av_get_packet(s->pb, pkt, c->sndsize - 4) < 0) |
2659 | 213 return AVERROR(EIO); |
214 pkt->stream_index = 1; | |
215 c->curstrm = 0; | |
216 } | |
217 if(!c->cur_frame || c->curstrm) | |
218 pkt->flags |= PKT_FLAG_KEY; | |
219 if (c->curstrm == -1) | |
220 c->cur_frame++; | |
221 }else{ | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2690
diff
changeset
|
222 size = av_get_packet(s->pb, pkt, c->block_align); |
2659 | 223 if(size <= 0) |
224 return AVERROR(EIO); | |
225 } | |
226 return pkt->size; | |
227 } | |
228 | |
229 AVInputFormat siff_demuxer = { | |
230 "siff", | |
3424
7a0230981402
Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents:
3399
diff
changeset
|
231 NULL_IF_CONFIG_SMALL("Beam Software SIFF"), |
2659 | 232 sizeof(SIFFContext), |
233 siff_probe, | |
234 siff_read_header, | |
235 siff_read_packet, | |
236 .extensions = "vb,son" | |
237 }; |