Mercurial > libavcodec.hg
annotate utils.c @ 229:f418b5c5ff67 libavcodec
PATCH by Rik Snel <rsnel@cube.dyndns.org>
this patch enhances the jpeg header writer. It can be asked to omit
quantisation and huffman tables and it can write different horizontal and
vertical sampling factors. (the last thing is useless for libavcodec
itself (because libavcodec only handles YUV420P at ecoder level), but the
values are initialized so that operation of libavcodec is not impaired)
author | arpi_esp |
---|---|
date | Sat, 09 Feb 2002 01:23:41 +0000 |
parents | 53da914d6f46 |
children | e1bacfb3f51f |
rev | line source |
---|---|
0 | 1 /* |
2 * utils for libavcodec | |
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 <stdio.h> | |
20 #include <string.h> | |
21 #include <errno.h> | |
22 #include "common.h" | |
23 #include "dsputil.h" | |
24 #include "avcodec.h" | |
80 | 25 #ifdef HAVE_MALLOC_H |
26 #include <malloc.h> | |
27 #else | |
28 #include <stdlib.h> | |
29 #endif | |
0 | 30 |
31 /* memory alloc */ | |
32 void *av_mallocz(int size) | |
33 { | |
34 void *ptr; | |
77 | 35 #if defined ( ARCH_X86 ) && defined ( HAVE_MEMALIGN ) |
36 ptr = memalign(64,size); | |
37 /* Why 64? | |
38 Indeed, we should align it: | |
39 on 4 for 386 | |
40 on 16 for 486 | |
41 on 32 for 586, PPro - k6-III | |
42 on 64 for K7 (maybe for P3 too). | |
43 Because L1 and L2 caches are aligned on those values. | |
44 But I don't want to code such logic here! | |
45 */ | |
46 #else | |
0 | 47 ptr = malloc(size); |
77 | 48 #endif |
0 | 49 if (!ptr) |
50 return NULL; | |
51 memset(ptr, 0, size); | |
52 return ptr; | |
53 } | |
54 | |
55 /* encoder management */ | |
56 AVCodec *first_avcodec; | |
57 | |
58 void register_avcodec(AVCodec *format) | |
59 { | |
60 AVCodec **p; | |
61 p = &first_avcodec; | |
62 while (*p != NULL) p = &(*p)->next; | |
63 *p = format; | |
64 format->next = NULL; | |
65 } | |
66 | |
67 int avcodec_open(AVCodecContext *avctx, AVCodec *codec) | |
68 { | |
69 int ret; | |
70 | |
71 avctx->codec = codec; | |
72 avctx->frame_number = 0; | |
73 avctx->priv_data = av_mallocz(codec->priv_data_size); | |
74 if (!avctx->priv_data) | |
75 return -ENOMEM; | |
76 ret = avctx->codec->init(avctx); | |
77 if (ret < 0) { | |
78 free(avctx->priv_data); | |
79 avctx->priv_data = NULL; | |
80 return ret; | |
81 } | |
82 return 0; | |
83 } | |
84 | |
85 int avcodec_encode_audio(AVCodecContext *avctx, UINT8 *buf, int buf_size, | |
86 const short *samples) | |
87 { | |
88 int ret; | |
89 | |
90 ret = avctx->codec->encode(avctx, buf, buf_size, (void *)samples); | |
91 avctx->frame_number++; | |
92 return ret; | |
93 } | |
94 | |
95 int avcodec_encode_video(AVCodecContext *avctx, UINT8 *buf, int buf_size, | |
96 const AVPicture *pict) | |
97 { | |
98 int ret; | |
99 | |
100 ret = avctx->codec->encode(avctx, buf, buf_size, (void *)pict); | |
101 avctx->frame_number++; | |
102 return ret; | |
103 } | |
104 | |
105 /* decode a frame. return -1 if error, otherwise return the number of | |
106 bytes used. If no frame could be decompressed, *got_picture_ptr is | |
107 zero. Otherwise, it is non zero */ | |
108 int avcodec_decode_video(AVCodecContext *avctx, AVPicture *picture, | |
109 int *got_picture_ptr, | |
110 UINT8 *buf, int buf_size) | |
111 { | |
112 int ret; | |
113 | |
114 ret = avctx->codec->decode(avctx, picture, got_picture_ptr, | |
115 buf, buf_size); | |
116 avctx->frame_number++; | |
117 return ret; | |
118 } | |
119 | |
120 /* decode an audio frame. return -1 if error, otherwise return the | |
121 *number of bytes used. If no frame could be decompressed, | |
122 *frame_size_ptr is zero. Otherwise, it is the decompressed frame | |
123 *size in BYTES. */ | |
124 int avcodec_decode_audio(AVCodecContext *avctx, INT16 *samples, | |
125 int *frame_size_ptr, | |
126 UINT8 *buf, int buf_size) | |
127 { | |
128 int ret; | |
129 | |
130 ret = avctx->codec->decode(avctx, samples, frame_size_ptr, | |
131 buf, buf_size); | |
132 avctx->frame_number++; | |
133 return ret; | |
134 } | |
135 | |
136 int avcodec_close(AVCodecContext *avctx) | |
137 { | |
138 if (avctx->codec->close) | |
139 avctx->codec->close(avctx); | |
140 free(avctx->priv_data); | |
141 avctx->priv_data = NULL; | |
142 avctx->codec = NULL; | |
143 return 0; | |
144 } | |
145 | |
146 AVCodec *avcodec_find_encoder(enum CodecID id) | |
147 { | |
148 AVCodec *p; | |
149 p = first_avcodec; | |
150 while (p) { | |
151 if (p->encode != NULL && p->id == id) | |
152 return p; | |
153 p = p->next; | |
154 } | |
155 return NULL; | |
156 } | |
157 | |
177 | 158 AVCodec *avcodec_find_encoder_by_name(const char *name) |
159 { | |
160 AVCodec *p; | |
161 p = first_avcodec; | |
162 while (p) { | |
163 if (p->encode != NULL && strcmp(name,p->name) == 0) | |
164 return p; | |
165 p = p->next; | |
166 } | |
167 return NULL; | |
168 } | |
169 | |
0 | 170 AVCodec *avcodec_find_decoder(enum CodecID id) |
171 { | |
172 AVCodec *p; | |
173 p = first_avcodec; | |
174 while (p) { | |
175 if (p->decode != NULL && p->id == id) | |
176 return p; | |
177 p = p->next; | |
178 } | |
179 return NULL; | |
180 } | |
181 | |
182 AVCodec *avcodec_find_decoder_by_name(const char *name) | |
183 { | |
184 AVCodec *p; | |
185 p = first_avcodec; | |
186 while (p) { | |
187 if (p->decode != NULL && strcmp(name,p->name) == 0) | |
188 return p; | |
189 p = p->next; | |
190 } | |
191 return NULL; | |
192 } | |
193 | |
194 AVCodec *avcodec_find(enum CodecID id) | |
195 { | |
196 AVCodec *p; | |
197 p = first_avcodec; | |
198 while (p) { | |
199 if (p->id == id) | |
200 return p; | |
201 p = p->next; | |
202 } | |
203 return NULL; | |
204 } | |
205 | |
55 | 206 const char *pix_fmt_str[] = { |
207 "yuv420p", | |
208 "yuv422", | |
209 "rgb24", | |
210 "bgr24", | |
211 "yuv422p", | |
212 "yuv444p", | |
213 }; | |
214 | |
0 | 215 void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) |
216 { | |
217 const char *codec_name; | |
218 AVCodec *p; | |
219 char buf1[32]; | |
92 | 220 int bitrate; |
0 | 221 |
222 if (encode) | |
223 p = avcodec_find_encoder(enc->codec_id); | |
224 else | |
225 p = avcodec_find_decoder(enc->codec_id); | |
226 | |
227 if (p) { | |
228 codec_name = p->name; | |
229 } else if (enc->codec_name[0] != '\0') { | |
230 codec_name = enc->codec_name; | |
231 } else { | |
232 /* output avi tags */ | |
233 if (enc->codec_type == CODEC_TYPE_VIDEO) { | |
234 snprintf(buf1, sizeof(buf1), "%c%c%c%c", | |
235 enc->codec_tag & 0xff, | |
236 (enc->codec_tag >> 8) & 0xff, | |
237 (enc->codec_tag >> 16) & 0xff, | |
238 (enc->codec_tag >> 24) & 0xff); | |
239 } else { | |
240 snprintf(buf1, sizeof(buf1), "0x%04x", enc->codec_tag); | |
241 } | |
242 codec_name = buf1; | |
243 } | |
244 | |
245 switch(enc->codec_type) { | |
246 case CODEC_TYPE_VIDEO: | |
247 snprintf(buf, buf_size, | |
248 "Video: %s%s", | |
249 codec_name, enc->flags & CODEC_FLAG_HQ ? " (hq)" : ""); | |
55 | 250 if (enc->codec_id == CODEC_ID_RAWVIDEO) { |
251 snprintf(buf + strlen(buf), buf_size - strlen(buf), | |
252 ", %s", | |
253 pix_fmt_str[enc->pix_fmt]); | |
254 } | |
0 | 255 if (enc->width) { |
256 snprintf(buf + strlen(buf), buf_size - strlen(buf), | |
257 ", %dx%d, %0.2f fps", | |
258 enc->width, enc->height, | |
259 (float)enc->frame_rate / FRAME_RATE_BASE); | |
260 } | |
92 | 261 bitrate = enc->bit_rate; |
0 | 262 break; |
263 case CODEC_TYPE_AUDIO: | |
264 snprintf(buf, buf_size, | |
265 "Audio: %s", | |
266 codec_name); | |
267 if (enc->sample_rate) { | |
268 snprintf(buf + strlen(buf), buf_size - strlen(buf), | |
269 ", %d Hz, %s", | |
270 enc->sample_rate, | |
271 enc->channels == 2 ? "stereo" : "mono"); | |
272 } | |
92 | 273 /* for PCM codecs, compute bitrate directly */ |
274 switch(enc->codec_id) { | |
275 case CODEC_ID_PCM_S16LE: | |
276 case CODEC_ID_PCM_S16BE: | |
277 case CODEC_ID_PCM_U16LE: | |
278 case CODEC_ID_PCM_U16BE: | |
94 | 279 bitrate = enc->sample_rate * enc->channels * 16; |
92 | 280 break; |
281 case CODEC_ID_PCM_S8: | |
282 case CODEC_ID_PCM_U8: | |
283 case CODEC_ID_PCM_ALAW: | |
284 case CODEC_ID_PCM_MULAW: | |
94 | 285 bitrate = enc->sample_rate * enc->channels * 8; |
92 | 286 break; |
287 default: | |
288 bitrate = enc->bit_rate; | |
289 break; | |
290 } | |
0 | 291 break; |
292 default: | |
293 abort(); | |
294 } | |
92 | 295 if (bitrate != 0) { |
0 | 296 snprintf(buf + strlen(buf), buf_size - strlen(buf), |
92 | 297 ", %d kb/s", bitrate / 1000); |
0 | 298 } |
299 } | |
300 | |
55 | 301 /* Picture field are filled with 'ptr' addresses */ |
302 void avpicture_fill(AVPicture *picture, UINT8 *ptr, | |
303 int pix_fmt, int width, int height) | |
304 { | |
305 int size; | |
306 | |
307 size = width * height; | |
308 switch(pix_fmt) { | |
309 case PIX_FMT_YUV420P: | |
310 picture->data[0] = ptr; | |
311 picture->data[1] = picture->data[0] + size; | |
312 picture->data[2] = picture->data[1] + size / 4; | |
313 picture->linesize[0] = width; | |
314 picture->linesize[1] = width / 2; | |
315 picture->linesize[2] = width / 2; | |
316 break; | |
317 case PIX_FMT_YUV422P: | |
318 picture->data[0] = ptr; | |
319 picture->data[1] = picture->data[0] + size; | |
320 picture->data[2] = picture->data[1] + size / 2; | |
321 picture->linesize[0] = width; | |
322 picture->linesize[1] = width / 2; | |
323 picture->linesize[2] = width / 2; | |
324 break; | |
325 case PIX_FMT_YUV444P: | |
326 picture->data[0] = ptr; | |
327 picture->data[1] = picture->data[0] + size; | |
328 picture->data[2] = picture->data[1] + size; | |
329 picture->linesize[0] = width; | |
330 picture->linesize[1] = width; | |
331 picture->linesize[2] = width; | |
332 break; | |
333 case PIX_FMT_RGB24: | |
334 case PIX_FMT_BGR24: | |
335 picture->data[0] = ptr; | |
336 picture->data[1] = NULL; | |
337 picture->data[2] = NULL; | |
338 picture->linesize[0] = width * 3; | |
339 break; | |
340 case PIX_FMT_YUV422: | |
341 picture->data[0] = ptr; | |
342 picture->data[1] = NULL; | |
343 picture->data[2] = NULL; | |
344 picture->linesize[0] = width * 2; | |
345 break; | |
346 default: | |
347 picture->data[0] = NULL; | |
348 picture->data[1] = NULL; | |
349 picture->data[2] = NULL; | |
350 break; | |
351 } | |
352 } | |
353 | |
354 int avpicture_get_size(int pix_fmt, int width, int height) | |
355 { | |
356 int size; | |
357 | |
358 size = width * height; | |
359 switch(pix_fmt) { | |
360 case PIX_FMT_YUV420P: | |
361 size = (size * 3) / 2; | |
362 break; | |
363 case PIX_FMT_YUV422P: | |
364 size = (size * 2); | |
365 break; | |
366 case PIX_FMT_YUV444P: | |
367 size = (size * 3); | |
368 break; | |
369 case PIX_FMT_RGB24: | |
370 case PIX_FMT_BGR24: | |
371 size = (size * 3); | |
372 break; | |
373 case PIX_FMT_YUV422: | |
374 size = (size * 2); | |
375 break; | |
376 default: | |
377 size = -1; | |
378 break; | |
379 } | |
380 return size; | |
381 } | |
382 | |
383 | |
0 | 384 /* must be called before any other functions */ |
385 void avcodec_init(void) | |
386 { | |
387 dsputil_init(); | |
388 } | |
389 | |
390 /* simple call to use all the codecs */ | |
391 void avcodec_register_all(void) | |
392 { | |
3
1bdbd869c1f0
added CONFIG_AC3, CONFIG_MPGLIB, CONFIG_DECODERS and CONFIG_ENCODERS (Arpi: don't forget to put CONFIG_DECODERS in mplayer)
glantau
parents:
0
diff
changeset
|
393 /* encoders */ |
1bdbd869c1f0
added CONFIG_AC3, CONFIG_MPGLIB, CONFIG_DECODERS and CONFIG_ENCODERS (Arpi: don't forget to put CONFIG_DECODERS in mplayer)
glantau
parents:
0
diff
changeset
|
394 #ifdef CONFIG_ENCODERS |
0 | 395 register_avcodec(&ac3_encoder); |
396 register_avcodec(&mp2_encoder); | |
397 register_avcodec(&mpeg1video_encoder); | |
398 register_avcodec(&h263_encoder); | |
399 register_avcodec(&h263p_encoder); | |
400 register_avcodec(&rv10_encoder); | |
401 register_avcodec(&mjpeg_encoder); | |
71 | 402 register_avcodec(&mpeg4_encoder); |
0 | 403 register_avcodec(&msmpeg4_encoder); |
3
1bdbd869c1f0
added CONFIG_AC3, CONFIG_MPGLIB, CONFIG_DECODERS and CONFIG_ENCODERS (Arpi: don't forget to put CONFIG_DECODERS in mplayer)
glantau
parents:
0
diff
changeset
|
404 #endif /* CONFIG_ENCODERS */ |
0 | 405 register_avcodec(&rawvideo_codec); |
3
1bdbd869c1f0
added CONFIG_AC3, CONFIG_MPGLIB, CONFIG_DECODERS and CONFIG_ENCODERS (Arpi: don't forget to put CONFIG_DECODERS in mplayer)
glantau
parents:
0
diff
changeset
|
406 |
0 | 407 /* decoders */ |
3
1bdbd869c1f0
added CONFIG_AC3, CONFIG_MPGLIB, CONFIG_DECODERS and CONFIG_ENCODERS (Arpi: don't forget to put CONFIG_DECODERS in mplayer)
glantau
parents:
0
diff
changeset
|
408 #ifdef CONFIG_DECODERS |
0 | 409 register_avcodec(&h263_decoder); |
71 | 410 register_avcodec(&mpeg4_decoder); |
0 | 411 register_avcodec(&msmpeg4_decoder); |
412 register_avcodec(&mpeg_decoder); | |
413 register_avcodec(&h263i_decoder); | |
414 register_avcodec(&rv10_decoder); | |
24 | 415 register_avcodec(&mjpeg_decoder); |
3
1bdbd869c1f0
added CONFIG_AC3, CONFIG_MPGLIB, CONFIG_DECODERS and CONFIG_ENCODERS (Arpi: don't forget to put CONFIG_DECODERS in mplayer)
glantau
parents:
0
diff
changeset
|
416 register_avcodec(&mp3_decoder); |
1bdbd869c1f0
added CONFIG_AC3, CONFIG_MPGLIB, CONFIG_DECODERS and CONFIG_ENCODERS (Arpi: don't forget to put CONFIG_DECODERS in mplayer)
glantau
parents:
0
diff
changeset
|
417 #ifdef CONFIG_AC3 |
1bdbd869c1f0
added CONFIG_AC3, CONFIG_MPGLIB, CONFIG_DECODERS and CONFIG_ENCODERS (Arpi: don't forget to put CONFIG_DECODERS in mplayer)
glantau
parents:
0
diff
changeset
|
418 register_avcodec(&ac3_decoder); |
1bdbd869c1f0
added CONFIG_AC3, CONFIG_MPGLIB, CONFIG_DECODERS and CONFIG_ENCODERS (Arpi: don't forget to put CONFIG_DECODERS in mplayer)
glantau
parents:
0
diff
changeset
|
419 #endif |
1bdbd869c1f0
added CONFIG_AC3, CONFIG_MPGLIB, CONFIG_DECODERS and CONFIG_ENCODERS (Arpi: don't forget to put CONFIG_DECODERS in mplayer)
glantau
parents:
0
diff
changeset
|
420 #endif /* CONFIG_DECODERS */ |
92 | 421 |
422 /* pcm codecs */ | |
423 | |
424 #define PCM_CODEC(id, name) \ | |
425 register_avcodec(& name ## _encoder); \ | |
426 register_avcodec(& name ## _decoder); \ | |
427 | |
428 PCM_CODEC(CODEC_ID_PCM_S16LE, pcm_s16le); | |
429 PCM_CODEC(CODEC_ID_PCM_S16BE, pcm_s16be); | |
430 PCM_CODEC(CODEC_ID_PCM_U16LE, pcm_u16le); | |
431 PCM_CODEC(CODEC_ID_PCM_U16BE, pcm_u16be); | |
432 PCM_CODEC(CODEC_ID_PCM_S8, pcm_s8); | |
433 PCM_CODEC(CODEC_ID_PCM_U8, pcm_u8); | |
434 PCM_CODEC(CODEC_ID_PCM_ALAW, pcm_alaw); | |
435 PCM_CODEC(CODEC_ID_PCM_MULAW, pcm_mulaw); | |
436 | |
437 #undef PCM_CODEC | |
0 | 438 } |
439 | |
440 static int encode_init(AVCodecContext *s) | |
441 { | |
442 return 0; | |
443 } | |
444 | |
445 static int decode_frame(AVCodecContext *avctx, | |
446 void *data, int *data_size, | |
447 UINT8 *buf, int buf_size) | |
448 { | |
449 return -1; | |
450 } | |
451 | |
452 static int encode_frame(AVCodecContext *avctx, | |
453 unsigned char *frame, int buf_size, void *data) | |
454 { | |
455 return -1; | |
456 } | |
457 | |
458 AVCodec rawvideo_codec = { | |
459 "rawvideo", | |
460 CODEC_TYPE_VIDEO, | |
461 CODEC_ID_RAWVIDEO, | |
462 0, | |
463 encode_init, | |
464 encode_frame, | |
465 NULL, | |
466 decode_frame, | |
467 }; |