d2c2c3486a524c0ec856489a66c06318db0af7ef
[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 };
205
206 AVFormat h263_format = {
207     "h263",
208     "raw h263",
209     "video/x-h263",
210     "h263",
211     0,
212     CODEC_ID_H263,
213     raw_write_header,
214     raw_write_packet,
215     raw_write_trailer,
216     video_read_header,
217     raw_read_packet,
218     raw_read_close,
219 };
220
221 AVFormat mpeg1video_format = {
222     "mpegvideo",
223     "MPEG video",
224     "video/x-mpeg",
225     "mpg,mpeg",
226     0,
227     CODEC_ID_MPEG1VIDEO,
228     raw_write_header,
229     raw_write_packet,
230     raw_write_trailer,
231     video_read_header,
232     raw_read_packet,
233     raw_read_close,
234 };
235
236 AVFormat mjpeg_format = {
237     "mjpeg",
238     "MJPEG video",
239     "video/x-mjpeg",
240     "mjpg,mjpeg",
241     0,
242     CODEC_ID_MJPEG,
243     raw_write_header,
244     raw_write_packet,
245     raw_write_trailer,
246     video_read_header,
247     raw_read_packet,
248     raw_read_close,
249 };
250
251 /* pcm formats */
252
253 AVFormat pcm_s16le_format = {
254     "s16le",
255     "pcm signed 16 bit little endian format",
256     NULL,
257 #ifdef WORDS_BIGENDIAN
258     "",
259 #else
260     "sw",
261 #endif
262     CODEC_ID_PCM_S16LE,
263     0,
264     raw_write_header,
265     raw_write_packet,
266     raw_write_trailer,
267
268     pcm_read_header,
269     raw_read_packet,
270     raw_read_close,
271 };
272
273 AVFormat pcm_s16be_format = {
274     "s16be",
275     "pcm signed 16 bit big endian format",
276     NULL,
277 #ifdef WORDS_BIGENDIAN
278     "sw",
279 #else
280     "",
281 #endif
282     CODEC_ID_PCM_S16BE,
283     0,
284     raw_write_header,
285     raw_write_packet,
286     raw_write_trailer,
287
288     pcm_read_header,
289     raw_read_packet,
290     raw_read_close,
291 };
292
293 AVFormat pcm_u16le_format = {
294     "u16le",
295     "pcm unsigned 16 bit little endian format",
296     NULL,
297 #ifdef WORDS_BIGENDIAN
298     "",
299 #else
300     "uw",
301 #endif
302     CODEC_ID_PCM_U16LE,
303     0,
304     raw_write_header,
305     raw_write_packet,
306     raw_write_trailer,
307
308     pcm_read_header,
309     raw_read_packet,
310     raw_read_close,
311 };
312
313 AVFormat pcm_u16be_format = {
314     "u16be",
315     "pcm unsigned 16 bit big endian format",
316     NULL,
317 #ifdef WORDS_BIGENDIAN
318     "uw",
319 #else
320     "",
321 #endif
322     CODEC_ID_PCM_U16BE,
323     0,
324     raw_write_header,
325     raw_write_packet,
326     raw_write_trailer,
327
328     pcm_read_header,
329     raw_read_packet,
330     raw_read_close,
331 };
332
333 AVFormat pcm_s8_format = {
334     "s8",
335     "pcm signed 8 bit format",
336     NULL,
337     "sb",
338     CODEC_ID_PCM_S8,
339     0,
340     raw_write_header,
341     raw_write_packet,
342     raw_write_trailer,
343
344     pcm_read_header,
345     raw_read_packet,
346     raw_read_close,
347 };
348
349 AVFormat pcm_u8_format = {
350     "u8",
351     "pcm unsigned 8 bit format",
352     NULL,
353     "ub",
354     CODEC_ID_PCM_U8,
355     0,
356     raw_write_header,
357     raw_write_packet,
358     raw_write_trailer,
359
360     pcm_read_header,
361     raw_read_packet,
362     raw_read_close,
363 };
364
365 AVFormat pcm_mulaw_format = {
366     "mulaw",
367     "pcm mu law format",
368     NULL,
369     "ul",
370     CODEC_ID_PCM_MULAW,
371     0,
372     raw_write_header,
373     raw_write_packet,
374     raw_write_trailer,
375
376     pcm_read_header,
377     raw_read_packet,
378     raw_read_close,
379 };
380
381 AVFormat pcm_alaw_format = {
382     "alaw",
383     "pcm A law format",
384     NULL,
385     "al",
386     CODEC_ID_PCM_ALAW,
387     0,
388     raw_write_header,
389     raw_write_packet,
390     raw_write_trailer,
391
392     pcm_read_header,
393     raw_read_packet,
394     raw_read_close,
395 };
396
397 int rawvideo_read_packet(AVFormatContext *s,
398                          AVPacket *pkt)
399 {
400     int packet_size, ret, width, height;
401     AVStream *st = s->streams[0];
402
403     width = st->codec.width;
404     height = st->codec.height;
405
406     switch(st->codec.pix_fmt) {
407     case PIX_FMT_YUV420P:
408         packet_size = (width * height * 3) / 2;
409         break;
410     case PIX_FMT_YUV422:
411         packet_size = (width * height * 2);
412         break;
413     case PIX_FMT_BGR24:
414     case PIX_FMT_RGB24:
415         packet_size = (width * height * 3);
416         break;
417     default:
418         abort();
419         break;
420     }
421
422     if (av_new_packet(pkt, packet_size) < 0)
423         return -EIO;
424
425     pkt->stream_index = 0;
426     /* bypass buffered I/O */
427     ret = url_read(url_fileno(&s->pb), pkt->data, pkt->size);
428     if (ret != pkt->size) {
429         av_free_packet(pkt);
430         return -EIO;
431     } else {
432         return 0;
433     }
434 }
435
436 AVFormat rawvideo_format = {
437     "rawvideo",
438     "raw video format",
439     NULL,
440     "yuv",
441     CODEC_ID_NONE,
442     CODEC_ID_RAWVIDEO,
443     raw_write_header,
444     raw_write_packet,
445     raw_write_trailer,
446
447     raw_read_header,
448     rawvideo_read_packet,
449     raw_read_close,
450 };