utils.c 21.5 KB
Newer Older
Fabrice Bellard's avatar
Fabrice Bellard committed
1 2
/*
 * utils for libavcodec
Fabrice Bellard's avatar
Fabrice Bellard committed
3
 * Copyright (c) 2001 Fabrice Bellard.
4
 * Copyright (c) 2003 Michel Bardiaux for the av_log API
5
 * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
Fabrice Bellard's avatar
Fabrice Bellard committed
6
 *
Fabrice Bellard's avatar
Fabrice Bellard committed
7 8 9 10
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
Fabrice Bellard's avatar
Fabrice Bellard committed
11
 *
Fabrice Bellard's avatar
Fabrice Bellard committed
12
 * This library is distributed in the hope that it will be useful,
Fabrice Bellard's avatar
Fabrice Bellard committed
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Fabrice Bellard's avatar
Fabrice Bellard committed
14 15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
Fabrice Bellard's avatar
Fabrice Bellard committed
16
 *
Fabrice Bellard's avatar
Fabrice Bellard committed
17 18 19
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Fabrice Bellard's avatar
Fabrice Bellard committed
20
 */
Michael Niedermayer's avatar
Michael Niedermayer committed
21 22 23 24 25 26
 
/**
 * @file utils.c
 * utils.
 */
 
Fabrice Bellard's avatar
Fabrice Bellard committed
27
#include "avcodec.h"
28
#include "dsputil.h"
Michael Niedermayer's avatar
Michael Niedermayer committed
29
#include "mpegvideo.h"
30
#include <stdarg.h>
Fabrice Bellard's avatar
Fabrice Bellard committed
31

32
void *av_mallocz(unsigned int size)
33 34
{
    void *ptr;
35
    
36 37 38 39 40 41 42
    ptr = av_malloc(size);
    if (!ptr)
        return NULL;
    memset(ptr, 0, size);
    return ptr;
}

43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
char *av_strdup(const char *s)
{
    char *ptr;
    int len;
    len = strlen(s) + 1;
    ptr = av_malloc(len);
    if (!ptr)
        return NULL;
    memcpy(ptr, s, len);
    return ptr;
}

/**
 * realloc which does nothing if the block is large enough
 */
58
void *av_fast_realloc(void *ptr, unsigned int *size, unsigned int min_size)
59 60 61 62 63 64 65 66 67 68
{
    if(min_size < *size) 
        return ptr;
    
    *size= min_size + 10*1024;

    return av_realloc(ptr, *size);
}


69 70 71 72 73 74
/* allocation of static arrays - do not use for normal allocation */
static unsigned int last_static = 0;
static char*** array_static = NULL;
static const unsigned int grow_static = 64; // ^2
void *__av_mallocz_static(void** location, unsigned int size)
{
75
    unsigned int l = (last_static + grow_static) & ~(grow_static - 1);
76 77 78 79 80 81 82
    void *ptr = av_mallocz(size);
    if (!ptr)
	return NULL;

    if (location)
    {
	if (l > last_static)
83
	    array_static = av_realloc(array_static, l);
84 85 86 87 88 89
	array_static[last_static++] = (char**) location;
	*location = ptr;
    }
    return ptr;
}
/* free all static arrays and reset pointers to 0 */
90
void av_free_static(void)
91 92 93 94 95 96
{
    if (array_static)
    {
	unsigned i;
	for (i = 0; i < last_static; i++)
	{
97
	    av_free(*array_static[i]);
98 99
            *array_static[i] = NULL;
	}
100
	av_free(array_static);
101 102 103 104 105
	array_static = 0;
    }
    last_static = 0;
}

Fabrice Bellard's avatar
Fabrice Bellard committed
106 107 108 109 110 111 112
/* cannot call it directly because of 'void **' casting is not automatic */
void __av_freep(void **ptr)
{
    av_free(*ptr);
    *ptr = NULL;
}

Fabrice Bellard's avatar
Fabrice Bellard committed
113 114 115 116 117 118 119 120 121 122 123 124
/* encoder management */
AVCodec *first_avcodec;

void register_avcodec(AVCodec *format)
{
    AVCodec **p;
    p = &first_avcodec;
    while (*p != NULL) p = &(*p)->next;
    *p = format;
    format->next = NULL;
}

125
typedef struct InternalBuffer{
Michael Niedermayer's avatar
cleanup  
Michael Niedermayer committed
126
    int last_pic_num;
127
    uint8_t *base[4];
Michael Niedermayer's avatar
cleanup  
Michael Niedermayer committed
128
    uint8_t *data[4];
129
    int linesize[4];
130 131 132
}InternalBuffer;

