Re: [FFmpeg-devel] [PATCH] avfilter/vf_overlay: add premultiplied alpha mode

2017-12-02 Thread Paul B Mahol
On 12/2/17, Marton Balint  wrote:
>
>
> On Sat, 2 Dec 2017, Paul B Mahol wrote:
>
>> On 12/2/17, Marton Balint  wrote:
>>>
>>>
>>> On Fri, 1 Dec 2017, Paul B Mahol wrote:
>>>
 Signed-off-by: Paul B Mahol 
 ---
 doc/filters.texi |   4 ++
 libavfilter/vf_overlay.c | 160
 ---
 2 files changed, 140 insertions(+), 24 deletions(-)

 diff --git a/doc/filters.texi b/doc/filters.texi
 index f7c371592f..0699728b7e 100644
 --- a/doc/filters.texi
 +++ b/doc/filters.texi
 @@ -11328,6 +11328,10 @@ Default value is @samp{yuv420}.

 @item repeatlast
 See @ref{framesync}.
 +
 +@item alpha
 +Set format of alpha, it can be @var{straight} or @var{premultiplied}.
 +Default is @var{straight}.
 @end table
>>>
>>> Does this mean that not only overlay, but input and output is also
>>> considered as premultiplied? Maybe better to clarify this in the docs.
>>
>> I done it for overlay only alpha. For rest I'm little confused what needs
>> doing.
>
> Ok, then just write in the docs:
>
> "Set format of alpha of the overlaid video."

Fixed locally, thanks!

>
>>
>>>
>>> Have you measured the slowdown caused by the extra condition in the pixel
>>> blending code? If it is more than 1-2%, then some DEFINE magic (or
>>> making the blend_image functions inline?) would be better IMHO.
>>
>> It should already be inlined. Thats why there are so many functions.
>
> Not all of them, blend_image_packed_rgb misses an av_always_inline.
>

Fixed locally, thanks!
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] avfilter/vf_overlay: add premultiplied alpha mode

2017-12-02 Thread Marton Balint



On Sat, 2 Dec 2017, Paul B Mahol wrote:


On 12/2/17, Marton Balint  wrote:



On Fri, 1 Dec 2017, Paul B Mahol wrote:


Signed-off-by: Paul B Mahol 
---
doc/filters.texi |   4 ++
libavfilter/vf_overlay.c | 160
---
2 files changed, 140 insertions(+), 24 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index f7c371592f..0699728b7e 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -11328,6 +11328,10 @@ Default value is @samp{yuv420}.

@item repeatlast
See @ref{framesync}.
+
+@item alpha
+Set format of alpha, it can be @var{straight} or @var{premultiplied}.
+Default is @var{straight}.
@end table


Does this mean that not only overlay, but input and output is also
considered as premultiplied? Maybe better to clarify this in the docs.


I done it for overlay only alpha. For rest I'm little confused what needs doing.


Ok, then just write in the docs:

"Set format of alpha of the overlaid video."





Have you measured the slowdown caused by the extra condition in the pixel
blending code? If it is more than 1-2%, then some DEFINE magic (or
making the blend_image functions inline?) would be better IMHO.


It should already be inlined. Thats why there are so many functions.


Not all of them, blend_image_packed_rgb misses an av_always_inline.

Regards,
Marton




