X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=avconv.c;h=94b6da2a8ba18f0481907af61006d858260dcdc5;hb=7abdd026df6a9a52d07d8174505b33cc89db7bf6;hp=57c02ac4fc8f75239c2aee7d444c71c82064689f;hpb=b0f36a0043d76436cc7ab8ff92ab99c94595d3c0;p=ffmpeg diff --git a/avconv.c b/avconv.c index 57c02ac4fc8..94b6da2a8ba 100644 --- a/avconv.c +++ b/avconv.c @@ -38,6 +38,7 @@ #include "libavutil/parseutils.h" #include "libavutil/samplefmt.h" #include "libavutil/fifo.h" +#include "libavutil/hwcontext.h" #include "libavutil/internal.h" #include "libavutil/intreadwrite.h" #include "libavutil/dict.h" @@ -190,7 +191,6 @@ static void avconv_cleanup(int ret) for (j = 0; j < ost->nb_bitstream_filters; j++) av_bsf_free(&ost->bsf_ctx[j]); av_freep(&ost->bsf_ctx); - av_freep(&ost->bitstream_filters); av_frame_free(&ost->filtered_frame); @@ -203,13 +203,14 @@ static void avconv_cleanup(int ret) avcodec_free_context(&ost->enc_ctx); - while (av_fifo_size(ost->muxing_queue)) { - AVPacket pkt; - av_fifo_generic_read(ost->muxing_queue, &pkt, sizeof(pkt), NULL); - av_packet_unref(&pkt); + if (ost->muxing_queue) { + while (av_fifo_size(ost->muxing_queue)) { + AVPacket pkt; + av_fifo_generic_read(ost->muxing_queue, &pkt, sizeof(pkt), NULL); + av_packet_unref(&pkt); + } + av_fifo_free(ost->muxing_queue); } - av_fifo_free(ost->muxing_queue); - av_freep(&output_streams[i]); } for (i = 0; i < nb_input_files; i++) { @@ -764,6 +765,15 @@ static int poll_filters(void) for (i = 0; i < nb_output_streams; i++) { int64_t pts = output_streams[i]->sync_opts; + if (output_streams[i]->filter && !output_streams[i]->filter->graph->graph && + !output_streams[i]->filter->graph->nb_inputs) { + ret = configure_filtergraph(output_streams[i]->filter->graph); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Error reinitializing filters!\n"); + return ret; + } + } + if (!output_streams[i]->filter || output_streams[i]->finished || !output_streams[i]->filter->graph->graph) continue; @@ -899,7 +909,7 @@ static void print_report(int is_last_report, int64_t timer_start) char buf[1024]; OutputStream *ost; AVFormatContext *oc; - int64_t total_size; + int64_t total_size = 0; AVCodecContext *enc; int frame_number, vid, i; double bitrate, ti1, pts; @@ -924,16 +934,17 @@ static void print_report(int is_last_report, int64_t timer_start) oc = output_files[0]->ctx; - - total_size = avio_size(oc->pb); - if (total_size <= 0) // FIXME improve avio_size() so it works with non seekable output too - total_size = avio_tell(oc->pb); - if (total_size < 0) { - char errbuf[128]; - av_strerror(total_size, errbuf, sizeof(errbuf)); - av_log(NULL, AV_LOG_VERBOSE, "Bitrate not available, " - "avio_tell() failed: %s\n", errbuf); - total_size = 0; + if (oc->pb) { + total_size = avio_size(oc->pb); + if (total_size <= 0) // FIXME improve avio_size() so it works with non seekable output too + total_size = avio_tell(oc->pb); + if (total_size < 0) { + char errbuf[128]; + av_strerror(total_size, errbuf, sizeof(errbuf)); + av_log(NULL, AV_LOG_VERBOSE, "Bitrate not available, " + "avio_tell() failed: %s\n", errbuf); + total_size = 0; + } } buf[0] = '\0'; @@ -1315,7 +1326,8 @@ int guess_input_channel_layout(InputStream *ist) return 1; } -static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) +static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output, + int *decode_failed) { AVFrame *decoded_frame, *f; AVCodecContext *avctx = ist->dec_ctx; @@ -1328,6 +1340,8 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) decoded_frame = ist->decoded_frame; ret = decode(avctx, decoded_frame, got_output, pkt); + if (ret < 0) + *decode_failed = 1; if (!*got_output || ret < 0) return ret; @@ -1337,7 +1351,7 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) /* if the decoder provides a pts, use it instead of the last packet pts. the decoder could be delaying output by a packet or more. */ if (decoded_frame->pts != AV_NOPTS_VALUE) - ist->next_dts = decoded_frame->pts; + ist->next_dts = av_rescale_q(decoded_frame->pts, ist->st->time_base, AV_TIME_BASE_Q); else if (pkt && pkt->pts != AV_NOPTS_VALUE) { decoded_frame->pts = pkt->pts; } @@ -1366,7 +1380,8 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) return err < 0 ? err : ret; } -static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) +static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output, + int *decode_failed) { AVFrame *decoded_frame, *f; int i, ret = 0, err = 0; @@ -1378,6 +1393,8 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) decoded_frame = ist->decoded_frame; ret = decode(ist->dec_ctx, decoded_frame, got_output, pkt); + if (ret < 0) + *decode_failed = 1; if (!*got_output || ret < 0) return ret; @@ -1418,13 +1435,16 @@ fail: return err < 0 ? err : ret; } -static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output) +static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output, + int *decode_failed) { AVSubtitle subtitle; int i, ret = avcodec_decode_subtitle2(ist->dec_ctx, &subtitle, got_output, pkt); - if (ret < 0) + if (ret < 0) { + *decode_failed = 1; return ret; + } if (!*got_output) return ret; @@ -1480,16 +1500,19 @@ static void process_input_packet(InputStream *ist, const AVPacket *pkt, int no_e while (ist->decoding_needed && (!pkt || avpkt.size > 0)) { int ret = 0; int got_output = 0; + int decode_failed = 0; if (!repeating) ist->last_dts = ist->next_dts; switch (ist->dec_ctx->codec_type) { case AVMEDIA_TYPE_AUDIO: - ret = decode_audio (ist, repeating ? NULL : &avpkt, &got_output); + ret = decode_audio (ist, repeating ? NULL : &avpkt, &got_output, + &decode_failed); break; case AVMEDIA_TYPE_VIDEO: - ret = decode_video (ist, repeating ? NULL : &avpkt, &got_output); + ret = decode_video (ist, repeating ? NULL : &avpkt, &got_output, + &decode_failed); if (repeating && !got_output) ; else if (pkt && pkt->duration) @@ -1506,16 +1529,21 @@ static void process_input_packet(InputStream *ist, const AVPacket *pkt, int no_e case AVMEDIA_TYPE_SUBTITLE: if (repeating) break; - ret = transcode_subtitles(ist, &avpkt, &got_output); + ret = transcode_subtitles(ist, &avpkt, &got_output, &decode_failed); break; default: return; } if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Error while decoding stream #%d:%d\n", - ist->file_index, ist->st->index); - if (exit_on_error) + if (decode_failed) { + av_log(NULL, AV_LOG_ERROR, "Error while decoding stream #%d:%d\n", + ist->file_index, ist->st->index); + } else { + av_log(NULL, AV_LOG_FATAL, "Error while processing the decoded " + "data for stream #%d:%d\n", ist->file_index, ist->st->index); + } + if (!decode_failed || exit_on_error) exit_program(1); break; } @@ -1770,17 +1798,8 @@ static int init_output_bsfs(OutputStream *ost) if (!ost->nb_bitstream_filters) return 0; - ost->bsf_ctx = av_mallocz_array(ost->nb_bitstream_filters, sizeof(*ost->bsf_ctx)); - if (!ost->bsf_ctx) - return AVERROR(ENOMEM); - for (i = 0; i < ost->nb_bitstream_filters; i++) { - ret = av_bsf_alloc(ost->bitstream_filters[i], &ctx); - if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Error allocating a bitstream filter context\n"); - return ret; - } - ost->bsf_ctx[i] = ctx; + ctx = ost->bsf_ctx[i]; ret = avcodec_parameters_copy(ctx->par_in, i ? ost->bsf_ctx[i - 1]->par_out : ost->st->codecpar); @@ -1792,12 +1811,11 @@ static int init_output_bsfs(OutputStream *ost) ret = av_bsf_init(ctx); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Error initializing bitstream filter: %s\n", - ost->bitstream_filters[i]->name); + ctx->filter->name); return ret; } } - ctx = ost->bsf_ctx[ost->nb_bitstream_filters - 1]; ret = avcodec_parameters_copy(ost->st->codecpar, ctx->par_out); if (ret < 0) return ret; @@ -1834,6 +1852,9 @@ static int init_output_stream_streamcopy(OutputStream *ost) ost->st->time_base = ist->st->time_base; + if (ost->bitrate_override) + par_dst->bit_rate = ost->bitrate_override; + if (ist->st->nb_side_data) { ost->st->side_data = av_realloc_array(NULL, ist->st->nb_side_data, sizeof(*ist->st->side_data)); @@ -1967,6 +1988,8 @@ static int init_output_stream_encode(OutputStream *ost) ost->filter->filter->inputs[0]->sample_aspect_ratio; enc_ctx->pix_fmt = ost->filter->filter->inputs[0]->format; + enc_ctx->framerate = ost->frame_rate; + ost->st->avg_frame_rate = ost->frame_rate; if (dec_ctx && @@ -2016,7 +2039,9 @@ static int init_output_stream(OutputStream *ost, char *error, int error_len) if (!av_dict_get(ost->encoder_opts, "threads", NULL, 0)) av_dict_set(&ost->encoder_opts, "threads", "auto", 0); - if (ost->filter && ost->filter->filter->inputs[0]->hw_frames_ctx) { + if (ost->filter && ost->filter->filter->inputs[0]->hw_frames_ctx && + ((AVHWFramesContext*)ost->filter->filter->inputs[0]->hw_frames_ctx->data)->format == + ost->filter->filter->inputs[0]->format) { ost->enc_ctx->hw_frames_ctx = av_buffer_ref(ost->filter->filter->inputs[0]->hw_frames_ctx); if (!ost->enc_ctx->hw_frames_ctx) return AVERROR(ENOMEM);