Statistics
| Branch: | Revision:

ffmpeg / libavcodec / utils.c @ 9d36bdc9

History | View | Annotate | Download (11.9 KB)

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"
25
#ifdef HAVE_MALLOC_H
26
#include <malloc.h>
27
#else
28
#include <stdlib.h>
29
#endif
30

    
31
/* memory alloc */
32
void *av_mallocz(int size)
33
{
34
    void *ptr;
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
47
    ptr = malloc(size);
48
#endif
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

    
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

    
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

    
206
const char *pix_fmt_str[] = {
207
    "yuv420p",
208
    "yuv422",
209
    "rgb24",
210
    "bgr24",
211
    "yuv422p",
212
    "yuv444p",
213
};
214
    
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];
220
    int bitrate;
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)" : "");
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
        }
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
        }
261
        bitrate = enc->bit_rate;
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
        /* 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:
279
            bitrate = enc->sample_rate * enc->channels * 16;
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:
285
            bitrate = enc->sample_rate * enc->channels * 8;
286
            break;
287
        default:
288
            bitrate = enc->bit_rate;
289
            break;
290
        }
291
        break;
292
    default:
293
        abort();
294
    }
295
    if (bitrate != 0) {
296
        snprintf(buf + strlen(buf), buf_size - strlen(buf), 
297
                 ", %d kb/s", bitrate / 1000);
298
    }
299
}
300

    
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

    
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
{
393
    /* encoders */
394
#ifdef CONFIG_ENCODERS
395
    register_avcodec(&ac3_encoder);
396
    register_avcodec(&mp2_encoder);
397
#ifdef CONFIG_MP3LAME
398
    register_avcodec(&mp3lame_encoder);
399
#endif
400
    register_avcodec(&mpeg1video_encoder);
401
    register_avcodec(&h263_encoder);
402
    register_avcodec(&h263p_encoder);
403
    register_avcodec(&rv10_encoder);
404
    register_avcodec(&mjpeg_encoder);
405
    register_avcodec(&mpeg4_encoder);
406
    register_avcodec(&msmpeg4_encoder);
407
#endif /* CONFIG_ENCODERS */
408
    register_avcodec(&rawvideo_codec);
409

    
410
    /* decoders */
411
#ifdef CONFIG_DECODERS
412
    register_avcodec(&h263_decoder);
413
    register_avcodec(&mpeg4_decoder);
414
    register_avcodec(&msmpeg4_decoder);
415
    register_avcodec(&mpeg_decoder);
416
    register_avcodec(&h263i_decoder);
417
    register_avcodec(&rv10_decoder);
418
    register_avcodec(&mjpeg_decoder);
419
    register_avcodec(&mp3_decoder);
420
#ifdef CONFIG_AC3
421
    register_avcodec(&ac3_decoder);
422
#endif
423
#endif /* CONFIG_DECODERS */
424

    
425
    /* pcm codecs */
426

    
427
#define PCM_CODEC(id, name) \
428
    register_avcodec(& name ## _encoder); \
429
    register_avcodec(& name ## _decoder); \
430

    
431
PCM_CODEC(CODEC_ID_PCM_S16LE, pcm_s16le);
432
PCM_CODEC(CODEC_ID_PCM_S16BE, pcm_s16be);
433
PCM_CODEC(CODEC_ID_PCM_U16LE, pcm_u16le);
434
PCM_CODEC(CODEC_ID_PCM_U16BE, pcm_u16be);
435
PCM_CODEC(CODEC_ID_PCM_S8, pcm_s8);
436
PCM_CODEC(CODEC_ID_PCM_U8, pcm_u8);
437
PCM_CODEC(CODEC_ID_PCM_ALAW, pcm_alaw);
438
PCM_CODEC(CODEC_ID_PCM_MULAW, pcm_mulaw);
439

    
440
#undef PCM_CODEC
441
}
442

    
443
static int encode_init(AVCodecContext *s)
444
{
445
    return 0;
446
}
447

    
448
static int decode_frame(AVCodecContext *avctx, 
449
                        void *data, int *data_size,
450
                        UINT8 *buf, int buf_size)
451
{
452
    return -1;
453
}
454

    
455
static int encode_frame(AVCodecContext *avctx,
456
                        unsigned char *frame, int buf_size, void *data)
457
{
458
    return -1;
459
}
460

    
461
AVCodec rawvideo_codec = {
462
    "rawvideo",
463
    CODEC_TYPE_VIDEO,
464
    CODEC_ID_RAWVIDEO,
465
    0,
466
    encode_init,
467
    encode_frame,
468
    NULL,
469
    decode_frame,
470
};