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