Message ID | 20200718161203.16643-1-onemda@gmail.com |
---|---|
State | New |
Headers | show |
Series | [FFmpeg-devel] avfilter: add radial and circular blur video filter | expand |
Context | Check | Description |
---|---|---|
andriy/default | pending | |
andriy/make | success | Make finished |
andriy/make_fate | success | Make fate finished |
On Sun, 19 Jul 2020, at 16:05, Paul B Mahol wrote:
> You all dislike me on discrimination basis and also object just for objecting.
Discriminate you based on what?
Noone has ever seen you, and therefore noone knows your gender, religion, skin color, race, or any other personal thing on you.
Paul B Mahol (12020-07-19): > I do not need to listen to you at all. > You all dislike me on discrimination basis and also object just for objecting. > > When I have objections to any patches they are silently ignored, other > way around > is different as this patch yet again demonstrates. I will not deny that the fact that I feel you have repeatedly abused me and used similar tactics against me makes pay extra attention to cases where I think you may abuse other contributors, and intervene if I think it necessary. If I am at fault here, we now have a committee that can put me right, and I welcome its judgement on my case. But it does not excuse you for threatening to ignore Steinar's concerns.
On Sun, Jul 19, 2020 at 03:58:32PM +0200, Nicolas George wrote: >> Will apply. > Certainly not before Steinar has had time to review it and tell us > whether you addressed all the concerns. The primary change that I see is the addition of bilinear filtering in the polar to Cartesian step. This makes the filter even slower, but it also increases the output quality significantly. There are still artifacts I've never seen in any other implementation of radial blur, and that stem directly from the choice of algorithm. The comment situation is unchanged, ie., there are none. If someone else thinks the patch as-is is acceptable, I won't block it, in the interest of less hostility. /* Steinar */
On 7/19/20, Steinar H. Gunderson <steinar+ffmpeg@gunderson.no> wrote: > On Sun, Jul 19, 2020 at 03:58:32PM +0200, Nicolas George wrote: >>> Will apply. >> Certainly not before Steinar has had time to review it and tell us >> whether you addressed all the concerns. > > The primary change that I see is the addition of bilinear filtering in the > polar to Cartesian step. This makes the filter even slower, but it also > increases the output quality significantly. There are still artifacts I've > never seen in any other implementation of radial blur, and that stem > directly > from the choice of algorithm. The comment situation is unchanged, ie., there > are none. > > If someone else thinks the patch as-is is acceptable, I won't block it, > in the interest of less hostility. Thanks for confirming you are being hostile. > > /* Steinar */ > -- > Homepage: https://www.sesse.net/ > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
On 7/19/20, Jean-Baptiste Kempf <jb@videolan.org> wrote: > On Sun, 19 Jul 2020, at 16:05, Paul B Mahol wrote: >> You all dislike me on discrimination basis and also object just for >> objecting. > > Discriminate you based on what? > Noone has ever seen you, and therefore noone knows your gender, religion, > skin color, race, or any other personal thing on you. You are now lying. Mr. President you are indeed lying. > > -- > Jean-Baptiste Kempf - President > +33 672 704 734 > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
On Sun, 19 Jul 2020, at 18:14, Paul B Mahol wrote: > On 7/19/20, Jean-Baptiste Kempf <jb@videolan.org> wrote: > > On Sun, 19 Jul 2020, at 16:05, Paul B Mahol wrote: > >> You all dislike me on discrimination basis and also object just for > >> objecting. > > > > Discriminate you based on what? > > Noone has ever seen you, and therefore noone knows your gender, religion, > > skin color, race, or any other personal thing on you. > > You are now lying. How so?
On 7/19/20, Nicolas George <george@nsup.org> wrote: > Paul B Mahol (12020-07-19): >> I do not need to listen to you at all. >> You all dislike me on discrimination basis and also object just for >> objecting. >> >> When I have objections to any patches they are silently ignored, other >> way around >> is different as this patch yet again demonstrates. > > I will not deny that the fact that I feel you have repeatedly abused me > and used similar tactics against me makes pay extra attention to cases > where I think you may abuse other contributors, and intervene if I think > it necessary. If I am at fault here, we now have a committee that can > put me right, and I welcome its judgement on my case. > > But it does not excuse you for threatening to ignore Steinar's concerns. Who abused you? I even asked why one of your patches you posted are not applied. I even vouched for untile filter to be applied. But than you came so high and polite and threatens me for applying against your blockage of my numerous patches out of pure hatred. > > -- > Nicolas George >
On 7/19/20, Jean-Baptiste Kempf <jb@videolan.org> wrote: > On Sun, 19 Jul 2020, at 18:14, Paul B Mahol wrote: >> On 7/19/20, Jean-Baptiste Kempf <jb@videolan.org> wrote: >> > On Sun, 19 Jul 2020, at 16:05, Paul B Mahol wrote: >> >> You all dislike me on discrimination basis and also object just for >> >> objecting. >> > >> > Discriminate you based on what? >> > Noone has ever seen you, and therefore noone knows your gender, >> > religion, >> > skin color, race, or any other personal thing on you. >> >> You are now lying. > > How so? You discriminate me just because I send big patches. While you, in your deepest self could never do such thing. > > -- > Jean-Baptiste Kempf - President > +33 672 704 734 > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
On Sun, 19 Jul 2020, at 18:20, Paul B Mahol wrote: > On 7/19/20, Jean-Baptiste Kempf <jb@videolan.org> wrote: > > On Sun, 19 Jul 2020, at 18:14, Paul B Mahol wrote: > >> On 7/19/20, Jean-Baptiste Kempf <jb@videolan.org> wrote: > >> > On Sun, 19 Jul 2020, at 16:05, Paul B Mahol wrote: > >> >> You all dislike me on discrimination basis and also object just for > >> >> objecting. > >> > > >> > Discriminate you based on what? > >> > Noone has ever seen you, and therefore noone knows your gender, > >> > religion, > >> > skin color, race, or any other personal thing on you. > >> > >> You are now lying. > > > > How so? > > You discriminate me just because I send big patches. "Discrimination is the act of making distinctions between human beings based on the groups, classes, or other categories to which they are perceived to belong. " I really doubt "sending big patches" fit the discrimination definition. And even if it did, I really doubt that the push-back from "all of us" you are seeing is because of discrimination, but more about your attitude towards others. Here, Steinar gives a substantiated remark on your code, which could improve quality and speed, which matches the goal of this project. Why not just apply what he did, and give us a better filter? This is not discrimination, just noone understand your points.
On 7/19/20, Jean-Baptiste Kempf <jb@videolan.org> wrote: > On Sun, 19 Jul 2020, at 18:20, Paul B Mahol wrote: >> On 7/19/20, Jean-Baptiste Kempf <jb@videolan.org> wrote: >> > On Sun, 19 Jul 2020, at 18:14, Paul B Mahol wrote: >> >> On 7/19/20, Jean-Baptiste Kempf <jb@videolan.org> wrote: >> >> > On Sun, 19 Jul 2020, at 16:05, Paul B Mahol wrote: >> >> >> You all dislike me on discrimination basis and also object just for >> >> >> objecting. >> >> > >> >> > Discriminate you based on what? >> >> > Noone has ever seen you, and therefore noone knows your gender, >> >> > religion, >> >> > skin color, race, or any other personal thing on you. >> >> >> >> You are now lying. >> > >> > How so? >> >> You discriminate me just because I send big patches. > > "Discrimination is the act of making distinctions between human beings based > on the groups, classes, or other categories to which they are perceived to > belong. " > > I really doubt "sending big patches" fit the discrimination definition. > > And even if it did, I really doubt that the push-back from "all of us" you > are seeing is because of discrimination, but more about your attitude > towards others. > > Here, Steinar gives a substantiated remark on your code, which could improve > quality and speed, which matches the goal of this project. > > Why not just apply what he did, and give us a better filter? > This is not discrimination, just noone understand your points. Dear Jean-Baptiste Kempf, if I knew how to implement what Steinar wish I would do it already. Clearly there is big miss-understanding here. Steinar could implement such filter already if he knew how to do it. I think he does not know that he does not know that algorithm. The only thing I could propose which would make filter faster under same parameters is to cache all results of atan2f / sqrtf calls. About radial blur center issues, i think Steinar is confusing radial blur with zoom blur.
On Sun, 19 Jul 2020, at 18:37, Paul B Mahol wrote: > > Here, Steinar gives a substantiated remark on your code, which could improve > > quality and speed, which matches the goal of this project. > > > > Why not just apply what he did, and give us a better filter? > > This is not discrimination, just noone understand your points. > > Dear Jean-Baptiste Kempf, if I knew how to implement what Steinar wish > I would do > it already. Clearly there is big miss-understanding here. You see, it would be simpler just to say that, in answer to Steinar, instead of starting a flamewar, noone knows the reason of. > Steinar could implement such filter already if he knew how to do it. > I think he does not know that he does not know that algorithm. I think Steinar knows a bit about filters algorithms: https://git.sesse.net/?p=movit;a=tree , but as all of us, he is human, so he can also make mistakes.
On 7/19/2020 1:13 PM, Paul B Mahol wrote: > On 7/19/20, Steinar H. Gunderson <steinar+ffmpeg@gunderson.no> wrote: >> On Sun, Jul 19, 2020 at 03:58:32PM +0200, Nicolas George wrote: >>>> Will apply. >>> Certainly not before Steinar has had time to review it and tell us >>> whether you addressed all the concerns. >> >> The primary change that I see is the addition of bilinear filtering in the >> polar to Cartesian step. This makes the filter even slower, but it also >> increases the output quality significantly. There are still artifacts I've >> never seen in any other implementation of radial blur, and that stem >> directly >> from the choice of algorithm. The comment situation is unchanged, ie., there >> are none. >> >> If someone else thinks the patch as-is is acceptable, I won't block it, >> in the interest of less hostility. > > > Thanks for confirming you are being hostile. He did no such thing. Please Paul, if you can implement his suggestions then do so, and if you can't then state as much and maybe explain why. But this entire discussion thread is absurd and had no reason to happen.
On Sun, Jul 19, 2020 at 06:37:16PM +0200, Paul B Mahol wrote: > About radial blur center issues, i think Steinar is confusing radial > blur with zoom blur. I must admit I don't know any such difference; this is one of many things that would be useful to have in comments or the commit message (many such effects have different variations under similar names). But I do not believe this is relevant to the artifacts in the center, or the staircase effect on the horizontal white lines -- no matter what you call an filter, they are not inherent to the effect. Both are much less pronounced than in the previous patch set, but still present. For those who want to judge for themselves: https://storage.sesse.net/ffmpeg-radialblur3.png /* Steinar */
On 7/19/20, Steinar H. Gunderson <steinar+ffmpeg@gunderson.no> wrote: > On Sun, Jul 19, 2020 at 06:37:16PM +0200, Paul B Mahol wrote: >> About radial blur center issues, i think Steinar is confusing radial >> blur with zoom blur. > > I must admit I don't know any such difference; this is one of many things > that would be useful to have in comments or the commit message (many such > effects have different variations under similar names). But I do not > believe this is relevant to the artifacts in the center, or the staircase > effect on the horizontal white lines -- no matter what you call an filter, > they are not inherent to the effect. Both are much less pronounced than in > the previous patch set, but still present. > > For those who want to judge for themselves: > > https://storage.sesse.net/ffmpeg-radialblur3.png > I see nothing wrong with that image. You still provided 0 valuable information for your perfect solution algorithm. > /* Steinar */ > -- > Homepage: https://www.sesse.net/ > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
On Sun, Jul 19, 2020 at 07:32:18PM +0200, Paul B Mahol wrote: > I see nothing wrong with that image. Let me provide some zooms. First, center artifacts (the “flower” should not be there): http://storage.sesse.net/ffmpeg-radialblur3-zoom1.png Then, staircase/uneven horizontal line near the edge (the line should not wobble up and down): http://storage.sesse.net/ffmpeg-radialblur3-zoom2.png > You still provided 0 valuable information for your perfect solution algorithm. I haven't claimed any perfect solutions, but I have suggested two different algorithms with details that I both believe would be more performant and sport higher output quality (actually three, but the last one was not with a lot of details). Could you suggest which information you would regard as valuable? Here's the source code for GIMP's zoom blur implementation, which works without any similar artifacts, and has no trigonometry per-pixel: https://gitlab.gnome.org/GNOME/gegl/-/blob/master/operations/common-gpl3+/motion-blur-zoom.c#L160 If you can explain what you mean the difference between radial and zoom blur is, it would probably be possible to adapt the idea. It also has a somewhat more efficient implementation of bilinear filtering than in your patch (three multiplies instead of eight, and also fewer add/sub), although it's likely that a fixed-point implementation would save yet more time if you're interested in trying that. /* Steinar */
On 7/19/20, Steinar H. Gunderson <steinar+ffmpeg@gunderson.no> wrote: > On Sun, Jul 19, 2020 at 07:32:18PM +0200, Paul B Mahol wrote: >> I see nothing wrong with that image. > > Let me provide some zooms. First, center artifacts (the “flower” should not > be there): > > http://storage.sesse.net/ffmpeg-radialblur3-zoom1.png > > Then, staircase/uneven horizontal line near the edge (the line should not > wobble up and down): > > http://storage.sesse.net/ffmpeg-radialblur3-zoom2.png Huh, since when we look at such small differences? > >> You still provided 0 valuable information for your perfect solution >> algorithm. > > I haven't claimed any perfect solutions, but I have suggested two different > algorithms with details that I both believe would be more performant and > sport higher output quality (actually three, but the last one was not with > a lot of details). Could you suggest which information you would regard as > valuable? > > Here's the source code for GIMP's zoom blur implementation, which works > without any similar artifacts, and has no trigonometry per-pixel: > > > https://gitlab.gnome.org/GNOME/gegl/-/blob/master/operations/common-gpl3+/motion-blur-zoom.c#L160 > > If you can explain what you mean the difference between radial and zoom blur > is, it would probably be possible to adapt the idea. That algorithm is very slow for big lengths, it takes ages to process single small image. > > It also has a somewhat more efficient implementation of bilinear filtering > than in your patch (three multiplies instead of eight, and also fewer > add/sub), although it's likely that a fixed-point implementation would save > yet more time if you're interested in trying that. Such micro-optimizations could be added any time later.
On Sun, Jul 19, 2020 at 08:20:40PM +0200, Paul B Mahol wrote: >> If you can explain what you mean the difference between radial and zoom blur >> is, it would probably be possible to adapt the idea. > That algorithm is very slow for big lengths, it takes ages to process > single small image. Yes, this is the non-recursive version, which is O(n) in the number of samples. This is why I recommended the recursive version, which is O(log n) in the number of samples and thus avoids the problem with big lengths. It is fairly straightforward to convert one to the other. >> It also has a somewhat more efficient implementation of bilinear filtering >> than in your patch (three multiplies instead of eight, and also fewer >> add/sub), although it's likely that a fixed-point implementation would save >> yet more time if you're interested in trying that. > Such micro-optimizations could be added any time later. Sure. /* Steinar */
On 7/19/20, Steinar H. Gunderson <steinar+ffmpeg@gunderson.no> wrote: > On Sun, Jul 19, 2020 at 08:20:40PM +0200, Paul B Mahol wrote: >>> If you can explain what you mean the difference between radial and zoom >>> blur >>> is, it would probably be possible to adapt the idea. >> That algorithm is very slow for big lengths, it takes ages to process >> single small image. > > Yes, this is the non-recursive version, which is O(n) in the number of > samples. This is why I recommended the recursive version, which is O(log n) > in the number of samples and thus avoids the problem with big lengths. > It is fairly straightforward to convert one to the other. Really? How so? > >>> It also has a somewhat more efficient implementation of bilinear >>> filtering >>> than in your patch (three multiplies instead of eight, and also fewer >>> add/sub), although it's likely that a fixed-point implementation would >>> save >>> yet more time if you're interested in trying that. >> Such micro-optimizations could be added any time later. > > Sure. > > /* Steinar */ > -- > Homepage: https://www.sesse.net/ > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
On Sun, Jul 19, 2020 at 09:02:30PM +0200, Paul B Mahol wrote: >> Yes, this is the non-recursive version, which is O(n) in the number of >> samples. This is why I recommended the recursive version, which is O(log n) >> in the number of samples and thus avoids the problem with big lengths. >> It is fairly straightforward to convert one to the other. > Really? How so? As previously mentioned, you do two samples, then save to a temporary buffer, two samples from that buffer with half the distance and so on until your samples are only one pixel apart. You can also try doing three or four samples at a time instead of two; experiment a bit and see what gives the best performance. /* Steinar */
On 7/19/20, Steinar H. Gunderson <steinar+ffmpeg@gunderson.no> wrote: > On Sun, Jul 19, 2020 at 09:02:30PM +0200, Paul B Mahol wrote: >>> Yes, this is the non-recursive version, which is O(n) in the number of >>> samples. This is why I recommended the recursive version, which is O(log >>> n) >>> in the number of samples and thus avoids the problem with big lengths. >>> It is fairly straightforward to convert one to the other. >> Really? How so? > > As previously mentioned, you do two samples, then save to a temporary > buffer, > two samples from that buffer with half the distance and so on until your > samples are only one pixel apart. > > You can also try doing three or four samples at a time instead of two; > experiment a bit and see what gives the best performance. This is very slow. > > /* Steinar */ > -- > Homepage: https://www.sesse.net/ > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
On 7/19/20, Paul B Mahol <onemda@gmail.com> wrote: > On 7/19/20, Steinar H. Gunderson <steinar+ffmpeg@gunderson.no> wrote: >> On Sun, Jul 19, 2020 at 09:02:30PM +0200, Paul B Mahol wrote: >>>> Yes, this is the non-recursive version, which is O(n) in the number of >>>> samples. This is why I recommended the recursive version, which is >>>> O(log >>>> n) >>>> in the number of samples and thus avoids the problem with big lengths. >>>> It is fairly straightforward to convert one to the other. >>> Really? How so? >> >> As previously mentioned, you do two samples, then save to a temporary >> buffer, >> two samples from that buffer with half the distance and so on until your >> samples are only one pixel apart. >> >> You can also try doing three or four samples at a time instead of two; >> experiment a bit and see what gives the best performance. > > This is very slow. > Also I fixed silly center artifacts in rblur implementation. Speed here on historic CPU for hd720 is 12-13 frames per second for 23 fps video with slice threading enabled on 4 core CPU. This could be made even faster at expense of more memory usage. I really doubt there is faster algorithm that needs less memory but with no quality drop.
On 7/19/20, Paul B Mahol <onemda@gmail.com> wrote: > On 7/19/20, Paul B Mahol <onemda@gmail.com> wrote: >> On 7/19/20, Steinar H. Gunderson <steinar+ffmpeg@gunderson.no> wrote: >>> On Sun, Jul 19, 2020 at 09:02:30PM +0200, Paul B Mahol wrote: >>>>> Yes, this is the non-recursive version, which is O(n) in the number of >>>>> samples. This is why I recommended the recursive version, which is >>>>> O(log >>>>> n) >>>>> in the number of samples and thus avoids the problem with big lengths. >>>>> It is fairly straightforward to convert one to the other. >>>> Really? How so? >>> >>> As previously mentioned, you do two samples, then save to a temporary >>> buffer, >>> two samples from that buffer with half the distance and so on until your >>> samples are only one pixel apart. >>> >>> You can also try doing three or four samples at a time instead of two; >>> experiment a bit and see what gives the best performance. >> >> This is very slow. >> > > Also I fixed silly center artifacts in rblur implementation. > > Speed here on historic CPU for hd720 is 12-13 frames per second for 23 > fps video with slice threading enabled on 4 core CPU. > > This could be made even faster at expense of more memory usage. > I really doubt there is faster algorithm that needs less memory but > with no quality drop. > Gonna apply this soon, as I'm happy with overall performance and output quality.
Paul B Mahol (12020-07-21):
> Gonna apply this soon, as I'm happy with overall performance and output quality.
Did you get another developer to approve it? If not, the block still
stands.
On 7/21/20, Nicolas George <george@nsup.org> wrote: > Paul B Mahol (12020-07-21): >> Gonna apply this soon, as I'm happy with overall performance and output >> quality. > > Did you get another developer to approve it? If not, the block still > stands. You have just approved it with reply to this same thread. > > -- > Nicolas George > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
On 7/21/20, Paul B Mahol <onemda@gmail.com> wrote: > On 7/21/20, Nicolas George <george@nsup.org> wrote: >> Paul B Mahol (12020-07-21): >>> Gonna apply this soon, as I'm happy with overall performance and output >>> quality. >> >> Did you get another developer to approve it? If not, the block still >> stands. > > You have just approved it with reply to this same thread. > Also it is new patch. >> >> -- >> Nicolas George >> _______________________________________________ >> ffmpeg-devel mailing list >> ffmpeg-devel@ffmpeg.org >> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel >> >> To unsubscribe, visit link above, or email >> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". >
Paul B Mahol (12020-07-21):
> Also it is new patch.
All the more reason not to apply and wait for it to be reviewed and
tested. Fortunately, there is somebody both competent and interested
in the matter.
On Tue, Jul 21, 2020 at 02:41:16PM +0200, Nicolas George wrote: >> Also it is new patch. > All the more reason not to apply and wait for it to be reviewed and > tested. Fortunately, there is somebody both competent and interested > in the matter. I don't intend to look more at this; Paul has made it clear what his position is, and I don't see the point in arguing further about it. Again, if someone else wants to approve the patch in this state, I'm fine by that, but I'm not doing it myself. (If a patch is good, it should be easy finding at least one other developer that is willing to +1 it.) /* Steinar */
Steinar H. Gunderson (12020-07-21): > I don't intend to look more at this; Paul has made it clear what his position > is, and I don't see the point in arguing further about it. Again, if someone > else wants to approve the patch in this state, I'm fine by that, but I'm not > doing it myself. (If a patch is good, it should be easy finding at least one > other developer that is willing to +1 it.) Thank you for weighing in. So to summary, this patch is blocked pending approval by an independent developer. Regards,
On 7/21/20, Steinar H. Gunderson <steinar+ffmpeg@gunderson.no> wrote: > On Tue, Jul 21, 2020 at 02:41:16PM +0200, Nicolas George wrote: >>> Also it is new patch. >> All the more reason not to apply and wait for it to be reviewed and >> tested. Fortunately, there is somebody both competent and interested >> in the matter. > > I don't intend to look more at this; Paul has made it clear what his > position > is, and I don't see the point in arguing further about it. Again, if someone > else wants to approve the patch in this state, I'm fine by that, but I'm not > doing it myself. (If a patch is good, it should be easy finding at least one > other developer that is willing to +1 it.) Could you write pseudo code of your O(1) algorithm for both radial and circular blur? If not, I see no point in trying to comply with imaginary standards. > > /* Steinar */ > -- > Homepage: https://www.sesse.net/ > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
diff --git a/doc/filters.texi b/doc/filters.texi index a2c31ff610..62705db984 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -7231,6 +7231,29 @@ Set planes to filter. Default value is to filter all planes except alpha plane. @end table +@section cblur +Apply a circular blur filter. + +The filter accepts the following options: + +@table @option +@item centerx, centery +Set central point position of circular blur. Default is @code{0.5}. + +@item amount +Set amount of circular blur. Default is @code{0.03}. + +@item planes +Set which planes to filter. By default all planes are filtered. +@end table + +@subsection Commands +This filter supports same @ref{commands} as options. +The command accepts the same syntax of the corresponding option. + +If the specified expression is not valid, it is kept at its current +value. + @section chromahold Remove all color information for all colors except for certain one. @@ -15768,6 +15791,29 @@ less than @code{0}, the filter will try to use a good random seed on a best effort basis. @end table +@section rblur +Apply a radial blur filter. + +The filter accepts the following options: + +@table @option +@item centerx, centery +Set central point position of radial blur. Default is @code{0.5}. + +@item amount +Set amount of radial blur. Default is @code{0.03}. + +@item planes +Set which planes to filter. By default all planes are filtered. +@end table + +@subsection Commands +This filter supports same @ref{commands} as options. +The command accepts the same syntax of the corresponding option. + +If the specified expression is not valid, it is kept at its current +value. + @section readeia608 Read closed captioning (EIA-608) information from the top lines of a video frame. diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 33dcc69392..30f2abf9e2 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -180,6 +180,7 @@ OBJS-$(CONFIG_BOXBLUR_OPENCL_FILTER) += vf_avgblur_opencl.o opencl.o \ opencl/avgblur.o boxblur.o OBJS-$(CONFIG_BWDIF_FILTER) += vf_bwdif.o yadif_common.o OBJS-$(CONFIG_CAS_FILTER) += vf_cas.o +OBJS-$(CONFIG_CBLUR_FILTER) += vf_rblur.o OBJS-$(CONFIG_CHROMABER_VULKAN_FILTER) += vf_chromaber_vulkan.o vulkan.o OBJS-$(CONFIG_CHROMAHOLD_FILTER) += vf_chromakey.o OBJS-$(CONFIG_CHROMAKEY_FILTER) += vf_chromakey.o @@ -358,6 +359,7 @@ OBJS-$(CONFIG_PSNR_FILTER) += vf_psnr.o framesync.o OBJS-$(CONFIG_PULLUP_FILTER) += vf_pullup.o OBJS-$(CONFIG_QP_FILTER) += vf_qp.o OBJS-$(CONFIG_RANDOM_FILTER) += vf_random.o +OBJS-$(CONFIG_RBLUR_FILTER) += vf_rblur.o OBJS-$(CONFIG_READEIA608_FILTER) += vf_readeia608.o OBJS-$(CONFIG_READVITC_FILTER) += vf_readvitc.o OBJS-$(CONFIG_REALTIME_FILTER) += f_realtime.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index b896a76c9e..38279a44eb 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -171,6 +171,7 @@ extern AVFilter ff_vf_boxblur; extern AVFilter ff_vf_boxblur_opencl; extern AVFilter ff_vf_bwdif; extern AVFilter ff_vf_cas; +extern AVFilter ff_vf_cblur; extern AVFilter ff_vf_chromahold; extern AVFilter ff_vf_chromakey; extern AVFilter ff_vf_chromanr; @@ -341,6 +342,7 @@ extern AVFilter ff_vf_psnr; extern AVFilter ff_vf_pullup; extern AVFilter ff_vf_qp; extern AVFilter ff_vf_random; +extern AVFilter ff_vf_rblur; extern AVFilter ff_vf_readeia608; extern AVFilter ff_vf_readvitc; extern AVFilter ff_vf_realtime; diff --git a/libavfilter/vf_rblur.c b/libavfilter/vf_rblur.c new file mode 100644 index 0000000000..080224bcf7 --- /dev/null +++ b/libavfilter/vf_rblur.c @@ -0,0 +1,560 @@ +/* + * Copyright (c) 2020 Paul B Mahol + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/imgutils.h" +#include "libavutil/opt.h" +#include "libavutil/pixdesc.h" +#include "avfilter.h" +#include "formats.h" +#include "internal.h" +#include "video.h" + +typedef struct RBlurContext { + const AVClass *class; + + float centerx, centery; + float amount; + int planes; + int cblur; + int center_x[4], center_y[4]; + + int depth; + int planewidth[4]; + int planeheight[4]; + int buffer_w[4], buffer_h[4]; + float *buffer, *buffer_out; + int nb_planes; + int (*filter)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs); +} RBlurContext; + +typedef struct ThreadData { + AVFrame *in, *out; + int height; + int width; + int plane; +} ThreadData; + +#define OFFSET(x) offsetof(RBlurContext, x) +#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM + +static const AVOption rblur_options[] = { + { "centerx", "set center X position", OFFSET(centerx), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGS }, + { "centery", "set center Y position", OFFSET(centery), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGS }, + { "amount", "set blur amount", OFFSET(amount), AV_OPT_TYPE_FLOAT, {.dbl=0.03}, 0, 1, FLAGS }, + { "planes", "set planes to filter", OFFSET(planes), AV_OPT_TYPE_INT, {.i64=0xF}, 0,0xF, FLAGS }, + { NULL } +}; + +AVFILTER_DEFINE_CLASS(rblur); + +static void cart_to_polar(float x, float y, float *r, float *a) +{ + *r = sqrtf(x * x + y * y); + *a = atan2f(y, x); +} + +static void polar_to_cart(float r, float a, float *x, float *y) +{ + *x = r * cosf(a); + *y = r * sinf(a); +} + +static inline int mod(int a, int b) +{ + const int res = a % b; + + if (res < 0) { + return res + b; + } else { + return res; + } +} + +static int filter_horizontally(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + RBlurContext *s = ctx->priv; + ThreadData *td = arg; + const int height = td->height; + const int width = td->width; + const int slice_start = (height * jobnr ) / nb_jobs; + const int slice_end = (height * (jobnr+1)) / nb_jobs; + const int size = s->amount * (width - 1); + float *buffer = s->buffer_out; + const float *src; + float *ptr; + int y; + + /* Filter horizontally along each row */ + for (y = slice_start; y < slice_end; y++) { + float acc = 0.f; + int count = 0; + + src = (const float *)s->buffer + width * y; + ptr = buffer + width * y; + + for (int i = 0; i <= size; i++) { + acc += src[mod(i, width)]; + count++; + } + + for (int i = 0; i < width; i++) { + ptr[mod(i + size / 2, width)] = acc / count; + acc += src[mod(i + size + 1, width)] - src[i]; + } + } + + return 0; +} + +static int filter_vertically(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + RBlurContext *s = ctx->priv; + ThreadData *td = arg; + const int height = td->height; + const int width = td->width; + const int slice_start = (width * jobnr ) / nb_jobs; + const int slice_end = (width * (jobnr+1)) / nb_jobs; + const int size = s->amount * (height - 1); + float *buffer = s->buffer_out; + const float *src; + float *ptr; + int x; + + /* Filter vertically along each column */ + for (x = slice_start; x < slice_end; x++) { + int count = 0; + float acc = 0.f; + + ptr = buffer + x; + src = s->buffer + x; + + for (int i = 0; i <= size; i++) { + acc += src[mod(i, height) * width]; + count++; + } + + for (int i = 0; i < height; i++) { + ptr[mod(i + size / 2, height) * width] = acc / count; + acc += src[mod(i + size + 1, height) * width] - src[i * width]; + } + } + + return 0; +} + +static int p2c(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + RBlurContext *s = ctx->priv; + ThreadData *td = arg; + const int plane = td->plane; + const uint8_t *src = td->in->data[plane]; + const uint16_t *src16 = (const uint16_t *)td->in->data[plane]; + const int in_linesize = td->in->linesize[plane]; + const int height = s->planeheight[plane]; + const int width = s->planewidth[plane]; + const int bheight = s->buffer_h[plane]; + const int bwidth = s->buffer_w[plane]; + const int center_x = s->center_x[plane]; + const int center_y = s->center_y[plane]; + const int slice_start = (bheight * jobnr ) / nb_jobs; + const int slice_end = (bheight * (jobnr+1)) / nb_jobs; + float *bptr = s->buffer + slice_start * bwidth; + + if (s->depth == 8) { + for (int y = slice_start; y < slice_end; y++) { + for (int x = 0; x < bwidth; x++) { + float fX, fY; + float u, v; + int iX, iY; + int X, Y; + float k[4]; + int p[4]; + + polar_to_cart(x, (y / (bheight - 1.f)) * 2.f * M_PI - M_PI, &fX, &fY); + iX = floorf(fX); + iY = floorf(fY); + u = fX - iX; + v = fY - iY; + k[0] = (1.f - u) * (1.f - v); + k[1] = u * (1.f - v); + k[2] = (1.f - u) * v; + k[3] = u * v; + X = av_clip(iX + center_x, 0, width - 1); + Y = av_clip(iY + center_y, 0, height - 1); + p[0] = src[Y * in_linesize + X]; + X = av_clip(iX + center_x + 1, 0, width - 1); + p[1] = src[Y * in_linesize + X]; + X = av_clip(iX + center_x, 0, width - 1); + Y = av_clip(iY + center_y + 1, 0, height - 1); + p[2] = src[Y * in_linesize + X]; + X = av_clip(iX + center_x + 1, 0, width - 1); + p[3] = src[Y * in_linesize + X]; + bptr[x] = p[0] * k[0] + p[1] * k[1] + p[2] * k[2] + p[3] * k[3]; + } + bptr += bwidth; + } + } else { + for (int y = slice_start; y < slice_end; y++) { + for (int x = 0; x < bwidth; x++) { + float fX, fY; + float u, v; + int iX, iY; + int X, Y; + float k[4]; + int p[4]; + + polar_to_cart(x, (y / (bheight - 1.f)) * 2.f * M_PI - M_PI, &fX, &fY); + iX = floorf(fX); + iY = floorf(fY); + u = fX - iX; + v = fY - iY; + k[0] = (1.f - u) * (1.f - v); + k[1] = u * (1.f - v); + k[2] = (1.f - u) * v; + k[3] = u * v; + X = av_clip(iX + center_x, 0, width - 1); + Y = av_clip(iY + center_y, 0, height - 1); + p[0] = src16[Y * in_linesize / 2 + X]; + X = av_clip(iX + center_x + 1, 0, width - 1); + p[1] = src16[Y * in_linesize / 2 + X]; + X = av_clip(iX + center_x, 0, width - 1); + Y = av_clip(iY + center_y + 1, 0, height - 1); + p[2] = src16[Y * in_linesize / 2 + X]; + X = av_clip(iX + center_x + 1, 0, width - 1); + p[3] = src16[Y * in_linesize / 2 + X]; + bptr[x] = p[0] * k[0] + p[1] * k[1] + p[2] * k[2] + p[3] * k[3]; + } + bptr += bwidth; + } + } + + return 0; +} + +static int c2p(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + RBlurContext *s = ctx->priv; + ThreadData *td = arg; + const int plane = td->plane; + const int out_linesize = td->out->linesize[plane]; + const int height = s->planeheight[plane]; + const int width = s->planewidth[plane]; + const int bheight = s->buffer_h[plane]; + const int bwidth = s->buffer_w[plane]; + const int center_x = s->center_x[plane]; + const int center_y = s->center_y[plane]; + const int slice_start = (height * jobnr ) / nb_jobs; + const int slice_end = (height * (jobnr+1)) / nb_jobs; + uint8_t *dst = td->out->data[plane] + slice_start * out_linesize; + uint16_t *dst16 = (uint16_t *)td->out->data[plane] + slice_start * out_linesize / 2; + float *bptr = s->buffer_out; + + if (s->depth == 8) { + for (int y = slice_start; y < slice_end; y++) { + for (int x = 0; x < width; x++) { + float fX, fY; + float u, v; + int iX, iY; + int X, Y; + float k[4]; + int p[4]; + + cart_to_polar(x - center_x, y - center_y, &fX, &fY); + iX = floorf(fX); + fY = ((fY + M_PI) / (2.f * M_PI)) * (bheight - 1); + iY = floorf(fY); + u = fX - iX; + v = fY - iY; + k[0] = (1.f - u) * (1.f - v); + k[1] = u * (1.f - v); + k[2] = (1.f - u) * v; + k[3] = u * v; + X = av_clip(iX, 0, bwidth - 1); + Y = av_clip(iY, 0, bheight - 1); + p[0] = bptr[Y * bwidth + X]; + X = av_clip(iX + 1, 0, bwidth - 1); + Y = av_clip(iY, 0, bheight - 1); + p[1] = bptr[Y * bwidth + X]; + X = av_clip(iX, 0, bwidth - 1); + Y = av_clip(iY + 1, 0, bheight - 1); + p[2] = bptr[Y * bwidth + X]; + X = av_clip(iX + 1, 0, bwidth - 1); + Y = av_clip(iY + 1, 0, bheight - 1); + p[3] = bptr[Y * bwidth + X]; + dst[x] = p[0] * k[0] + p[1] * k[1] + p[2] * k[2] + p[3] * k[3]; + } + dst += out_linesize; + } + } else { + for (int y = slice_start; y < slice_end; y++) { + for (int x = 0; x < width; x++) { + float fX, fY; + float u, v; + int iX, iY; + int X, Y; + float k[4]; + int p[4]; + + cart_to_polar(x - center_x, y - center_y, &fX, &fY); + iX = floorf(fX); + fY = ((fY + M_PI) / (2.f * M_PI)) * (bheight - 1); + iY = floorf(fY); + u = fX - iX; + v = fY - iY; + k[0] = (1.f - u) * (1.f - v); + k[1] = u * (1.f - v); + k[2] = (1.f - u) * v; + k[3] = u * v; + X = av_clip(iX, 0, bwidth - 1); + Y = av_clip(iY, 0, bheight - 1); + p[0] = bptr[Y * bwidth + X]; + X = av_clip(iX + 1, 0, bwidth - 1); + Y = av_clip(iY, 0, bheight - 1); + p[1] = bptr[Y * bwidth + X]; + X = av_clip(iX, 0, bwidth - 1); + Y = av_clip(iY + 1, 0, bheight - 1); + p[2] = bptr[Y * bwidth + X]; + X = av_clip(iX + 1, 0, bwidth - 1); + Y = av_clip(iY + 1, 0, bheight - 1); + p[3] = bptr[Y * bwidth + X]; + dst16[x] = p[0] * k[0] + p[1] * k[1] + p[2] * k[2] + p[3] * k[3]; + } + dst16 += out_linesize / 2; + } + } + + return 0; +} + +static void polar2cart(AVFilterContext *ctx, AVFrame *in, int plane) +{ + RBlurContext *s = ctx->priv; + const int nb_threads = ff_filter_get_nb_threads(ctx); + ThreadData td; + + td.plane = plane; + td.in = in; + + ctx->internal->execute(ctx, p2c, &td, NULL, FFMIN(s->buffer_h[plane], nb_threads)); +} + +static void cart2polar(AVFilterContext *ctx, AVFrame *out, int plane) +{ + RBlurContext *s = ctx->priv; + const int nb_threads = ff_filter_get_nb_threads(ctx); + ThreadData td; + + td.plane = plane; + td.out = out; + + ctx->internal->execute(ctx, c2p, &td, NULL, FFMIN(s->planeheight[plane], nb_threads)); +} + +static void ririir2d(AVFilterContext *ctx, int plane) +{ + RBlurContext *s = ctx->priv; + const int nb_threads = ff_filter_get_nb_threads(ctx); + ThreadData td; + + td.width = s->buffer_w[plane]; + td.height = s->buffer_h[plane]; + + ctx->internal->execute(ctx, s->filter, &td, NULL, FFMIN(td.height, nb_threads)); +} + +static int query_formats(AVFilterContext *ctx) +{ + static const enum AVPixelFormat pix_fmts[] = { + AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV440P, + AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P, + AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUV420P, + AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ420P, + AV_PIX_FMT_YUVJ411P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, + AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9, + AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, + AV_PIX_FMT_YUV420P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV440P12, + AV_PIX_FMT_YUV420P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV444P14, + AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16, + AV_PIX_FMT_YUVA420P9, AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA444P9, + AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA444P10, + AV_PIX_FMT_YUVA422P12, AV_PIX_FMT_YUVA444P12, + AV_PIX_FMT_YUVA420P16, AV_PIX_FMT_YUVA422P16, AV_PIX_FMT_YUVA444P16, + AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, + AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, + AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16, + AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY14, AV_PIX_FMT_GRAY16, + AV_PIX_FMT_NONE + }; + + return ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); +} + +static void set_params(AVFilterContext *ctx) +{ + RBlurContext *s = ctx->priv; + AVFilterLink *inlink = ctx->inputs[0]; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); + + s->center_x[1] = s->center_x[2] = AV_CEIL_RSHIFT(lrintf(inlink->w * s->centerx), desc->log2_chroma_w); + s->center_x[0] = s->center_x[3] = lrintf(inlink->w * s->centerx); + s->center_y[1] = s->center_y[2] = AV_CEIL_RSHIFT(lrintf(inlink->h * s->centery), desc->log2_chroma_h); + s->center_y[0] = s->center_y[3] = lrintf(inlink->h * s->centery); +} + +static int config_input(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->dst; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); + RBlurContext *s = ctx->priv; + + s->cblur = !strcmp(ctx->filter->name, "cblur"); + + set_params(ctx); + s->depth = desc->comp[0].depth; + s->planewidth[1] = s->planewidth[2] = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w); + s->planewidth[0] = s->planewidth[3] = inlink->w; + s->planeheight[1] = s->planeheight[2] = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h); + s->planeheight[0] = s->planeheight[3] = inlink->h; + + s->nb_planes = av_pix_fmt_count_planes(inlink->format); + s->buffer_w[0] = ceilf(hypotf(s->planewidth[0], s->planeheight[0]) / 2.f); + s->buffer_w[1] = ceilf(hypotf(s->planewidth[1], s->planeheight[1]) / 2.f); + s->buffer_w[2] = ceilf(hypotf(s->planewidth[2], s->planeheight[2]) / 2.f); + s->buffer_w[3] = ceilf(hypotf(s->planewidth[3], s->planeheight[3]) / 2.f); + s->buffer_h[0] = s->planewidth[0] + s->planeheight[0]; + s->buffer_h[1] = s->planewidth[1] + s->planeheight[1]; + s->buffer_h[2] = s->planewidth[2] + s->planeheight[2]; + s->buffer_h[3] = s->planewidth[3] + s->planeheight[3]; + + s->buffer = av_malloc_array(s->buffer_w[0], s->buffer_h[0] * sizeof(*s->buffer)); + s->buffer_out = av_malloc_array(s->buffer_w[0], s->buffer_h[0] * sizeof(*s->buffer_out)); + if (!s->buffer || !s->buffer_out) + return AVERROR(ENOMEM); + + s->filter = s->cblur ? filter_vertically : filter_horizontally; + + return 0; +} + +static int filter_frame(AVFilterLink *inlink, AVFrame *in) +{ + AVFilterContext *ctx = inlink->dst; + RBlurContext *s = ctx->priv; + AVFilterLink *outlink = ctx->outputs[0]; + AVFrame *out; + int plane; + + if (av_frame_is_writable(in)) { + out = in; + } else { + out = ff_get_video_buffer(outlink, outlink->w, outlink->h); + if (!out) { + av_frame_free(&in); + return AVERROR(ENOMEM); + } + av_frame_copy_props(out, in); + } + + set_params(ctx); + + for (plane = 0; plane < s->nb_planes; plane++) { + const int height = s->planeheight[plane]; + const int width = s->planewidth[plane]; + + if (!(s->planes & (1 << plane))) { + if (out != in) + av_image_copy_plane(out->data[plane], out->linesize[plane], + in->data[plane], in->linesize[plane], + width * ((s->depth + 7) / 8), height); + continue; + } + + polar2cart(ctx, in, plane); + ririir2d(ctx, plane); + cart2polar(ctx, out, plane); + } + + if (out != in) + av_frame_free(&in); + return ff_filter_frame(outlink, out); +} + +static av_cold void uninit(AVFilterContext *ctx) +{ + RBlurContext *s = ctx->priv; + + av_freep(&s->buffer); + av_freep(&s->buffer_out); +} + +static const AVFilterPad rblur_inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .config_props = config_input, + .filter_frame = filter_frame, + }, + { NULL } +}; + +static const AVFilterPad rblur_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + }, + { NULL } +}; + +#if CONFIG_RBLUR_FILTER + +AVFilter ff_vf_rblur = { + .name = "rblur", + .description = NULL_IF_CONFIG_SMALL("Apply Radial Blur filter."), + .priv_size = sizeof(RBlurContext), + .priv_class = &rblur_class, + .uninit = uninit, + .query_formats = query_formats, + .inputs = rblur_inputs, + .outputs = rblur_outputs, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS, + .process_command = ff_filter_process_command, +}; + +#endif /* CONFIG_RBLUR_FILTER */ + +#if CONFIG_CBLUR_FILTER + +#define cblur_options rblur_options +AVFILTER_DEFINE_CLASS(cblur); + +AVFilter ff_vf_cblur = { + .name = "cblur", + .description = NULL_IF_CONFIG_SMALL("Apply Circular Blur filter."), + .priv_size = sizeof(RBlurContext), + .priv_class = &cblur_class, + .uninit = uninit, + .query_formats = query_formats, + .inputs = rblur_inputs, + .outputs = rblur_outputs, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS, + .process_command = ff_filter_process_command, +}; + +#endif /* CONFIG_CBLUR_FILTER */
Signed-off-by: Paul B Mahol <onemda@gmail.com> --- doc/filters.texi | 46 ++++ libavfilter/Makefile | 2 + libavfilter/allfilters.c | 2 + libavfilter/vf_rblur.c | 560 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 610 insertions(+) create mode 100644 libavfilter/vf_rblur.c