X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=avconv.c;h=8e76863becc026fafb6a1636b30d46c88bf1a807;hb=724cbea7193945fe5a5b4dea8ede344803572844;hp=2cee09bc226bc3a576b1c7f0e4baaed698237a18;hpb=dc40d88625d7e402d58ac3f3df69fbf27aa31ea0;p=ffmpeg diff --git a/avconv.c b/avconv.c index 2cee09bc226..8e76863becc 100644 --- a/avconv.c +++ b/avconv.c @@ -191,6 +191,8 @@ static void avconv_cleanup(int ret) av_freep(&ost->avfilter); av_freep(&ost->logfile_prefix); + avcodec_free_context(&ost->enc_ctx); + av_freep(&output_streams[i]); } for (i = 0; i < nb_input_files; i++) { @@ -206,6 +208,8 @@ static void avconv_cleanup(int ret) av_freep(&ist->filters); av_freep(&ist->hwaccel_device); + avcodec_free_context(&ist->dec_ctx); + av_freep(&input_streams[i]); } @@ -314,7 +318,7 @@ static void update_sample_fmt(AVCodecContext *dec, AVCodec *dec_codec, static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost) { AVBitStreamFilterContext *bsfc = ost->bitstream_filters; - AVCodecContext *avctx = ost->st->codec; + AVCodecContext *avctx = ost->enc_ctx; int ret; /* @@ -392,7 +396,7 @@ static int check_recording_time(OutputStream *ost) OutputFile *of = output_files[ost->file_index]; if (of->recording_time != INT64_MAX && - av_compare_ts(ost->sync_opts - ost->first_pts, ost->st->codec->time_base, of->recording_time, + av_compare_ts(ost->sync_opts - ost->first_pts, ost->enc_ctx->time_base, of->recording_time, AV_TIME_BASE_Q) >= 0) { ost->finished = 1; return 0; @@ -403,7 +407,7 @@ static int check_recording_time(OutputStream *ost) static void do_audio_out(AVFormatContext *s, OutputStream *ost, AVFrame *frame) { - AVCodecContext *enc = ost->st->codec; + AVCodecContext *enc = ost->enc_ctx; AVPacket pkt; int got_packet = 0; @@ -424,13 +428,7 @@ static void do_audio_out(AVFormatContext *s, OutputStream *ost, } if (got_packet) { - if (pkt.pts != AV_NOPTS_VALUE) - pkt.pts = av_rescale_q(pkt.pts, enc->time_base, ost->st->time_base); - if (pkt.dts != AV_NOPTS_VALUE) - pkt.dts = av_rescale_q(pkt.dts, enc->time_base, ost->st->time_base); - if (pkt.duration > 0) - pkt.duration = av_rescale_q(pkt.duration, enc->time_base, ost->st->time_base); - + av_packet_rescale_ts(&pkt, enc->time_base, ost->st->time_base); write_frame(s, &pkt, ost); } } @@ -454,7 +452,7 @@ static void do_subtitle_out(AVFormatContext *s, return; } - enc = ost->st->codec; + enc = ost->enc_ctx; if (!subtitle_out) { subtitle_out = av_malloc(subtitle_out_max_size); @@ -511,7 +509,7 @@ static void do_video_out(AVFormatContext *s, { int ret, format_video_sync; AVPacket pkt; - AVCodecContext *enc = ost->st->codec; + AVCodecContext *enc = ost->enc_ctx; *frame_size = 0; @@ -561,13 +559,12 @@ static void do_video_out(AVFormatContext *s, } else { int got_packet; - if (ost->st->codec->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME) && + if (enc->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME) && ost->top_field_first >= 0) in_picture->top_field_first = !!ost->top_field_first; - in_picture->quality = ost->st->codec->global_quality; - if (!enc->me_threshold) - in_picture->pict_type = 0; + in_picture->quality = enc->global_quality; + in_picture->pict_type = 0; if (ost->forced_kf_index < ost->forced_kf_count && in_picture->pts >= ost->forced_kf_pts[ost->forced_kf_index]) { in_picture->pict_type = AV_PICTURE_TYPE_I; @@ -583,11 +580,7 @@ static void do_video_out(AVFormatContext *s, } if (got_packet) { - if (pkt.pts != AV_NOPTS_VALUE) - pkt.pts = av_rescale_q(pkt.pts, enc->time_base, ost->st->time_base); - if (pkt.dts != AV_NOPTS_VALUE) - pkt.dts = av_rescale_q(pkt.dts, enc->time_base, ost->st->time_base); - + av_packet_rescale_ts(&pkt, enc->time_base, ost->st->time_base); write_frame(s, &pkt, ost); *frame_size = pkt.size; @@ -626,7 +619,7 @@ static void do_video_stats(OutputStream *ost, int frame_size) } } - enc = ost->st->codec; + enc = ost->enc_ctx; if (enc->codec_type == AVMEDIA_TYPE_VIDEO) { frame_number = ost->frame_number; fprintf(vstats_file, "frame= %5d q= %2.1f ", frame_number, enc->coded_frame->quality / (float)FF_QP2LAMBDA); @@ -664,7 +657,7 @@ static int poll_filter(OutputStream *ost) if (ost->enc->type == AVMEDIA_TYPE_AUDIO && !(ost->enc->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)) ret = av_buffersink_get_samples(ost->filter->filter, filtered_frame, - ost->st->codec->frame_size); + ost->enc_ctx->frame_size); else ret = av_buffersink_get_frame(ost->filter->filter, filtered_frame); @@ -675,16 +668,16 @@ static int poll_filter(OutputStream *ost) int64_t start_time = (of->start_time == AV_NOPTS_VALUE) ? 0 : of->start_time; filtered_frame->pts = av_rescale_q(filtered_frame->pts, ost->filter->filter->inputs[0]->time_base, - ost->st->codec->time_base) - + ost->enc_ctx->time_base) - av_rescale_q(start_time, AV_TIME_BASE_Q, - ost->st->codec->time_base); + ost->enc_ctx->time_base); } switch (ost->filter->filter->inputs[0]->type) { case AVMEDIA_TYPE_VIDEO: if (!ost->frame_aspect_ratio) - ost->st->codec->sample_aspect_ratio = filtered_frame->sample_aspect_ratio; + ost->enc_ctx->sample_aspect_ratio = filtered_frame->sample_aspect_ratio; do_video_out(of->ctx, ost, filtered_frame, &frame_size); if (vstats_filename && frame_size) @@ -703,6 +696,19 @@ static int poll_filter(OutputStream *ost) return 0; } +static void finish_output_stream(OutputStream *ost) +{ + OutputFile *of = output_files[ost->file_index]; + int i; + + ost->finished = 1; + + if (of->shortest) { + for (i = 0; i < of->ctx->nb_streams; i++) + output_streams[of->ost_index + i]->finished = 1; + } +} + /* * Read as many frames from possible from lavfi and encode them. * @@ -713,7 +719,7 @@ static int poll_filter(OutputStream *ost) */ static int poll_filters(void) { - int i, j, ret = 0; + int i, ret = 0; while (ret >= 0 && !received_sigterm) { OutputStream *ost = NULL; @@ -726,7 +732,7 @@ static int poll_filters(void) if (!output_streams[i]->filter || output_streams[i]->finished) continue; - pts = av_rescale_q(pts, output_streams[i]->st->codec->time_base, + pts = av_rescale_q(pts, output_streams[i]->enc_ctx->time_base, AV_TIME_BASE_Q); if (pts < min_pts) { min_pts = pts; @@ -740,15 +746,7 @@ static int poll_filters(void) ret = poll_filter(ost); if (ret == AVERROR_EOF) { - OutputFile *of = output_files[ost->file_index]; - - ost->finished = 1; - - if (of->shortest) { - for (j = 0; j < of->ctx->nb_streams; j++) - output_streams[of->ost_index + j]->finished = 1; - } - + finish_output_stream(ost); ret = 0; } else if (ret == AVERROR(EAGAIN)) return 0; @@ -766,12 +764,12 @@ static void print_final_stats(int64_t total_size) for (i = 0; i < nb_output_streams; i++) { OutputStream *ost = output_streams[i]; - switch (ost->st->codec->codec_type) { + switch (ost->enc_ctx->codec_type) { case AVMEDIA_TYPE_VIDEO: video_size += ost->data_size; break; case AVMEDIA_TYPE_AUDIO: audio_size += ost->data_size; break; default: other_size += ost->data_size; break; } - extra_size += ost->st->codec->extradata_size; + extra_size += ost->enc_ctx->extradata_size; data_size += ost->data_size; } @@ -800,7 +798,7 @@ static void print_final_stats(int64_t total_size) for (j = 0; j < f->nb_streams; j++) { InputStream *ist = input_streams[f->ist_index + j]; - enum AVMediaType type = ist->st->codec->codec_type; + enum AVMediaType type = ist->dec_ctx->codec_type; total_size += ist->data_size; total_packets += ist->nb_packets; @@ -834,7 +832,7 @@ static void print_final_stats(int64_t total_size) for (j = 0; j < of->ctx->nb_streams; j++) { OutputStream *ost = output_streams[of->ost_index + j]; - enum AVMediaType type = ost->st->codec->codec_type; + enum AVMediaType type = ost->enc_ctx->codec_type; total_size += ost->data_size; total_packets += ost->packets_written; @@ -878,7 +876,7 @@ static void print_report(int is_last_report, int64_t timer_start) if (!is_last_report) { int64_t cur_time; /* display the report every 0.5 seconds */ - cur_time = av_gettime(); + cur_time = av_gettime_relative(); if (last_time == -1) { last_time = cur_time; return; @@ -908,14 +906,14 @@ static void print_report(int is_last_report, int64_t timer_start) for (i = 0; i < nb_output_streams; i++) { float q = -1; ost = output_streams[i]; - enc = ost->st->codec; + enc = ost->enc_ctx; if (!ost->stream_copy && enc->coded_frame) q = enc->coded_frame->quality / (float)FF_QP2LAMBDA; if (vid && enc->codec_type == AVMEDIA_TYPE_VIDEO) { snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "q=%2.1f ", q); } if (!vid && enc->codec_type == AVMEDIA_TYPE_VIDEO) { - float t = (av_gettime() - timer_start) / 1000000.0; + float t = (av_gettime_relative() - timer_start) / 1000000.0; frame_number = ost->frame_number; snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "frame=%5d fps=%3d q=%3.1f ", @@ -987,23 +985,23 @@ static void flush_encoders(void) for (i = 0; i < nb_output_streams; i++) { OutputStream *ost = output_streams[i]; - AVCodecContext *enc = ost->st->codec; + AVCodecContext *enc = ost->enc_ctx; AVFormatContext *os = output_files[ost->file_index]->ctx; int stop_encoding = 0; if (!ost->encoding_needed) continue; - if (ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO && enc->frame_size <= 1) + if (enc->codec_type == AVMEDIA_TYPE_AUDIO && enc->frame_size <= 1) continue; - if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && (os->oformat->flags & AVFMT_RAWPICTURE) && enc->codec->id == AV_CODEC_ID_RAWVIDEO) + if (enc->codec_type == AVMEDIA_TYPE_VIDEO && (os->oformat->flags & AVFMT_RAWPICTURE) && enc->codec->id == AV_CODEC_ID_RAWVIDEO) continue; for (;;) { int (*encode)(AVCodecContext*, AVPacket*, const AVFrame*, int*) = NULL; const char *desc; - switch (ost->st->codec->codec_type) { + switch (enc->codec_type) { case AVMEDIA_TYPE_AUDIO: encode = avcodec_encode_audio2; desc = "Audio"; @@ -1035,12 +1033,7 @@ static void flush_encoders(void) stop_encoding = 1; break; } - if (pkt.pts != AV_NOPTS_VALUE) - pkt.pts = av_rescale_q(pkt.pts, enc->time_base, ost->st->time_base); - if (pkt.dts != AV_NOPTS_VALUE) - pkt.dts = av_rescale_q(pkt.dts, enc->time_base, ost->st->time_base); - if (pkt.duration > 0) - pkt.duration = av_rescale_q(pkt.duration, enc->time_base, ost->st->time_base); + av_packet_rescale_ts(&pkt, enc->time_base, ost->st->time_base); write_frame(os, &pkt, ost); } @@ -1098,7 +1091,7 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p } /* force the input stream PTS */ - if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) + if (ost->enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO) ost->sync_opts++; if (pkt->pts != AV_NOPTS_VALUE) @@ -1116,10 +1109,10 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p opkt.flags = pkt->flags; // FIXME remove the following 2 lines they shall be replaced by the bitstream filters - if ( ost->st->codec->codec_id != AV_CODEC_ID_H264 - && ost->st->codec->codec_id != AV_CODEC_ID_MPEG1VIDEO - && ost->st->codec->codec_id != AV_CODEC_ID_MPEG2VIDEO - && ost->st->codec->codec_id != AV_CODEC_ID_VC1 + if ( ost->enc_ctx->codec_id != AV_CODEC_ID_H264 + && ost->enc_ctx->codec_id != AV_CODEC_ID_MPEG1VIDEO + && ost->enc_ctx->codec_id != AV_CODEC_ID_MPEG2VIDEO + && ost->enc_ctx->codec_id != AV_CODEC_ID_VC1 ) { if (av_parser_change(ost->parser, ost->st->codec, &opkt.data, &opkt.size, @@ -1139,7 +1132,7 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p int guess_input_channel_layout(InputStream *ist) { - AVCodecContext *dec = ist->st->codec; + AVCodecContext *dec = ist->dec_ctx; if (!dec->channel_layout) { char layout_name[256]; @@ -1158,7 +1151,7 @@ int guess_input_channel_layout(InputStream *ist) static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) { AVFrame *decoded_frame, *f; - AVCodecContext *avctx = ist->st->codec; + AVCodecContext *avctx = ist->dec_ctx; int i, ret, err = 0, resample_changed; if (!ist->decoded_frame && !(ist->decoded_frame = av_frame_alloc())) @@ -1231,7 +1224,7 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) if (decoded_frame->pts != AV_NOPTS_VALUE) decoded_frame->pts = av_rescale_q(decoded_frame->pts, ist->st->time_base, - (AVRational){1, ist->st->codec->sample_rate}); + (AVRational){1, avctx->sample_rate}); for (i = 0; i < ist->nb_filters; i++) { if (i < ist->nb_filters - 1) { f = ist->filter_frame; @@ -1262,7 +1255,7 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) return AVERROR(ENOMEM); decoded_frame = ist->decoded_frame; - ret = avcodec_decode_video2(ist->st->codec, + ret = avcodec_decode_video2(ist->dec_ctx, decoded_frame, got_output, pkt); if (!*got_output || ret < 0) { if (!pkt->size) { @@ -1275,7 +1268,7 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) ist->frames_decoded++; if (ist->hwaccel_retrieve_data && decoded_frame->format == ist->hwaccel_pix_fmt) { - err = ist->hwaccel_retrieve_data(ist->st->codec, decoded_frame); + err = ist->hwaccel_retrieve_data(ist->dec_ctx, decoded_frame); if (err < 0) goto fail; } @@ -1337,7 +1330,7 @@ fail: static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output) { AVSubtitle subtitle; - int i, ret = avcodec_decode_subtitle2(ist->st->codec, + int i, ret = avcodec_decode_subtitle2(ist->dec_ctx, &subtitle, got_output, pkt); if (ret < 0) return ret; @@ -1360,7 +1353,7 @@ static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output) } /* pkt = NULL means EOF (needed to flush decoder buffers) */ -static int output_packet(InputStream *ist, const AVPacket *pkt) +static int process_input_packet(InputStream *ist, const AVPacket *pkt) { int i; int got_output; @@ -1369,7 +1362,7 @@ static int output_packet(InputStream *ist, const AVPacket *pkt) if (ist->next_dts == AV_NOPTS_VALUE) ist->next_dts = ist->last_dts; - if (pkt == NULL) { + if (!pkt) { /* EOF handling */ av_init_packet(&avpkt); avpkt.data = NULL; @@ -1396,7 +1389,7 @@ static int output_packet(InputStream *ist, const AVPacket *pkt) ist->showed_multi_packet_warning = 1; } - switch (ist->st->codec->codec_type) { + switch (ist->dec_ctx->codec_type) { case AVMEDIA_TYPE_AUDIO: ret = decode_audio (ist, &avpkt, &got_output); break; @@ -1407,10 +1400,10 @@ static int output_packet(InputStream *ist, const AVPacket *pkt) else if (ist->st->avg_frame_rate.num) ist->next_dts += av_rescale_q(1, av_inv_q(ist->st->avg_frame_rate), AV_TIME_BASE_Q); - else if (ist->st->codec->time_base.num != 0) { + else if (ist->dec_ctx->framerate.num != 0) { int ticks = ist->st->parser ? ist->st->parser->repeat_pict + 1 : - ist->st->codec->ticks_per_frame; - ist->next_dts += av_rescale_q(ticks, ist->st->codec->time_base, AV_TIME_BASE_Q); + ist->dec_ctx->ticks_per_frame; + ist->next_dts += av_rescale_q(ticks, ist->dec_ctx->framerate, AV_TIME_BASE_Q); } break; case AVMEDIA_TYPE_SUBTITLE: @@ -1435,17 +1428,17 @@ static int output_packet(InputStream *ist, const AVPacket *pkt) /* handle stream copy */ if (!ist->decoding_needed) { ist->last_dts = ist->next_dts; - switch (ist->st->codec->codec_type) { + switch (ist->dec_ctx->codec_type) { case AVMEDIA_TYPE_AUDIO: - ist->next_dts += ((int64_t)AV_TIME_BASE * ist->st->codec->frame_size) / - ist->st->codec->sample_rate; + ist->next_dts += ((int64_t)AV_TIME_BASE * ist->dec_ctx->frame_size) / + ist->dec_ctx->sample_rate; break; case AVMEDIA_TYPE_VIDEO: - if (ist->st->codec->time_base.num != 0) { - int ticks = ist->st->parser ? ist->st->parser->repeat_pict + 1 : ist->st->codec->ticks_per_frame; + if (ist->dec_ctx->framerate.num != 0) { + int ticks = ist->st->parser ? ist->st->parser->repeat_pict + 1 : ist->dec_ctx->ticks_per_frame; ist->next_dts += ((int64_t)AV_TIME_BASE * - ist->st->codec->time_base.num * ticks) / - ist->st->codec->time_base.den; + ist->dec_ctx->framerate.den * ticks) / + ist->dec_ctx->framerate.num; } break; } @@ -1544,7 +1537,7 @@ static int init_input_stream(int ist_index, char *error, int error_len) AVCodec *codec = ist->dec; if (!codec) { snprintf(error, error_len, "Decoder (codec id %d) not found for input stream #%d:%d", - ist->st->codec->codec_id, ist->file_index, ist->st->index); + ist->dec_ctx->codec_id, ist->file_index, ist->st->index); return AVERROR(EINVAL); } @@ -1553,21 +1546,21 @@ static int init_input_stream(int ist_index, char *error, int error_len) for (i = 0; i < nb_output_streams; i++) { OutputStream *ost = output_streams[i]; if (ost->source_index == ist_index) { - update_sample_fmt(ist->st->codec, codec, ost->st->codec); + update_sample_fmt(ist->dec_ctx, codec, ost->enc_ctx); break; } } - ist->st->codec->opaque = ist; - ist->st->codec->get_format = get_format; - ist->st->codec->get_buffer2 = get_buffer; - ist->st->codec->thread_safe_callbacks = 1; + ist->dec_ctx->opaque = ist; + ist->dec_ctx->get_format = get_format; + ist->dec_ctx->get_buffer2 = get_buffer; + ist->dec_ctx->thread_safe_callbacks = 1; - av_opt_set_int(ist->st->codec, "refcounted_frames", 1, 0); + av_opt_set_int(ist->dec_ctx, "refcounted_frames", 1, 0); if (!av_dict_get(ist->decoder_opts, "threads", NULL, 0)) av_dict_set(&ist->decoder_opts, "threads", "auto", 0); - if ((ret = avcodec_open2(ist->st->codec, codec, &ist->decoder_opts)) < 0) { + if ((ret = avcodec_open2(ist->dec_ctx, codec, &ist->decoder_opts)) < 0) { char errbuf[128]; if (ret == AVERROR_EXPERIMENTAL) abort_codec_experimental(codec, 0); @@ -1583,7 +1576,7 @@ static int init_input_stream(int ist_index, char *error, int error_len) assert_avoptions(ist->decoder_opts); } - ist->last_dts = ist->st->avg_frame_rate.num ? - ist->st->codec->has_b_frames * AV_TIME_BASE / av_q2d(ist->st->avg_frame_rate) : 0; + ist->last_dts = ist->st->avg_frame_rate.num ? - ist->dec_ctx->has_b_frames * AV_TIME_BASE / av_q2d(ist->st->avg_frame_rate) : 0; ist->next_dts = AV_NOPTS_VALUE; init_pts_correction(&ist->pts_ctx); @@ -1600,7 +1593,7 @@ static InputStream *get_input_stream(OutputStream *ost) int i; for (i = 0; i < fg->nb_inputs; i++) - if (fg->inputs[i]->ist->st->codec->codec_type == ost->st->codec->codec_type) + if (fg->inputs[i]->ist->dec_ctx->codec_type == ost->enc_ctx->codec_type) return fg->inputs[i]->ist; } @@ -1680,7 +1673,7 @@ static int transcode_init(void) InputFile *ifile = input_files[i]; if (ifile->rate_emu) for (j = 0; j < ifile->nb_streams; j++) - input_streams[j + ifile->ist_index]->start = av_gettime(); + input_streams[j + ifile->ist_index]->start = av_gettime_relative(); } /* output stream init */ @@ -1709,10 +1702,10 @@ static int transcode_init(void) if (ost->attachment_filename) continue; - enc_ctx = ost->st->codec; + enc_ctx = ost->enc_ctx; if (ist) { - dec_ctx = ist->st->codec; + dec_ctx = ist->dec_ctx; ost->st->disposition = ist->st->disposition; enc_ctx->bits_per_raw_sample = dec_ctx->bits_per_raw_sample; @@ -1760,6 +1753,26 @@ static int transcode_init(void) } else enc_ctx->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 (j = 0; j < ist->st->nb_side_data; j++) { + const AVPacketSideData *sd_src = &ist->st->side_data[j]; + AVPacketSideData *sd_dst = &ost->st->side_data[j]; + + 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(enc_ctx->codec_id); switch (enc_ctx->codec_type) { @@ -1891,7 +1904,7 @@ static int transcode_init(void) if (ost->forced_keyframes) parse_forced_key_frames(ost->forced_keyframes, ost, - ost->st->codec); + ost->enc_ctx); break; case AVMEDIA_TYPE_SUBTITLE: enc_ctx->time_base = (AVRational){1, 1000}; @@ -1943,19 +1956,21 @@ static int transcode_init(void) AVCodecContext *dec = NULL; if ((ist = get_input_stream(ost))) - dec = ist->st->codec; + dec = ist->dec_ctx; if (dec && dec->subtitle_header) { - ost->st->codec->subtitle_header = av_malloc(dec->subtitle_header_size); - if (!ost->st->codec->subtitle_header) { + ost->enc_ctx->subtitle_header = av_malloc(dec->subtitle_header_size); + if (!ost->enc_ctx->subtitle_header) { ret = AVERROR(ENOMEM); goto dump_format; } - memcpy(ost->st->codec->subtitle_header, dec->subtitle_header, dec->subtitle_header_size); - ost->st->codec->subtitle_header_size = dec->subtitle_header_size; + memcpy(ost->enc_ctx->subtitle_header, dec->subtitle_header, dec->subtitle_header_size); + ost->enc_ctx->subtitle_header_size = dec->subtitle_header_size; } if (!av_dict_get(ost->encoder_opts, "threads", NULL, 0)) av_dict_set(&ost->encoder_opts, "threads", "auto", 0); - if ((ret = avcodec_open2(ost->st->codec, codec, &ost->encoder_opts)) < 0) { + av_dict_set(&ost->encoder_opts, "side_data_only_packets", "1", 0); + + if ((ret = avcodec_open2(ost->enc_ctx, codec, &ost->encoder_opts)) < 0) { if (ret == AVERROR_EXPERIMENTAL) abort_codec_experimental(codec, 1); snprintf(error, sizeof(error), "Error while opening encoder for output stream #%d:%d - maybe incorrect parameters such as bit_rate, rate, width or height", @@ -1963,12 +1978,23 @@ static int transcode_init(void) goto dump_format; } assert_avoptions(ost->encoder_opts); - if (ost->st->codec->bit_rate && ost->st->codec->bit_rate < 1000) + if (ost->enc_ctx->bit_rate && ost->enc_ctx->bit_rate < 1000) av_log(NULL, AV_LOG_WARNING, "The bitrate parameter is set too low." "It takes bits/s as argument, not kbits/s\n"); } else { - av_opt_set_dict(ost->st->codec, &ost->encoder_opts); + ret = av_opt_set_dict(ost->enc_ctx, &ost->encoder_opts); + if (ret < 0) + return ret; + } + + ret = avcodec_copy_context(ost->st->codec, ost->enc_ctx); + if (ret < 0) { + av_log(NULL, AV_LOG_FATAL, + "Error initializing the output stream codec context.\n"); + exit_program(1); } + + ost->st->time_base = ost->enc_ctx->time_base; } /* init input streams */ @@ -2068,10 +2094,32 @@ static int transcode_init(void) ost->sync_ist->st->index); if (ost->stream_copy) av_log(NULL, AV_LOG_INFO, " (copy)"); - else - av_log(NULL, AV_LOG_INFO, " (%s -> %s)", input_streams[ost->source_index]->dec ? - input_streams[ost->source_index]->dec->name : "?", - ost->enc ? ost->enc->name : "?"); + else { + const AVCodec *in_codec = input_streams[ost->source_index]->dec; + const AVCodec *out_codec = ost->enc; + const char *decoder_name = "?"; + const char *in_codec_name = "?"; + const char *encoder_name = "?"; + const char *out_codec_name = "?"; + + if (in_codec) { + decoder_name = in_codec->name; + in_codec_name = avcodec_descriptor_get(in_codec->id)->name; + if (!strcmp(decoder_name, in_codec_name)) + decoder_name = "native"; + } + + if (out_codec) { + encoder_name = out_codec->name; + out_codec_name = avcodec_descriptor_get(out_codec->id)->name; + if (!strcmp(encoder_name, out_codec_name)) + encoder_name = "native"; + } + + av_log(NULL, AV_LOG_INFO, " (%s (%s) -> %s (%s))", + in_codec_name, decoder_name, + out_codec_name, encoder_name); + } av_log(NULL, AV_LOG_INFO, "\n"); } @@ -2253,7 +2301,7 @@ static int get_input_packet(InputFile *f, AVPacket *pkt) for (i = 0; i < f->nb_streams; i++) { InputStream *ist = input_streams[f->ist_index + i]; int64_t pts = av_rescale(ist->last_dts, 1000000, AV_TIME_BASE); - int64_t now = av_gettime() - ist->start; + int64_t now = av_gettime_relative() - ist->start; if (pts > now) return AVERROR(EAGAIN); } @@ -2333,7 +2381,7 @@ static int process_input(void) for (i = 0; i < ifile->nb_streams; i++) { ist = input_streams[ifile->ist_index + i]; if (ist->decoding_needed) - output_packet(ist, NULL); + process_input_packet(ist, NULL); /* mark all outputs that don't go through lavfi as finished */ for (j = 0; j < nb_output_streams; j++) { @@ -2341,7 +2389,7 @@ static int process_input(void) if (ost->source_index == ifile->ist_index + i && (ost->stream_copy || ost->enc->type == AVMEDIA_TYPE_SUBTITLE)) - ost->finished= 1; + finish_output_stream(ost); } } @@ -2393,7 +2441,9 @@ static int process_input(void) if (pkt.dts != AV_NOPTS_VALUE) pkt.dts *= ist->ts_scale; - if (pkt.dts != AV_NOPTS_VALUE && ist->next_dts != AV_NOPTS_VALUE && + if ((ist->dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO || + ist->dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) && + pkt.dts != AV_NOPTS_VALUE && ist->next_dts != AV_NOPTS_VALUE && (is->iformat->flags & AVFMT_TS_DISCONT)) { int64_t pkt_dts = av_rescale_q(pkt.dts, ist->st->time_base, AV_TIME_BASE_Q); int64_t delta = pkt_dts - ist->next_dts; @@ -2409,7 +2459,7 @@ static int process_input(void) } } - ret = output_packet(ist, &pkt); + ret = process_input_packet(ist, &pkt); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Error while decoding stream #%d:%d\n", ist->file_index, ist->st->index); @@ -2441,7 +2491,7 @@ static int transcode(void) av_log(NULL, AV_LOG_INFO, "Press ctrl-c to stop encoding\n"); term_init(); - timer_start = av_gettime(); + timer_start = av_gettime_relative(); #if HAVE_PTHREADS if ((ret = init_input_threads()) < 0) @@ -2482,7 +2532,7 @@ static int transcode(void) for (i = 0; i < nb_input_streams; i++) { ist = input_streams[i]; if (!input_files[ist->file_index]->eof_reached && ist->decoding_needed) { - output_packet(ist, NULL); + process_input_packet(ist, NULL); } } poll_filters(); @@ -2503,8 +2553,7 @@ static int transcode(void) for (i = 0; i < nb_output_streams; i++) { ost = output_streams[i]; if (ost->encoding_needed) { - av_freep(&ost->st->codec->stats_in); - avcodec_close(ost->st->codec); + av_freep(&ost->enc_ctx->stats_in); } } @@ -2512,9 +2561,9 @@ static int transcode(void) for (i = 0; i < nb_input_streams; i++) { ist = input_streams[i]; if (ist->decoding_needed) { - avcodec_close(ist->st->codec); + avcodec_close(ist->dec_ctx); if (ist->hwaccel_uninit) - ist->hwaccel_uninit(ist->st->codec); + ist->hwaccel_uninit(ist->dec_ctx); } } @@ -2530,13 +2579,10 @@ static int transcode(void) for (i = 0; i < nb_output_streams; i++) { ost = output_streams[i]; if (ost) { - if (ost->stream_copy) - av_freep(&ost->st->codec->extradata); if (ost->logfile) { fclose(ost->logfile); ost->logfile = NULL; } - av_freep(&ost->st->codec->subtitle_header); av_free(ost->forced_kf_pts); av_dict_free(&ost->encoder_opts); av_dict_free(&ost->resample_opts); @@ -2560,7 +2606,7 @@ static int64_t getutime(void) GetProcessTimes(proc, &c, &e, &k, &u); return ((int64_t) u.dwHighDateTime << 32 | u.dwLowDateTime) / 10; #else - return av_gettime(); + return av_gettime_relative(); #endif }