avconv.c 162 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
/*
 * avconv main
 * Copyright (c) 2000-2011 The libav developers.
 *
 * This file is part of Libav.
 *
 * Libav 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.1 of the License, or (at your option) any later version.
 *
 * Libav is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with Libav; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include "config.h"
#include <ctype.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <errno.h>
#include <signal.h>
#include <limits.h>
#include <unistd.h>
#include "libavformat/avformat.h"
#include "libavdevice/avdevice.h"
#include "libswscale/swscale.h"
#include "libavutil/opt.h"
#include "libavcodec/audioconvert.h"
#include "libavutil/audioconvert.h"
#include "libavutil/parseutils.h"
#include "libavutil/samplefmt.h"
#include "libavutil/colorspace.h"
#include "libavutil/fifo.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/dict.h"
#include "libavutil/mathematics.h"
#include "libavutil/pixdesc.h"
#include "libavutil/avstring.h"
#include "libavutil/libm.h"
47
#include "libavutil/imgutils.h"
48 49 50 51 52
#include "libavformat/os_support.h"

#if CONFIG_AVFILTER
# include "libavfilter/avfilter.h"
# include "libavfilter/avfiltergraph.h"
53
# include "libavfilter/buffersrc.h"
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
# include "libavfilter/vsrc_buffer.h"
#endif

#if HAVE_SYS_RESOURCE_H
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
#elif HAVE_GETPROCESSTIMES
#include <windows.h>
#endif
#if HAVE_GETPROCESSMEMORYINFO
#include <windows.h>
#include <psapi.h>
#endif

#if HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif

#include <time.h>

#include "cmdutils.h"

#include "libavutil/avassert.h"

79 80 81 82 83
#define VSYNC_AUTO       -1
#define VSYNC_PASSTHROUGH 0
#define VSYNC_CFR         1
#define VSYNC_VFR         2

84 85 86 87 88
const char program_name[] = "avconv";
const int program_birth_year = 2000;

/* select an input stream for an output stream */
typedef struct StreamMap {
89
    int disabled;           /** 1 is this mapping is disabled by a negative map */
90 91 92 93 94 95 96 97 98 99
    int file_index;
    int stream_index;
    int sync_file_index;
    int sync_stream_index;
} StreamMap;

/**
 * select an input file for an output file
 */
typedef struct MetadataMap {
100 101 102
    int  file;      ///< file index
    char type;      ///< type of metadata to copy -- (g)lobal, (s)tream, (c)hapter or (p)rogram
    int  index;     ///< stream/chapter/program number
103 104 105 106 107
} MetadataMap;

static const OptionDef options[];

static int video_discard = 0;
108
static int same_quant = 0;
109 110 111 112 113 114 115 116 117 118
static int do_deinterlace = 0;
static int intra_dc_precision = 8;
static int qp_hist = 0;

static int file_overwrite = 0;
static int do_benchmark = 0;
static int do_hex_dump = 0;
static int do_pkt_dump = 0;
static int do_pass = 0;
static char *pass_logfilename_prefix = NULL;
119
static int video_sync_method = VSYNC_AUTO;
Aneesh Dogra's avatar
Aneesh Dogra committed
120 121 122
static int audio_sync_method = 0;
static float audio_drift_threshold = 0.1;
static int copy_ts = 0;
123
static int copy_tb = 1;
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
static int opt_shortest = 0;
static char *vstats_filename;
static FILE *vstats_file;

static int audio_volume = 256;

static int exit_on_error = 0;
static int using_stdin = 0;
static int64_t video_size = 0;
static int64_t audio_size = 0;
static int64_t extra_size = 0;
static int nb_frames_dup = 0;
static int nb_frames_drop = 0;
static int input_sync;

static float dts_delta_threshold = 10;

141 142
static int print_stats = 1;

143 144 145 146 147 148
static uint8_t *audio_buf;
static uint8_t *audio_out;
static unsigned int allocated_audio_out_size, allocated_audio_buf_size;

#define DEFAULT_PASS_LOGFILENAME_PREFIX "av2pass"

149 150 151 152 153 154 155 156 157 158 159 160 161
typedef struct FrameBuffer {
    uint8_t *base[4];
    uint8_t *data[4];
    int  linesize[4];

    int h, w;
    enum PixelFormat pix_fmt;

    int refcount;
    struct InputStream *ist;
    struct FrameBuffer *next;
} FrameBuffer;

162 163 164 165 166 167
typedef struct InputStream {
    int file_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' */
    AVCodec *dec;
168 169
    AVFrame *decoded_frame;
    AVFrame *filtered_frame;
170 171 172 173 174 175 176 177 178 179

    int64_t       start;     /* time when read started */
    int64_t       next_pts;  /* synthetic pts for cases where pkt.pts
                                is not defined */
    int64_t       pts;       /* current pts */
    PtsCorrectionContext pts_ctx;
    double ts_scale;
    int is_start;            /* is 1 at the start and after a discontinuity */
    int showed_multi_packet_warning;
    AVDictionary *opts;
180 181 182

    /* a pool of free buffers for decoded data */
    FrameBuffer *buffer_pool;
183 184 185 186 187 188 189 190
} InputStream;

typedef struct InputFile {
    AVFormatContext *ctx;
    int eof_reached;      /* true if eof reached */
    int ist_index;        /* index of first stream in ist_table */
    int buffer_size;      /* current total buffer size */
    int64_t ts_offset;
191 192
    int nb_streams;       /* number of stream that avconv is aware of; may be different
                             from ctx.nb_streams if new streams appear during av_read_frame() */
193
    int rate_emu;
194
} InputFile;
195 196 197 198 199 200 201 202 203 204