#define INTERNAL_BUFFER_SIZE 32
Michael Niedermayer's avatar
cleanup  
Michael Niedermayer committed
133

134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
#define ALIGN(x, a) (((x)+(a)-1)&~((a)-1))

void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height){
    int w_align= 1;    
    int h_align= 1;    
    
    switch(s->pix_fmt){
    case PIX_FMT_YUV420P:
    case PIX_FMT_YUV422:
    case PIX_FMT_YUV422P:
    case PIX_FMT_YUV444P:
    case PIX_FMT_GRAY8:
    case PIX_FMT_YUVJ420P:
    case PIX_FMT_YUVJ422P:
    case PIX_FMT_YUVJ444P:
        w_align= 16; //FIXME check for non mpeg style codecs and use less alignment
        h_align= 16;
        break;
    case PIX_FMT_YUV411P:
        w_align=32;
        h_align=8;
        break;
    case PIX_FMT_YUV410P:
        if(s->codec_id == CODEC_ID_SVQ1){
            w_align=64;
            h_align=64;
        }
        break;
    default:
        w_align= 1;
        h_align= 1;
        break;
    }

    *width = ALIGN(*width , w_align);
    *height= ALIGN(*height, h_align);
}

Michael Niedermayer's avatar
Michael Niedermayer committed
172
int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){
Michael Niedermayer's avatar
cleanup  
Michael Niedermayer committed
173
    int i;
174 175
    int w= s->width;
    int h= s->height;
176
    InternalBuffer *buf;
177
    int *picture_number;
Michael Niedermayer's avatar
Michael Niedermayer committed
178 179
    
    assert(pic->data[0]==NULL);
180
    assert(INTERNAL_BUFFER_SIZE > s->internal_buffer_count);
Michael Niedermayer's avatar
cleanup  
Michael Niedermayer committed
181

182 183 184 185 186 187 188 189 190 191 192 193
    if(s->internal_buffer==NULL){
        s->internal_buffer= av_mallocz(INTERNAL_BUFFER_SIZE*sizeof(InternalBuffer));
    }
#if 0
    s->internal_buffer= av_fast_realloc(
        s->internal_buffer, 
        &s->internal_buffer_size, 
        sizeof(InternalBuffer)*FFMAX(99,  s->internal_buffer_count+1)/*FIXME*/
        );
#endif
     
    buf= &((InternalBuffer*)s->internal_buffer)[s->internal_buffer_count];
194 195 196
    picture_number= &(((InternalBuffer*)s->internal_buffer)[INTERNAL_BUFFER_SIZE-1]).last_pic_num; //FIXME ugly hack
    (*picture_number)++;
    
197
    if(buf->base[0]){
198 199
        pic->age= *picture_number - buf->last_pic_num;
        buf->last_pic_num= *picture_number;
Michael Niedermayer's avatar
cleanup  
Michael Niedermayer committed
200
    }else{
201 202
        int h_chroma_shift, v_chroma_shift;
        int s_align, pixel_size;
Michael Niedermayer's avatar
cleanup  
Michael Niedermayer committed
203 204
        
        avcodec_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift, &v_chroma_shift);
205
        
Michael Niedermayer's avatar
cleanup  
Michael Niedermayer committed
206
        switch(s->pix_fmt){
Michael Niedermayer's avatar
Michael Niedermayer committed
207 208
        case PIX_FMT_RGB555:
        case PIX_FMT_RGB565:
Michael Niedermayer's avatar
cleanup  
Michael Niedermayer committed
209 210 211 212 213 214 215 216 217 218 219 220 221
        case PIX_FMT_YUV422:
            pixel_size=2;
            break;
        case PIX_FMT_RGB24:
        case PIX_FMT_BGR24:
            pixel_size=3;
            break;
        case PIX_FMT_RGBA32:
            pixel_size=4;
            break;
        default:
            pixel_size=1;
        }
222 223 224 225 226 227 228 229

        avcodec_align_dimensions(s, &w, &h);
#if defined(ARCH_POWERPC) || defined(HAVE_MMI) //FIXME some cleaner check
        s_align= 16;
#else
        s_align= 8;
#endif
            
Michael Niedermayer's avatar
cleanup  
Michael Niedermayer committed
230 231 232 233 234
        if(!(s->flags&CODEC_FLAG_EMU_EDGE)){
            w+= EDGE_WIDTH*2;
            h+= EDGE_WIDTH*2;
        }
        
235
        buf->last_pic_num= -256*256*256*64;
Michael Niedermayer's avatar
cleanup  
Michael Niedermayer committed
236 237

        for(i=0; i<3; i++){
Michael Niedermayer's avatar
10l  
Michael Niedermayer committed
238 239
            const int h_shift= i==0 ? 0 : h_chroma_shift;
            const int v_shift= i==0 ? 0 : v_chroma_shift;
Michael Niedermayer's avatar
cleanup  
Michael Niedermayer committed
240

241
            buf->linesize[i]= ALIGN(pixel_size*w>>h_shift, s_align);
Michael Niedermayer's avatar
cleanup  
Michael Niedermayer committed
242

243
            buf->base[i]= av_mallocz((buf->linesize[i]*h>>v_shift)+16); //FIXME 16
244
            if(buf->base[i]==NULL) return -1;
245
            memset(buf->base[i], 128, buf->linesize[i]*h>>v_shift);
Michael Niedermayer's avatar
cleanup  
Michael Niedermayer committed
246 247
        
            if(s->flags&CODEC_FLAG_EMU_EDGE)
248
                buf->data[i] = buf->base[i];
Michael Niedermayer's avatar
cleanup  
Michael Niedermayer committed
249
            else
250
                buf->data[i] = buf->base[i] + ALIGN((buf->linesize[i]*EDGE_WIDTH>>v_shift) + (EDGE_WIDTH>>h_shift), s_align);
Michael Niedermayer's avatar
cleanup  
Michael Niedermayer committed
251 252 253
        }
        pic->age= 256*256*256*64;
    }
