added raw mjpeg
[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)
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             /* XXX: endianness */
72             break;
73         case CODEC_TYPE_VIDEO:
74             st->codec.frame_rate = ap->frame_rate;
75             st->codec.width = ap->width;
76             st->codec.height = ap->height;
77             break;
78         default:
79             return -1;
80         }
81     } else {
82         return -1;
83     }
84     return 0;
85 }
86
87 #define MIN_SIZE 1024
88
89 int raw_read_packet(AVFormatContext *s,
90                     AVPacket *pkt)
91 {
92     int packet_size, n, ret;
93
94     if (url_feof(&s->pb))
95         return -EIO;
96
97     packet_size = url_get_packet_size(&s->pb);
98     n = MIN_SIZE / packet_size;
99     if (n <= 0)
100         n = 1;
101     if (av_new_packet(pkt, n * packet_size) < 0)
102         return -EIO;
103
104     pkt->stream_index = 0;
105     ret = get_buffer(&s->pb, pkt->data, pkt->size);
106     if (ret < 0)
107         av_free_packet(pkt);
108     return ret;
109 }
110
111 int raw_read_close(AVFormatContext *s)
112 {
113     return 0;
114 }
115
116 /* mp3 read */
117 static int mp3_read_header(AVFormatContext *s,
118                            AVFormatParameters *ap)
119 {
120     AVStream *st;
121
122     st = malloc(sizeof(AVStream));
123     if (!st)
124         return -1;
125     s->nb_streams = 1;
126     s->streams[0] = st;
127
128     st->id = 0;
129
130     st->codec.codec_type = CODEC_TYPE_AUDIO;
131     st->codec.codec_id = CODEC_ID_MP2;
132     /* the parameters will be extracted from the compressed bitstream */
133     return 0;
134 }
135
136 /* mpeg1/h263 input */
137 static int video_read_header(AVFormatContext *s,
138                              AVFormatParameters *ap)
139 {
140     AVStream *st;
141
142     st = av_mallocz(sizeof(AVStream));
143     if (!st)
144         return -1;
145     s->nb_streams = 1;
146     s->streams[0] = st;
147
148     st->codec.codec_type = CODEC_TYPE_VIDEO;
149     st->codec.codec_id = s->format->video_codec;
150     /* for mjpeg, specify frame rate */
151     if (st->codec.codec_id == CODEC_ID_MJPEG) {
152         if (ap) {
153             st->codec.frame_rate = ap->frame_rate;
154         } else {
155             st->codec.frame_rate = 25 * FRAME_RATE_BASE;
156         }
157     }
158     return 0;
159 }
160
161 AVFormat mp2_format = {
162     "mp2",
163     "MPEG audio",
164     "audio/x-mpeg",
165     "mp2,mp3",
166     CODEC_ID_MP2,
167     0,
168     raw_write_header,
169     raw_write_packet,
170     raw_write_trailer,
171
172     mp3_read_header,
173     raw_read_packet,
174     raw_read_close,
175 };
176
177 AVFormat ac3_format = {
178     "ac3",
179     "raw ac3",
180     "audio/x-ac3", 
181     "ac3",
182     CODEC_ID_AC3,
183     0,
184     raw_write_header,
185     raw_write_packet,
186     raw_write_trailer,
187 };
188
189 AVFormat h263_format = {
190     "h263",
191     "raw h263",
192     "video/x-h263",
193     "h263",
194     0,
195     CODEC_ID_H263,
196     raw_write_header,
197     raw_write_packet,
198     raw_write_trailer,
199     video_read_header,
200     raw_read_packet,
201     raw_read_close,
202 };
203
204 AVFormat mpeg1video_format = {
205     "mpegvideo",
206     "MPEG video",
207     "video/x-mpeg",
208     "mpg,mpeg",
209     0,
210     CODEC_ID_MPEG1VIDEO,
211     raw_write_header,
212     raw_write_packet,
213     raw_write_trailer,
214     video_read_header,
215     raw_read_packet,
216     raw_read_close,
217 };
218
219 AVFormat mjpeg_format = {
220     "mjpeg",
221     "MJPEG video",
222     "video/x-mjpeg",
223     "mjpg,mjpeg",
224     0,
225     CODEC_ID_MJPEG,
226     raw_write_header,
227     raw_write_packet,
228     raw_write_trailer,
229     video_read_header,
230     raw_read_packet,
231     raw_read_close,
232 };
233
234 AVFormat pcm_format = {
235     "pcm",
236     "pcm raw format",
237     NULL,
238     "sw",
239     CODEC_ID_PCM,
240     0,
241     raw_write_header,
242     raw_write_packet,
243     raw_write_trailer,
244
245     raw_read_header,
246     raw_read_packet,
247     raw_read_close,
248 };
249
250 int rawvideo_read_packet(AVFormatContext *s,
251                          AVPacket *pkt)
252 {
253     int packet_size, ret, width, height;
254     AVStream *st = s->streams[0];
255
256     width = st->codec.width;
257     height = st->codec.height;
258
259     switch(st->codec.pix_fmt) {
260     case PIX_FMT_YUV420P:
261         packet_size = (width * height * 3) / 2;
262         break;
263     case PIX_FMT_YUV422:
264         packet_size = (width * height * 2);
265         break;
266     case PIX_FMT_BGR24:
267     case PIX_FMT_RGB24:
268         packet_size = (width * height * 3);
269         break;
270     default:
271         abort();
272         break;
273     }
274
275     if (av_new_packet(pkt, packet_size) < 0)
276         return -EIO;
277
278     pkt->stream_index = 0;
279     /* bypass buffered I/O */
280     ret = url_read(url_fileno(&s->pb), pkt->data, pkt->size);
281     if (ret != pkt->size) {
282         av_free_packet(pkt);
283         return -EIO;
284     } else {
285         return 0;
286     }
287 }
288
289 AVFormat rawvideo_format = {
290     "rawvideo",
291     "raw video format",
292     NULL,
293     "yuv",
294     CODEC_ID_NONE,
295     CODEC_ID_RAWVIDEO,
296     raw_write_header,
297     raw_write_packet,
298     raw_write_trailer,
299
300     raw_read_header,
301     rawvideo_read_packet,
302     raw_read_close,
303 };