typedef struct OutputStream {
    int file_index;          /* file index */
    int index;               /* stream index in the output file */
    int source_index;        /* InputStream index */
    AVStream *st;            /* stream in the output file */
    int encoding_needed;     /* true if encoding needed for this stream */
    int frame_number;
    /* input pts and corresponding output pts
       for A/V sync */
Aneesh Dogra's avatar
Aneesh Dogra committed
205
    // double sync_ipts;        /* dts from the AVPacket of the demuxer in second units */
206
    struct InputStream *sync_ist; /* input stream to sync against */
Aneesh Dogra's avatar
Aneesh Dogra committed
207
    int64_t sync_opts;       /* output frame counter, could be changed to some true timestamp */ // FIXME look at frame_number
208 209
    AVBitStreamFilterContext *bitstream_filters;
    AVCodec *enc;
210
    int64_t max_frames;
211 212 213 214 215 216 217 218 219

    /* video only */
    int video_resample;
    AVFrame pict_tmp;      /* temporary image for resampling */
    struct SwsContext *img_resample_ctx; /* for image resampling */
    int resample_height;
    int resample_width;
    int resample_pix_fmt;
    AVRational frame_rate;
220
    int force_fps;
221
    int top_field_first;
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248

    float frame_aspect_ratio;

    /* forced key frames */
    int64_t *forced_kf_pts;
    int forced_kf_count;
    int forced_kf_index;

    /* audio only */
    int audio_resample;
    ReSampleContext *resample; /* for audio resampling */
    int resample_sample_fmt;
    int resample_channels;
    int resample_sample_rate;
    int reformat_pair;
    AVAudioConvert *reformat_ctx;
    AVFifoBuffer *fifo;     /* for compression: one audio fifo per codec */
    FILE *logfile;

#if CONFIG_AVFILTER
    AVFilterContext *output_video_filter;
    AVFilterContext *input_video_filter;
    AVFilterBufferRef *picref;
    char *avfilter;
    AVFilterGraph *graph;
#endif

Anton Khirnov's avatar
Anton Khirnov committed
249 250 251 252 253 254
    int64_t sws_flags;
    AVDictionary *opts;
    int is_past_recording_time;
    int stream_copy;
    const char *attachment_filename;
    int copy_initial_nonkeyframes;
255 256 257
} OutputStream;


258 259 260
typedef struct OutputFile {
    AVFormatContext *ctx;
    AVDictionary *opts;
261
    int ost_index;       /* index of the first stream in output_streams */
262
    int64_t recording_time; /* desired length of the resulting file in microseconds */
263
    int64_t start_time;     /* start time in microseconds */
264
    uint64_t limit_filesize;
265 266
} OutputFile;

Aneesh Dogra's avatar
Aneesh Dogra committed
267
static InputStream *input_streams   = NULL;
268
static int         nb_input_streams = 0;
Aneesh Dogra's avatar
Aneesh Dogra committed
269
static InputFile   *input_files     = NULL;
270 271
static int         nb_input_files   = 0;

272 273
static OutputStream *output_streams = NULL;
static int        nb_output_streams = 0;
274 275 276
static OutputFile   *output_files   = NULL;
static int        nb_output_files   = 0;

277
typedef struct OptionsContext {
278 279
    /* input/output options */
    int64_t start_time;
280
    const char *format;
281

282 283
    SpecifierOpt *codec_names;
    int        nb_codec_names;
284 285
    SpecifierOpt *audio_channels;
    int        nb_audio_channels;
286 287
    SpecifierOpt *audio_sample_rate;
    int        nb_audio_sample_rate;
288 289
    SpecifierOpt *frame_rates;
    int        nb_frame_rates;
290 291
    SpecifierOpt *frame_sizes;
    int        nb_frame_sizes;
292 293
    SpecifierOpt *frame_pix_fmts;
    int        nb_frame_pix_fmts;
294

295 296
    /* input options */
    int64_t input_ts_offset;
297
    int rate_emu;
298

299 300
    SpecifierOpt *ts_scale;
    int        nb_ts_scale;
301 302
    SpecifierOpt *dump_attachment;
    int        nb_dump_attachment;
303

304 305 306
    /* output options */
    StreamMap *stream_maps;
    int     nb_stream_maps;
307 308 309 310 311 312
    /* first item specifies output metadata, second is input */
    MetadataMap (*meta_data_maps)[2];
    int nb_meta_data_maps;
    int metadata_global_manual;
    int metadata_streams_manual;
    int metadata_chapters_manual;
Anton Khirnov's avatar
Anton Khirnov committed
313 314
    const char **attachments;
    int       nb_attachments;
315

316 317
    int chapters_input_file;

318
    int64_t recording_time;
319
    uint64_t limit_filesize;
320 321
    float mux_preload;
    float mux_max_delay;
322

323 324 325 326 327
    int video_disable;
    int audio_disable;
    int subtitle_disable;
    int data_disable;

328 329 330 331
    /* indexed by output file stream index */
    int   *streamid_map;
    int nb_streamid_map;

332 333
    SpecifierOpt *metadata;
    int        nb_metadata;
334 335
    SpecifierOpt *max_frames;
    int        nb_max_frames;
336 337
    SpecifierOpt *bitstream_filters;
    int        nb_bitstream_filters;
338 339
    SpecifierOpt *codec_tags;
    int        nb_codec_tags;
340 341
    SpecifierOpt *sample_fmts;
    int        nb_sample_fmts;
342 343
    SpecifierOpt *qscale;
    int        nb_qscale;
344 345
    SpecifierOpt *forced_key_frames;
    int        nb_forced_key_frames;
346 347
    SpecifierOpt *force_fps;
    int        nb_force_fps;
348 349
    SpecifierOpt *frame_aspect_ratios;
    int        nb_frame_aspect_ratios;
350 351
    SpecifierOpt *rc_overrides;
    int        nb_rc_overrides;
352 353 354 355
    SpecifierOpt *intra_matrices;
    int        nb_intra_matrices;
    SpecifierOpt *inter_matrices;
    int        nb_inter_matrices;
356 357
    SpecifierOpt *top_field_first;
    int        nb_top_field_first;
358 359
    SpecifierOpt *metadata_map;
    int        nb_metadata_map;
Alexandra Khirnova's avatar
Alexandra Khirnova committed
360 361
    SpecifierOpt *presets;
    int        nb_presets;
362 363
    SpecifierOpt *copy_initial_nonkeyframes;
    int        nb_copy_initial_nonkeyframes;
Anton Khirnov's avatar
Anton Khirnov committed
364 365 366 367
#if CONFIG_AVFILTER
    SpecifierOpt *filters;
    int        nb_filters;
#endif
368 369
} OptionsContext;