254
    pic->type= FF_BUFFER_TYPE_INTERNAL;
Michael Niedermayer's avatar
cleanup  
Michael Niedermayer committed
255

256 257 258
    for(i=0; i<4; i++){
        pic->base[i]= buf->base[i];
        pic->data[i]= buf->data[i];
259
        pic->linesize[i]= buf->linesize[i];
260 261 262
    }
    s->internal_buffer_count++;

Michael Niedermayer's avatar
cleanup  
Michael Niedermayer committed
263 264 265
    return 0;
}

Michael Niedermayer's avatar
Michael Niedermayer committed
266
void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic){
Michael Niedermayer's avatar
cleanup  
Michael Niedermayer committed
267
    int i;
268 269
    InternalBuffer *buf, *last, temp;

Michael Niedermayer's avatar
Michael Niedermayer committed
270
    assert(pic->type==FF_BUFFER_TYPE_INTERNAL);
Michael Niedermayer's avatar
Michael Niedermayer committed
271
    assert(s->internal_buffer_count);
272

Fabrice Bellard's avatar
Fabrice Bellard committed
273
    buf = NULL; /* avoids warning */
274 275 276 277 278 279 280 281 282 283 284 285 286 287
    for(i=0; i<s->internal_buffer_count; i++){ //just 3-5 checks so is not worth to optimize
        buf= &((InternalBuffer*)s->internal_buffer)[i];
        if(buf->data[0] == pic->data[0])
            break;
    }
    assert(i < s->internal_buffer_count);
    s->internal_buffer_count--;
    last = &((InternalBuffer*)s->internal_buffer)[s->internal_buffer_count];

    temp= *buf;
    *buf= *last;
    *last= temp;

    for(i=0; i<3; i++){
Michael Niedermayer's avatar
cleanup  
Michael Niedermayer committed
288
        pic->data[i]=NULL;
289 290
//        pic->base[i]=NULL;
    }
Michael Niedermayer's avatar
cleanup  
Michael Niedermayer committed
291 292 293
//printf("R%X\n", pic->opaque);
}

294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325
int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic){
    AVFrame temp_pic;
    int i;

    /* If no picture return a new buffer */
    if(pic->data[0] == NULL) {
        /* We will copy from buffer, so must be readable */
        pic->buffer_hints |= FF_BUFFER_HINTS_READABLE;
        return s->get_buffer(s, pic);
    }

    /* If internal buffer type return the same buffer */
    if(pic->type == FF_BUFFER_TYPE_INTERNAL)
        return 0;

    /*
     * Not internal type and reget_buffer not overridden, emulate cr buffer
     */
    temp_pic = *pic;
    for(i = 0; i < 4; i++)
        pic->data[i] = pic->base[i] = NULL;
    pic->opaque = NULL;
    /* Allocate new frame */
    if (s->get_buffer(s, pic))
        return -1;
    /* Copy image data from old buffer to new buffer */
    img_copy((AVPicture*)pic, (AVPicture*)&temp_pic, s->pix_fmt, s->width,
             s->height);
    s->release_buffer(s, &temp_pic); // Release old frame
    return 0;
}

