ffmpeg.c 79.8 KB
Newer Older
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
1 2
/*
 * FFmpeg main 
3
 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
4
 *
5 6 7 8
 * 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
merge  
Fabrice Bellard committed
9
 *
10
 * This library is distributed in the hope that it will be useful,
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
14
 *
15 16 17
 * 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
merge  
Fabrice Bellard committed
18
 */
19 20
#define HAVE_AV_CONFIG_H
#include "avformat.h"
21
#include "tick.h"
22

Fabrice Bellard's avatar
Fabrice Bellard committed
23
#ifndef CONFIG_WIN32
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
24 25 26 27 28
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <termios.h>
Fabrice Bellard's avatar
Fabrice Bellard committed
29
#include <sys/resource.h>
Fabrice Bellard's avatar
Fabrice Bellard committed
30
#endif
31 32 33 34
#ifdef __BEOS__
/* for snooze() */
#include <OS.h>
#endif
35 36
#include <time.h>
#include <ctype.h>
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
37 38


Fabrice Bellard's avatar
Fabrice Bellard committed
39 40
#define MAXINT64 INT64_C(0x7fffffffffffffff)

Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
typedef struct {
    const char *name;
    int flags;
#define HAS_ARG    0x0001
#define OPT_BOOL   0x0002
#define OPT_EXPERT 0x0004
#define OPT_STRING 0x0008
    union {
        void (*func_arg)();
        int *int_arg;
        char **str_arg;
    } u;
    const char *help;
    const char *argname;
} OptionDef;

/* select an input stream for an output stream */
typedef struct AVStreamMap {
    int file_index;
    int stream_index;
} AVStreamMap;

extern const OptionDef options[];

void show_help(void);

#define MAX_FILES 20

static AVFormatContext *input_files[MAX_FILES];
static int nb_input_files = 0;

static AVFormatContext *output_files[MAX_FILES];
static int nb_output_files = 0;

static AVStreamMap stream_maps[MAX_FILES];
static int nb_stream_maps;

78 79
static AVInputFormat *file_iformat;
static AVOutputFormat *file_oformat;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
80 81
static int frame_width  = 160;
static int frame_height = 128;
82 83 84 85
static int frame_topBand  = 0;
static int frame_bottomBand = 0;
static int frame_leftBand  = 0;
static int frame_rightBand = 0;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
86
static int frame_rate = 25 * FRAME_RATE_BASE;
Michael Niedermayer's avatar
Michael Niedermayer committed
87 88
static int video_bit_rate = 200*1000;
static int video_bit_rate_tolerance = 4000*1000;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
89
static int video_qscale = 0;
Michael Niedermayer's avatar
Michael Niedermayer committed
90 91
static int video_qmin = 2;
static int video_qmax = 31;
92 93 94
static int video_qdiff = 3;
static float video_qblur = 0.5;
static float video_qcomp = 0.5;
Michael Niedermayer's avatar
Michael Niedermayer committed
95 96 97 98 99 100 101 102 103 104 105 106
static float video_rc_qsquish=1.0;
static float video_rc_qmod_amp=0;
static int video_rc_qmod_freq=0;
static char *video_rc_override_string=NULL;
static char *video_rc_eq="tex^qComp";
static int video_rc_buffer_size=0;
static float video_rc_buffer_aggressivity=1.0;
static int video_rc_max_rate=0;
static int video_rc_min_rate=0;
static float video_rc_initial_cplx=0;
static float video_b_qfactor = 1.25;
static float video_b_qoffset = 1.25;
107
static float video_i_qfactor = -0.8;
Michael Niedermayer's avatar
Michael Niedermayer committed
108
static float video_i_qoffset = 0.0;
109
static int me_method = 0;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
110 111 112
static int video_disable = 0;
static int video_codec_id = CODEC_ID_NONE;
static int same_quality = 0;
113
static int b_frames = 0;
114
static int use_hq = 0;
115
static int use_4mv = 0;
116
static int do_deinterlace = 0;
117 118 119
static int workaround_bugs = FF_BUG_AUTODETECT;
static int error_resilience = 2;
static int error_concealment = 3;
120
static int dct_algo = 0;
121
static int idct_algo = 0;
122 123
static int use_part = 0;
static int packet_size = 0;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138

static int gop_size = 12;
static int intra_only = 0;
static int audio_sample_rate = 44100;
static int audio_bit_rate = 64000;
static int audio_disable = 0;
static int audio_channels = 1;
static int audio_codec_id = CODEC_ID_NONE;

static INT64 recording_time = 0;
static int file_overwrite = 0;
static char *str_title = NULL;
static char *str_author = NULL;
static char *str_copyright = NULL;
static char *str_comment = NULL;
Fabrice Bellard's avatar
Fabrice Bellard committed
139
static int do_benchmark = 0;
140
static int do_hex_dump = 0;
141
static int do_play = 0;
142
static int do_psnr = 0;
143
static int do_vstats = 0;
144 145
static int do_pass = 0;
static char *pass_logfilename = NULL;
146 147
static int audio_stream_copy = 0;
static int video_stream_copy = 0;
148 149

#define DEFAULT_PASS_LOGFILENAME "ffmpeg2pass"
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
150