370 371 372 373 374 375 376 377 378 379 380 381
#define MATCH_PER_STREAM_OPT(name, type, outvar, fmtctx, st)\
{\
    int i, ret;\
    for (i = 0; i < o->nb_ ## name; i++) {\
        char *spec = o->name[i].specifier;\
        if ((ret = check_stream_specifier(fmtctx, st, spec)) > 0)\
            outvar = o->name[i].u.type;\
        else if (ret < 0)\
            exit_program(1);\
    }\
}

382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405
static void reset_options(OptionsContext *o)
{
    const OptionDef *po = options;

    /* all OPT_SPEC and OPT_STRING can be freed in generic way */
    while (po->name) {
        void *dst = (uint8_t*)o + po->u.off;

        if (po->flags & OPT_SPEC) {
            SpecifierOpt **so = dst;
            int i, *count = (int*)(so + 1);
            for (i = 0; i < *count; i++) {
                av_freep(&(*so)[i].specifier);
                if (po->flags & OPT_STRING)
                    av_freep(&(*so)[i].u.str);
            }
            av_freep(so);
            *count = 0;
        } else if (po->flags & OPT_OFFSET && po->flags & OPT_STRING)
            av_freep(dst);
        po++;
    }

    av_freep(&o->stream_maps);
406
    av_freep(&o->meta_data_maps);
407
    av_freep(&o->streamid_map);
408 409

    memset(o, 0, sizeof(*o));
410

411
    o->mux_max_delay  = 0.7;
412
    o->recording_time = INT64_MAX;
413
    o->limit_filesize = UINT64_MAX;
414
    o->chapters_input_file = INT_MAX;
415

416 417 418 419
    uninit_opts();
    init_opts();
}

420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 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
static int alloc_buffer(InputStream *ist, FrameBuffer **pbuf)
{
    AVCodecContext *s = ist->st->codec;
    FrameBuffer  *buf = av_mallocz(sizeof(*buf));
    int ret;
    const int pixel_size = av_pix_fmt_descriptors[s->pix_fmt].comp[0].step_minus1+1;
    int h_chroma_shift, v_chroma_shift;
    int edge = 32; // XXX should be avcodec_get_edge_width(), but that fails on svq1
    int w = s->width, h = s->height;

    if (!buf)
        return AVERROR(ENOMEM);

    if (!(s->flags & CODEC_FLAG_EMU_EDGE)) {
        w += 2*edge;
        h += 2*edge;
    }

    avcodec_align_dimensions(s, &w, &h);
    if ((ret = av_image_alloc(buf->base, buf->linesize, w, h,
                              s->pix_fmt, 32)) < 0) {
        av_freep(&buf);
        return ret;
    }
    /* XXX this shouldn't be needed, but some tests break without this line
     * those decoders are buggy and need to be fixed.
     * the following tests fail:
     * bethsoft-vid, cdgraphics, ansi, aasc, fraps-v1, qtrle-1bit
     */
    memset(buf->base[0], 128, ret);

    avcodec_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift, &v_chroma_shift);
    for (int i = 0; i < FF_ARRAY_ELEMS(buf->data); i++) {
        const int h_shift = i==0 ? 0 : h_chroma_shift;
        const int v_shift = i==0 ? 0 : v_chroma_shift;
        if (s->flags & CODEC_FLAG_EMU_EDGE)
            buf->data[i] = buf->base[i];
        else
            buf->data[i] = buf->base[i] +
                           FFALIGN((buf->linesize[i]*edge >> v_shift) +
                                   (pixel_size*edge >> h_shift), 32);
    }
    buf->w       = s->width;
    buf->h       = s->height;
    buf->pix_fmt = s->pix_fmt;
    buf->ist     = ist;

    *pbuf = buf;
    return 0;
}

static void free_buffer_pool(InputStream *ist)
{
    FrameBuffer *buf = ist->buffer_pool;
    while (buf) {
        ist->buffer_pool = buf->next;
        av_freep(&buf->base[0]);
        av_free(buf);
        buf = ist->buffer_pool;
    }
}

static void unref_buffer(InputStream *ist, FrameBuffer *buf)
{
    av_assert0(buf->refcount);
    buf->refcount--;
    if (!buf->refcount) {
        buf->next = ist->buffer_pool;
        ist->buffer_pool = buf;
    }
}

static int codec_get_buffer(AVCodecContext *s, AVFrame *frame)
{
    InputStream *ist = s->opaque;
    FrameBuffer *buf;
    int ret, i;

    if (!ist->buffer_pool && (ret = alloc_buffer(ist, &ist->buffer_pool)) < 0)
        return ret;

    buf              = ist->buffer_pool;
    ist->buffer_pool = buf->next;
    buf->next        = NULL;
    if (buf->w != s->width || buf->h != s->height || buf->pix_fmt != s->pix_fmt) {
        av_freep(&buf->base[0]);
        av_free(buf);
        if ((ret = alloc_buffer(ist, &buf)) < 0)
            return ret;
    }
    buf->refcount++;

    frame->opaque        = buf;
    frame->type          = FF_BUFFER_TYPE_USER;
    frame->extended_data = frame->data;
    frame->pkt_pts       = s->pkt ? s->pkt->pts : AV_NOPTS_VALUE;

    for (i = 0; i < FF_ARRAY_ELEMS(buf->data); i++) {
        frame->base[i]     = buf->base[i];  // XXX h264.c uses base though it shouldn't
        frame->data[i]     = buf->data[i];
        frame->linesize[i] = buf->linesize[i];
    }

    return 0;
}

static void codec_release_buffer(AVCodecContext *s, AVFrame *frame)
{
    InputStream *ist = s->opaque;
    FrameBuffer *buf = frame->opaque;
    int i;

    for (i = 0; i < FF_ARRAY_ELEMS(frame->data); i++)
        frame->data[i] = NULL;

    unref_buffer(ist, buf);
}

