+ for (i = 0; i < of->ctx->nb_streams; i++) {
+ OutputStream *ost = output_streams[of->ost_index + i];
+ if (!ost->initialized)
+ return 0;
+ }
+
+ of->ctx->interrupt_callback = int_cb;
+
+ ret = avformat_write_header(of->ctx, &of->opts);
+ if (ret < 0) {
+ char errbuf[128];
+
+ av_strerror(ret, errbuf, sizeof(errbuf));
+
+ av_log(NULL, AV_LOG_ERROR,
+ "Could not write header for output file #%d "
+ "(incorrect codec parameters ?): %s",
+ file_index, errbuf);
+ return ret;
+ }
+ assert_avoptions(of->opts);
+ of->header_written = 1;
+
+ av_dump_format(of->ctx, file_index, of->ctx->filename, 1);
+
+ if (want_sdp)
+ print_sdp();
+
+ /* flush the muxing queues */
+ for (i = 0; i < of->ctx->nb_streams; i++) {
+ OutputStream *ost = output_streams[of->ost_index + i];
+
+ while (av_fifo_size(ost->muxing_queue)) {
+ AVPacket pkt;
+ av_fifo_generic_read(ost->muxing_queue, &pkt, sizeof(pkt), NULL);
+ write_packet(of, &pkt, ost);
+ }
+ }
+
+ return 0;
+}
+
+static int init_output_bsfs(OutputStream *ost)
+{
+ AVBSFContext *ctx;
+ int i, ret;
+
+ if (!ost->nb_bitstream_filters)
+ return 0;
+
+ for (i = 0; i < ost->nb_bitstream_filters; i++) {
+ ctx = ost->bsf_ctx[i];
+
+ ret = avcodec_parameters_copy(ctx->par_in,
+ i ? ost->bsf_ctx[i - 1]->par_out : ost->st->codecpar);
+ if (ret < 0)
+ return ret;
+
+ ctx->time_base_in = i ? ost->bsf_ctx[i - 1]->time_base_out : ost->st->time_base;
+
+ ret = av_bsf_init(ctx);
+ if (ret < 0) {
+ av_log(NULL, AV_LOG_ERROR, "Error initializing bitstream filter: %s\n",
+ ctx->filter->name);
+ return ret;
+ }
+ }
+
+ ret = avcodec_parameters_copy(ost->st->codecpar, ctx->par_out);
+ if (ret < 0)
+ return ret;
+
+ ost->st->time_base = ctx->time_base_out;
+
+ return 0;
+}
+
+static int init_output_stream_streamcopy(OutputStream *ost)
+{
+ OutputFile *of = output_files[ost->file_index];
+ InputStream *ist = get_input_stream(ost);
+ AVCodecParameters *par_dst = ost->st->codecpar;
+ AVCodecParameters *par_src = ist->st->codecpar;
+ AVRational sar;
+ uint32_t codec_tag = par_dst->codec_tag;
+ int i, ret;
+
+ if (!codec_tag) {
+ if (!of->ctx->oformat->codec_tag ||
+ av_codec_get_id (of->ctx->oformat->codec_tag, par_src->codec_tag) == par_src->codec_id ||
+ av_codec_get_tag(of->ctx->oformat->codec_tag, par_src->codec_id) <= 0)
+ codec_tag = par_src->codec_tag;
+ }
+
+ ret = avcodec_parameters_copy(par_dst, par_src);
+ if (ret < 0)
+ return ret;
+
+ par_dst->codec_tag = codec_tag;
+
+ ost->st->disposition = ist->st->disposition;
+
+ ost->st->time_base = ist->st->time_base;
+
+ if (ist->st->nb_side_data) {
+ ost->st->side_data = av_realloc_array(NULL, ist->st->nb_side_data,
+ sizeof(*ist->st->side_data));
+ if (!ost->st->side_data)
+ return AVERROR(ENOMEM);
+
+ for (i = 0; i < ist->st->nb_side_data; i++) {
+ const AVPacketSideData *sd_src = &ist->st->side_data[i];
+ AVPacketSideData *sd_dst = &ost->st->side_data[i];
+
+ sd_dst->data = av_malloc(sd_src->size);
+ if (!sd_dst->data)
+ return AVERROR(ENOMEM);
+ memcpy(sd_dst->data, sd_src->data, sd_src->size);
+ sd_dst->size = sd_src->size;
+ sd_dst->type = sd_src->type;
+ ost->st->nb_side_data++;
+ }
+ }
+
+ ost->parser = av_parser_init(par_dst->codec_id);
+ ost->parser_avctx = avcodec_alloc_context3(NULL);
+ if (!ost->parser_avctx)
+ return AVERROR(ENOMEM);
+
+ if (par_dst->codec_type == AVMEDIA_TYPE_VIDEO) {
+ if (ost->frame_aspect_ratio)
+ sar = av_d2q(ost->frame_aspect_ratio * par_dst->height / par_dst->width, 255);
+ else if (ist->st->sample_aspect_ratio.num)
+ sar = ist->st->sample_aspect_ratio;
+ else
+ sar = par_src->sample_aspect_ratio;
+ ost->st->sample_aspect_ratio = par_dst->sample_aspect_ratio = sar;
+ }
+
+ return 0;
+}
+
+static void set_encoder_id(OutputFile *of, OutputStream *ost)
+{
+ AVDictionaryEntry *e;
+
+ uint8_t *encoder_string;
+ int encoder_string_len;
+ int format_flags = 0;
+
+ e = av_dict_get(of->opts, "fflags", NULL, 0);
+ if (e) {
+ const AVOption *o = av_opt_find(of->ctx, "fflags", NULL, 0, 0);
+ if (!o)
+ return;
+ av_opt_eval_flags(of->ctx, o, e->value, &format_flags);
+ }
+
+ encoder_string_len = sizeof(LIBAVCODEC_IDENT) + strlen(ost->enc->name) + 2;
+ encoder_string = av_mallocz(encoder_string_len);
+ if (!encoder_string)
+ exit_program(1);
+
+ if (!(format_flags & AVFMT_FLAG_BITEXACT))
+ av_strlcpy(encoder_string, LIBAVCODEC_IDENT " ", encoder_string_len);
+ av_strlcat(encoder_string, ost->enc->name, encoder_string_len);
+ av_dict_set(&ost->st->metadata, "encoder", encoder_string,
+ AV_DICT_DONT_STRDUP_VAL | AV_DICT_DONT_OVERWRITE);
+}
+
+static void parse_forced_key_frames(char *kf, OutputStream *ost,
+ AVCodecContext *avctx)
+{
+ char *p;
+ int n = 1, i;
+ int64_t t;
+
+ for (p = kf; *p; p++)
+ if (*p == ',')
+ n++;
+ ost->forced_kf_count = n;
+ ost->forced_kf_pts = av_malloc(sizeof(*ost->forced_kf_pts) * n);
+ if (!ost->forced_kf_pts) {
+ av_log(NULL, AV_LOG_FATAL, "Could not allocate forced key frames array.\n");