Michael Niedermayer's avatar
Michael Niedermayer committed
326 327 328 329
enum PixelFormat avcodec_default_get_format(struct AVCodecContext *s, enum PixelFormat * fmt){
    return fmt[0];
}

Michael Niedermayer's avatar
Michael Niedermayer committed
330
void avcodec_get_context_defaults(AVCodecContext *s){
Michael Niedermayer's avatar
Michael Niedermayer committed
331 332
    s->bit_rate= 800*1000;
    s->bit_rate_tolerance= s->bit_rate*10;
Michael Niedermayer's avatar
Michael Niedermayer committed
333 334
    s->qmin= 2;
    s->qmax= 31;
Michael Niedermayer's avatar
Michael Niedermayer committed
335 336
    s->mb_qmin= 2;
    s->mb_qmax= 31;
Michael Niedermayer's avatar
Michael Niedermayer committed
337 338
    s->rc_eq= "tex^qComp";
    s->qcompress= 0.5;
Michael Niedermayer's avatar
Michael Niedermayer committed
339 340 341
    s->max_qdiff= 3;
    s->b_quant_factor=1.25;
    s->b_quant_offset=1.25;
342
    s->i_quant_factor=-0.8;
Michael Niedermayer's avatar
Michael Niedermayer committed
343
    s->i_quant_offset=0.0;
344
    s->error_concealment= 3;
Michael Niedermayer's avatar
Michael Niedermayer committed
345
    s->error_resilience= 1;
346
    s->workaround_bugs= FF_BUG_AUTODETECT;
347 348
    s->frame_rate_base= 1;
    s->frame_rate = 25;
Michael Niedermayer's avatar
Michael Niedermayer committed
349 350
    s->gop_size= 50;
    s->me_method= ME_EPZS;
Michael Niedermayer's avatar
cleanup  
Michael Niedermayer committed
351 352
    s->get_buffer= avcodec_default_get_buffer;
    s->release_buffer= avcodec_default_release_buffer;
Michael Niedermayer's avatar
Michael Niedermayer committed
353
    s->get_format= avcodec_default_get_format;
Michael Niedermayer's avatar
Michael Niedermayer committed
354
    s->me_subpel_quality=8;
355 356
    s->lmin= FF_QP2LAMBDA * s->qmin;
    s->lmax= FF_QP2LAMBDA * s->qmax;
Michael Niedermayer's avatar
Michael Niedermayer committed
357
    s->sample_aspect_ratio= (AVRational){0,1};
Michael Niedermayer's avatar
10l  
Michael Niedermayer committed
358
    s->ildct_cmp= FF_CMP_VSAD;
359 360 361
    
    s->intra_quant_bias= FF_DEFAULT_QUANT_BIAS;
    s->inter_quant_bias= FF_DEFAULT_QUANT_BIAS;
362
    s->palctrl = NULL;
363
    s->reget_buffer= avcodec_default_reget_buffer;
Michael Niedermayer's avatar
Michael Niedermayer committed
364 365 366 367 368 369
}

/**
 * allocates a AVCodecContext and set it to defaults.
 * this can be deallocated by simply calling free() 
 */
Falk Hüffner's avatar
Falk Hüffner committed
370
AVCodecContext *avcodec_alloc_context(void){
Michael Niedermayer's avatar
Michael Niedermayer committed
371 372 373 374 375 376 377 378 379
    AVCodecContext *avctx= av_mallocz(sizeof(AVCodecContext));
    
    if(avctx==NULL) return NULL;
    
    avcodec_get_context_defaults(avctx);
    
    return avctx;
}

Michael Niedermayer's avatar
cleanup  
Michael Niedermayer committed
380
/**
Michael Niedermayer's avatar
Michael Niedermayer committed
381
 * allocates a AVPFrame and set it to defaults.
Michael Niedermayer's avatar
cleanup  
Michael Niedermayer committed
382 383
 * this can be deallocated by simply calling free() 
 */
Michael Niedermayer's avatar
Michael Niedermayer committed
384 385
AVFrame *avcodec_alloc_frame(void){
    AVFrame *pic= av_mallocz(sizeof(AVFrame));
Michael Niedermayer's avatar
cleanup  
Michael Niedermayer committed
386 387 388 389
    
    return pic;
}