538 539 540 541 542 543 544
static void filter_release_buffer(AVFilterBuffer *fb)
{
    FrameBuffer *buf = fb->priv;
    av_free(fb);
    unref_buffer(buf->ist, buf);
}

545 546 547 548 549 550 551 552 553 554 555 556 557 558 559
#if CONFIG_AVFILTER

static int configure_video_filters(InputStream *ist, OutputStream *ost)
{
    AVFilterContext *last_filter, *filter;
    /** filter graph containing all filters including input & output */
    AVCodecContext *codec = ost->st->codec;
    AVCodecContext *icodec = ist->st->codec;
    FFSinkContext ffsink_ctx = { .pix_fmt = codec->pix_fmt };
    AVRational sample_aspect_ratio;
    char args[255];
    int ret;

    ost->graph = avfilter_graph_alloc();

Aneesh Dogra's avatar
Aneesh Dogra committed
560
    if (ist->st->sample_aspect_ratio.num) {
561
        sample_aspect_ratio = ist->st->sample_aspect_ratio;
Aneesh Dogra's avatar
Aneesh Dogra committed
562
    } else
563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578
        sample_aspect_ratio = ist->st->codec->sample_aspect_ratio;

    snprintf(args, 255, "%d:%d:%d:%d:%d:%d:%d", ist->st->codec->width,
             ist->st->codec->height, ist->st->codec->pix_fmt, 1, AV_TIME_BASE,
             sample_aspect_ratio.num, sample_aspect_ratio.den);

    ret = avfilter_graph_create_filter(&ost->input_video_filter, avfilter_get_by_name("buffer"),
                                       "src", args, NULL, ost->graph);
    if (ret < 0)
        return ret;
    ret = avfilter_graph_create_filter(&ost->output_video_filter, &ffsink,
                                       "out", NULL, &ffsink_ctx, ost->graph);
    if (ret < 0)
        return ret;
    last_filter = ost->input_video_filter;

Aneesh Dogra's avatar
Aneesh Dogra committed
579
    if (codec->width != icodec->width || codec->height != icodec->height) {
580 581 582
        snprintf(args, 255, "%d:%d:flags=0x%X",
                 codec->width,
                 codec->height,
583
                 (unsigned)ost->sws_flags);
584 585 586 587 588 589 590 591
        if ((ret = avfilter_graph_create_filter(&filter, avfilter_get_by_name("scale"),
                                                NULL, args, NULL, ost->graph)) < 0)
            return ret;
        if ((ret = avfilter_link(last_filter, 0, filter, 0)) < 0)
            return ret;
        last_filter = filter;
    }

592
    snprintf(args, sizeof(args), "flags=0x%X", (unsigned)ost->sws_flags);
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
    ost->graph->scale_sws_opts = av_strdup(args);

    if (ost->avfilter) {
        AVFilterInOut *outputs = av_malloc(sizeof(AVFilterInOut));
        AVFilterInOut *inputs  = av_malloc(sizeof(AVFilterInOut));

        outputs->name    = av_strdup("in");
        outputs->filter_ctx = last_filter;
        outputs->pad_idx = 0;
        outputs->next    = NULL;

        inputs->name    = av_strdup("out");
        inputs->filter_ctx = ost->output_video_filter;
        inputs->pad_idx = 0;
        inputs->next    = NULL;

        if ((ret = avfilter_graph_parse(ost->graph, ost->avfilter, inputs, outputs, NULL)) < 0)
            return ret;
        av_freep(&ost->avfilter);
    } else {
        if ((ret = avfilter_link(last_filter, 0, ost->output_video_filter, 0)) < 0)
            return ret;
    }

    if ((ret = avfilter_graph_config(ost->graph, NULL)) < 0)
        return ret;

    codec->width  = ost->output_video_filter->inputs[0]->w;
    codec->height = ost->output_video_filter->inputs[0]->h;
    codec->sample_aspect_ratio = ost->st->sample_aspect_ratio =
Alex Converse's avatar
Alex Converse committed
623
        ost->frame_aspect_ratio ? // overridden by the -aspect cli option
Aneesh Dogra's avatar
Aneesh Dogra committed
624
        av_d2q(ost->frame_aspect_ratio * codec->height/codec->width, 255) :
625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648
        ost->output_video_filter->inputs[0]->sample_aspect_ratio;

    return 0;
}
#endif /* CONFIG_AVFILTER */

static void term_exit(void)
{
    av_log(NULL, AV_LOG_QUIET, "");
}

static volatile int received_sigterm = 0;
static volatile int received_nb_signals = 0;

static void
sigterm_handler(int sig)
{
    received_sigterm = sig;
    received_nb_signals++;
    term_exit();
}

static void term_init(void)
{
Aneesh Dogra's avatar
Aneesh Dogra committed
649
    signal(SIGINT , sigterm_handler); /* Interrupt (ANSI).    */
650 651 652 653 654 655
    signal(SIGTERM, sigterm_handler); /* Termination (ANSI).  */
#ifdef SIGXCPU
    signal(SIGXCPU, sigterm_handler);
#endif
}

656
static int decode_interrupt_cb(void *ctx)
657 658 659 660
{
    return received_nb_signals > 1;
}

661 662
static const AVIOInterruptCB int_cb = { decode_interrupt_cb, NULL };

663
void exit_program(int ret)
664 665 666 667
{
    int i;

    /* close files */
Aneesh Dogra's avatar
Aneesh Dogra committed
668
    for (i = 0; i < nb_output_files; i++) {
669
        AVFormatContext *s = output_files[i].ctx;
670 671 672
        if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb)
            avio_close(s->pb);
        avformat_free_context(s);
673
        av_dict_free(&output_files[i].opts);
674
    }
Janne Grunau's avatar
Janne Grunau committed
675 676 677 678 679 680 681 682 683
    for (i = 0; i < nb_output_streams; i++) {
        AVBitStreamFilterContext *bsfc = output_streams[i].bitstream_filters;
        while (bsfc) {
            AVBitStreamFilterContext *next = bsfc->next;
            av_bitstream_filter_close(bsfc);
            bsfc = next;
        }
        output_streams[i].bitstream_filters = NULL;
    }