151 152 153 154 155 156 157
#ifndef CONFIG_AUDIO_OSS
const char *audio_device = "none";
#endif
#ifndef CONFIG_VIDEO4LINUX
const char *v4l_device = "none";
#endif

Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
typedef struct AVOutputStream {
    int file_index;          /* file index */
    int index;               /* stream index in the output file */
    int source_index;        /* AVInputStream index */
    AVStream *st;            /* stream in the output file */
    int encoding_needed;   /* true if encoding needed for this stream */

    /* video only */
    AVPicture pict_tmp;         /* temporary image for resizing */
    int video_resample;
    ImgReSampleContext *img_resample_ctx; /* for image resampling */
    
    /* audio only */
    int audio_resample;
    ReSampleContext *resample; /* for audio resampling */
    FifoBuffer fifo;     /* for compression: one audio fifo per codec */
174
    FILE *logfile;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
175 176 177 178 179 180 181 182
} AVOutputStream;

typedef struct AVInputStream {
    int file_index;
    int index;
    AVStream *st;
    int discard;             /* true if stream data should be discarded */
    int decoding_needed;     /* true if the packets must be decoded in 'raw_fifo' */
183 184
    Ticker pts_ticker;       /* Ticker for PTS calculation */
    int ticker_inited;       /* to signal if the ticker was initialized */
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
185
    INT64 pts;               /* current pts */
186
    int   pts_increment;     /* expected pts increment for next packet */
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
187 188 189 190 191 192 193 194 195 196
    int frame_number;        /* current frame */
    INT64 sample_index;      /* current sample */
} AVInputStream;

typedef struct AVInputFile {
    int eof_reached;      /* true if eof reached */
    int ist_index;        /* index of first stream in ist_table */
    int buffer_size;      /* current total buffer size */
    int buffer_size_max;  /* buffer size at which we consider we can stop
                             buffering */
197
    int nb_streams;       /* nb streams we are aware of */
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
198 199
} AVInputFile;

Fabrice Bellard's avatar
Fabrice Bellard committed
200 201
#ifndef CONFIG_WIN32

Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
/* init terminal so that we can grab keys */
static struct termios oldtty;

static void term_exit(void)
{
    tcsetattr (0, TCSANOW, &oldtty);
}

static void term_init(void)
{
    struct termios tty;

    tcgetattr (0, &tty);
    oldtty = tty;

    tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
                          |INLCR|IGNCR|ICRNL|IXON);
    tty.c_oflag |= OPOST;
    tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
    tty.c_cflag &= ~(CSIZE|PARENB);
    tty.c_cflag |= CS8;
    tty.c_cc[VMIN] = 1;
    tty.c_cc[VTIME] = 0;
    
    tcsetattr (0, TCSANOW, &tty);

    atexit(term_exit);
}

/* read a key without blocking */
static int read_key(void)
{
    struct timeval tv;
    int n;
    unsigned char ch;
    fd_set rfds;

    FD_ZERO(&rfds);
    FD_SET(0, &rfds);
    tv.tv_sec = 0;
    tv.tv_usec = 0;
    n = select(1, &rfds, NULL, NULL, &tv);
    if (n > 0) {
245 246
        n = read(0, &ch, 1);
        if (n == 1)
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
247
            return ch;
248 249

        return n;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
250 251 252 253
    }
    return -1;
}

254
#else
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
255

256 257
/* no interactive support */
static void term_exit(void)
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
258
{
259
}
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
260

261 262 263
static void term_init(void)
{
}
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
264

265 266
static int read_key(void)
{
267
    return 0;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
268 269
}

270
#endif
Fabrice Bellard's avatar
Fabrice Bellard committed
271

Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
272 273
int read_ffserver_streams(AVFormatContext *s, const char *filename)
{
274
    int i, err;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
275 276
    AVFormatContext *ic;

277 278 279
    err = av_open_input_file(&ic, filename, NULL, FFM_PACKET_SIZE, NULL);
    if (err < 0)
        return err;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
280 281 282 283 284 285 286 287 288 289 290 291 292 293 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
    /* copy stream format */
    s->nb_streams = ic->nb_streams;
    for(i=0;i<ic->nb_streams;i++) {
        AVStream *st;
        st = av_mallocz(sizeof(AVFormatContext));
        memcpy(st, ic->streams[i], sizeof(AVStream));
        s->streams[i] = st;
    }

    av_close_input_file(ic);
    return 0;
}

#define MAX_AUDIO_PACKET_SIZE 16384

static void do_audio_out(AVFormatContext *s, 
                         AVOutputStream *ost, 
                         AVInputStream *ist,
                         unsigned char *buf, int size)
{
    UINT8 *buftmp;
    UINT8 audio_buf[2*MAX_AUDIO_PACKET_SIZE]; /* XXX: allocate it */
    UINT8 audio_out[MAX_AUDIO_PACKET_SIZE]; /* XXX: allocate it */
    int size_out, frame_bytes, ret;
    AVCodecContext *enc;

    enc = &ost->st->codec;

    if (ost->audio_resample) {
        buftmp = audio_buf;
        size_out = audio_resample(ost->resample, 
                                  (short *)buftmp, (short *)buf,
                                  size / (ist->st->codec.channels * 2));
        size_out = size_out * enc->channels * 2;
    } else {
        buftmp = buf;
        size_out = size;
    }

    /* now encode as many frames as possible */
320
    if (enc->frame_size > 1) {
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
321 322 323 324 325 326 327 328
        /* output resampled raw samples */
        fifo_write(&ost->fifo, buftmp, size_out, 
                   &ost->fifo.wptr);

        frame_bytes = enc->frame_size * 2 * enc->channels;
        
        while (fifo_read(&ost->fifo, audio_buf, frame_bytes, 
                     &ost->fifo.rptr) == 0) {
329 330
            ret = avcodec_encode_audio(enc, audio_out, sizeof(audio_out), 
                                       (short *)audio_buf);
331
            s->oformat->write_packet(s, ost->index, audio_out, ret, 0);
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
332 333
        }
    } else {
334 335 336 337 338 339 340 341 342 343 344 345 346 347
        /* output a pcm frame */
        /* XXX: change encoding codec API to avoid this ? */
        switch(enc->codec->id) {
        case CODEC_ID_PCM_S16LE:
        case CODEC_ID_PCM_S16BE:
        case CODEC_ID_PCM_U16LE:
        case CODEC_ID_PCM_U16BE:
            break;
        default:
            size_out = size_out >> 1;
            break;
        }
        ret = avcodec_encode_audio(enc, audio_out, size_out, 
                                   (short *)buftmp);
348
        s->oformat->write_packet(s, ost->index, audio_out, ret, 0);
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
349 350 351 352
    }
}