Fabrice Bellard's avatar
Fabrice Bellard committed
390 391 392 393
int avcodec_open(AVCodecContext *avctx, AVCodec *codec)
{
    int ret;

394 395 396
    if(avctx->codec)
        return -1;

Fabrice Bellard's avatar
Fabrice Bellard committed
397
    avctx->codec = codec;
Zdenek Kabelac's avatar
Zdenek Kabelac committed
398
    avctx->codec_id = codec->id;
Fabrice Bellard's avatar
Fabrice Bellard committed
399
    avctx->frame_number = 0;
400 401 402 403 404 405 406
    if (codec->priv_data_size > 0) {
        avctx->priv_data = av_mallocz(codec->priv_data_size);
        if (!avctx->priv_data) 
            return -ENOMEM;
    } else {
        avctx->priv_data = NULL;
    }
Fabrice Bellard's avatar
Fabrice Bellard committed
407 408
    ret = avctx->codec->init(avctx);
    if (ret < 0) {
409
        av_freep(&avctx->priv_data);
Fabrice Bellard's avatar
Fabrice Bellard committed
410 411 412 413 414
        return ret;
    }
    return 0;
}

415
int avcodec_encode_audio(AVCodecContext *avctx, uint8_t *buf, int buf_size, 
Fabrice Bellard's avatar
Fabrice Bellard committed
416 417 418 419 420 421 422 423 424
                         const short *samples)
{
    int ret;

    ret = avctx->codec->encode(avctx, buf, buf_size, (void *)samples);
    avctx->frame_number++;
    return ret;
}

425
int avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf, int buf_size, 
Michael Niedermayer's avatar
Michael Niedermayer committed
426
                         const AVFrame *pict)
Fabrice Bellard's avatar
Fabrice Bellard committed
427 428 429 430
{
    int ret;

    ret = avctx->codec->encode(avctx, buf, buf_size, (void *)pict);
431 432 433
    
    emms_c(); //needed to avoid a emms_c() call before every return;

Fabrice Bellard's avatar
Fabrice Bellard committed
434 435 436 437
    avctx->frame_number++;
    return ret;
}

438 439 440 441 442 443 444 445 446
/** 
 * decode a frame. 
 * @param buf bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE larger then the actual read bytes
 * because some optimized bitstream readers read 32 or 64 bit at once and could read over the end
 * @param buf_size the size of the buffer in bytes
 * @param got_picture_ptr zero if no frame could be decompressed, Otherwise, it is non zero
 * @return -1 if error, otherwise return the number of
 * bytes used. 
 */
Michael Niedermayer's avatar
Michael Niedermayer committed
447
int avcodec_decode_video(AVCodecContext *avctx, AVFrame *picture, 
Fabrice Bellard's avatar
Fabrice Bellard committed
448
                         int *got_picture_ptr,
449
                         uint8_t *buf, int buf_size)
Fabrice Bellard's avatar
Fabrice Bellard committed
450 451
{
    int ret;
Michael Niedermayer's avatar
cleanup  
Michael Niedermayer committed
452
    
Fabrice Bellard's avatar
Fabrice Bellard committed
453 454
    ret = avctx->codec->decode(avctx, picture, got_picture_ptr, 
                               buf, buf_size);
455 456

    emms_c(); //needed to avoid a emms_c() call before every return;
Michael Niedermayer's avatar
cleanup  
Michael Niedermayer committed
457
    
458 459
    if (*got_picture_ptr)                           
        avctx->frame_number++;
Fabrice Bellard's avatar
Fabrice Bellard committed
460 461 462 463 464 465 466
    return ret;
}

/* decode an audio frame. return -1 if error, otherwise return the
   *number of bytes used. If no frame could be decompressed,
   *frame_size_ptr is zero. Otherwise, it is the decompressed frame
   *size in BYTES. */
467
int avcodec_decode_audio(AVCodecContext *avctx, int16_t *samples, 
Fabrice Bellard's avatar
Fabrice Bellard committed
468
                         int *frame_size_ptr,
469
                         uint8_t *buf, int buf_size)
Fabrice Bellard's avatar
Fabrice Bellard committed
470 471 472 473 474 475 476 477 478 479 480 481 482
{
    int ret;

    ret = avctx->codec->decode(avctx, samples, frame_size_ptr, 
                               buf, buf_size);
    avctx->frame_number++;
    return ret;
}

int avcodec_close(AVCodecContext *avctx)
{
    if (avctx->codec->close)
        avctx->codec->close(avctx);
483
    av_freep(&avctx->priv_data);
Fabrice Bellard's avatar
Fabrice Bellard committed
484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499
    avctx->codec = NULL;
    return 0;
}

AVCodec *avcodec_find_encoder(enum CodecID id)
{
    AVCodec *p;
    p = first_avcodec;
    while (p) {
        if (p->encode != NULL && p->id == id)
            return p;
        p = p->next;
    }
    return NULL;
}