Aneesh Dogra's avatar
Aneesh Dogra committed
684
    for (i = 0; i < nb_input_files; i++) {
685
        avformat_close_input(&input_files[i].ctx);
686
    }
687 688 689
    for (i = 0; i < nb_input_streams; i++) {
        av_freep(&input_streams[i].decoded_frame);
        av_freep(&input_streams[i].filtered_frame);
690
        av_dict_free(&input_streams[i].opts);
691
        free_buffer_pool(&input_streams[i]);
692
    }
693 694 695 696 697 698 699

    if (vstats_file)
        fclose(vstats_file);
    av_free(vstats_filename);

    av_freep(&input_streams);
    av_freep(&input_files);
700
    av_freep(&output_streams);
701
    av_freep(&output_files);
702 703 704 705

    uninit_opts();
    av_free(audio_buf);
    av_free(audio_out);
Aneesh Dogra's avatar
Aneesh Dogra committed
706
    allocated_audio_buf_size = allocated_audio_out_size = 0;
707 708 709 710

#if CONFIG_AVFILTER
    avfilter_uninit();
#endif
711
    avformat_network_deinit();
712 713

    if (received_sigterm) {
714 715
        av_log(NULL, AV_LOG_INFO, "Received signal %d: terminating.\n",
               (int) received_sigterm);
716 717 718
        exit (255);
    }

719
    exit(ret);
720 721 722 723 724 725
}

