X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=fftools%2Fffmpeg.c;h=b72884673d423d2e553e354cad892f333ff35446;hb=60c9a2553041152a32e7093756f728898593a585;hp=a37de2ff98419f2f0eb7c4ba92f4f556d195cf05;hpb=9471122a1b5dec34572c3d4c675737f0493d140e;p=ffmpeg diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index a37de2ff984..b72884673d4 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -551,9 +551,6 @@ static void ffmpeg_cleanup(int ret) av_frame_free(&ost->last_frame); av_dict_free(&ost->encoder_opts); - av_parser_close(ost->parser); - avcodec_free_context(&ost->parser_avctx); - av_freep(&ost->forced_keyframes); av_expr_free(ost->forced_keyframes_pexpr); av_freep(&ost->avfilter); @@ -1637,8 +1634,7 @@ static void print_final_stats(int64_t total_size) static void print_report(int is_last_report, int64_t timer_start, int64_t cur_time) { - char buf[1024]; - AVBPrint buf_script; + AVBPrint buf, buf_script; OutputStream *ost; AVFormatContext *oc; int64_t total_size; @@ -1650,6 +1646,7 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti static int64_t last_time = -1; static int qp_histogram[52]; int hours, mins, secs, us; + const char *hours_sign; int ret; float t; @@ -1675,8 +1672,8 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti if (total_size <= 0) // FIXME improve avio_size() so it works with non seekable output too total_size = avio_tell(oc->pb); - buf[0] = '\0'; vid = 0; + av_bprint_init(&buf, 0, AV_BPRINT_SIZE_AUTOMATIC); av_bprint_init(&buf_script, 0, 1); for (i = 0; i < nb_output_streams; i++) { float q = -1; @@ -1686,7 +1683,7 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti q = ost->quality / (float) FF_QP2LAMBDA; if (vid && enc->codec_type == AVMEDIA_TYPE_VIDEO) { - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "q=%2.1f ", q); + av_bprintf(&buf, "q=%2.1f ", q); av_bprintf(&buf_script, "stream_%d_%d_q=%.1f\n", ost->file_index, ost->index, q); } @@ -1695,21 +1692,21 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti frame_number = ost->frame_number; fps = t > 1 ? frame_number / t : 0; - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "frame=%5d fps=%3.*f q=%3.1f ", + av_bprintf(&buf, "frame=%5d fps=%3.*f q=%3.1f ", frame_number, fps < 9.95, fps, q); av_bprintf(&buf_script, "frame=%d\n", frame_number); av_bprintf(&buf_script, "fps=%.1f\n", fps); av_bprintf(&buf_script, "stream_%d_%d_q=%.1f\n", ost->file_index, ost->index, q); if (is_last_report) - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "L"); + av_bprintf(&buf, "L"); if (qp_hist) { int j; int qp = lrintf(q); if (qp >= 0 && qp < FF_ARRAY_ELEMS(qp_histogram)) qp_histogram[qp]++; for (j = 0; j < 32; j++) - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%X", av_log2(qp_histogram[j] + 1)); + av_bprintf(&buf, "%X", av_log2(qp_histogram[j] + 1)); } if ((enc->flags & AV_CODEC_FLAG_PSNR) && (ost->pict_type != AV_PICTURE_TYPE_NONE || is_last_report)) { @@ -1718,7 +1715,7 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti double scale, scale_sum = 0; double p; char type[3] = { 'Y','U','V' }; - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "PSNR="); + av_bprintf(&buf, "PSNR="); for (j = 0; j < 3; j++) { if (is_last_report) { error = enc->error[j]; @@ -1732,12 +1729,12 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti error_sum += error; scale_sum += scale; p = psnr(error / scale); - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%c:%2.2f ", type[j], p); + av_bprintf(&buf, "%c:%2.2f ", type[j], p); av_bprintf(&buf_script, "stream_%d_%d_psnr_%c=%2.2f\n", ost->file_index, ost->index, type[j] | 32, p); } p = psnr(error_sum / scale_sum); - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "*:%2.2f ", psnr(error_sum / scale_sum)); + av_bprintf(&buf, "*:%2.2f ", psnr(error_sum / scale_sum)); av_bprintf(&buf_script, "stream_%d_%d_psnr_all=%2.2f\n", ost->file_index, ost->index, p); } @@ -1757,57 +1754,62 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti secs %= 60; hours = mins / 60; mins %= 60; + hours_sign = (pts < 0) ? "-" : ""; bitrate = pts && total_size >= 0 ? total_size * 8 / (pts / 1000.0) : -1; speed = t != 0.0 ? (double)pts / AV_TIME_BASE / t : -1; - if (total_size < 0) snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), - "size=N/A time="); - else snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), - "size=%8.0fkB time=", total_size / 1024.0); - if (pts < 0) - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "-"); - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), - "%02d:%02d:%02d.%02d ", hours, mins, secs, - (100 * us) / AV_TIME_BASE); + if (total_size < 0) av_bprintf(&buf, "size=N/A time="); + else av_bprintf(&buf, "size=%8.0fkB time=", total_size / 1024.0); + if (pts == AV_NOPTS_VALUE) { + av_bprintf(&buf, "N/A "); + } else { + av_bprintf(&buf, "%s%02d:%02d:%02d.%02d ", + hours_sign, hours, mins, secs, (100 * us) / AV_TIME_BASE); + } if (bitrate < 0) { - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),"bitrate=N/A"); + av_bprintf(&buf, "bitrate=N/A"); av_bprintf(&buf_script, "bitrate=N/A\n"); }else{ - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),"bitrate=%6.1fkbits/s", bitrate); + av_bprintf(&buf, "bitrate=%6.1fkbits/s", bitrate); av_bprintf(&buf_script, "bitrate=%6.1fkbits/s\n", bitrate); } if (total_size < 0) av_bprintf(&buf_script, "total_size=N/A\n"); else av_bprintf(&buf_script, "total_size=%"PRId64"\n", total_size); - av_bprintf(&buf_script, "out_time_ms=%"PRId64"\n", pts); - av_bprintf(&buf_script, "out_time=%02d:%02d:%02d.%06d\n", - hours, mins, secs, us); + if (pts == AV_NOPTS_VALUE) { + av_bprintf(&buf_script, "out_time_ms=N/A\n"); + av_bprintf(&buf_script, "out_time=N/A\n"); + } else { + av_bprintf(&buf_script, "out_time_ms=%"PRId64"\n", pts); + av_bprintf(&buf_script, "out_time=%s%02d:%02d:%02d.%06d\n", + hours_sign, hours, mins, secs, us); + } if (nb_frames_dup || nb_frames_drop) - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " dup=%d drop=%d", - nb_frames_dup, nb_frames_drop); + av_bprintf(&buf, " dup=%d drop=%d", nb_frames_dup, nb_frames_drop); av_bprintf(&buf_script, "dup_frames=%d\n", nb_frames_dup); av_bprintf(&buf_script, "drop_frames=%d\n", nb_frames_drop); if (speed < 0) { - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf)," speed=N/A"); + av_bprintf(&buf, " speed=N/A"); av_bprintf(&buf_script, "speed=N/A\n"); } else { - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf)," speed=%4.3gx", speed); + av_bprintf(&buf, " speed=%4.3gx", speed); av_bprintf(&buf_script, "speed=%4.3gx\n", speed); } if (print_stats || is_last_report) { const char end = is_last_report ? '\n' : '\r'; if (print_stats==1 && AV_LOG_INFO > av_log_get_level()) { - fprintf(stderr, "%s %c", buf, end); + fprintf(stderr, "%s %c", buf.str, end); } else - av_log(NULL, AV_LOG_INFO, "%s %c", buf, end); + av_log(NULL, AV_LOG_INFO, "%s %c", buf.str, end); fflush(stderr); } + av_bprint_finalize(&buf, NULL); if (progress_avio) { av_bprintf(&buf_script, "progress=%s\n", @@ -1827,6 +1829,19 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti print_final_stats(total_size); } +static void ifilter_parameters_from_codecpar(InputFilter *ifilter, AVCodecParameters *par) +{ + // We never got any input. Set a fake format, which will + // come from libavformat. + ifilter->format = par->format; + ifilter->sample_rate = par->sample_rate; + ifilter->channels = par->channels; + ifilter->channel_layout = par->channel_layout; + ifilter->width = par->width; + ifilter->height = par->height; + ifilter->sample_aspect_ratio = par->sample_aspect_ratio; +} + static void flush_encoders(void) { int i, ret; @@ -1853,18 +1868,8 @@ static void flush_encoders(void) int x; for (x = 0; x < fg->nb_inputs; x++) { InputFilter *ifilter = fg->inputs[x]; - if (ifilter->format < 0) { - AVCodecParameters *par = ifilter->ist->st->codecpar; - // We never got any input. Set a fake format, which will - // come from libavformat. - ifilter->format = par->format; - ifilter->sample_rate = par->sample_rate; - ifilter->channels = par->channels; - ifilter->channel_layout = par->channel_layout; - ifilter->width = par->width; - ifilter->height = par->height; - ifilter->sample_aspect_ratio = par->sample_aspect_ratio; - } + if (ifilter->format < 0) + ifilter_parameters_from_codecpar(ifilter, ifilter->ist->st->codecpar); } if (!ifilter_has_all_input_formats(fg)) @@ -2046,30 +2051,15 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p opkt.duration = av_rescale_q(pkt->duration, ist->st->time_base, ost->mux_timebase); opkt.flags = pkt->flags; - // FIXME remove the following 2 lines they shall be replaced by the bitstream filters - if ( ost->st->codecpar->codec_id != AV_CODEC_ID_H264 - && ost->st->codecpar->codec_id != AV_CODEC_ID_MPEG1VIDEO - && ost->st->codecpar->codec_id != AV_CODEC_ID_MPEG2VIDEO - && ost->st->codecpar->codec_id != AV_CODEC_ID_VC1 - ) { - int ret = av_parser_change(ost->parser, ost->parser_avctx, - &opkt.data, &opkt.size, - pkt->data, pkt->size, - pkt->flags & AV_PKT_FLAG_KEY); - if (ret < 0) { - av_log(NULL, AV_LOG_FATAL, "av_parser_change failed: %s\n", - av_err2str(ret)); + + if (pkt->buf) { + opkt.buf = av_buffer_ref(pkt->buf); + if (!opkt.buf) exit_program(1); - } - if (ret) { - opkt.buf = av_buffer_create(opkt.data, opkt.size, av_buffer_default_free, NULL, 0); - if (!opkt.buf) - exit_program(1); - } - } else { - opkt.data = pkt->data; - opkt.size = pkt->size; } + opkt.data = pkt->data; + opkt.size = pkt->size; + av_copy_packet_side_data(&opkt, pkt); output_packet(of, &opkt, ost, 0); @@ -2175,10 +2165,7 @@ static int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame) ret = reap_filters(1); if (ret < 0 && ret != AVERROR_EOF) { - char errbuf[128]; - av_strerror(ret, errbuf, sizeof(errbuf)); - - av_log(NULL, AV_LOG_ERROR, "Error while filtering: %s\n", errbuf); + av_log(NULL, AV_LOG_ERROR, "Error while filtering: %s\n", av_err2str(ret)); return ret; } @@ -2212,6 +2199,12 @@ static int ifilter_send_eof(InputFilter *ifilter, int64_t pts) } else { // the filtergraph was never configured FilterGraph *fg = ifilter->graph; + if (ifilter->format < 0) + ifilter_parameters_from_codecpar(ifilter, ifilter->ist->st->codecpar); + if (ifilter->format < 0 && (ifilter->type == AVMEDIA_TYPE_AUDIO || ifilter->type == AVMEDIA_TYPE_VIDEO)) { + av_log(NULL, AV_LOG_ERROR, "Cannot determine format of input stream %d:%d after EOF\n", ifilter->ist->file_index, ifilter->ist->st->index); + return AVERROR_INVALIDDATA; + } for (i = 0; i < fg->nb_inputs; i++) if (!fg->inputs[i]->eof) break; @@ -3122,11 +3115,6 @@ static int init_output_stream_streamcopy(OutputStream *ost) av_display_rotation_set((int32_t *)sd, -ost->rotate_override_value); } - ost->parser = av_parser_init(par_dst->codec_id); - ost->parser_avctx = avcodec_alloc_context3(NULL); - if (!ost->parser_avctx) - return AVERROR(ENOMEM); - switch (par_dst->codec_type) { case AVMEDIA_TYPE_AUDIO: if (audio_volume != 256) { @@ -3502,7 +3490,8 @@ static int init_output_stream(OutputStream *ost, char *error, int error_len) av_buffersink_set_frame_size(ost->filter->filter, ost->enc_ctx->frame_size); assert_avoptions(ost->encoder_opts); - if (ost->enc_ctx->bit_rate && ost->enc_ctx->bit_rate < 1000) + if (ost->enc_ctx->bit_rate && ost->enc_ctx->bit_rate < 1000 && + ost->enc_ctx->codec_id != AV_CODEC_ID_CODEC2 /* don't complain about 700 bit/s modes */) av_log(NULL, AV_LOG_WARNING, "The bitrate parameter is set too low." " It takes bits/s as argument, not kbits/s\n"); @@ -3566,14 +3555,6 @@ static int init_output_stream(OutputStream *ost, char *error, int error_len) ret = init_output_stream_streamcopy(ost); if (ret < 0) return ret; - - /* - * FIXME: will the codec context used by the parser during streamcopy - * This should go away with the new parser API. - */ - ret = avcodec_parameters_to_context(ost->parser_avctx, ost->st->codecpar); - if (ret < 0) - return ret; } // parse user provided disposition, and update stream values @@ -3592,6 +3573,7 @@ static int init_output_stream(OutputStream *ost, char *error, int error_len) { "clean_effects" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_CLEAN_EFFECTS }, .unit = "flags" }, { "captions" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_CAPTIONS }, .unit = "flags" }, { "descriptions" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_DESCRIPTIONS }, .unit = "flags" }, + { "dependent" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_DEPENDENT }, .unit = "flags" }, { "metadata" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_METADATA }, .unit = "flags" }, { NULL }, }; @@ -4166,12 +4148,6 @@ static int seek_to_start(InputFile *ifile, AVFormatContext *is) ist = input_streams[ifile->ist_index + i]; avctx = ist->dec_ctx; - // flush decoders - if (ist->decoding_needed) { - process_input_packet(ist, NULL, 1); - avcodec_flush_buffers(avctx); - } - /* duration is the length of the last frame in a stream * when audio stream is present we don't care about * last video frame length because it's not defined exactly */ @@ -4240,6 +4216,17 @@ static int process_input(int file_index) return ret; } if (ret < 0 && ifile->loop) { + AVCodecContext *avctx; + for (i = 0; i < ifile->nb_streams; i++) { + ist = input_streams[ifile->ist_index + i]; + avctx = ist->dec_ctx; + if (ist->decoding_needed) { + ret = process_input_packet(ist, NULL, 1); + if (ret>0) + return 0; + avcodec_flush_buffers(avctx); + } + } ret = seek_to_start(ifile, is); if (ret < 0) av_log(NULL, AV_LOG_WARNING, "Seek to start failed.\n"); @@ -4636,10 +4623,7 @@ static int transcode(void) ret = transcode_step(); if (ret < 0 && ret != AVERROR_EOF) { - char errbuf[128]; - av_strerror(ret, errbuf, sizeof(errbuf)); - - av_log(NULL, AV_LOG_ERROR, "Error while filtering: %s\n", errbuf); + av_log(NULL, AV_LOG_ERROR, "Error while filtering: %s\n", av_err2str(ret)); break; }