* encoding of AC3 with more than 2 channels
[ffmpeg.git] / libav / raw.c
1 /* 
2  * RAW encoder and decoder
3  * Copyright (c) 2001 Gerard Lantau.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 #include "avformat.h"
20
21 /* simple formats */
22 int raw_write_header(struct AVFormatContext *s)
23 {
24     return 0;
25 }
26
27 int raw_write_packet(struct AVFormatContext *s, 
28                      int stream_index,
29                      unsigned char *buf, int size, int force_pts)
30 {
31     put_buffer(&s->pb, buf, size);
32     put_flush_packet(&s->pb);
33     return 0;
34 }
35
36 int raw_write_trailer(struct AVFormatContext *s)
37 {
38     return 0;
39 }
40
41 /* raw input */
42 static int raw_read_header(AVFormatContext *s,
43                            AVFormatParameters *ap)
44 {
45     AVStream *st;
46
47     st = malloc(sizeof(AVStream));
48     if (!st)
49         return -1;
50     s->nb_streams = 1;
51     s->streams[0] = st;
52
53     st->id = 0;
54
55     if (ap) {
56         if (s->format->audio_codec != CODEC_ID_NONE) {
57             st->codec.codec_type = CODEC_TYPE_AUDIO;
58             st->codec.codec_id = s->format->audio_codec;
59         } else if (s->format->video_codec != CODEC_ID_NONE) {
60             st->codec.codec_type = CODEC_TYPE_VIDEO;
61             st->codec.codec_id = s->format->video_codec;
62         } else {
63             free(st);
64             return -1;
65         }
66         
67         switch(st->codec.codec_type) {
68         case CODEC_TYPE_AUDIO:
69             st->codec.sample_rate = ap->sample_rate;
70             st->codec.channels = ap->channels;
71             break;
72         case CODEC_TYPE_VIDEO:
73             st->codec.frame_rate = ap->frame_rate;
74             st->codec.width = ap->width;
75             st->codec.height = ap->height;
76             break;
77         default:
78             return -1;
79         }
80     } else {
81         return -1;
82     }
83     return 0;
84 }
85
86 /* raw input */
87 static int pcm_read_header(AVFormatContext *s,
88                            AVFormatParameters *ap)
89 {
90     AVStream *st;
91
92     st = malloc(sizeof(AVStream));
93     if (!st)
94         return -1;
95     s->nb_streams = 1;
96     s->streams[0] = st;
97
98     st->id = 0;
99
100     st->codec.codec_type = CODEC_TYPE_AUDIO;
101     st->codec.codec_id = s->format->audio_codec;
102
103     return 0;
104 }
105
106 #define RAW_PACKET_SIZE 1024
107
108 int raw_read_packet(AVFormatContext *s,
109                     AVPacket *pkt)
110 {
111     int ret;
112
113     if (av_new_packet(pkt, RAW_PACKET_SIZE) < 0)
114         return -EIO;
115
116     pkt->stream_index = 0;
117     ret = get_buffer(&s->pb, pkt->data, RAW_PACKET_SIZE);
118     if (ret <= 0) {
119         av_free_packet(pkt);
120         return -EIO;
121     }
122     /* note: we need to modify the packet size here to handle the last
123        packet */
124     pkt->size = ret;
125     return ret;
126 }
127
128 int raw_read_close(AVFormatContext *s)
129 {
130     return 0;
131 }
132
133 /* mp3 read */
134 static int mp3_read_header(AVFormatContext *s,
135                            AVFormatParameters *ap)
136 {
137     AVStream *st;
138
139     st = malloc(sizeof(AVStream));
140     if (!st)
141         return -1;
142     s->nb_streams = 1;
143     s->streams[0] = st;
144
145     st->id = 0;
146
147     st->codec.codec_type = CODEC_TYPE_AUDIO;
148     st->codec.codec_id = CODEC_ID_MP2;
149     /* the parameters will be extracted from the compressed bitstream */
150     return 0;
151 }
152
153 /* mpeg1/h263 input */
154 static int video_read_header(AVFormatContext *s,
155                              AVFormatParameters *ap)
156 {
157     AVStream *st;
158
159     st = av_mallocz(sizeof(AVStream));
160     if (!st)
161         return -1;
162     s->nb_streams = 1;
163     s->streams[0] = st;
164
165     st->codec.codec_type = CODEC_TYPE_VIDEO;
166     st->codec.codec_id = s->format->video_codec;
167     /* for mjpeg, specify frame rate */
168     if (st->codec.codec_id == CODEC_ID_MJPEG) {
169         if (ap) {
170             st->codec.frame_rate = ap->frame_rate;
171         } else {
172             st->codec.frame_rate = 25 * FRAME_RATE_BASE;
173         }
174     }
175     return 0;
176 }
177
178 AVFormat mp2_format = {
179     "mp2",
180     "MPEG audio",
181     "audio/x-mpeg",
182     "mp2,mp3",
183     CODEC_ID_MP2,
184     0,
185     raw_write_header,
186     raw_write_packet,
187     raw_write_trailer,
188
189     mp3_read_header,
190     raw_read_packet,
191     raw_read_close,
192 };
193
194 AVFormat ac3_format = {
195     "ac3",
196     "raw ac3",
197     "audio/x-ac3", 
198     "ac3",
199     CODEC_ID_AC3,
200     0,
201     raw_write_header,
202     raw_write_packet,
203     raw_write_trailer,
204     raw_read_header,
205     raw_read_packet,
206     raw_read_close,
207 };
208
209 AVFormat h263_format = {
210     "h263",
211     "raw h263",
212     "video/x-h263",
213     "h263",
214     0,
215     CODEC_ID_H263,
216     raw_write_header,
217     raw_write_packet,
218     raw_write_trailer,
219     video_read_header,
220     raw_read_packet,
221     raw_read_close,
222 };
223
224 AVFormat mpeg1video_format = {
225     "mpegvideo",
226     "MPEG video",
227     "video/x-mpeg",
228     "mpg,mpeg",
229     0,
230     CODEC_ID_MPEG1VIDEO,
231     raw_write_header,
232     raw_write_packet,
233     raw_write_trailer,
234     video_read_header,
235     raw_read_packet,
236     raw_read_close,
237 };
238
239 AVFormat mjpeg_format = {
240     "mjpeg",
241     "MJPEG video",
242     "video/x-mjpeg",
243     "mjpg,mjpeg",
244     0,
245     CODEC_ID_MJPEG,
246     raw_write_header,
247     raw_write_packet,
248     raw_write_trailer,
249     video_read_header,
250     raw_read_packet,
251     raw_read_close,
252 };
253
254 /* pcm formats */
255
256 AVFormat pcm_s16le_format = {
257     "s16le",
258     "pcm signed 16 bit little endian format",
259     NULL,
260 #ifdef WORDS_BIGENDIAN
261     "",
262 #else
263     "sw",
264 #endif
265     CODEC_ID_PCM_S16LE,
266     0,
267     raw_write_header,
268     raw_write_packet,
269     raw_write_trailer,
270
271     pcm_read_header,
272     raw_read_packet,
273     raw_read_close,
274 };
275
276 AVFormat pcm_s16be_format = {
277     "s16be",
278     "pcm signed 16 bit big endian format",
279     NULL,
280 #ifdef WORDS_BIGENDIAN
281     "sw",
282 #else
283     "",
284 #endif
285     CODEC_ID_PCM_S16BE,
286     0,
287     raw_write_header,
288     raw_write_packet,
289     raw_write_trailer,
290
291     pcm_read_header,
292     raw_read_packet,
293     raw_read_close,
294 };
295
296 AVFormat pcm_u16le_format = {
297     "u16le",
298     "pcm unsigned 16 bit little endian format",
299     NULL,
300 #ifdef WORDS_BIGENDIAN
301     "",
302 #else
303     "uw",
304 #endif
305     CODEC_ID_PCM_U16LE,
306     0,
307     raw_write_header,
308     raw_write_packet,
309     raw_write_trailer,
310
311     pcm_read_header,
312     raw_read_packet,
313     raw_read_close,
314 };
315
316 AVFormat pcm_u16be_format = {
317     "u16be",
318     "pcm unsigned 16 bit big endian format",
319     NULL,
320 #ifdef WORDS_BIGENDIAN
321     "uw",
322 #else
323     "",
324 #endif
325     CODEC_ID_PCM_U16BE,
326     0,
327     raw_write_header,
328     raw_write_packet,
329     raw_write_trailer,
330
331     pcm_read_header,
332     raw_read_packet,
333     raw_read_close,
334 };
335
336 AVFormat pcm_s8_format = {
337     "s8",
338     "pcm signed 8 bit format",
339     NULL,
340     "sb",
341     CODEC_ID_PCM_S8,
342     0,
343     raw_write_header,
344     raw_write_packet,
345     raw_write_trailer,
346
347     pcm_read_header,
348     raw_read_packet,
349     raw_read_close,
350 };
351
352 AVFormat pcm_u8_format = {
353     "u8",
354     "pcm unsigned 8 bit format",
355     NULL,
356     "ub",
357     CODEC_ID_PCM_U8,
358     0,
359     raw_write_header,
360     raw_write_packet,
361     raw_write_trailer,
362
363     pcm_read_header,
364     raw_read_packet,
365     raw_read_close,
366 };
367
368 AVFormat pcm_mulaw_format = {
369     "mulaw",
370     "pcm mu law format",
371     NULL,
372     "ul",
373     CODEC_ID_PCM_MULAW,
374     0,
375     raw_write_header,
376     raw_write_packet,
377     raw_write_trailer,
378
379     pcm_read_header,
380     raw_read_packet,
381     raw_read_close,
382 };
383
384 AVFormat pcm_alaw_format = {
385     "alaw",
386     "pcm A law format",
387     NULL,
388     "al",
389     CODEC_ID_PCM_ALAW,
390     0,
391     raw_write_header,
392     raw_write_packet,
393     raw_write_trailer,
394
395     pcm_read_header,
396     raw_read_packet,
397     raw_read_close,
398 };
399
400 int rawvideo_read_packet(AVFormatContext *s,
401                          AVPacket *pkt)
402 {
403     int packet_size, ret, width, height;
404     AVStream *st = s->streams[0];
405
406     width = st->codec.width;
407     height = st->codec.height;
408
409     switch(st->codec.pix_fmt) {
410     case PIX_FMT_YUV420P:
411         packet_size = (width * height * 3) / 2;
412         break;
413     case PIX_FMT_YUV422:
414         packet_size = (width * height * 2);
415         break;
416     case PIX_FMT_BGR24:
417     case PIX_FMT_RGB24:
418         packet_size = (width * height * 3);
419         break;
420     default:
421         abort();
422         break;
423     }
424
425     if (av_new_packet(pkt, packet_size) < 0)
426         return -EIO;
427
428     pkt->stream_index = 0;
429     /* bypass buffered I/O */
430     ret = url_read(url_fileno(&s->pb), pkt->data, pkt->size);
431     if (ret != pkt->size) {
432         av_free_packet(pkt);
433         return -EIO;
434     } else {
435         return 0;
436     }
437 }
438
439 AVFormat rawvideo_format = {
440     "rawvideo",
441     "raw video format",
442     NULL,
443     "yuv",
444     CODEC_ID_NONE,
445     CODEC_ID_RAWVIDEO,
446     raw_write_header,
447     raw_write_packet,
448     raw_write_trailer,
449
450     raw_read_header,
451     rawvideo_read_packet,
452     raw_read_close,
453 };