static void assert_avoptions(AVDictionary *m)
{
    AVDictionaryEntry *t;
    if ((t = av_dict_get(m, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
726
        av_log(NULL, AV_LOG_FATAL, "Option %s not found.\n", t->key);
727 728 729 730 731 732 733 734 735 736
        exit_program(1);
    }
}

static void assert_codec_experimental(AVCodecContext *c, int encoder)
{
    const char *codec_string = encoder ? "encoder" : "decoder";
    AVCodec *codec;
    if (c->codec->capabilities & CODEC_CAP_EXPERIMENTAL &&
        c->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
737
        av_log(NULL, AV_LOG_FATAL, "%s '%s' is experimental and might produce bad "
738 739 740 741
                "results.\nAdd '-strict experimental' if you want to use it.\n",
                codec_string, c->codec->name);
        codec = encoder ? avcodec_find_encoder(c->codec->id) : avcodec_find_decoder(c->codec->id);
        if (!(codec->capabilities & CODEC_CAP_EXPERIMENTAL))
742
            av_log(NULL, AV_LOG_FATAL, "Or use the non experimental %s '%s'.\n",
743 744 745 746 747 748 749
                   codec_string, codec->name);
        exit_program(1);
    }
}

static void choose_sample_fmt(AVStream *st, AVCodec *codec)
{
Aneesh Dogra's avatar
Aneesh Dogra committed
750 751 752 753
    if (codec && codec->sample_fmts) {
        const enum AVSampleFormat *p = codec->sample_fmts;
        for (; *p != -1; p++) {
            if (*p == st->codec->sample_fmt)
754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 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 806 807 808
                break;
        }
        if (*p == -1) {
            av_log(NULL, AV_LOG_WARNING,
                   "Incompatible sample format '%s' for codec '%s', auto-selecting format '%s'\n",
                   av_get_sample_fmt_name(st->codec->sample_fmt),
                   codec->name,
                   av_get_sample_fmt_name(codec->sample_fmts[0]));
            st->codec->sample_fmt = codec->sample_fmts[0];
        }
    }
}

/**
 * Update the requested input sample format based on the output sample format.
 * This is currently only used to request float output from decoders which
 * support multiple sample formats, one of which is AV_SAMPLE_FMT_FLT.
 * Ideally this will be removed in the future when decoders do not do format
 * conversion and only output in their native format.
 */
static void update_sample_fmt(AVCodecContext *dec, AVCodec *dec_codec,
                              AVCodecContext *enc)
{
    /* if sample formats match or a decoder sample format has already been
       requested, just return */
    if (enc->sample_fmt == dec->sample_fmt ||
        dec->request_sample_fmt > AV_SAMPLE_FMT_NONE)
        return;

    /* if decoder supports more than one output format */
    if (dec_codec && dec_codec->sample_fmts &&
        dec_codec->sample_fmts[0] != AV_SAMPLE_FMT_NONE &&
        dec_codec->sample_fmts[1] != AV_SAMPLE_FMT_NONE) {
        const enum AVSampleFormat *p;
        int min_dec = -1, min_inc = -1;

        /* find a matching sample format in the encoder */
        for (p = dec_codec->sample_fmts; *p != AV_SAMPLE_FMT_NONE; p++) {
            if (*p == enc->sample_fmt) {
                dec->request_sample_fmt = *p;
                return;
            } else if (*p > enc->sample_fmt) {
                min_inc = FFMIN(min_inc, *p - enc->sample_fmt);
            } else
                min_dec = FFMIN(min_dec, enc->sample_fmt - *p);
        }

        /* if none match, provide the one that matches quality closest */
        dec->request_sample_fmt = min_inc > 0 ? enc->sample_fmt + min_inc :
                                  enc->sample_fmt - min_dec;
    }
}

static void choose_sample_rate(AVStream *st, AVCodec *codec)
{
Aneesh Dogra's avatar
Aneesh Dogra committed
809 810 811 812 813 814 815 816 817
    if (codec && codec->supported_samplerates) {
        const int *p  = codec->supported_samplerates;
        int best      = 0;
        int best_dist = INT_MAX;
        for (; *p; p++) {
            int dist = abs(st->codec->sample_rate - *p);
            if (dist < best_dist) {
                best_dist = dist;
                best      = *p;
818 819
            }
        }
Aneesh Dogra's avatar
Aneesh Dogra committed
820
        if (best_dist) {
821 822
            av_log(st->codec, AV_LOG_WARNING, "Requested sampling rate unsupported using closest supported (%d)\n", best);
        }
Aneesh Dogra's avatar
Aneesh Dogra committed
823
        st->codec->sample_rate = best;
824 825 826 827 828
    }
}

static void choose_pixel_fmt(AVStream *st, AVCodec *codec)
{
Aneesh Dogra's avatar
Aneesh Dogra committed
829 830 831 832 833 834 835 836
    if (codec && codec->pix_fmts) {
        const enum PixelFormat *p = codec->pix_fmts;
        if (st->codec->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
            if (st->codec->codec_id == CODEC_ID_MJPEG) {
                p = (const enum PixelFormat[]) { PIX_FMT_YUVJ420P, PIX_FMT_YUVJ422P, PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_NONE };
            } else if (st->codec->codec_id == CODEC_ID_LJPEG) {
                p = (const enum PixelFormat[]) { PIX_FMT_YUVJ420P, PIX_FMT_YUVJ422P, PIX_FMT_YUVJ444P, PIX_FMT_YUV420P,
                                                 PIX_FMT_YUV422P, PIX_FMT_YUV444P, PIX_FMT_BGRA, PIX_FMT_NONE };
837 838
            }
        }
839
        for (; *p != PIX_FMT_NONE; p++) {
Aneesh Dogra's avatar
Aneesh Dogra committed
840
            if (*p == st->codec->pix_fmt)
841 842
                break;
        }
843
        if (*p == PIX_FMT_NONE) {
Aneesh Dogra's avatar
Aneesh Dogra committed
844
            if (st->codec->pix_fmt != PIX_FMT_NONE)
845
                av_log(NULL, AV_LOG_WARNING,
Aneesh Dogra's avatar
Aneesh Dogra committed
846 847 848 849
                       "Incompatible pixel format '%s' for codec '%s', auto-selecting format '%s'\n",
                       av_pix_fmt_descriptors[st->codec->pix_fmt].name,
                       codec->name,
                       av_pix_fmt_descriptors[codec->pix_fmts[0]].name);
850 851 852 853 854 855 856 857 858
            st->codec->pix_fmt = codec->pix_fmts[0];
        }
    }
}

static double
get_sync_ipts(const OutputStream *ost)
{
    const InputStream *ist = ost->sync_ist;
859
    OutputFile *of = &output_files[ost->file_index];
Aneesh Dogra's avatar
Aneesh Dogra committed
860
    return (double)(ist->pts - of->start_time) / AV_TIME_BASE;
861 862
}

863
static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
Aneesh Dogra's avatar
Aneesh Dogra committed
864
{
865 866
    AVBitStreamFilterContext *bsfc = ost->bitstream_filters;
    AVCodecContext          *avctx = ost->st->codec;
867 868
    int ret;

Aneesh Dogra's avatar
Aneesh Dogra committed
869 870 871 872 873 874 875
    while (bsfc) {
        AVPacket new_pkt = *pkt;
        int a = av_bitstream_filter_filter(bsfc, avctx, NULL,
                                           &new_pkt.data, &new_pkt.size,
                                           pkt->data, pkt->size,
                                           pkt->flags & AV_PKT_FLAG_KEY);
        if (a > 0) {
876
            av_free_packet(pkt);
Aneesh Dogra's avatar
Aneesh Dogra committed
877 878
            new_pkt.destruct = av_destruct_packet;
        } else if (a < 0) {
879 880 881
            av_log(NULL, AV_LOG_ERROR, "%s failed for stream %d, codec %s",
                   bsfc->filter->name, pkt->stream_index,
                   avctx->codec ? avctx->codec->name : "copy");
882 883 884 885
            print_error("", a);
            if (exit_on_error)
                exit_program(1);
        }
Aneesh Dogra's avatar
Aneesh Dogra committed
886
        *pkt = new_pkt;
887

Aneesh Dogra's avatar
Aneesh Dogra committed
888
        bsfc = bsfc->next;
889 890
    }

Aneesh Dogra's avatar
Aneesh Dogra committed
891 892
    ret = av_interleaved_write_frame(s, pkt);
    if (ret < 0) {
893 894 895
        print_error("av_interleaved_write_frame()", ret);
        exit_program(1);
    }
896
    ost->frame_number++;
897 898
}

899 900 901 902 903 904 905 906
static void generate_silence(uint8_t* buf, enum AVSampleFormat sample_fmt, size_t size)
{
    int fill_char = 0x00;
    if (sample_fmt == AV_SAMPLE_FMT_U8)
        fill_char = 0x80;
    memset(buf, fill_char, size);
}

907 908
static void do_audio_out(AVFormatContext *s, OutputStream *ost,
                         InputStream *ist, AVFrame *decoded_frame)
909 910 911 912 913
{
    uint8_t *buftmp;
    int64_t audio_out_size, audio_buf_size;

    int size_out, frame_bytes, ret, resample_changed;
Aneesh Dogra's avatar
Aneesh Dogra committed
914 915
    AVCodecContext *enc = ost->st->codec;
    AVCodecContext *dec = ist->st->codec;
916 917 918
    int osize = av_get_bytes_per_sample(enc->sample_fmt);
    int isize = av_get_bytes_per_sample(dec->sample_fmt);
    const int coded_bps = av_get_bits_per_sample(enc->codec->id);
919 920 921
    uint8_t *buf = decoded_frame->data[0];
    int size     = decoded_frame->nb_samples * dec->channels * isize;
    int64_t allocated_for_size = size;
922 923

need_realloc:
Aneesh Dogra's avatar
Aneesh Dogra committed
924 925 926 927 928 929 930 931 932
    audio_buf_size  = (allocated_for_size + isize * dec->channels - 1) / (isize * dec->channels);
    audio_buf_size  = (audio_buf_size * enc->sample_rate + dec->sample_rate) / dec->sample_rate;
    audio_buf_size  = audio_buf_size * 2 + 10000; // safety factors for the deprecated resampling API
    audio_buf_size  = FFMAX(audio_buf_size, enc->frame_size);
    audio_buf_size *= osize * enc->channels;

    audio_out_size = FFMAX(audio_buf_size, enc->frame_size * osize * enc->channels);
    if (coded_bps > 8 * osize)
        audio_out_size = audio_out_size * coded_bps / (8*osize);
933 934
    audio_out_size += FF_MIN_BUFFER_SIZE;

Aneesh Dogra's avatar
Aneesh Dogra committed
935
    if (audio_out_size > INT_MAX || audio_buf_size > INT_MAX) {
936
        av_log(NULL, AV_LOG_FATAL, "Buffer sizes too large\n");
937 938 939 940 941
        exit_program(1);
    }

    av_fast_malloc(&audio_buf, &allocated_audio_buf_size, audio_buf_size);
    av_fast_malloc(&audio_out, &allocated_audio_out_size, audio_out_size);
Aneesh Dogra's avatar
Aneesh Dogra committed
942
    if (!audio_buf || !audio_out) {
943
        av_log(NULL, AV_LOG_FATAL, "Out of memory in do_audio_out\n");
944 945 946 947 948 949 950 951 952 953 954 955
        exit_program(1);
    }

    if (enc->channels != dec->channels || enc->sample_rate != dec->sample_rate)
        ost->audio_resample = 1;

    resample_changed = ost->resample_sample_fmt  != dec->sample_fmt ||
                       ost->resample_channels    != dec->channels   ||
                       ost->resample_sample_rate != dec->sample_rate;

    if ((ost->audio_resample && !ost->resample) || resample_changed) {
        if (resample_changed) {
956
            av_log(NULL, AV_LOG_INFO, "Input stream #%d:%d frame changed from rate:%d fmt:%s ch:%d to rate:%d fmt:%s ch:%d\n",
957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974
                   ist->file_index, ist->st->index,
                   ost->resample_sample_rate, av_get_sample_fmt_name(ost->resample_sample_fmt), ost->resample_channels,
                   dec->sample_rate, av_get_sample_fmt_name(dec->sample_fmt), dec->channels);
            ost->resample_sample_fmt  = dec->sample_fmt;
            ost->resample_channels    = dec->channels;
            ost->resample_sample_rate = dec->sample_rate;
            if (ost->resample)
                audio_resample_close(ost->resample);
        }
        /* if audio_sync_method is >1 the resampler is needed for audio drift compensation */
        if (audio_sync_method <= 1 &&
            ost->resample_sample_fmt  == enc->sample_fmt &&
            ost->resample_channels    == enc->channels   &&
            ost->resample_sample_rate == enc->sample_rate) {
            ost->resample = NULL;
            ost->audio_resample = 0;
        } else if (ost->audio_resample) {
            if (dec->sample_fmt != AV_SAMPLE_FMT_S16)
975
                av_log(NULL, AV_LOG_WARNING, "Using s16 intermediate sample format for resampling\n");
976 977 978 979 980
            ost->resample = av_audio_resample_init(enc->channels,    dec->channels,
                                                   enc->sample_rate, dec->sample_rate,
                                                   enc->sample_fmt,  dec->sample_fmt,
                                                   16, 10, 0, 0.8);
            if (!ost->resample) {
981 982 983
                av_log(NULL, AV_LOG_FATAL, "Can not resample %d channels @ %d Hz to %d channels @ %d Hz\n",
                       dec->channels, dec->sample_rate,
                       enc->channels, enc->sample_rate);
984 985 986 987 988 989
                exit_program(1);
            }
        }
    }

#define MAKE_SFMT_PAIR(a,b) ((a)+AV_SAMPLE_FMT_NB*(b))
Aneesh Dogra's avatar
Aneesh Dogra committed
990 991
    if (!ost->audio_resample && dec->sample_fmt != enc->sample_fmt &&
        MAKE_SFMT_PAIR(enc->sample_fmt,dec->sample_fmt) != ost->reformat_pair) {
992 993 994 995 996
        if (ost->reformat_ctx)
            av_audio_convert_free(ost->reformat_ctx);
        ost->reformat_ctx = av_audio_convert_alloc(enc->sample_fmt, 1,
                                                   dec->sample_fmt, 1, NULL, 0);
        if (!ost->reformat_ctx) {
997 998 999
            av_log(NULL, AV_LOG_FATAL, "Cannot convert %s sample format to %s sample format\n",
                   av_get_sample_fmt_name(dec->sample_fmt),
                   av_get_sample_fmt_name(enc->sample_fmt));
1000 1001
            exit_program(1);
        }
Aneesh Dogra's avatar
Aneesh Dogra committed
1002
        ost->reformat_pair = MAKE_SFMT_PAIR(enc->sample_fmt,dec->sample_fmt);
1003 1004
    }

Aneesh Dogra's avatar
Aneesh Dogra committed
1005 1006 1007
    if (audio_sync_method) {
        double delta = get_sync_ipts(ost) * enc->sample_rate - ost->sync_opts -
                       av_fifo_size(ost->fifo) / (enc->channels * osize);
1008 1009
        int idelta = delta * dec->sample_rate / enc->sample_rate;
        int byte_delta = idelta * isize * dec->channels;
1010

Aneesh Dogra's avatar
Aneesh Dogra committed
1011 1012 1013 1014 1015
        // FIXME resample delay
        if (fabs(delta) > 50) {
            if (ist->is_start || fabs(delta) > audio_drift_threshold*enc->sample_rate) {
                if (byte_delta < 0) {
                    byte_delta = FFMAX(byte_delta, -size);
1016 1017
                    size += byte_delta;
                    buf  -= byte_delta;
1018 1019
                    av_log(NULL, AV_LOG_VERBOSE, "discarding %d audio samples\n",
                           -byte_delta / (isize * dec->channels));
Aneesh Dogra's avatar
Aneesh Dogra committed
1020
                    if (!size)
1021
                        return;
Aneesh Dogra's avatar
Aneesh Dogra committed
1022 1023 1024 1025
                    ist->is_start = 0;
                } else {
                    static uint8_t *input_tmp = NULL;
                    input_tmp = av_realloc(input_tmp, byte_delta + size);
1026

Aneesh Dogra's avatar
Aneesh Dogra committed
1027 1028
                    if (byte_delta > allocated_for_size - size) {
                        allocated_for_size = byte_delta + (int64_t)size;
1029 1030
                        goto need_realloc;
                    }
Aneesh Dogra's avatar
Aneesh Dogra committed
1031
                    ist->is_start = 0;
1032

1033
                    generate_silence(input_tmp, dec->sample_fmt, byte_delta);
1034
                    memcpy(input_tmp + byte_delta, buf, size);
Aneesh Dogra's avatar
Aneesh Dogra committed
1035
                    buf = input_tmp;
1036
                    size += byte_delta;
1037
                    av_log(NULL, AV_LOG_VERBOSE, "adding %d audio samples of silence\n", idelta);
1038
                }
Aneesh Dogra's avatar
Aneesh Dogra committed
1039 1040
            } else if (audio_sync_method > 1) {
                int comp = av_clip(delta, -audio_sync_method, audio_sync_method);
1041
                av_assert0(ost->audio_resample);
1042 1043
                av_log(NULL, AV_LOG_VERBOSE, "compensating audio timestamp drift:%f compensation:%d in:%d\n",
                       delta, comp, enc->sample_rate);
1044 1045 1046 1047
//                fprintf(stderr, "drift:%f len:%d opts:%"PRId64" ipts:%"PRId64" fifo:%d\n", delta, -1, ost->sync_opts, (int64_t)(get_sync_ipts(ost) * enc->sample_rate), av_fifo_size(ost->fifo)/(ost->st->codec->channels * 2));
                av_resample_compensate(*(struct AVResampleContext**)ost->resample, comp, enc->sample_rate);
            }
        }
Aneesh Dogra's avatar
Aneesh Dogra committed
1048 1049 1050
    } else
        ost->sync_opts = lrintf(get_sync_ipts(ost) * enc->sample_rate) -
                                av_fifo_size(ost->fifo) / (enc->channels * osize); // FIXME wrong
1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062

    if (ost->audio_resample) {
        buftmp = audio_buf;
        size_out = audio_resample(ost->resample,
                                  (short *)buftmp, (short *)buf,
                                  size / (dec->channels * isize));
        size_out = size_out * enc->channels * osize;
    } else {
        buftmp = buf;
        size_out = size;
    }

Aneesh Dogra's avatar
Aneesh Dogra committed
1063 1064 1065 1066 1067 1068 1069
    if (!ost->audio_resample && dec->sample_fmt != enc->sample_fmt) {
        const void *ibuf[6] = { buftmp };
        void *obuf[6]  = { audio_buf };
        int istride[6] = { isize };
        int ostride[6] = { osize };
        int len = size_out / istride[0];
        if (av_audio_convert(ost->reformat_ctx, obuf, ostride, ibuf, istride, len) < 0) {
1070 1071 1072 1073 1074 1075
            printf("av_audio_convert() failed\n");
            if (exit_on_error)
                exit_program(1);
            return;
        }
        buftmp = audio_buf;
Aneesh Dogra's avatar
Aneesh Dogra committed
1076
        size_out = len * osize;
1077 1078 1079 1080 1081 1082
    }

    /* now encode as many frames as possible */
    if (enc->frame_size > 1) {
        /* output resampled raw samples */
        if (av_fifo_realloc2(ost->fifo, av_fifo_size(ost->fifo) + size_out) < 0) {
1083
            av_log(NULL, AV_LOG_FATAL, "av_fifo_realloc2() failed\n");
1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095
            exit_program(1);
        }
        av_fifo_generic_write(ost->fifo, buftmp, size_out, NULL);

        frame_bytes = enc->frame_size * osize * enc->channels;

        while (av_fifo_size(ost->fifo) >= frame_bytes) {
            AVPacket pkt;
            av_init_packet(&pkt);

            av_fifo_generic_read(ost->fifo, audio_buf, frame_bytes, NULL);

Aneesh Dogra's avatar
Aneesh Dogra committed
1096
            // FIXME pass ost->sync_opts as AVFrame.pts in avcodec_encode_audio()
1097 1098 1099 1100

            ret = avcodec_encode_audio(enc, audio_out, audio_out_size,
                                       (short *)audio_buf);
            if (ret < 0) {
1101
                av_log(NULL, AV_LOG_FATAL, "Audio encoding failed\n");
1102 1103 1104
                exit_program(1);
            }
            audio_size += ret;
Aneesh Dogra's avatar
Aneesh Dogra committed
1105 1106 1107 1108 1109
            pkt.stream_index = ost->index;
            pkt.data = audio_out;
            pkt.size = ret;
            if (enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE)
                pkt.pts = av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base);
1110
            pkt.flags |= AV_PKT_FLAG_KEY;
1111
            write_frame(s, &pkt, ost);
1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124

            ost->sync_opts += enc->frame_size;
        }
    } else {
        AVPacket pkt;
        av_init_packet(&pkt);

        ost->sync_opts += size_out / (osize * enc->channels);

        /* output a pcm frame */
        /* determine the size of the coded buffer */
        size_out /= osize;
        if (coded_bps)
Aneesh Dogra's avatar
Aneesh Dogra committed
1125
            size_out = size_out * coded_bps / 8;
1126

Aneesh Dogra's avatar
Aneesh Dogra committed
1127
        if (size_out > audio_out_size) {
1128
            av_log(NULL, AV_LOG_FATAL, "Internal error, buffer size too small\n");
1129 1130 1131
            exit_program(1);
        }

Aneesh Dogra's avatar
Aneesh Dogra committed
1132
        // FIXME pass ost->sync_opts as AVFrame.pts in avcodec_encode_audio()
1133 1134 1135
        ret = avcodec_encode_audio(enc, audio_out, size_out,
                                   (short *)buftmp);
        if (ret < 0) {
1136
            av_log(NULL, AV_LOG_FATAL, "Audio encoding failed\n");
1137 1138 1139
            exit_program(1);
        }
        audio_size += ret;
Aneesh Dogra's avatar
Aneesh Dogra committed
1140 1141 1142 1143 1144
        pkt.stream_index = ost->index;
        pkt.data = audio_out;
        pkt.size = ret;
        if (enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE)
            pkt.pts = av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base);
1145
        pkt.flags |= AV_PKT_FLAG_KEY;
1146
        write_frame(s, &pkt, ost);
1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164
    }
}

static void pre_process_video_frame(InputStream *ist,<