/* write a picture to a raw mux */
353 354
static void write_picture(AVFormatContext *s, int index, AVPicture *picture, 
                          int pix_fmt, int w, int h)
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
355 356 357
{
    UINT8 *buf, *src, *dest;
    int size, j, i;
358

Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
359 360
    /* XXX: not efficient, should add test if we can take
       directly the AVPicture */
361 362
    switch(pix_fmt) {
    case PIX_FMT_YUV420P:
363
        size = avpicture_get_size(pix_fmt, w, h);
Fabrice Bellard's avatar
Fabrice Bellard committed
364
        buf = av_malloc(size);
365 366
        if (!buf)
            return;
367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382
        dest = buf;
        for(i=0;i<3;i++) {
            if (i == 1) {
                w >>= 1;
                h >>= 1;
            }
            src = picture->data[i];
            for(j=0;j<h;j++) {
                memcpy(dest, src, w);
                dest += w;
                src += picture->linesize[i];
            }
        }
        break;
    case PIX_FMT_YUV422P:
        size = (w * h) * 2; 
Fabrice Bellard's avatar
Fabrice Bellard committed
383
        buf = av_malloc(size);
384 385
        if (!buf)
            return;
386 387 388 389 390 391 392 393 394 395 396 397 398 399 400
        dest = buf;
        for(i=0;i<3;i++) {
            if (i == 1) {
                w >>= 1;
            }
            src = picture->data[i];
            for(j=0;j<h;j++) {
                memcpy(dest, src, w);
                dest += w;
                src += picture->linesize[i];
            }
        }
        break;
    case PIX_FMT_YUV444P:
        size = (w * h) * 3; 
Fabrice Bellard's avatar
Fabrice Bellard committed
401
        buf = av_malloc(size);
402 403
        if (!buf)
            return;
404 405 406 407 408 409 410 411 412 413 414 415
        dest = buf;
        for(i=0;i<3;i++) {
            src = picture->data[i];
            for(j=0;j<h;j++) {
                memcpy(dest, src, w);
                dest += w;
                src += picture->linesize[i];
            }
        }
        break;
    case PIX_FMT_YUV422:
        size = (w * h) * 2; 
Fabrice Bellard's avatar
Fabrice Bellard committed
416
        buf = av_malloc(size);
417 418
        if (!buf)
            return;
419 420 421 422 423 424
        dest = buf;
        src = picture->data[0];
        for(j=0;j<h;j++) {
            memcpy(dest, src, w * 2);
            dest += w * 2;
            src += picture->linesize[0];
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
425
        }
426 427 428 429
        break;
    case PIX_FMT_RGB24:
    case PIX_FMT_BGR24:
        size = (w * h) * 3; 
Fabrice Bellard's avatar
Fabrice Bellard committed
430
        buf = av_malloc(size);
431 432
        if (!buf)
            return;
433 434
        dest = buf;
        src = picture->data[0];
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
435
        for(j=0;j<h;j++) {
436 437 438
            memcpy(dest, src, w * 3);
            dest += w * 3;
            src += picture->linesize[0];
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
439
        }
440 441 442
        break;
    default:
        return;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
443
    }
444
    s->oformat->write_packet(s, index, buf, size, 0);
Fabrice Bellard's avatar
Fabrice Bellard committed
445
    av_free(buf);
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
446 447 448 449 450 451
}