500 501 502 503 504 505 506 507 508 509 510 511
AVCodec *avcodec_find_encoder_by_name(const char *name)
{
    AVCodec *p;
    p = first_avcodec;
    while (p) {
        if (p->encode != NULL && strcmp(name,p->name) == 0)
            return p;
        p = p->next;
    }
    return NULL;
}

Fabrice Bellard's avatar
Fabrice Bellard committed
512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552
AVCodec *avcodec_find_decoder(enum CodecID id)
{
    AVCodec *p;
    p = first_avcodec;
    while (p) {
        if (p->decode != NULL && p->id == id)
            return p;
        p = p->next;
    }
    return NULL;
}

AVCodec *avcodec_find_decoder_by_name(const char *name)
{
    AVCodec *p;
    p = first_avcodec;
    while (p) {
        if (p->decode != NULL && strcmp(name,p->name) == 0)
            return p;
        p = p->next;
    }
    return NULL;
}

AVCodec *avcodec_find(enum CodecID id)
{
    AVCodec *p;
    p = first_avcodec;
    while (p) {
        if (p->id == id)
            return p;
        p = p->next;
    }
    return NULL;
}

void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode)
{
    const char *codec_name;
    AVCodec *p;
    char buf1[32];
553
    char channels_str[100];
Fabrice Bellard's avatar
Fabrice Bellard committed
554
    int bitrate;
Fabrice Bellard's avatar
Fabrice Bellard committed
555 556 557 558 559 560 561 562

    if (encode)
        p = avcodec_find_encoder(enc->codec_id);
    else
        p = avcodec_find_decoder(enc->codec_id);

    if (p) {
        codec_name = p->name;
563 564 565 566 567 568
        if (!encode && enc->codec_id == CODEC_ID_MP3) {
            if (enc->sub_id == 2)
                codec_name = "mp2";
            else if (enc->sub_id == 1)
                codec_name = "mp1";
        }
569 570 571 572
    } else if (enc->codec_id == CODEC_ID_MPEG2TS) {
        /* fake mpeg2 transport stream codec (currently not
           registered) */
        codec_name = "mpeg2ts";
Fabrice Bellard's avatar
Fabrice Bellard committed
573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592
    } else if (enc->codec_name[0] != '\0') {
        codec_name = enc->codec_name;
    } else {
        /* output avi tags */
        if (enc->codec_type == CODEC_TYPE_VIDEO) {
            snprintf(buf1, sizeof(buf1), "%c%c%c%c", 
                     enc->codec_tag & 0xff,
                     (enc->codec_tag >> 8) & 0xff,
                     (enc->codec_tag >> 16) & 0xff,
                     (enc->codec_tag >> 24) & 0xff);
        } else {
            snprintf(buf1, sizeof(buf1), "0x%04x", enc->codec_tag);
        }
        codec_name = buf1;
    }

    switch(enc->codec_type) {
    case CODEC_TYPE_VIDEO:
        snprintf(buf, buf_size,
                 "Video: %s%s",
593
                 codec_name, enc->mb_decision ? " (hq)" : "");
Fabrice Bellard's avatar
Fabrice Bellard committed
594 595 596
        if (enc->codec_id == CODEC_ID_RAWVIDEO) {
            snprintf(buf + strlen(buf), buf_size - strlen(buf),
                     ", %s",
597
                     avcodec_get_pix_fmt_name(enc->pix_fmt));
Fabrice Bellard's avatar
Fabrice Bellard committed
598
        }
Fabrice Bellard's avatar
Fabrice Bellard committed
599 600 601 602
        if (enc->width) {
            snprintf(buf + strlen(buf), buf_size - strlen(buf),
                     ", %dx%d, %0.2f fps",
                     enc->width, enc->height, 
603
                     (float)enc->frame_rate / enc->frame_rate_base);
Fabrice Bellard's avatar
Fabrice Bellard committed
604
        }
Fabrice Bellard's avatar
Fabrice Bellard committed
605 606 607 608
        if (encode) {
            snprintf(buf + strlen(buf), buf_size - strlen(buf),
                     ", q=%d-%d", enc->qmin, enc->qmax);
        }
Fabrice Bellard's avatar
Fabrice Bellard committed
609
        bitrate = enc->bit_rate;
Fabrice Bellard's avatar
Fabrice Bellard committed
610 611 612 613 614
        break;
    case CODEC_TYPE_AUDIO:
        snprintf(buf, buf_size,
                 "Audio: %s",
                 codec_name);
615 616
        switch (enc->channels) {
            case 1:
617
                strcpy(channels_str, "mono");
618 619
                break;
            case 2:
620
                strcpy(channels_str, "stereo");
621 622
                break;
            case 6:
623
                strcpy(channels_str, "5:1");
624 625 626 627 628
                break;
            default:
                sprintf(channels_str, "%d channels", enc->channels);
                break;
        }
Fabrice Bellard's avatar
Fabrice Bellard committed
629 630 631 632
        if (enc->sample_rate) {
            snprintf(buf + strlen(buf), buf_size - strlen(buf),
                     ", %d Hz, %s",
                     enc->sample_rate,
633
                     channels_str);
Fabrice Bellard's avatar
Fabrice Bellard committed
634
        }
635
        
Fabrice Bellard's avatar
Fabrice Bellard committed
636 637 638 639 640 641
        /* for PCM codecs, compute bitrate directly */
        switch(enc->codec_id) {
        case CODEC_ID_PCM_S16LE:
        case CODEC_ID_PCM_S16BE:
        case CODEC_ID_PCM_U16LE:
        case CODEC_ID_PCM_U16BE:
Fabrice Bellard's avatar
Fabrice Bellard committed
642
            bitrate = enc->sample_rate * enc->channels * 16;
Fabrice Bellard's avatar
Fabrice Bellard committed
643 644 645 646 647
            break;
        case CODEC_ID_PCM_S8:
        case CODEC_ID_PCM_U8:
        case CODEC_ID_PCM_ALAW:
        case CODEC_ID_PCM_MULAW:
Fabrice Bellard's avatar
Fabrice Bellard committed
648
            bitrate = enc->sample_rate * enc->channels * 8;
Fabrice Bellard's avatar
Fabrice Bellard committed
649 650 651 652 653
            break;
        default:
            bitrate = enc->bit_rate;
            break;
        }
Fabrice Bellard's avatar
Fabrice Bellard committed
654
        break;
655 656 657 658
    case CODEC_TYPE_DATA:
        snprintf(buf, buf_size, "Data: %s", codec_name);
        bitrate = enc->bit_rate;
        break;
Fabrice Bellard's avatar
Fabrice Bellard committed
659
    default:
660
        av_abort();
Fabrice Bellard's avatar
Fabrice Bellard committed
661
    }
Fabrice Bellard's avatar
Fabrice Bellard committed
662 663 664 665 666 667 668 669
    if (encode) {
        if (enc->flags & CODEC_FLAG_PASS1)
            snprintf(buf + strlen(buf), buf_size - strlen(buf),
                     ", pass 1");
        if (enc->flags & CODEC_FLAG_PASS2)
            snprintf(buf + strlen(buf), buf_size - strlen(buf),
                     ", pass 2");
    }
Fabrice Bellard's avatar
Fabrice Bellard committed
670
    if (bitrate != 0) {
Fabrice Bellard's avatar
Fabrice Bellard committed
671
        snprintf(buf + strlen(buf), buf_size - strlen(buf), 
Fabrice Bellard's avatar
Fabrice Bellard committed
672
                 ", %d kb/s", bitrate / 1000);
Fabrice Bellard's avatar
Fabrice Bellard committed
673 674 675
    }
}