The @option{x}, and @option{y} expressions can contain the following
diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c
index 5bf3d66cf1..8206dae454 100644
--- a/libavfilter/vf_overlay.c
+++ b/libavfilter/vf_overlay.c
@@ -109,6 +109,7 @@ typedef struct OverlayContext {
uint8_t overlay_rgba_map[4];
uint8_t overlay_has_alpha;
int format; ///< OverlayFormat
+int alpha_format;
int eval_mode;  ///< EvalMode

FFFrameSync fs;
@@ -403,7 +404,8 @@ static int config_output(AVFilterLink *outlink)

static void blend_image_packed_rgb(AVFilterContext *ctx,
   AVFrame *dst, const AVFrame *src,
-   int main_has_alpha, int x, int y)
+   int main_has_alpha, int x, int y,
+   int is_straight)
{
OverlayContext *s = ctx->priv;
int i, imax, j, jmax;
@@ -454,9 +456,9 @@ static void blend_image_packed_rgb(AVFilterContext
*ctx,
default:
// main_value = main_value * (1 - alpha) + overlay_value *
alpha
// since alpha is in the range 0-255, the result must
divided by 255
-d[dr] = FAST_DIV255(d[dr] * (255 - alpha) + S[sr] *
alpha);
-d[dg] = FAST_DIV255(d[dg] * (255 - alpha) + S[sg] *
alpha);
-d[db] = FAST_DIV255(d[db] * (255 - alpha) + S[sb] *
alpha);
+d[dr] = is_straight ? FAST_DIV255(d[dr] * (255 - alpha) +
S[sr] * alpha) : FAST_DIV255(d[dr] * (255 - alpha) + S[sr]);
+d[dg] = is_straight ? FAST_DIV255(d[dg] * (255 - alpha) +
S[sg] * alpha) : FAST_DIV255(d[dr] * (255 - alpha) + S[sr]);
+d[db] = is_straight ? FAST_DIV255(d[db] * (255 - alpha) +
S[sb] * alpha) : FAST_DIV255(d[dr] * (255 - alpha) + S[sr]);
}
if (main_has_alpha) {
switch (alpha) {
@@ -487,7 +489,9 @@ static av_always_inline void
blend_plane(AVFilterContext *ctx,
 int main_has_alpha,
 int dst_plane,
 int dst_offset,
- int dst_step)
+ int dst_step,
+ int straight,
+ int yuv)
{
int src_wp = AV_CEIL_RSHIFT(src_w, hsub);
int src_hp = AV_CEIL_RSHIFT(src_h, vsub);
@@ -546,7 +550,14 @@ static av_always_inline void
blend_plane(AVFilterContext *ctx,
alpha_d = da[0];
alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d);
}
-*d = FAST_DIV255(*d * (255 - alpha) + *s * alpha);
+if (straight) {
+*d = FAST_DIV255(*d * (255 - alpha) + *s * alpha);
+} else {
+if (i && yuv)
+*d = av_clip(FAST_DIV255((*d - 128) * (255 - alpha))
+ *s - 128, -128, 128) + 128;
+else
+*d = FFMIN(FAST_DIV255(*d * (255 - alpha)) + *s,
255);
+}
s++;
d += dst_step;
da += 1 << hsub;
@@ -605,7 +616,8 @@ static av_always_inline void
blend_image_yuv(AVFilterContext *ctx,
 AVFrame *dst, const AVFrame
*src,
 int hsub, int vsub,
 int main_has_alpha,
- int x, int y)
+ int x, int y,
+   

Re: [FFmpeg-devel] [PATCH] avfilter/vf_overlay: add premultiplied alpha mode

2017-12-02 Thread Paul B Mahol
On 12/2/17, Marton Balint  wrote:
>
>
> On Fri, 1 Dec 2017, Paul B Mahol wrote:
>
>> Signed-off-by: Paul B Mahol 
>> ---
>> doc/filters.texi |   4 ++
>> libavfilter/vf_overlay.c | 160
>> ---
>> 2 files changed, 140 insertions(+), 24 deletions(-)
>>
>> diff --git a/doc/filters.texi b/doc/filters.texi
>> index f7c371592f..0699728b7e 100644
>> --- a/doc/filters.texi
>> +++ b/doc/filters.texi
>> @@ -11328,6 +11328,10 @@ Default value is @samp{yuv420}.
>>
>> @item repeatlast
>> See @ref{framesync}.
>> +
>> +@item alpha
>> +Set format of alpha, it can be @var{straight} or @var{premultiplied}.
>> +Default is @var{straight}.
>> @end table
>
> Does this mean that not only overlay, but input and output is also
> considered as premultiplied? Maybe better to clarify this in the docs.

I done it for overlay only alpha. For rest I'm little confused what needs doing.

>
> Have you measured the slowdown caused by the extra condition in the pixel
> blending code? If it is more than 1-2%, then some DEFINE magic (or
> making the blend_image functions inline?) would be better IMHO.

It should already be inlined. Thats why there are so many functions.

>
> Regards,
> Marton
>
>>
>> The @option{x}, and @option{y} expressions can contain the following
>> diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c
>> index 5bf3d66cf1..8206dae454 100644
>> --- a/libavfilter/vf_overlay.c
>> +++ b/libavfilter/vf_overlay.c
>> @@ -109,6 +109,7 @@ typedef struct OverlayContext {
>> uint8_t overlay_rgba_map[4];
>> uint8_t overlay_has_alpha;
>> int format; ///< OverlayFormat
>> +int alpha_format;
>> int eval_mode;  ///< EvalMode
>>
>> FFFrameSync fs;
>> @@ -403,7 +404,8 @@ static int config_output(AVFilterLink *outlink)
>>
>> static void blend_image_packed_rgb(AVFilterContext *ctx,
>>AVFrame *dst, const AVFrame *src,
>> -   int main_has_alpha, int x, int y)
>> +   int main_has_alpha, int x, int y,
>> +   int is_straight)
>> {
>> OverlayContext *s = ctx->priv;
>> int i, imax, j, jmax;
>> @@ -454,9 +456,9 @@ static void blend_image_packed_rgb(AVFilterContext
>> *ctx,
>> default:
>> // main_value = main_value * (1 - alpha) + overlay_value *
>> alpha
>> // since alpha is in the range 0-255, the result must
>> divided by 255
>> -d[dr] = FAST_DIV255(d[dr] * (255 - alpha) + S[sr] *
>> alpha);
>> -d[dg] = FAST_DIV255(d[dg] * (255 - alpha) + S[sg] *
>> alpha);
>> -d[db] = FAST_DIV255(d[db] * (255 - alpha) + S[sb] *
>> alpha);
>> +d[dr] = is_straight ? FAST_DIV255(d[dr] * (255 - alpha) +
>> S[sr] * alpha) : FAST_DIV255(d[dr] * (255 - alpha) + S[sr]);
>> +d[dg] = is_straight ? FAST_DIV255(d[dg] * (255 - alpha) +
>> S[sg] * alpha) : FAST_DIV255(d[dr] * (255 - alpha) + S[sr]);
>> +d[db] = is_straight ? FAST_DIV255(d[db] * (255 - alpha) +
>> S[sb] * alpha) : FAST_DIV255(d[dr] * (255 - alpha) + S[sr]);
>> }
>> if (main_has_alpha) {
>> switch (alpha) {
>> @@ -487,7 +489,9 @@ static av_always_inline void
>> blend_plane(AVFilterContext *ctx,
>>  int main_has_alpha,
>>  int dst_plane,
>>  int dst_offset,
>> - int dst_step)
>> + int dst_step,
>> + int straight,
>> + int yuv)
>> {
>> int src_wp = AV_CEIL_RSHIFT(src_w, hsub);
>> int src_hp = AV_CEIL_RSHIFT(src_h, vsub);
>> @@ -546,7 +550,14 @@ static av_always_inline void
>> blend_plane(AVFilterContext *ctx,
>> alpha_d = da[0];
>> alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d);
>> }
>> -*d = FAST_DIV255(*d * (255 - alpha) + *s * alpha);
>> +if (straight) {
>> +*d = FAST_DIV255(*d * (255 - alpha) + *s * alpha);
>> +} else {
>> +if (i && yuv)
>> +*d = av_clip(FAST_DIV255((*d - 128) * (255 - alpha))
>> + *s - 128, -128, 128) + 128;
>> +else
>> +*d = FFMIN(FAST_DIV255(*d * (255 - alpha)) + *s,
>> 255);
>> +}
>> s++;
>> d += dst_step;
>> da += 1 << hsub;
>> @@ -605,7 +616,8 @@ static av_always_inline void
>> blend_image_yuv(AVFilterContext *ctx,
>>  AVFrame *dst, const AVFrame
>> *src,
>>  int hsub, int vsub,
>>  int main_has_alpha,

Re: [FFmpeg-devel] [PATCH] avfilter/vf_overlay: add premultiplied alpha mode

2017-12-02 Thread Marton Balint



On Fri, 1 Dec 2017, Paul B Mahol wrote:


Signed-off-by: Paul B Mahol 
---
doc/filters.texi |   4 ++
libavfilter/vf_overlay.c | 160 ---
2 files changed, 140 insertions(+), 24 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index f7c371592f..0699728b7e 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -11328,6 +11328,10 @@ Default value is @samp{yuv420}.

@item repeatlast
See @ref{framesync}.
+
+@item alpha
+Set format of alpha, it can be @var{straight} or @var{premultiplied}.
+Default is @var{straight}.
@end table


Does this mean that not only overlay, but input and output is also 
considered as premultiplied? Maybe better to clarify this in the docs.


Have you measured the slowdown caused by the extra condition in the pixel 
blending code? If it is more than 1-2%, then some DEFINE magic (or 
making the blend_image functions inline?) would be better IMHO.


Regards,
Marton



The @option{x}, and @option{y} expressions can contain the following
diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c
index 5bf3d66cf1..8206dae454 100644
--- a/libavfilter/vf_overlay.c
+++ b/libavfilter/vf_overlay.c
@@ -109,6 +109,7 @@ typedef struct OverlayContext {
uint8_t overlay_rgba_map[4];
uint8_t overlay_has_alpha;
int format; ///< OverlayFormat
+int alpha_format;
int eval_mode;  ///< EvalMode

FFFrameSync fs;
@@ -403,7 +404,8 @@ static int config_output(AVFilterLink *outlink)

static void blend_image_packed_rgb(AVFilterContext *ctx,
   AVFrame *dst, const AVFrame *src,
-   int main_has_alpha, int x, int y)
+   int main_has_alpha, int x, int y,
+   int is_straight)
{
OverlayContext *s = ctx->priv;
int i, imax, j, jmax;
@@ -454,9 +456,9 @@ static void blend_image_packed_rgb(AVFilterContext *ctx,
default:
// main_value = main_value * (1 - alpha) + overlay_value * alpha
// since alpha is in the range 0-255, the result must divided 
by 255
-d[dr] = FAST_DIV255(d[dr] * (255 - alpha) + S[sr] * alpha);
-d[dg] = FAST_DIV255(d[dg] * (255 - alpha) + S[sg] * alpha);
-d[db] = FAST_DIV255(d[db] * (255 - alpha) + S[sb] * alpha);
+d[dr] = is_straight ? FAST_DIV255(d[dr] * (255 - alpha) + 
S[sr] * alpha) : FAST_DIV255(d[dr] * (255 - alpha) + S[sr]);
+d[dg] = is_straight ? FAST_DIV255(d[dg] * (255 - alpha) + 
S[sg] * alpha) : FAST_DIV255(d[dr] * (255 - alpha) + S[sr]);
+d[db] = is_straight ? FAST_DIV255(d[db] * (255 - alpha) + 
S[sb] * alpha) : FAST_DIV255(d[dr] * (255 - alpha) + S[sr]);
}
if (main_has_alpha) {
switch (alpha) {
@@ -487,7 +489,9 @@ static av_always_inline void blend_plane(AVFilterContext 
*ctx,
 int main_has_alpha,
 int dst_plane,
 int dst_offset,
- int dst_step)
+ int dst_step,
+ int straight,
+ int yuv)
{
int src_wp = AV_CEIL_RSHIFT(src_w, hsub);
int src_hp = AV_CEIL_RSHIFT(src_h, vsub);
@@ -546,7 +550,14 @@ static av_always_inline void blend_plane(AVFilterContext 
*ctx,
alpha_d = da[0];
alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d);
}
-*d = FAST_DIV255(*d * (255 - alpha) + *s * alpha);
+if (straight) {
+*d = FAST_DIV255(*d * (255 - alpha) + *s * alpha);
+} else {
+if (i && yuv)
+*d = av_clip(FAST_DIV255((*d - 128) * (255 - alpha)) + *s 
- 128, -128, 128) + 128;
+else
+*d = FFMIN(FAST_DIV255(*d * (255 - alpha)) + *s, 255);
+}
s++;
d += dst_step;
da += 1 << hsub;
@@ -605,7 +616,8 @@ static av_always_inline void 
blend_image_yuv(AVFilterContext *ctx,
 AVFrame *dst, const AVFrame *src,
 int hsub, int vsub,
 int main_has_alpha,
- int x, int y)
+ int x, int y,
+ int is_straight)
{
OverlayContext *s = ctx->priv;
const int src_w = src->width;
@@ -614,11 +626,11 @@ static av_always_inline void 
blend_image_yuv(AVFilterContext *ctx,
const int dst_h = dst->height;

blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 0, 0,   0, x, y, 
main_has_alpha,
-