static void do_video_out(AVFormatContext *s, 
                         AVOutputStream *ost, 
                         AVInputStream *ist,
452 453
                         AVPicture *picture1,
                         int *frame_size)
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
454
{
455
    int n1, n2, nb, i, ret, frame_number, dec_frame_rate;
456 457
    AVPicture *picture, *picture2, *pict;
    AVPicture picture_tmp1, picture_tmp2;
458
    static UINT8 *video_buffer;
459 460
    UINT8 *buf = NULL, *buf1 = NULL;
    AVCodecContext *enc, *dec;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
461

Michael Niedermayer's avatar
Michael Niedermayer committed
462 463
#define VIDEO_BUFFER_SIZE (1024*1024)

Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
464
    enc = &ost->st->codec;
465
    dec = &ist->st->codec;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
466 467

    frame_number = ist->frame_number;
468
    dec_frame_rate = ist->st->r_frame_rate;
469
    //    fprintf(stderr, "\n%d", dec_frame_rate);
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
470
    /* first drop frame if needed */
471 472
    n1 = ((INT64)frame_number * enc->frame_rate) / dec_frame_rate;
    n2 = (((INT64)frame_number + 1) * enc->frame_rate) / dec_frame_rate;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
473
    nb = n2 - n1;
474
    if (nb <= 0) 
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
475
        return;
476

477 478
    if (!video_buffer)
        video_buffer= av_malloc(VIDEO_BUFFER_SIZE);
479 480
    if(!video_buffer) return;

481 482 483 484 485 486
    /* deinterlace : must be done before any resize */
    if (do_deinterlace) {
        int size;

        /* create temporary picture */
        size = avpicture_get_size(dec->pix_fmt, dec->width, dec->height);
Fabrice Bellard's avatar
Fabrice Bellard committed
487
        buf1 = av_malloc(size);
488 489 490 491 492 493 494 495 496
        if (!buf1)
            return;
        
        picture2 = &picture_tmp2;
        avpicture_fill(picture2, buf1, dec->pix_fmt, dec->width, dec->height);

        if (avpicture_deinterlace(picture2, picture1, 
                                  dec->pix_fmt, dec->width, dec->height) < 0) {
            /* if error, do not deinterlace */
Fabrice Bellard's avatar
Fabrice Bellard committed
497
            av_free(buf1);
498 499 500 501 502 503 504 505 506 507 508 509 510
            buf1 = NULL;
            picture2 = picture1;
        }
    } else {
        picture2 = picture1;
    }

    /* convert pixel format if needed */
    if (enc->pix_fmt != dec->pix_fmt) {
        int size;

        /* create temporary picture */
        size = avpicture_get_size(enc->pix_fmt, dec->width, dec->height);
Fabrice Bellard's avatar
Fabrice Bellard committed
511
        buf = av_malloc(size);
512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529
        if (!buf)
            return;
        pict = &picture_tmp1;
        avpicture_fill(pict, buf, enc->pix_fmt, dec->width, dec->height);
        
        if (img_convert(pict, enc->pix_fmt, 
                        picture2, dec->pix_fmt, 
                        dec->width, dec->height) < 0) {
            fprintf(stderr, "pixel format conversion not handled\n");
            goto the_end;
        }
    } else {
        pict = picture2;
    }

    /* XXX: resampling could be done before raw format convertion in
       some cases to go faster */
    /* XXX: only works for YUV420P */
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
530 531 532 533 534 535
    if (ost->video_resample) {
        picture = &ost->pict_tmp;
        img_resample(ost->img_resample_ctx, picture, pict);
    } else {
        picture = pict;
    }
536
    nb=1;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
537 538 539 540 541 542 543
    /* duplicates frame if needed */
    /* XXX: pb because no interleaving */
    for(i=0;i<nb;i++) {
        if (enc->codec_id != CODEC_ID_RAWVIDEO) {
            /* handles sameq here. This is not correct because it may
               not be a global option */
            if (same_quality) {
544
                enc->quality = dec->quality;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
545
            }
546
            
547
            ret = avcodec_encode_video(enc, 
Michael Niedermayer's avatar
Michael Niedermayer committed
548
                                       video_buffer, VIDEO_BUFFER_SIZE,
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
549
                                       picture);
550
            //enc->frame_number = enc->real_pict_num;
551
            s->oformat->write_packet(s, ost->index, video_buffer, ret, 0);
552
            *frame_size = ret;
Juanjo's avatar
Juanjo committed
553
            //fprintf(stderr,"\nFrame: %3d %3d size: %5d type: %d",
554
            //        enc->frame_number-1, enc->real_pict_num, ret,
Juanjo's avatar
Juanjo committed
555
            //        enc->pict_type);
556 557 558 559
            /* if two pass, output log */
            if (ost->logfile && enc->stats_out) {
                fprintf(ost->logfile, "%s", enc->stats_out);
            }
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
560
        } else {
Fabrice Bellard's avatar
Fabrice Bellard committed
561 562 563 564 565 566 567 568 569
            if (s->oformat->flags & AVFMT_RAWPICTURE) {
                /* raw pictures are written as AVPicture structure to
                   avoid any copies. We support temorarily the older
                   method. */
                s->oformat->write_packet(s, ost->index, 
                                         (UINT8 *)picture, sizeof(AVPicture), 0);
            } else {
                write_picture(s, ost->index, picture, enc->pix_fmt, enc->width, enc->height);
            }
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
570 571
        }
    }
572
    the_end:
Fabrice Bellard's avatar
Fabrice Bellard committed
573 574
    av_free(buf);
    av_free(buf1);
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
575 576
}