Nick Kurshev's avatar
Nick Kurshev committed
676 677 678 679
unsigned avcodec_version( void )
{
  return LIBAVCODEC_VERSION_INT;
}
Fabrice Bellard's avatar
Fabrice Bellard committed
680

Nick Kurshev's avatar
Nick Kurshev committed
681 682 683 684 685
unsigned avcodec_build( void )
{
  return LIBAVCODEC_BUILD;
}

Fabrice Bellard's avatar
Fabrice Bellard committed
686 687 688
/* must be called before any other functions */
void avcodec_init(void)
{
689 690 691 692 693 694
    static int inited = 0;

    if (inited != 0)
	return;
    inited = 1;

Fabrice Bellard's avatar
Fabrice Bellard committed
695
    dsputil_static_init();
Fabrice Bellard's avatar
Fabrice Bellard committed
696 697
}

Michael Niedermayer's avatar
Michael Niedermayer committed
698 699 700
/**
 * Flush buffers, should be called when seeking or when swicthing to a different stream.
 */
Michael Niedermayer's avatar
Michael Niedermayer committed
701 702
void avcodec_flush_buffers(AVCodecContext *avctx)
{
Michael Niedermayer's avatar
Michael Niedermayer committed
703 704
    if(avctx->codec->flush)
        avctx->codec->flush(avctx);
Michael Niedermayer's avatar
Michael Niedermayer committed
705 706
}

