]> git.sesse.net Git - ffmpeg/blob - libavcodec/utils.c
f1253abfd9a7da1b317e56a1ceb5857100f7fcab
[ffmpeg] / libavcodec / utils.c
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 <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <errno.h>
23 #include <limits.h> /* __GLIBC__ and __GLIBC_MINOR__ are defined here */
24 #if __GLIBC__ >=2 && __GLIBC_MINOR__ >= 1 /* Fixme about glibc-2.0 */
25 #define HAVE_MEMALIGN 1
26 #include <malloc.h>
27 #endif
28 #include "common.h"
29 #include "dsputil.h"
30 #include "avcodec.h"
31
32 /* memory alloc */
33 void *av_mallocz(int size)
34 {
35     void *ptr;
36 #if defined ( ARCH_X86 ) && defined ( HAVE_MEMALIGN )
37 /*
38    From glibc-2.1.x manuals:
39    -------------------------
40    The address of a block returned by `malloc' or `realloc' in the GNU
41 system is always a multiple of eight (or sixteen on 64-bit systems).
42 If you need a block whose address is a multiple of a higher power of
43 two than that, use `memalign' or `valloc'.  These functions are
44 declared in `stdlib.h'.
45
46    With the GNU library, you can use `free' to free the blocks that
47 `memalign' and `valloc' return.  That does not work in BSD,
48 however--BSD does not provide any way to free such blocks.
49 */
50     ptr = memalign(64,size);
51     /* Why 64? 
52        Indeed, we should align it:
53          on 4 for 386
54          on 16 for 486
55          on 32 for 586, PPro - k6-III
56          on 64 for K7 (maybe for P3 too).
57        Because L1 and L2 caches are aligned on those values.
58        But I don't want to code such logic here!
59      */
60 #else
61     ptr = malloc(size);
62 #endif
63     if (!ptr)
64         return NULL;
65     memset(ptr, 0, size);
66     return ptr;
67 }
68
69 /* encoder management */
70 AVCodec *first_avcodec;
71
72 void register_avcodec(AVCodec *format)
73 {
74     AVCodec **p;
75     p = &first_avcodec;
76     while (*p != NULL) p = &(*p)->next;
77     *p = format;
78     format->next = NULL;
79 }
80
81 int avcodec_open(AVCodecContext *avctx, AVCodec *codec)
82 {
83     int ret;
84
85     avctx->codec = codec;
86     avctx->frame_number = 0;
87     avctx->priv_data = av_mallocz(codec->priv_data_size);
88     if (!avctx->priv_data) 
89         return -ENOMEM;
90     ret = avctx->codec->init(avctx);
91     if (ret < 0) {
92         free(avctx->priv_data);
93         avctx->priv_data = NULL;
94         return ret;
95     }
96     return 0;
97 }
98
99 int avcodec_encode_audio(AVCodecContext *avctx, UINT8 *buf, int buf_size, 
100                          const short *samples)
101 {
102     int ret;
103
104     ret = avctx->codec->encode(avctx, buf, buf_size, (void *)samples);
105     avctx->frame_number++;
106     return ret;
107 }
108
109 int avcodec_encode_video(AVCodecContext *avctx, UINT8 *buf, int buf_size, 
110                          const AVPicture *pict)
111 {
112     int ret;
113
114     ret = avctx->codec->encode(avctx, buf, buf_size, (void *)pict);
115     avctx->frame_number++;
116     return ret;
117 }
118
119 /* decode a frame. return -1 if error, otherwise return the number of
120    bytes used. If no frame could be decompressed, *got_picture_ptr is
121    zero. Otherwise, it is non zero */
122 int avcodec_decode_video(AVCodecContext *avctx, AVPicture *picture, 
123                          int *got_picture_ptr,
124                          UINT8 *buf, int buf_size)
125 {
126     int ret;
127
128     ret = avctx->codec->decode(avctx, picture, got_picture_ptr, 
129                                buf, buf_size);
130     avctx->frame_number++;
131     return ret;
132 }
133
134 /* decode an audio frame. return -1 if error, otherwise return the
135    *number of bytes used. If no frame could be decompressed,
136    *frame_size_ptr is zero. Otherwise, it is the decompressed frame
137    *size in BYTES. */
138 int avcodec_decode_audio(AVCodecContext *avctx, INT16 *samples, 
139                          int *frame_size_ptr,
140                          UINT8 *buf, int buf_size)
141 {
142     int ret;
143
144     ret = avctx->codec->decode(avctx, samples, frame_size_ptr, 
145                                buf, buf_size);
146     avctx->frame_number++;
147     return ret;
148 }
149
150 int avcodec_close(AVCodecContext *avctx)
151 {
152     if (avctx->codec->close)
153         avctx->codec->close(avctx);
154     free(avctx->priv_data);
155     avctx->priv_data = NULL;
156     avctx->codec = NULL;
157     return 0;
158 }
159
160 AVCodec *avcodec_find_encoder(enum CodecID id)
161 {
162     AVCodec *p;
163     p = first_avcodec;
164     while (p) {
165         if (p->encode != NULL && p->id == id)
166             return p;
167         p = p->next;
168     }
169     return NULL;
170 }
171
172 AVCodec *avcodec_find_decoder(enum CodecID id)
173 {
174     AVCodec *p;
175     p = first_avcodec;
176     while (p) {
177         if (p->decode != NULL && p->id == id)
178             return p;
179         p = p->next;
180     }
181     return NULL;
182 }
183
184 AVCodec *avcodec_find_decoder_by_name(const char *name)
185 {
186     AVCodec *p;
187     p = first_avcodec;
188     while (p) {
189         if (p->decode != NULL && strcmp(name,p->name) == 0)
190             return p;
191         p = p->next;
192     }
193     return NULL;
194 }
195
196 AVCodec *avcodec_find(enum CodecID id)
197 {
198     AVCodec *p;
199     p = first_avcodec;
200     while (p) {
201         if (p->id == id)
202             return p;
203         p = p->next;
204     }
205     return NULL;
206 }
207
208 const char *pix_fmt_str[] = {
209     "yuv420p",
210     "yuv422",
211     "rgb24",
212     "bgr24",
213     "yuv422p",
214     "yuv444p",
215 };
216     
217 void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode)
218 {
219     const char *codec_name;
220     AVCodec *p;
221     char buf1[32];
222
223     if (encode)
224         p = avcodec_find_encoder(enc->codec_id);
225     else
226         p = avcodec_find_decoder(enc->codec_id);
227
228     if (p) {
229         codec_name = p->name;
230     } else if (enc->codec_name[0] != '\0') {
231         codec_name = enc->codec_name;
232     } else {
233         /* output avi tags */
234         if (enc->codec_type == CODEC_TYPE_VIDEO) {
235             snprintf(buf1, sizeof(buf1), "%c%c%c%c", 
236                      enc->codec_tag & 0xff,
237                      (enc->codec_tag >> 8) & 0xff,
238                      (enc->codec_tag >> 16) & 0xff,
239                      (enc->codec_tag >> 24) & 0xff);
240         } else {
241             snprintf(buf1, sizeof(buf1), "0x%04x", enc->codec_tag);
242         }
243         codec_name = buf1;
244     }
245
246     switch(enc->codec_type) {
247     case CODEC_TYPE_VIDEO:
248         snprintf(buf, buf_size,
249                  "Video: %s%s",
250                  codec_name, enc->flags & CODEC_FLAG_HQ ? " (hq)" : "");
251         if (enc->codec_id == CODEC_ID_RAWVIDEO) {
252             snprintf(buf + strlen(buf), buf_size - strlen(buf),
253                      ", %s",
254                      pix_fmt_str[enc->pix_fmt]);
255         }
256         if (enc->width) {
257             snprintf(buf + strlen(buf), buf_size - strlen(buf),
258                      ", %dx%d, %0.2f fps",
259                      enc->width, enc->height, 
260                      (float)enc->frame_rate / FRAME_RATE_BASE);
261         }
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         }
273         break;
274     default:
275         abort();
276     }
277     if (enc->bit_rate != 0) {
278         snprintf(buf + strlen(buf), buf_size - strlen(buf), 
279                  ", %d kb/s", enc->bit_rate / 1000);
280     }
281 }
282
283 /* Picture field are filled with 'ptr' addresses */
284 void avpicture_fill(AVPicture *picture, UINT8 *ptr,
285                     int pix_fmt, int width, int height)
286 {
287     int size;
288
289     size = width * height;
290     switch(pix_fmt) {
291     case PIX_FMT_YUV420P:
292         picture->data[0] = ptr;
293         picture->data[1] = picture->data[0] + size;
294         picture->data[2] = picture->data[1] + size / 4;
295         picture->linesize[0] = width;
296         picture->linesize[1] = width / 2;
297         picture->linesize[2] = width / 2;
298         break;
299     case PIX_FMT_YUV422P:
300         picture->data[0] = ptr;
301         picture->data[1] = picture->data[0] + size;
302         picture->data[2] = picture->data[1] + size / 2;
303         picture->linesize[0] = width;
304         picture->linesize[1] = width / 2;
305         picture->linesize[2] = width / 2;
306         break;
307     case PIX_FMT_YUV444P:
308         picture->data[0] = ptr;
309         picture->data[1] = picture->data[0] + size;
310         picture->data[2] = picture->data[1] + size;
311         picture->linesize[0] = width;
312         picture->linesize[1] = width;
313         picture->linesize[2] = width;
314         break;
315     case PIX_FMT_RGB24:
316     case PIX_FMT_BGR24:
317         picture->data[0] = ptr;
318         picture->data[1] = NULL;
319         picture->data[2] = NULL;
320         picture->linesize[0] = width * 3;
321         break;
322     case PIX_FMT_YUV422:
323         picture->data[0] = ptr;
324         picture->data[1] = NULL;
325         picture->data[2] = NULL;
326         picture->linesize[0] = width * 2;
327         break;
328     default:
329         picture->data[0] = NULL;
330         picture->data[1] = NULL;
331         picture->data[2] = NULL;
332         break;
333     }
334 }
335
336 int avpicture_get_size(int pix_fmt, int width, int height)
337 {
338     int size;
339
340     size = width * height;
341     switch(pix_fmt) {
342     case PIX_FMT_YUV420P:
343         size = (size * 3) / 2;
344         break;
345     case PIX_FMT_YUV422P:
346         size = (size * 2);
347         break;
348     case PIX_FMT_YUV444P:
349         size = (size * 3);
350         break;
351     case PIX_FMT_RGB24:
352     case PIX_FMT_BGR24:
353         size = (size * 3);
354         break;
355     case PIX_FMT_YUV422:
356         size = (size * 2);
357         break;
358     default:
359         size = -1;
360         break;
361     }
362     return size;
363 }
364
365
366 /* must be called before any other functions */
367 void avcodec_init(void)
368 {
369     dsputil_init();
370 }
371
372 /* simple call to use all the codecs */
373 void avcodec_register_all(void)
374 {
375     /* encoders */
376 #ifdef CONFIG_ENCODERS
377     register_avcodec(&ac3_encoder);
378     register_avcodec(&mp2_encoder);
379     register_avcodec(&mpeg1video_encoder);
380     register_avcodec(&h263_encoder);
381     register_avcodec(&h263p_encoder);
382     register_avcodec(&rv10_encoder);
383     register_avcodec(&mjpeg_encoder);
384     register_avcodec(&mpeg4_encoder);
385     register_avcodec(&msmpeg4_encoder);
386 #endif /* CONFIG_ENCODERS */
387     register_avcodec(&pcm_codec);
388     register_avcodec(&rawvideo_codec);
389
390     /* decoders */
391 #ifdef CONFIG_DECODERS
392     register_avcodec(&h263_decoder);
393     register_avcodec(&mpeg4_decoder);
394     register_avcodec(&msmpeg4_decoder);
395     register_avcodec(&mpeg_decoder);
396     register_avcodec(&h263i_decoder);
397     register_avcodec(&rv10_decoder);
398     register_avcodec(&mjpeg_decoder);
399 #ifdef CONFIG_MPGLIB
400     register_avcodec(&mp3_decoder);
401 #endif
402 #ifdef CONFIG_AC3
403     register_avcodec(&ac3_decoder);
404 #endif
405 #endif /* CONFIG_DECODERS */
406 }
407
408 static int encode_init(AVCodecContext *s)
409 {
410     return 0;
411 }
412
413 static int decode_frame(AVCodecContext *avctx, 
414                         void *data, int *data_size,
415                         UINT8 *buf, int buf_size)
416 {
417     return -1;
418 }
419
420 static int encode_frame(AVCodecContext *avctx,
421                         unsigned char *frame, int buf_size, void *data)
422 {
423     return -1;
424 }
425
426 /* dummy pcm codec */
427 AVCodec pcm_codec = {
428     "pcm",
429     CODEC_TYPE_AUDIO,
430     CODEC_ID_PCM,
431     0,
432     encode_init,
433     encode_frame,
434     NULL,
435     decode_frame,
436 };
437
438 AVCodec rawvideo_codec = {
439     "rawvideo",
440     CODEC_TYPE_VIDEO,
441     CODEC_ID_RAWVIDEO,
442     0,
443     encode_init,
444     encode_frame,
445     NULL,
446     decode_frame,
447 };