577 578 579 580 581 582 583
static void do_video_stats(AVOutputStream *ost, 
                         AVInputStream *ist,
                         int frame_size)
{
    static FILE *fvstats=NULL;
    static INT64 total_size = 0;
    char filename[40];
584 585
    time_t today2;
    struct tm *today;
586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632
    AVCodecContext *enc;
    int frame_number;
    INT64 ti;
    double ti1, bitrate, avg_bitrate;
    
    if (!fvstats) {
        today2 = time(NULL);
        today = localtime(&today2);
        sprintf(filename, "vstats_%02d%02d%02d.log", today->tm_hour,
                                               today->tm_min,
                                               today->tm_sec);
        fvstats = fopen(filename,"w");
        if (!fvstats) {
            perror("fopen");
            exit(1);
        }
    }
    
    ti = MAXINT64;
    enc = &ost->st->codec;
    total_size += frame_size;
    if (enc->codec_type == CODEC_TYPE_VIDEO) {
        frame_number = ist->frame_number;
        fprintf(fvstats, "frame= %5d q= %2d ", frame_number, enc->quality);
        if (do_psnr)
            fprintf(fvstats, "PSNR= %6.2f ", enc->psnr_y);
        
        fprintf(fvstats,"f_size= %6d ", frame_size);
        /* compute min pts value */
        if (!ist->discard && ist->pts < ti) {
            ti = ist->pts;
        }
        ti1 = (double)ti / 1000000.0;
        if (ti1 < 0.01)
            ti1 = 0.01;
    
        bitrate = (double)(frame_size * 8) * enc->frame_rate / FRAME_RATE_BASE / 1000.0;
        avg_bitrate = (double)(total_size * 8) / ti1 / 1000.0;
        fprintf(fvstats, "s_size= %8.0fkB time= %0.3f br= %7.1fkbits/s avg_br= %7.1fkbits/s ",
            (double)total_size / 1024, ti1, bitrate, avg_bitrate);
        fprintf(fvstats,"type= %s\n", enc->key_frame == 1 ? "I" : "P");        
    }

    
    
}

Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
633 634 635 636 637 638 639 640 641
/*
 * The following code is the main loop of the file converter
 */