707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723
void avcodec_default_free_buffers(AVCodecContext *s){
    int i, j;

    if(s->internal_buffer==NULL) return;
    
    for(i=0; i<INTERNAL_BUFFER_SIZE; i++){
        InternalBuffer *buf= &((InternalBuffer*)s->internal_buffer)[i];
        for(j=0; j<4; j++){
            av_freep(&buf->base[j]);
            buf->data[j]= NULL;
        }
    }
    av_freep(&s->internal_buffer);
    
    s->internal_buffer_count=0;
}

Michael Niedermayer's avatar
cleanup  
Michael Niedermayer committed
724 725 726 727 728 729 730 731 732 733 734 735
char av_get_pict_type_char(int pict_type){
    switch(pict_type){
    case I_TYPE: return 'I'; 
    case P_TYPE: return 'P'; 
    case B_TYPE: return 'B'; 
    case S_TYPE: return 'S'; 
    case SI_TYPE:return 'i'; 
    case SP_TYPE:return 'p'; 
    default:     return '?';
    }
}

736 737
int av_reduce(int *dst_nom, int *dst_den, int64_t nom, int64_t den, int64_t max){
    int exact=1, sign=0;
738
    int64_t gcd;
739 740 741 742 743 744 745 746 747 748 749 750 751

    assert(den != 0);

    if(den < 0){
        den= -den;
        nom= -nom;
    }
    
    if(nom < 0){
        nom= -nom;
        sign= 1;
    }
    
752 753 754
    gcd = ff_gcd(nom, den);
    nom /= gcd;
    den /= gcd;
755
    
756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775
    if(nom > max || den > max){
        AVRational a0={0,1}, a1={1,0};
        exact=0;

        for(;;){
            int64_t x= nom / den;
            int64_t a2n= x*a1.num + a0.num;
            int64_t a2d= x*a1.den + a0.den;

            if(a2n > max || a2d > max) break;

            nom %= den;
        
            a0= a1;
            a1= (AVRational){a2n, a2d};
            if(nom==0) break;
            x= nom; nom=den; den=x;
        }
        nom= a1.num;
        den= a1.den;
776 777
    }
    
778 779
    assert(ff_gcd(nom, den) == 1);
    
780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805
    if(sign) nom= -nom;
    
    *dst_nom = nom;
    *dst_den = den;
    
    return exact;
}

int64_t av_rescale(int64_t a, int b, int c){
    uint64_t h, l;
    assert(c > 0);
    assert(b >=0);
    
    if(a<0) return -av_rescale(-a, b, c);
    
    h= a>>32;
    if(h==0) return a*b/c;
    
    l= a&0xFFFFFFFF;
    l *= b;
    h *= b;

    l += (h%c)<<32;

    return ((h/c)<<32) + l/c;
}
806 807 808 809 810 811 812 813 814 815 816 817

/* av_log API */

#ifdef AV_LOG_TRAP_PRINTF
#undef stderr
#undef fprintf
#endif

static int av_log_level = AV_LOG_DEBUG;

static void av_log_default_callback(AVCodecContext* avctx, int level, const char* fmt, va_list vl)
{
Michael Niedermayer's avatar
Michael Niedermayer committed
818 819
    static int print_prefix=1;

820 821
    if(level>av_log_level)
	    return;
Michael Niedermayer's avatar
Michael Niedermayer committed
822
    if(avctx && print_prefix)
Michael Niedermayer's avatar
Michael Niedermayer committed
823
        fprintf(stderr, "[%s @ %p]", avctx->codec ? avctx->codec->name : "?", avctx);
Michael Niedermayer's avatar
Michael Niedermayer committed
824 825 826
        
    print_prefix= (int)strstr(fmt, "\n");
        
827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859
    vfprintf(stderr, fmt, vl);
}

static void (*av_log_callback)(AVCodecContext*, int, const char*, va_list) = av_log_default_callback;

void av_log(AVCodecContext* avctx, int level, const char *fmt, ...)
{
    va_list vl;
    va_start(vl, fmt);
    av_vlog(avctx, level, fmt, vl);
    va_end(vl);
}

void av_vlog(AVCodecContext* avctx, int level, const char *fmt, va_list vl)
{
    av_log_callback(avctx, level, fmt, vl);
}

int av_log_get_level(void)
{
    return av_log_level;
}

void av_log_set_level(int level)
{
    av_log_level = level;
}

void av_log_set_callback(void (*callback)(AVCodecContext*, int, const char*, va_list))
{
    av_log_callback = callback;
}