Unified · Split
| @@ -39,6 +39,7 @@ · 38 unmodified lines | ||
| 39 | 39 | #include "libswresample/swresample.h" |
| 40 | 40 | #include "audio.h" |
| 41 | 41 | #include "avfilter.h" |
| 42 | +#include "filters.h" | |
| 42 | 43 | #include "formats.h" |
| 43 | 44 | #include "internal.h" |
| 44 | 45 | |
| @@ -106,6 +107,9 @@ typedef struct EBUR128Context { · 61 unmodified lines | ||
| 106 | 107 | int nb_channels; ///< number of channels in the input |
| 107 | 108 | double *ch_weighting; ///< channel weighting mapping |
| 108 | 109 | int sample_count; ///< sample count used for refresh frequency, reset at refresh |
| 110 | + int nb_samples; ///< number of samples to consume per single input frame | |
| 111 | + int idx_insample; ///< current sample position of processed samples in single input frame | |
| 112 | + AVFrame *insamples; ///< input samples reference, updated regularly | |
| 109 | 113 | |
| 110 | 114 | /* Filter caches. |
| 111 | 115 | * The mult by 3 in the following is for X[i], X[i-1] and X[i-2] */ |
| @@ -413,8 +417,7 @@ static int config_audio_input(AVFilterLink *inlink) · 301 unmodified lines | ||
| 413 | 417 | * can be more complex to integrate in the one-sample loop of |
| 414 | 418 | * filter_frame()). */ |
| 415 | 419 | if (ebur128->metadata || (ebur128->peak_mode & PEAK_MODE_TRUE_PEAKS)) |
| 416 | − inlink->min_samples = | |
| 417 | − inlink->max_samples = inlink->sample_rate / 10; | |
| 420 | + ebur128->nb_samples = inlink->sample_rate / 10; | |
| 418 | 421 | return 0; |
| 419 | 422 | } |
| 420 | 423 | |
| @@ -621,7 +624,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) · 200 unmodified lines | ||
| 621 | 624 | AVFrame *pic = ebur128->outpicref; |
| 622 | 625 | |
| 623 | 626 | #if CONFIG_SWRESAMPLE |
| 624 | − if (ebur128->peak_mode & PEAK_MODE_TRUE_PEAKS) { | |
| 627 | + if (ebur128->peak_mode & PEAK_MODE_TRUE_PEAKS && ebur128->idx_insample == 0) { | |
| 625 | 628 | const double *swr_samples = ebur128->swr_buf; |
| 626 | 629 | int ret = swr_convert(ebur128->swr_ctx, (uint8_t**)&ebur128->swr_buf, 19200, |
| 627 | 630 | (const uint8_t **)insamples->data, nb_samples); |
| @@ -640,7 +643,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) · 12 unmodified lines | ||
| 640 | 643 | } |
| 641 | 644 | #endif |
| 642 | 645 | |
| 643 | − for (idx_insample = 0; idx_insample < nb_samples; idx_insample++) { | |
| 646 | + for (idx_insample = ebur128->idx_insample; idx_insample < nb_samples; idx_insample++) { | |
| 644 | 647 | const int bin_id_400 = ebur128->i400.cache_pos; |
| 645 | 648 | const int bin_id_3000 = ebur128->i3000.cache_pos; |
| 646 | 649 | |
| @@ -660,9 +663,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) · 13 unmodified lines | ||
| 660 | 663 | double bin; |
| 661 | 664 | |
| 662 | 665 | if (ebur128->peak_mode & PEAK_MODE_SAMPLES_PEAKS) |
| 663 | − ebur128->sample_peaks[ch] = FFMAX(ebur128->sample_peaks[ch], fabs(*samples)); | |
| 666 | + ebur128->sample_peaks[ch] = FFMAX(ebur128->sample_peaks[ch], fabs(samples[idx_insample * nb_channels + ch])); | |
| 664 | 667 | |
| 665 | − ebur128->x[ch * 3] = *samples++; // set X[i] | |
| 668 | + ebur128->x[ch * 3] = samples[idx_insample * nb_channels + ch]; // set X[i] | |
| 666 | 669 | |
| 667 | 670 | if (!ebur128->ch_weighting[ch]) |
| 668 | 671 | continue; |
| @@ -801,7 +804,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) · 132 unmodified lines | ||
| 801 | 804 | /* push one video frame */ |
| 802 | 805 | if (ebur128->do_video) { |
| 803 | 806 | AVFrame *clone; |
| 804 | − int x, y, ret; | |
| 807 | + int x, y; | |
| 805 | 808 | uint8_t *p; |
| 806 | 809 | double gauge_value; |
| 807 | 810 | int y_loudness_lu_graph, y_loudness_lu_gauge; |
| @@ -853,9 +856,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) · 45 unmodified lines | ||
| 853 | 856 | clone = av_frame_clone(pic); |
| 854 | 857 | if (!clone) |
| 855 | 858 | return AVERROR(ENOMEM); |
| 856 | − ret = ff_filter_frame(outlink, clone); | |
| 857 | − if (ret < 0) | |
| 858 | − return ret; | |
| 859 | + ebur128->idx_insample = idx_insample + 1; | |
| 860 | + ff_filter_set_ready(ctx, 100); | |
| 861 | + return ff_filter_frame(outlink, clone); | |
| 859 | 862 | } |
| 860 | 863 | |
| 861 | 864 | if (ebur128->metadata) { /* happens only once per filter_frame call */ |
| @@ -919,12 +922,53 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) · 57 unmodified lines | ||
| 919 | 922 | PRINT_PEAKS("FTPK", ebur128->true_peaks_per_frame, TRUE); |
| 920 | 923 | PRINT_PEAKS("TPK", ebur128->true_peaks, TRUE); |
| 921 | 924 | av_log(ctx, ebur128->loglevel, "\n"); |
| 925 | + | |
| 922 | 926 | } |
| 923 | 927 | } |
| 924 | 928 | |
| 929 | + ebur128->idx_insample = 0; | |
| 930 | + ebur128->insamples = NULL; | |
| 931 | + | |
| 925 | 932 | return ff_filter_frame(ctx->outputs[ebur128->do_video], insamples); |
| 926 | 933 | } |
| 927 | 934 | |
| 935 | +static int activate(AVFilterContext *ctx) | |
| 936 | +{ | |
| 937 | + AVFilterLink *inlink = ctx->inputs[0]; | |
| 938 | + EBUR128Context *ebur128 = ctx->priv; | |
| 939 | + AVFilterLink *voutlink = ctx->outputs[0]; | |
| 940 | + AVFilterLink *outlink = ctx->outputs[ebur128->do_video]; | |
| 941 | + int ret; | |
| 942 | + | |
| 943 | + FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink); | |
| 944 | + if (ebur128->do_video) | |
| 945 | + FF_FILTER_FORWARD_STATUS_BACK(voutlink, inlink); | |
| 946 | + | |
| 947 | + if (!ebur128->insamples) { | |
| 948 | + AVFrame *in; | |
| 949 | + | |
| 950 | + if (ebur128->nb_samples > 0) { | |
| 951 | + ret = ff_inlink_consume_samples(inlink, ebur128->nb_samples, ebur128->nb_samples, &in); | |
| 952 | + } else { | |
| 953 | + ret = ff_inlink_consume_frame(inlink, &in); | |
| 954 | + } | |
| 955 | + if (ret < 0) | |
| 956 | + return ret; | |
| 957 | + if (ret > 0) | |
| 958 | + ebur128->insamples = in; | |
| 959 | + } | |
| 960 | + | |
| 961 | + if (ebur128->insamples) | |
| 962 | + ret = filter_frame(inlink, ebur128->insamples); | |
| 963 | + | |
| 964 | + FF_FILTER_FORWARD_STATUS_ALL(inlink, ctx); | |
| 965 | + FF_FILTER_FORWARD_WANTED(outlink, inlink); | |
| 966 | + if (ebur128->do_video) | |
| 967 | + FF_FILTER_FORWARD_WANTED(voutlink, inlink); | |
| 968 | + | |
| 969 | + return ret; | |
| 970 | +} | |
| 971 | + | |
| 928 | 972 | static int query_formats(AVFilterContext *ctx) |
| 929 | 973 | { |
| 930 | 974 | EBUR128Context *ebur128 = ctx->priv; |
| @@ -1040,7 +1084,6 @@ static const AVFilterPad ebur128_inputs[] = { · 109 unmodified lines | ||
| 1040 | 1084 | { |
| 1041 | 1085 | .name = "default", |
| 1042 | 1086 | .type = AVMEDIA_TYPE_AUDIO, |
| 1043 | − .filter_frame = filter_frame, | |
| 1044 | 1087 | .config_props = config_audio_input, |
| 1045 | 1088 | }, |
| 1046 | 1089 | }; |
| @@ -1051,6 +1094,7 @@ const AVFilter ff_af_ebur128 = { · 4 unmodified lines | ||
| 1051 | 1094 | .priv_size = sizeof(EBUR128Context), |
| 1052 | 1095 | .init = init, |
| 1053 | 1096 | .uninit = uninit, |
| 1097 | + .activate = activate, | |
| 1054 | 1098 | FILTER_INPUTS(ebur128_inputs), |
| 1055 | 1099 | .outputs = NULL, |
| 1056 | 1100 | FILTER_QUERY_FUNC(query_formats), |