static int av_encode(AVFormatContext **output_files,
                     int nb_output_files,
                     AVFormatContext **input_files,
                     int nb_input_files,
                     AVStreamMap *stream_maps, int nb_stream_maps)
{
Fabrice Bellard's avatar
Fabrice Bellard committed
642
    int ret, i, j, k, n, nb_istreams = 0, nb_ostreams = 0;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
643 644 645 646 647
    AVFormatContext *is, *os;
    AVCodecContext *codec, *icodec;
    AVOutputStream *ost, **ost_table = NULL;
    AVInputStream *ist, **ist_table = NULL;
    INT64 min_pts, start_time;
Fabrice Bellard's avatar
Fabrice Bellard committed
648
    AVInputFile *file_table;
649
    AVFormatContext *stream_no_data;
650
    int key;
Fabrice Bellard's avatar
Fabrice Bellard committed
651

652
    file_table= (AVInputFile*) av_mallocz(nb_input_files * sizeof(AVInputFile));
Fabrice Bellard's avatar
Fabrice Bellard committed
653 654
    if (!file_table)
        goto fail;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
655 656 657 658 659 660

    /* input stream init */
    j = 0;
    for(i=0;i<nb_input_files;i++) {
        is = input_files[i];
        file_table[i].ist_index = j;
661
        file_table[i].nb_streams = is->nb_streams;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
662 663 664 665 666 667
        j += is->nb_streams;
    }
    nb_istreams = j;

    ist_table = av_mallocz(nb_istreams * sizeof(AVInputStream *));
    if (!ist_table)
Fabrice Bellard's avatar
Fabrice Bellard committed
668
        goto fail;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762
    
    for(i=0;i<nb_istreams;i++) {
        ist = av_mallocz(sizeof(AVInputStream));
        if (!ist)
            goto fail;
        ist_table[i] = ist;
    }
    j = 0;
    for(i=0;i<nb_input_files;i++) {
        is = input_files[i];
        for(k=0;k<is->nb_streams;k++) {
            ist = ist_table[j++];
            ist->st = is->streams[k];
            ist->file_index = i;
            ist->index = k;
            ist->discard = 1; /* the stream is discarded by default
                                 (changed later) */
        }
    }

    /* output stream init */
    nb_ostreams = 0;
    for(i=0;i<nb_output_files;i++) {
        os = output_files[i];
        nb_ostreams += os->nb_streams;
    }
    if (nb_stream_maps > 0 && nb_stream_maps != nb_ostreams) {
        fprintf(stderr, "Number of stream maps must match number of output streams\n");
        exit(1);
    }

    ost_table = av_mallocz(sizeof(AVOutputStream *) * nb_ostreams);
    if (!ost_table)
        goto fail;
    for(i=0;i<nb_ostreams;i++) {
        ost = av_mallocz(sizeof(AVOutputStream));
        if (!ost)
            goto fail;
        ost_table[i] = ost;
    }
    
    n = 0;
    for(k=0;k<nb_output_files;k++) {
        os = output_files[k];
        for(i=0;i<os->nb_streams;i++) {
            int found;
            ost = ost_table[n++];
            ost->file_index = k;
            ost->index = i;
            ost->st = os->streams[i];
            if (nb_stream_maps > 0) {
                ost->source_index = file_table[stream_maps[n-1].file_index].ist_index + 
                    stream_maps[n-1].stream_index;
            } else {
                /* get corresponding input stream index : we select the first one with the right type */
                found = 0;
                for(j=0;j<nb_istreams;j++) {
                    ist = ist_table[j];
                    if (ist->discard && 
                        ist->st->codec.codec_type == ost->st->codec.codec_type) {
                        ost->source_index = j;
                        found = 1;
                    }
                }
                
                if (!found) {
                    /* try again and reuse existing stream */
                    for(j=0;j<nb_istreams;j++) {
                        ist = ist_table[j];
                        if (ist->st->codec.codec_type == ost->st->codec.codec_type) {
                            ost->source_index = j;
                            found = 1;
                        }
                    }
                    if (!found) {
                        fprintf(stderr, "Could not find input stream matching output stream #%d.%d\n",
                                ost->file_index, ost->index);
                        exit(1);
                    }
                }
            }
            ist = ist_table[ost->source_index];
            ist->discard = 0;
        }
    }

    /* for each output stream, we compute the right encoding parameters */
    for(i=0;i<nb_ostreams;i++) {
        ost = ost_table[i];
        ist = ist_table[ost->source_index];

        codec = &ost->st->codec;
        icodec = &ist->st->codec;

763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784
        if (ost->st->stream_copy) {
            /* if stream_copy is selected, no need to decode or encode */
            codec->codec_id = icodec->codec_id;
            codec->codec_type = icodec->codec_type;
            codec->codec_tag = icodec->codec_tag;
            codec->bit_rate = icodec->bit_rate;
            switch(codec->codec_type) {
            case CODEC_TYPE_AUDIO:
                codec->sample_rate = icodec->sample_rate;
                codec->channels = icodec->channels;
                break;
            case CODEC_TYPE_VIDEO:
                codec->frame_rate = icodec->frame_rate;
                codec->width = icodec->width;
                codec->height = icodec->height;
                break;
            default:
                av_abort();
            }
        } else {
            switch(codec->codec_type) {
            case CODEC_TYPE_AUDIO:
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
785 786
                if (fifo_init(&ost->fifo, 2 * MAX_AUDIO_PACKET_SIZE))
                    goto fail;
787
                
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
788 789 790 791
                if (codec->channels == icodec->channels &&
                    codec->sample_rate == icodec->sample_rate) {
                    ost->audio_resample = 0;
                } else {
792 793 794 795
                    if (codec->channels != icodec->channels &&
                        icodec->codec_id == CODEC_ID_AC3) {
                        /* Special case for 5:1 AC3 input */
                        /* and mono or stereo output      */
796 797 798 799 800 801 802 803 804 805
                        /* Request specific number of channels */
                        icodec->channels = codec->channels;
                        if (codec->sample_rate == icodec->sample_rate)
                            ost->audio_resample = 0;
                        else {
                            ost->audio_resample = 1;
                            ost->resample = audio_resample_init(codec->channels, icodec->channels,
                                                        codec->sample_rate, 
                                                        icodec->sample_rate);
                        }
806 807 808 809 810
                        /* Request specific number of channels */
                        icodec->channels = codec->channels;
                    } else {
                        ost->audio_resample = 1; 
                        ost->resample = audio_resample_init(codec->channels, icodec->channels,
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
811 812
                                                        codec->sample_rate, 
                                                        icodec->sample_rate);
813
                    }
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
814 815 816
                }
                ist->decoding_needed = 1;
                ost->encoding_needed = 1;
817 818
                break;
            case CODEC_TYPE_VIDEO:
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
819 820 821 822 823 824
                if (codec->width == icodec->width &&
                    codec->height == icodec->height) {
                    ost->video_resample = 0;
                } else {
                    UINT8 *buf;
                    ost->video_resample = 1;
Fabrice Bellard's avatar
Fabrice Bellard committed
825
                    buf = av_malloc((codec->width * codec->height * 3) / 2);
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
826 827 828 829 830 831 832 833 834
                    if (!buf)
                        goto fail;
                    ost->pict_tmp.data[0] = buf;
                    ost->pict_tmp.data[1] = ost->pict_tmp.data[0] + (codec->width * codec->height);
                    ost->pict_tmp.data[2] = ost->pict_tmp.data[1] + (codec->width * codec->height) / 4;
                    ost->pict_tmp.linesize[0] = codec->width;
                    ost->pict_tmp.linesize[1] = codec->width / 2;
                    ost->pict_tmp.linesize[2] = codec->width / 2;

835
                    ost->img_resample_ctx = img_resample_full_init( 
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
836
                                      ost->st->codec.width, ost->st->codec.height,
837 838 839
                                      ist->st->codec.width, ist->st->codec.height,
                                      frame_topBand, frame_bottomBand,
                                      frame_leftBand, frame_rightBand);
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
840 841 842
                }
                ost->encoding_needed = 1;
                ist->decoding_needed = 1;
843 844 845
                break;
            default:
                av_abort();
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
846
            }
847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883
            /* two pass mode */
            if (ost->encoding_needed && 
                (codec->flags & (CODEC_FLAG_PASS1 | CODEC_FLAG_PASS2))) {
                char logfilename[1024];
                FILE *f;
                int size;
                char *logbuffer;
                
                snprintf(logfilename, sizeof(logfilename), "%s-%d.log", 
                         pass_logfilename ? 
                         pass_logfilename : DEFAULT_PASS_LOGFILENAME, i);
                if (codec->flags & CODEC_FLAG_PASS1) {
                    f = fopen(logfilename, "w");
                    if (!f) {
                        perror(logfilename);
                        exit(1);
                    }
                    ost->logfile = f;
                } else {
                    /* read the log file */
                    f = fopen(logfilename, "r");
                    if (!f) {
                        perror(logfilename);
                        exit(1);
                    }
                    fseek(f, 0, SEEK_END);
                    size = ftell(f);
                    fseek(f, 0, SEEK_SET);
                    logbuffer = av_malloc(size + 1);
                    if (!logbuffer) {
                        fprintf(stderr, "Could not allocate log buffer\n");
                        exit(1);
                    }
                    fread(logbuffer, 1, size, f);
                    fclose(f);
                    logbuffer[size] = '\0';
                    codec->stats_in = logbuffer;
884 885 886
                }
            }
        }
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
887 888
    }

889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905
    /* dump the file output parameters - cannot be done before in case
       of stream copy */
    for(i=0;i<nb_output_files;i++) {
        dump_format(output_files[i], i, output_files[i]->filename, 1);
    }

    /* dump the stream mapping */
    fprintf(stderr, "Stream mapping:\n");
    for(i=0;i<nb_ostreams;i++) {
        ost = ost_table[i];
        fprintf(stderr, "  Stream #%d.%d -> #%d.%d\n",
                ist_table[ost->source_index]->file_index,
                ist_table[ost->source_index]->index,
                ost->file_index, 
                ost->index);
    }

Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940
    /* open each encoder */
    for(i=0;i<nb_ostreams;i++) {
        ost = ost_table[i];
        if (ost->encoding_needed) {
            AVCodec *codec;
            codec = avcodec_find_encoder(ost->st->codec.codec_id);
            if (!codec) {
                fprintf(stderr, "Unsupported codec for output stream #%d.%d\n", 
                        ost->file_index, ost->index);
                exit(1);
            }
            if (avcodec_open(&ost->st->codec, codec) < 0) {
                fprintf(stderr, "Error while opening codec for stream #%d.%d - maybe incorrect parameters such as bit_rate, rate, width or height\n", 
                        ost->file_index, ost->index);
                exit(1);
            }
        }
    }

    /* open each decoder */
    for(i=0;i<nb_istreams;i++) {
        ist = ist_table[i];
        if (ist->decoding_needed) {
            AVCodec *codec;
            codec = avcodec_find_decoder(ist->st->codec.codec_id);
            if (!codec) {
                fprintf(stderr, "Unsupported codec for input stream #%d.%d\n", 
                        ist->file_index, ist->index);
                exit(1);
            }
            if (avcodec_open(&ist->st->codec, codec) < 0) {
                fprintf(stderr, "Error while opening codec for input stream #%d.%d\n", 
                        ist->file_index, ist->index);
                exit(1);
            }
941 942
            //if (ist->st->codec.codec_type == CODEC_TYPE_VIDEO)
            //    ist->st->codec.flags |= CODEC_FLAG_REPEAT_FIELD;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960
        }
    }

    /* init pts */
    for(i=0;i<nb_istreams;i++) {
        ist = ist_table[i];
        ist->pts = 0;
        ist->frame_number = 0;
    }
    
    /* compute buffer size max (should use a complete heuristic) */
    for(i=0;i<nb_input_files;i++) {
        file_table[i].buffer_size_max = 2048;
    }

    /* open files and write file headers */
    for(i=0;i<nb_output_files;i++) {
        os = output_files[i];
961
        if (av_write_header(os) < 0) {
962 963 964 965
            fprintf(stderr, "Could not write header for output file #%d (incorrect codec paramters ?)\n", i);
            ret = -EINVAL;
            goto fail;
        }
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
966 967
    }

968 969 970 971 972 973 974 975 976
#ifndef CONFIG_WIN32
    if (!do_play) {
        fprintf(stderr, "Press [q] to stop encoding\n");
    } else {
        fprintf(stderr, "Press [q] to stop playing\n");
    }
#endif
    term_init();

977
    start_time = av_gettime();
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
978
    min_pts = 0;
979
    stream_no_data = 0;
980
    key = -1;
981

Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
982 983 984 985 986 987 988 989 990 991 992
    for(;;) {
        int file_index, ist_index;
        AVPacket pkt;
        UINT8 *ptr;
        int len;
        UINT8 *data_buf;
        int data_size, got_picture;
        AVPicture picture;
        short samples[AVCODEC_MAX_AUDIO_FRAME_SIZE / 2];

    redo:
993
        /* if 'q' pressed, exits */
994 995 996 997 998 999
        if (key) {
            /* read_key() returns 0 on EOF */
            key = read_key();
            if (key == 'q')
                break;
        }
1000 1001

        /* select the input file with the smallest pts */
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
1002
        file_index = -1;
Fabrice Bellard's avatar
Fabrice Bellard committed
1003
        min_pts = MAXINT64;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
1004 1005
        for(i=0;i<nb_istreams;i++) {
            ist = ist_table[i];
1006 1007 1008 1009
            /* For some reason, the pts_increment code breaks q estimation?!? */
            if (!ist->discard && !file_table[ist->file_index].eof_reached && 
                ist->pts /* + ist->pts_increment */ < min_pts && input_files[ist->file_index] != stream_no_data) {
                min_pts = ist->pts /* + ist->pts_increment */;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
1010 1011 1012 1013
                file_index = ist->file_index;
            }
        }
        /* if none, if is finished */
1014 1015
        if (file_index < 0) {
            if (stream_no_data) {
1016 1017 1018 1019 1020 1021
#ifndef CONFIG_WIN32 /* no usleep in VisualC ? */
#ifdef __BEOS__
                snooze(10 * 1000); /* mmu_man */ /* in microsec */
#elif defined(__CYGWIN__)
                usleep(10 * 1000); 
#else
1022 1023 1024 1025 1026
                struct timespec ts;

                ts.tv_sec = 0;
                ts.tv_nsec = 1000 * 1000 * 10;
                nanosleep(&ts, 0);
1027
#endif
1028
#endif
1029 1030 1031
                stream_no_data = 0;
                continue;
            }
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
1032
            break;
1033
        }    
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
1034 1035 1036 1037 1038 1039 1040 1041 1042
        /* finish if recording time exhausted */
        if (recording_time > 0 && min_pts >= recording_time)
            break;
        /* read a packet from it and output it in the fifo */
        is = input_files[file_index];
        if (av_read_packet(is, &pkt) < 0) {
            file_table[file_index].eof_reached = 1;
            continue;
        }
1043 1044 1045 1046 1047
        if (!pkt.size) {
            stream_no_data = is;
        } else {
            stream_no_data = 0;
        }
1048 1049 1050
        /* the following test is needed in case new streams appear
           dynamically in stream : we ignore them */
        if (pkt.stream_index >= file_table[file_index].nb_streams)
1051
            goto discard_packet;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
1052 1053
        ist_index = file_table[file_index].ist_index + pkt.stream_index;
        ist = ist_table[ist_index];
1054 1055
        if (ist->discard)
            goto discard_packet;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
1056

1057 1058 1059
        if (pkt.flags & PKT_FLAG_DROPPED_FRAME)
            ist->frame_number++;

1060 1061
        if (do_hex_dump) {
            printf("stream #%d, size=%d:\n", pkt.stream_index, pkt.size);
1062
            av_hex_dump(pkt.data, pkt.size);
1063
        }
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076

        //        printf("read #%d.%d size=%d\n", ist->file_index, ist->index, pkt.size);

        len = pkt.size;
        ptr = pkt.data;
        while (len > 0) {

            /* decode the packet if needed */
            data_buf = NULL; /* fail safe */
            data_size = 0;
            if (ist->decoding_needed) {
                switch(ist->st->codec.codec_type) {
                case CODEC_TYPE_AUDIO:
1077 1078 1079 1080 1081 1082
                    /* XXX: could avoid copy if PCM 16 bits with same
                       endianness as CPU */
                    ret = avcodec_decode_audio(&ist->st->codec, samples, &data_size,
                                               ptr, len);
                    if (ret < 0)
                        goto fail_decode;
1083 1084 1085
                    /* Some bug in mpeg audio decoder gives */
                    /* data_size < 0, it seems they are overflows */
                    if (data_size <= 0) {
1086 1087 1088 1089
                        /* no audio frame */
                        ptr += ret;
                        len -= ret;
                        continue;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
1090
                    }
1091
                    data_buf = (UINT8 *)samples;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
1092 1093 1094 1095
                    break;
                case CODEC_TYPE_VIDEO:
                    if (ist->st->codec.codec_id == CODEC_ID_RAWVIDEO) {
                        int size;
1096

Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
1097
                        size = (ist->st->codec.width * ist->st->codec.height);
1098 1099 1100 1101
                        avpicture_fill(&picture, ptr, 
                                     ist->st->codec.pix_fmt,
                                     ist->st->codec.width,
                                     ist->st->codec.height);
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119
                        ret = len;
                    } else {
                        data_size = (ist->st->codec.width * ist->st->codec.height * 3) / 2;
                        ret = avcodec_decode_video(&ist->st->codec, 
                                                   &picture, &got_picture, ptr, len);
                        if (ret < 0) {
                        fail_decode:
                            fprintf(stderr, "Error while decoding stream #%d.%d\n",
                                    ist->file_index, ist->index);
                            av_free_packet(&pkt);
                            goto redo;
                        }
                        if (!got_picture) {
                            /* no picture yet */
                            ptr += ret;
                            len -= ret;
                            continue;
                        }
1120
                                  
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
1121 1122 1123 1124 1125 1126 1127 1128 1129 1130
                    }
                    break;
                default:
                    goto fail_decode;
                }
            } else {
                data_buf = ptr;
                data_size = len;
                ret = len;
            }
1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146
            /* init tickers */
            if (!ist->ticker_inited) {
                switch (ist->st->codec.codec_type) {
                case CODEC_TYPE_AUDIO:
                    ticker_init(&ist->pts_ticker,
                            (INT64)ist->st->codec.sample_rate,
                            (INT64)(1000000));
                    ist->ticker_inited = 1;
                    break;
                case CODEC_TYPE_VIDEO:
                    ticker_init(&ist->pts_ticker,
                            (INT64)ist->st->r_frame_rate,
                            ((INT64)1000000 * FRAME_RATE_BASE));
                    ist->ticker_inited = 1;
                    break;
                default:
1147
                    av_abort();
1148 1149
                }
            }
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
1150 1151 1152
            /* update pts */
            switch(ist->st->codec.codec_type) {
            case CODEC_TYPE_AUDIO:
1153
                //ist->pts = (INT64)1000000 * ist->sample_index / ist->st->codec.sample_rate;
1154
                ist->pts = ticker_abs(&ist->pts_ticker, ist->sample_index);
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
1155
                ist->sample_index += data_size / (2 * ist->st->codec.channels);
1156
                ist->pts_increment = (INT64) (data_size / (2 * ist->st->codec.channels)) * 1000000 / ist->st->codec.sample_rate;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
1157 1158 1159
                break;
            case CODEC_TYPE_VIDEO:
                ist->frame_number++;
1160 1161
                //ist->pts = ((INT64)ist->frame_number * 1000000 * FRAME_RATE_BASE) / 
                //    ist->st->codec.frame_rate;
1162
                ist->pts = ticker_abs(&ist->