Showing the changes to libavfilter (1 of 1 file). Show all
Unified · Split
| @@ -93,6 +93,11 @@ typedef struct DynamicAudioNormalizerContext { · 92 unmodified lines | |||
| 93 | AVFrame *window; | 93 | AVFrame *window; |
| 94 | } DynamicAudioNormalizerContext; | 94 | } DynamicAudioNormalizerContext; |
| 95 | 95 | ||
| 96 | typedef struct ThreadData { | ||
| 97 | AVFrame *in, *out; | ||
| 98 | int enabled; | ||
| 99 | } ThreadData; | ||
| 100 | |||
| 96 | #define OFFSET(x) offsetof(DynamicAudioNormalizerContext, x) | 101 | #define OFFSET(x) offsetof(DynamicAudioNormalizerContext, x) |
| 97 | #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM | 102 | #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM |
| 98 | 103 | ||
| @@ -521,6 +526,20 @@ static void update_gain_history(DynamicAudioNormalizerContext *s, int channel, · 422 unmodified lines | |||
| 521 | } | 526 | } |
| 522 | } | 527 | } |
| 523 | 528 | ||
| 529 | static int update_gain_histories(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) | ||
| 530 | { | ||
| 531 | DynamicAudioNormalizerContext *s = ctx->priv; | ||
| 532 | AVFrame *analyze_frame = arg; | ||
| 533 | const int channels = s->channels; | ||
| 534 | const int start = (channels * jobnr) / nb_jobs; | ||
| 535 | const int end = (channels * (jobnr+1)) / nb_jobs; | ||
| 536 | |||
| 537 | for (int c = start; c < end; c++) | ||
| 538 | update_gain_history(s, c, get_max_local_gain(s, analyze_frame, c)); | ||
| 539 | |||
| 540 | return 0; | ||
| 541 | } | ||
| 542 | |||
| 524 | static inline double update_value(double new, double old, double aggressiveness) | 543 | static inline double update_value(double new, double old, double aggressiveness) |
| 525 | { | 544 | { |
| 526 | av_assert0((aggressiveness >= 0.0) && (aggressiveness <= 1.0)); | 545 | av_assert0((aggressiveness >= 0.0) && (aggressiveness <= 1.0)); |
| @@ -655,8 +674,9 @@ static void perform_compression(DynamicAudioNormalizerContext *s, AVFrame *frame · 128 unmodified lines | |||
| 655 | } | 674 | } |
| 656 | } | 675 | } |
| 657 | 676 | ||
| 658 | static int analyze_frame(DynamicAudioNormalizerContext *s, AVFilterLink *outlink, AVFrame **frame) | 677 | static int analyze_frame(AVFilterContext *ctx, AVFilterLink *outlink, AVFrame **frame) |
| 659 | { | 678 | { |
| 679 | DynamicAudioNormalizerContext *s = ctx->priv; | ||
| 660 | AVFrame *analyze_frame; | 680 | AVFrame *analyze_frame; |
| 661 | 681 | ||
| 662 | if (s->dc_correction || s->compress_factor > DBL_EPSILON) { | 682 | if (s->dc_correction || s->compress_factor > DBL_EPSILON) { |
| @@ -716,34 +736,49 @@ static int analyze_frame(DynamicAudioNormalizerContext *s, AVFilterLink *outlink · 53 unmodified lines | |||
| 716 | for (int c = 0; c < s->channels; c++) | 736 | for (int c = 0; c < s->channels; c++) |
| 717 | update_gain_history(s, c, gain); | 737 | update_gain_history(s, c, gain); |
| 718 | } else { | 738 | } else { |
| 719 | for (int c = 0; c < s->channels; c++) | 739 | ff_filter_execute(ctx, update_gain_histories, analyze_frame, NULL, |
| 720 | update_gain_history(s, c, get_max_local_gain(s, analyze_frame, c)); | 740 | FFMIN(s->channels, ff_filter_get_nb_threads(ctx))); |
| 721 | } | 741 | } |
| 722 | 742 | ||
| 723 | return 0; | 743 | return 0; |
| 724 | } | 744 | } |
| 725 | 745 | ||
| 726 | static void amplify_frame(DynamicAudioNormalizerContext *s, AVFrame *in, | 746 | static void amplify_channel(DynamicAudioNormalizerContext *s, AVFrame *in, |
| 727 | AVFrame *frame, int enabled) | 747 | AVFrame *frame, int enabled, int c) |
| 728 | { | 748 | { |
| 729 | for (int c = 0; c < s->channels; c++) { | 749 | const int bypass = bypass_channel(s, frame, c); |
| 730 | const int bypass = bypass_channel(s, frame, c); | 750 | const double *src_ptr = (const double *)in->extended_data[c]; |
| 731 | const double *src_ptr = (const double *)in->extended_data[c]; | 751 | double *dst_ptr = (double *)frame->extended_data[c]; |
| 732 | double *dst_ptr = (double *)frame->extended_data[c]; | 752 | double current_amplification_factor; |
| 733 | double current_amplification_factor; | ||
| 734 | |||
| 735 | cqueue_dequeue(s->gain_history_smoothed[c], ¤t_amplification_factor); | ||
| 736 | 753 | ||
| 737 | for (int i = 0; i < frame->nb_samples && enabled && !bypass; i++) { | 754 | cqueue_dequeue(s->gain_history_smoothed[c], ¤t_amplification_factor); |
| 738 | const double amplification_factor = fade(s->prev_amplification_factor[c], | ||
| 739 | current_amplification_factor, i, | ||
| 740 | frame->nb_samples); | ||
| 741 | 755 | ||
| 742 | dst_ptr[i] = src_ptr[i] * amplification_factor; | 756 | for (int i = 0; i < frame->nb_samples && enabled && !bypass; i++) { |
| 743 | } | 757 | const double amplification_factor = fade(s->prev_amplification_factor[c], |
| 758 | current_amplification_factor, i, | ||
| 759 | frame->nb_samples); | ||
| 744 | 760 | ||
| 745 | s->prev_amplification_factor[c] = current_amplification_factor; | 761 | dst_ptr[i] = src_ptr[i] * amplification_factor; |
| 746 | } | 762 | } |
| 763 | |||
| 764 | s->prev_amplification_factor[c] = current_amplification_factor; | ||
| 765 | } | ||
| 766 | |||
| 767 | static int amplify_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) | ||
| 768 | { | ||
| 769 | DynamicAudioNormalizerContext *s = ctx->priv; | ||
| 770 | ThreadData *td = arg; | ||
| 771 | AVFrame *out = td->out; | ||
| 772 | AVFrame *in = td->in; | ||
| 773 | const int enabled = td->enabled; | ||
| 774 | const int channels = s->channels; | ||
| 775 | const int start = (channels * jobnr) / nb_jobs; | ||
| 776 | const int end = (channels * (jobnr+1)) / nb_jobs; | ||
| 777 | |||
| 778 | for (int ch = start; ch < end; ch++) | ||
| 779 | amplify_channel(s, in, out, enabled, ch); | ||
| 780 | |||
| 781 | return 0; | ||
| 747 | } | 782 | } |
| 748 | 783 | ||
| 749 | static int filter_frame(AVFilterLink *inlink, AVFrame *in) | 784 | static int filter_frame(AVFilterLink *inlink, AVFrame *in) |
| @@ -751,6 +786,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) · 1 unmodified line | |||
| 751 | AVFilterContext *ctx = inlink->dst; | 786 | AVFilterContext *ctx = inlink->dst; |
| 752 | DynamicAudioNormalizerContext *s = ctx->priv; | 787 | DynamicAudioNormalizerContext *s = ctx->priv; |
| 753 | AVFilterLink *outlink = ctx->outputs[0]; | 788 | AVFilterLink *outlink = ctx->outputs[0]; |
| 789 | ThreadData td; | ||
| 754 | int ret; | 790 | int ret; |
| 755 | 791 | ||
| 756 | while (((s->queue.available >= s->filter_size) || | 792 | while (((s->queue.available >= s->filter_size) || |
| @@ -773,7 +809,12 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) · 16 unmodified lines | |||
| 773 | av_frame_copy_props(out, in); | 809 | av_frame_copy_props(out, in); |
| 774 | } | 810 | } |
| 775 | 811 | ||
| 776 | amplify_frame(s, in, out, is_enabled > 0.); | 812 | td.in = in; |
| 813 | td.out = out; | ||
| 814 | td.enabled = is_enabled > 0.; | ||
| 815 | ff_filter_execute(ctx, amplify_channels, &td, NULL, | ||
| 816 | FFMIN(s->channels, ff_filter_get_nb_threads(ctx))); | ||
| 817 | |||
| 777 | s->pts = out->pts + av_rescale_q(out->nb_samples, av_make_q(1, outlink->sample_rate), | 818 | s->pts = out->pts + av_rescale_q(out->nb_samples, av_make_q(1, outlink->sample_rate), |
| 778 | outlink->time_base); | 819 | outlink->time_base); |
| 779 | if (out != in) | 820 | if (out != in) |
| @@ -783,7 +824,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) · 3 unmodified lines | |||
| 783 | return ret; | 824 | return ret; |
| 784 | } | 825 | } |
| 785 | 826 | ||
| 786 | ret = analyze_frame(s, outlink, &in); | 827 | ret = analyze_frame(ctx, outlink, &in); |
| 787 | if (ret < 0) | 828 | if (ret < 0) |
| 788 | return ret; | 829 | return ret; |
| 789 | if (!s->eof) { | 830 | if (!s->eof) { |
| @@ -940,6 +981,7 @@ const AVFilter ff_af_dynaudnorm = { · 150 unmodified lines | |||
| 940 | FILTER_OUTPUTS(avfilter_af_dynaudnorm_outputs), | 981 | FILTER_OUTPUTS(avfilter_af_dynaudnorm_outputs), |
| 941 | FILTER_SINGLE_SAMPLEFMT(AV_SAMPLE_FMT_DBLP), | 982 | FILTER_SINGLE_SAMPLEFMT(AV_SAMPLE_FMT_DBLP), |
| 942 | .priv_class = &dynaudnorm_class, | 983 | .priv_class = &dynaudnorm_class, |
| 943 | .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL, | 984 | .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | |
| 985 | AVFILTER_FLAG_SLICE_THREADS, | ||
| 944 | .process_command = process_command, | 986 | .process_command = process_command, |
| 945 | }; | 987 | }; |