X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=ffmpeg.c;h=a5ec3c38338eb6a02ccee07263368fcadbc55b35;hb=17ab8f7e6852a9db46aec3267bc8a7e40dde849f;hp=bf5e9834395d4a4993d423ca60e13d0b7ea60535;hpb=28765693955fcfb843009b834d4e2a4fe0211526;p=ffmpeg diff --git a/ffmpeg.c b/ffmpeg.c index bf5e9834395..a5ec3c38338 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -527,6 +527,8 @@ static void ffmpeg_cleanup(int ret) av_freep(&ost->audio_channels_map); ost->audio_channels_mapped = 0; + av_dict_free(&ost->sws_dict); + avcodec_free_context(&ost->enc_ctx); av_freep(&output_streams[i]); @@ -554,8 +556,12 @@ static void ffmpeg_cleanup(int ret) av_freep(&input_streams[i]); } - if (vstats_file) - fclose(vstats_file); + if (vstats_file) { + if (fclose(vstats_file)) + av_log(NULL, AV_LOG_ERROR, + "Error closing vstats file, loss of information possible: %s\n", + av_err2str(AVERROR(errno))); + } av_freep(&vstats_filename); av_freep(&input_streams); @@ -683,47 +689,10 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost) if (bsfc) av_packet_split_side_data(pkt); - while (bsfc) { - AVPacket new_pkt = *pkt; - AVDictionaryEntry *bsf_arg = av_dict_get(ost->bsf_args, - bsfc->filter->name, - NULL, 0); - int a = av_bitstream_filter_filter(bsfc, avctx, - bsf_arg ? bsf_arg->value : NULL, - &new_pkt.data, &new_pkt.size, - pkt->data, pkt->size, - pkt->flags & AV_PKT_FLAG_KEY); - if(a == 0 && new_pkt.data != pkt->data) { - uint8_t *t = av_malloc(new_pkt.size + AV_INPUT_BUFFER_PADDING_SIZE); //the new should be a subset of the old so cannot overflow - if(t) { - memcpy(t, new_pkt.data, new_pkt.size); - memset(t + new_pkt.size, 0, AV_INPUT_BUFFER_PADDING_SIZE); - new_pkt.data = t; - new_pkt.buf = NULL; - a = 1; - } else - a = AVERROR(ENOMEM); - } - if (a > 0) { - pkt->side_data = NULL; - pkt->side_data_elems = 0; - av_packet_unref(pkt); - new_pkt.buf = av_buffer_create(new_pkt.data, new_pkt.size, - av_buffer_default_free, NULL, 0); - if (!new_pkt.buf) - exit_program(1); - } else if (a < 0) { - new_pkt = *pkt; - av_log(NULL, AV_LOG_ERROR, "Failed to open bitstream filter %s for stream %d with codec %s", - bsfc->filter->name, pkt->stream_index, - avctx->codec ? avctx->codec->name : "copy"); - print_error("", a); - if (exit_on_error) - exit_program(1); - } - *pkt = new_pkt; - - bsfc = bsfc->next; + if ((ret = av_apply_bitstream_filters(avctx, pkt, bsfc)) < 0) { + print_error("", ret); + if (exit_on_error) + exit_program(1); } if (!(s->oformat->flags & AVFMT_NOTIMESTAMPS)) { @@ -1533,10 +1502,13 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti AVCodecContext *enc; int frame_number, vid, i; double bitrate; + double speed; int64_t pts = INT64_MIN + 1; static int64_t last_time = -1; static int qp_histogram[52]; int hours, mins, secs, us; + int ret; + float t; if (!print_stats && !is_last_report && !progress_avio) return; @@ -1551,6 +1523,8 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti last_time = cur_time; } + t = (cur_time-timer_start) / 1000000.0; + oc = output_files[0]->ctx; @@ -1574,7 +1548,7 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti ost->file_index, ost->index, q); } if (!vid && enc->codec_type == AVMEDIA_TYPE_VIDEO) { - float fps, t = (cur_time-timer_start) / 1000000.0; + float fps; frame_number = ost->frame_number; fps = t > 1 ? frame_number / t : 0; @@ -1592,7 +1566,7 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti 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", (int)lrintf(log2(qp_histogram[j] + 1))); + snprintf(buf + strlen(buf), sizeof(buf) - strlen(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)) { @@ -1642,6 +1616,7 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti mins %= 60; 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="); @@ -1673,6 +1648,14 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti 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_script, "speed=N/A\n"); + } else { + snprintf(buf + strlen(buf), sizeof(buf) - strlen(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()) { @@ -1691,7 +1674,9 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti avio_flush(progress_avio); av_bprint_finalize(&buf_script, NULL); if (is_last_report) { - avio_closep(&progress_avio); + if ((ret = avio_closep(&progress_avio)) < 0) + av_log(NULL, AV_LOG_ERROR, + "Error closing progress log, loss of information possible: %s\n", av_err2str(ret)); } } @@ -1726,11 +1711,11 @@ static void flush_encoders(void) switch (enc->codec_type) { case AVMEDIA_TYPE_AUDIO: encode = avcodec_encode_audio2; - desc = "Audio"; + desc = "audio"; break; case AVMEDIA_TYPE_VIDEO: encode = avcodec_encode_video2; - desc = "Video"; + desc = "video"; break; default: stop_encoding = 1; @@ -1746,7 +1731,7 @@ static void flush_encoders(void) update_benchmark(NULL); ret = encode(enc, &pkt, NULL, &got_packet); - update_benchmark("flush %s %d.%d", desc, ost->file_index, ost->index); + update_benchmark("flush_%s %d.%d", desc, ost->file_index, ost->index); if (ret < 0) { av_log(NULL, AV_LOG_FATAL, "%s encoding failed: %s\n", desc, @@ -1831,7 +1816,7 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p if (f->recording_time != INT64_MAX) { start_time = f->ctx->start_time; - if (f->start_time != AV_NOPTS_VALUE) + if (f->start_time != AV_NOPTS_VALUE && copy_ts) start_time += f->start_time; if (ist->pts >= f->recording_time + start_time) { close_output_stream(ost); @@ -2643,6 +2628,28 @@ static int init_output_stream(OutputStream *ost, char *error, int error_len) exit_program(1); } + if (ost->enc_ctx->nb_coded_side_data) { + int i; + + ost->st->side_data = av_realloc_array(NULL, ost->enc_ctx->nb_coded_side_data, + sizeof(*ost->st->side_data)); + if (!ost->st->side_data) + return AVERROR(ENOMEM); + + for (i = 0; i < ost->enc_ctx->nb_coded_side_data; i++) { + const AVPacketSideData *sd_src = &ost->enc_ctx->coded_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++; + } + } + // copy timebase while removing common factors ost->st->time_base = av_add_q(ost->enc_ctx->time_base, (AVRational){0, 1}); ost->st->codec->codec= ost->enc_ctx->codec; @@ -3395,6 +3402,18 @@ static OutputStream *choose_output(void) return ost_min; } +static void set_tty_echo(int on) +{ +#if HAVE_TERMIOS_H + struct termios tty; + if (tcgetattr(0, &tty) == 0) { + if (on) tty.c_lflag |= ECHO; + else tty.c_lflag &= ~ECHO; + tcsetattr(0, TCSANOW, &tty); + } +#endif +} + static int check_keyboard_interaction(int64_t cur_time) { int i, ret, key; @@ -3427,10 +3446,13 @@ static int check_keyboard_interaction(int64_t cur_time) int k, n = 0; fprintf(stderr, "\nEnter command: |all