mpeg4 raw output support patch by ("Maksim (Max) Krasnyanskiy" <maxk at qualcomm...
[ffmpeg.git] / libav / raw.c
1 /* 
2  * RAW encoder and decoder
3  * Copyright (c) 2001 Fabrice Bellard.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library 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 GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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     int id;
47
48     st = av_new_stream(s, 0);
49     if (!st)
50         return AVERROR_NOMEM;
51     if (ap) {
52         id = s->iformat->value;
53         if (id == CODEC_ID_RAWVIDEO) {
54             st->codec.codec_type = CODEC_TYPE_VIDEO;
55         } else {
56             st->codec.codec_type = CODEC_TYPE_AUDIO;
57         }
58         st->codec.codec_id = id;
59
60         switch(st->codec.codec_type) {
61         case CODEC_TYPE_AUDIO:
62             st->codec.sample_rate = ap->sample_rate;
63             st->codec.channels = ap->channels;
64             break;
65         case CODEC_TYPE_VIDEO:
66             st->codec.frame_rate = ap->frame_rate;
67             st->codec.width = ap->width;
68             st->codec.height = ap->height;
69             break;
70         default:
71             return -1;
72         }
73     } else {
74         return -1;
75     }
76     return 0;
77 }
78
79 #define RAW_PACKET_SIZE 1024
80
81 int raw_read_packet(AVFormatContext *s,
82                     AVPacket *pkt)
83 {
84     int ret;
85
86     if (av_new_packet(pkt, RAW_PACKET_SIZE) < 0)
87         return -EIO;
88
89     pkt->stream_index = 0;
90     ret = get_buffer(&s->pb, pkt->data, RAW_PACKET_SIZE);
91     if (ret <= 0) {
92         av_free_packet(pkt);
93         return -EIO;
94     }
95     /* note: we need to modify the packet size here to handle the last
96        packet */
97     pkt->size = ret;
98     return ret;
99 }
100
101 int raw_read_close(AVFormatContext *s)
102 {
103     return 0;
104 }
105
106 /* mp3 read */
107 static int mp3_read_header(AVFormatContext *s,
108                            AVFormatParameters *ap)
109 {
110     AVStream *st;
111
112     st = av_new_stream(s, 0);
113     if (!st)
114         return AVERROR_NOMEM;
115
116     st->codec.codec_type = CODEC_TYPE_AUDIO;
117     st->codec.codec_id = CODEC_ID_MP2;
118     /* the parameters will be extracted from the compressed bitstream */
119     return 0;
120 }
121
122 /* mpeg1/h263 input */
123 static int video_read_header(AVFormatContext *s,
124                              AVFormatParameters *ap)
125 {
126     AVStream *st;
127
128     st = av_new_stream(s, 0);
129     if (!st)
130         return AVERROR_NOMEM;
131
132     st->codec.codec_type = CODEC_TYPE_VIDEO;
133     st->codec.codec_id = s->iformat->value;
134     /* for mjpeg, specify frame rate */
135     if (st->codec.codec_id == CODEC_ID_MJPEG) {
136         if (ap) {
137             st->codec.frame_rate = ap->frame_rate;
138         } else {
139             st->codec.frame_rate = 25 * FRAME_RATE_BASE;
140         }
141     }
142     return 0;
143 }
144
145 #define SEQ_START_CODE          0x000001b3
146 #define GOP_START_CODE          0x000001b8
147 #define PICTURE_START_CODE      0x00000100
148
149 /* XXX: improve that by looking at several start codes */
150 static int mpegvideo_probe(AVProbeData *p)
151 {
152     int code, c, i;
153     code = 0xff;
154
155     /* we search the first start code. If it is a sequence, gop or
156        picture start code then we decide it is an mpeg video
157        stream. We do not send highest value to give a chance to mpegts */
158     for(i=0;i<p->buf_size;i++) {
159         c = p->buf[i];
160         code = (code << 8) | c;
161         if ((code & 0xffffff00) == 0x100) {
162             if (code == SEQ_START_CODE ||
163                 code == GOP_START_CODE ||
164                 code == PICTURE_START_CODE)
165                 return AVPROBE_SCORE_MAX - 1;
166             else
167                 return 0;
168         }
169     }
170     return 0;
171 }
172
173 AVInputFormat mp3_iformat = {
174     "mp3",
175     "MPEG audio",
176     0,
177     NULL,
178     mp3_read_header,
179     raw_read_packet,
180     raw_read_close,
181     extensions: "mp2,mp3", /* XXX: use probe */
182 };
183
184 AVOutputFormat mp2_oformat = {
185     "mp2",
186     "MPEG audio layer 2",
187     "audio/x-mpeg",
188     "mp2,mp3",
189     0,
190     CODEC_ID_MP2,
191     0,
192     raw_write_header,
193     raw_write_packet,
194     raw_write_trailer,
195 };
196
197
198 AVInputFormat ac3_iformat = {
199     "ac3",
200     "raw ac3",
201     0,
202     NULL,
203     raw_read_header,
204     raw_read_packet,
205     raw_read_close,
206     extensions: "ac3",
207     value: CODEC_ID_AC3,
208 };
209
210 AVOutputFormat ac3_oformat = {
211     "ac3",
212     "raw ac3",
213     "audio/x-ac3", 
214     "ac3",
215     0,
216     CODEC_ID_AC3,
217     0,
218     raw_write_header,
219     raw_write_packet,
220     raw_write_trailer,
221 };
222
223 AVOutputFormat h263_oformat = {
224     "h263",
225     "raw h263",
226     "video/x-h263",
227     "h263",
228     0,
229     0,
230     CODEC_ID_H263,
231     raw_write_header,
232     raw_write_packet,
233     raw_write_trailer,
234 };
235
236 AVOutputFormat m4v_oformat = {
237     "m4v",
238     "raw MPEG4 video format",
239     NULL,
240     "m4v",
241     0,
242     CODEC_ID_NONE,
243     CODEC_ID_MPEG4,
244     raw_write_header,
245     raw_write_packet,
246     raw_write_trailer,
247 };
248
249 AVInputFormat mpegvideo_iformat = {
250     "mpegvideo",
251     "MPEG video",
252     0,
253     mpegvideo_probe,
254     video_read_header,
255     raw_read_packet,
256     raw_read_close,
257     value: CODEC_ID_MPEG1VIDEO,
258 };
259
260 AVOutputFormat mpeg1video_oformat = {
261     "mpeg1video",
262     "MPEG video",
263     "video/x-mpeg",
264     "mpg,mpeg",
265     0,
266     0,
267     CODEC_ID_MPEG1VIDEO,
268     raw_write_header,
269     raw_write_packet,
270     raw_write_trailer,
271 };
272
273 AVInputFormat mjpeg_iformat = {
274     "mjpeg",
275     "MJPEG video",
276     0,
277     NULL,
278     video_read_header,
279     raw_read_packet,
280     raw_read_close,
281     extensions: "mjpg,mjpeg",
282     value: CODEC_ID_MJPEG,
283 };
284
285 AVOutputFormat mjpeg_oformat = {
286     "mjpeg",
287     "MJPEG video",
288     "video/x-mjpeg",
289     "mjpg,mjpeg",
290     0,
291     0,
292     CODEC_ID_MJPEG,
293     raw_write_header,
294     raw_write_packet,
295     raw_write_trailer,
296 };
297
298 /* pcm formats */
299
300 #define PCMDEF(name, long_name, ext, codec) \
301 AVInputFormat pcm_ ## name ## _iformat = {\
302     #name,\
303     long_name,\
304     0,\
305     NULL,\
306     raw_read_header,\
307     raw_read_packet,\
308     raw_read_close,\
309     extensions: ext,\
310     value: codec,\
311 };\
312 \
313 AVOutputFormat pcm_ ## name ## _oformat = {\
314     #name,\
315     long_name,\
316     NULL,\
317     ext,\
318     0,\
319     codec,\
320     0,\
321     raw_write_header,\
322     raw_write_packet,\
323     raw_write_trailer,\
324 };
325
326 #ifdef WORDS_BIGENDIAN
327 #define BE_DEF(s) s
328 #define LE_DEF(s) NULL
329 #else
330 #define BE_DEF(s) NULL
331 #define LE_DEF(s) s
332 #endif
333
334
335 PCMDEF(s16le, "pcm signed 16 bit little endian format", 
336        LE_DEF("sw"), CODEC_ID_PCM_S16LE)
337
338 PCMDEF(s16be, "pcm signed 16 bit big endian format", 
339        BE_DEF("sw"), CODEC_ID_PCM_S16BE)
340
341 PCMDEF(u16le, "pcm unsigned 16 bit little endian format", 
342        LE_DEF("uw"), CODEC_ID_PCM_U16LE)
343
344 PCMDEF(u16be, "pcm unsigned 16 bit big endian format", 
345        BE_DEF("uw"), CODEC_ID_PCM_U16BE)
346
347 PCMDEF(s8, "pcm signed 8 bit format", 
348        "sb", CODEC_ID_PCM_S8)
349
350 PCMDEF(u8, "pcm unsigned 8 bit format", 
351        "ub", CODEC_ID_PCM_U8)
352
353 PCMDEF(mulaw, "pcm mu law format", 
354        "ul", CODEC_ID_PCM_MULAW)
355
356 PCMDEF(alaw, "pcm A law format", 
357        "al", CODEC_ID_PCM_ALAW)
358
359 int rawvideo_read_packet(AVFormatContext *s,
360                          AVPacket *pkt)
361 {
362     int packet_size, ret, width, height;
363     AVStream *st = s->streams[0];
364
365     width = st->codec.width;
366     height = st->codec.height;
367
368     switch(st->codec.pix_fmt) {
369     case PIX_FMT_YUV420P:
370         packet_size = (width * height * 3) / 2;
371         break;
372     case PIX_FMT_YUV422:
373         packet_size = (width * height * 2);
374         break;
375     case PIX_FMT_BGR24:
376     case PIX_FMT_RGB24:
377         packet_size = (width * height * 3);
378         break;
379     default:
380         abort();
381         break;
382     }
383
384     if (av_new_packet(pkt, packet_size) < 0)
385         return -EIO;
386
387     pkt->stream_index = 0;
388 #if 0
389     /* bypass buffered I/O */
390     ret = url_read(url_fileno(&s->pb), pkt->data, pkt->size);
391 #else
392     ret = get_buffer(&s->pb, pkt->data, pkt->size);
393 #endif
394     if (ret != pkt->size) {
395         av_free_packet(pkt);
396         return -EIO;
397     } else {
398         return 0;
399     }
400 }
401
402 AVInputFormat rawvideo_iformat = {
403     "rawvideo",
404     "raw video format",
405     0,
406     NULL,
407     raw_read_header,
408     rawvideo_read_packet,
409     raw_read_close,
410     extensions: "yuv",
411     value: CODEC_ID_RAWVIDEO,
412 };
413
414 AVOutputFormat rawvideo_oformat = {
415     "rawvideo",
416     "raw video format",
417     NULL,
418     "yuv",
419     0,
420     CODEC_ID_NONE,
421     CODEC_ID_RAWVIDEO,
422     raw_write_header,
423     raw_write_packet,
424     raw_write_trailer,
425 };
426
427 int raw_init(void)
428 {
429     av_register_input_format(&mp3_iformat);
430     av_register_output_format(&mp2_oformat);
431     
432     av_register_input_format(&ac3_iformat);
433     av_register_output_format(&ac3_oformat);
434
435     av_register_output_format(&h263_oformat);
436     
437     av_register_output_format(&m4v_oformat);
438
439     av_register_input_format(&mpegvideo_iformat);
440     av_register_output_format(&mpeg1video_oformat);
441
442     av_register_input_format(&mjpeg_iformat);
443     av_register_output_format(&mjpeg_oformat);
444
445     av_register_input_format(&pcm_s16le_iformat);
446     av_register_output_format(&pcm_s16le_oformat);
447     av_register_input_format(&pcm_s16be_iformat);
448     av_register_output_format(&pcm_s16be_oformat);
449     av_register_input_format(&pcm_u16le_iformat);
450     av_register_output_format(&pcm_u16le_oformat);
451     av_register_input_format(&pcm_u16be_iformat);
452     av_register_output_format(&pcm_u16be_oformat);
453     av_register_input_format(&pcm_s8_iformat);
454     av_register_output_format(&pcm_s8_oformat);
455     av_register_input_format(&pcm_u8_iformat);
456     av_register_output_format(&pcm_u8_oformat);
457     av_register_input_format(&pcm_mulaw_iformat);
458     av_register_output_format(&pcm_mulaw_oformat);
459     av_register_input_format(&pcm_alaw_iformat);
460     av_register_output_format(&pcm_alaw_oformat);
461
462     av_register_input_format(&rawvideo_iformat);
463     av_register_output_format(&rawvideo_oformat);
464     return 0;
465 }