[FFmpeg-devel] [PATCH v2] fix issues with transparent crop. (see https://trac.ffmpeg.org/ticket/7890)

2019-05-09 Thread Bjorn Roche
From: Jacob Graff 

Resolves issues with some transparent gifs.
see https://trac.ffmpeg.org/ticket/7890
contribution by Jacob Graff 

---
 libavcodec/gif.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/libavcodec/gif.c b/libavcodec/gif.c
index 94c8b1af49..d7768b4426 100644
--- a/libavcodec/gif.c
+++ b/libavcodec/gif.c
@@ -136,7 +136,7 @@ static void gif_crop_translucent(AVCodecContext *avctx,
 while (*y_start < y_end) {
 int is_trans = 1;
 for (int i = 0; i < w; i++) {
-if (buf[w * *y_start + i] != trans) {
+if (buf[linesize * *y_start + i] != trans) {
 is_trans = 0;
 break;
 }
@@ -148,10 +148,10 @@ static void gif_crop_translucent(AVCodecContext *avctx,
 }
 
 // crop bottom
-while (y_end < h) {
+while (y_end > *y_start) {
 int is_trans = 1;
 for (int i = 0; i < w; i++) {
-if (buf[w * y_end + i] != trans) {
+if (buf[linesize * y_end + i] != trans) {
 is_trans = 0;
 break;
 }
@@ -165,7 +165,7 @@ static void gif_crop_translucent(AVCodecContext *avctx,
 while (*x_start < x_end) {
 int is_trans = 1;
 for (int i = *y_start; i < y_end; i++) {
-if (buf[w * i + *x_start] != trans) {
+if (buf[linesize * i + *x_start] != trans) {
 is_trans = 0;
 break;
 }
@@ -176,10 +176,10 @@ static void gif_crop_translucent(AVCodecContext *avctx,
 }
 
 // crop right
-while (x_end < w) {
+while (x_end > *x_start) {
 int is_trans = 1;
 for (int i = *y_start; i < y_end; i++) {
-if (buf[w * i + x_end] != trans) {
+if (buf[linesize * i + x_end] != trans) {
 is_trans = 0;
 break;
 }
-- 
2.19.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH] fix issues with transparent crop. (see https://trac.ffmpeg.org/ticket/7890)

2019-05-09 Thread Bjorn Roche
This patch should be attributed to Jacob Graff .

On Thu, May 9, 2019 at 10:37 AM Bjorn Roche  wrote:

> From: Bjorn Roche 
>
> ---
>  libavcodec/gif.c | 12 ++--
>  1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/libavcodec/gif.c b/libavcodec/gif.c
> index 94c8b1af49..d7768b4426 100644
> --- a/libavcodec/gif.c
> +++ b/libavcodec/gif.c
> @@ -136,7 +136,7 @@ static void gif_crop_translucent(AVCodecContext *avctx,
>  while (*y_start < y_end) {
>  int is_trans = 1;
>  for (int i = 0; i < w; i++) {
> -if (buf[w * *y_start + i] != trans) {
> +if (buf[linesize * *y_start + i] != trans) {
>  is_trans = 0;
>  break;
>  }
> @@ -148,10 +148,10 @@ static void gif_crop_translucent(AVCodecContext
> *avctx,
>  }
>
>  // crop bottom
> -while (y_end < h) {
> +while (y_end > *y_start) {
>  int is_trans = 1;
>  for (int i = 0; i < w; i++) {
> -if (buf[w * y_end + i] != trans) {
> +if (buf[linesize * y_end + i] != trans) {
>  is_trans = 0;
>  break;
>  }
> @@ -165,7 +165,7 @@ static void gif_crop_translucent(AVCodecContext *avctx,
>  while (*x_start < x_end) {
>  int is_trans = 1;
>  for (int i = *y_start; i < y_end; i++) {
> -if (buf[w * i + *x_start] != trans) {
> +if (buf[linesize * i + *x_start] != trans) {
>  is_trans = 0;
>  break;
>  }
> @@ -176,10 +176,10 @@ static void gif_crop_translucent(AVCodecContext
> *avctx,
>  }
>
>  // crop right
> -while (x_end < w) {
> +while (x_end > *x_start) {
>  int is_trans = 1;
>  for (int i = *y_start; i < y_end; i++) {
> -if (buf[w * i + x_end] != trans) {
> +if (buf[linesize * i + x_end] != trans) {
>  is_trans = 0;
>  break;
>  }
> --
> 2.19.1
>
>

-- 

Bjorn Roche

Engineering Manager

bj...@giphy.com
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH] fix issues with transparent crop. (see https://trac.ffmpeg.org/ticket/7890)

2019-05-09 Thread Bjorn Roche
From: Bjorn Roche 

---
 libavcodec/gif.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/libavcodec/gif.c b/libavcodec/gif.c
index 94c8b1af49..d7768b4426 100644
--- a/libavcodec/gif.c
+++ b/libavcodec/gif.c
@@ -136,7 +136,7 @@ static void gif_crop_translucent(AVCodecContext *avctx,
 while (*y_start < y_end) {
 int is_trans = 1;
 for (int i = 0; i < w; i++) {
-if (buf[w * *y_start + i] != trans) {
+if (buf[linesize * *y_start + i] != trans) {
 is_trans = 0;
 break;
 }
@@ -148,10 +148,10 @@ static void gif_crop_translucent(AVCodecContext *avctx,
 }
 
 // crop bottom
-while (y_end < h) {
+while (y_end > *y_start) {
 int is_trans = 1;
 for (int i = 0; i < w; i++) {
-if (buf[w * y_end + i] != trans) {
+if (buf[linesize * y_end + i] != trans) {
 is_trans = 0;
 break;
 }
@@ -165,7 +165,7 @@ static void gif_crop_translucent(AVCodecContext *avctx,
 while (*x_start < x_end) {
 int is_trans = 1;
 for (int i = *y_start; i < y_end; i++) {
-if (buf[w * i + *x_start] != trans) {
+if (buf[linesize * i + *x_start] != trans) {
 is_trans = 0;
 break;
 }
@@ -176,10 +176,10 @@ static void gif_crop_translucent(AVCodecContext *avctx,
 }
 
 // crop right
-while (x_end < w) {
+while (x_end > *x_start) {
 int is_trans = 1;
 for (int i = *y_start; i < y_end; i++) {
-if (buf[w * i + x_end] != trans) {
+if (buf[linesize * i + x_end] != trans) {
 is_trans = 0;
 break;
 }
-- 
2.19.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] Pull requests

2018-02-27 Thread Bjorn Roche
On Tue, Feb 27, 2018 at 11:55 AM, James Almer <jamr...@gmail.com> wrote:

> On 2/27/2018 1:28 PM, Bjorn Roche wrote:
> > On Tue, Feb 27, 2018 at 10:34 AM, wm4 <nfx...@googlemail.com> wrote:
> >
> > According to Carl Eugen Hoyos: "This is Clément's code, he has to review
> > your patch."
>
> He's on vacations, so that'd explain why he hasn't looked at it.
>

Thanks James. If no one else can look at it, I'll just resubmit when he
comes back.

bjorn

-- 


Bjorn Roche

Sr. Video Pipeline Engineer

bj...@giphy.com
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] Pull requests

2018-02-27 Thread Bjorn Roche
On Tue, Feb 27, 2018 at 10:34 AM, Paul B Mahol <one...@gmail.com> wrote:

> On 2/27/18, Bjorn Roche <bj...@giphy.com> wrote:
> > On Tue, Feb 27, 2018 at 5:47 AM, wm4 <nfx...@googlemail.com> wrote:
> >
> >> On Mon, 26 Feb 2018 17:15:26 -0500
> >> Bjorn Roche <bj...@giphy.com> wrote:
> >>
> >> > Okay, thanks Nicolas.
> >> >
> >> > I already submitted a patch to the mailing list a few months ago, I
> was
> >> > just hoping for an easier way to keep it fresh since it's gone stale,
> >> and I
> >> > had some more fixes for it.
> >>
> >> Just ping it a few times or resend it. It's pretty easy for patches to
> >> get lost/ignored, but we don't use the github mirror's PR system at
> >> all. Github merely doesn't let us disable it.
> >
> >
> > There was a fair bit of very helpful discussion, so it was not ignored,
> but
> > the relevant maintainer on that code never commented. I emailed him
> > privately and got nothing, nor have I seen him on the mailing list. I was
> > just hoping you guys now accepted PRs so it would be easier for us to
> keep
> > it fresh.
>
> Please, keep pinging relevant patch. Current maintainer is very busy.
>

To be honest, I don't see the point if the one person who can approve is
not going to look at it. It takes a fair bit of time to freshen and prepare
these patches for email.

-- 


Bjorn Roche

Sr. Video Pipeline Engineer

bj...@giphy.com
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] Pull requests

2018-02-27 Thread Bjorn Roche
On Tue, Feb 27, 2018 at 10:34 AM, wm4 <nfx...@googlemail.com> wrote:

> On Tue, 27 Feb 2018 10:25:17 -0500
> Bjorn Roche <bj...@giphy.com> wrote:
>
> > On Tue, Feb 27, 2018 at 5:47 AM, wm4 <nfx...@googlemail.com> wrote:
> >
> > > On Mon, 26 Feb 2018 17:15:26 -0500
> > > Bjorn Roche <bj...@giphy.com> wrote:
> > >
> > > > Okay, thanks Nicolas.
> > > >
> > > > I already submitted a patch to the mailing list a few months ago, I
> was
> > > > just hoping for an easier way to keep it fresh since it's gone stale,
> > > and I
> > > > had some more fixes for it.
> > >
> > > Just ping it a few times or resend it. It's pretty easy for patches to
> > > get lost/ignored, but we don't use the github mirror's PR system at
> > > all. Github merely doesn't let us disable it.
> >
> >
> > There was a fair bit of very helpful discussion, so it was not ignored,
> but
> > the relevant maintainer on that code never commented. I emailed him
> > privately and got nothing, nor have I seen him on the mailing list. I was
> > just hoping you guys now accepted PRs so it would be easier for us to
> keep
> > it fresh.
>
> The MAINTAINERS file is usually stale and outdated, so just ask whether
> someone else can push it.

Jan 16

According to Carl Eugen Hoyos: "This is Clément's code, he has to review
your patch."

-- 


Bjorn Roche

Sr. Video Pipeline Engineer

bj...@giphy.com
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] Pull requests

2018-02-27 Thread Bjorn Roche
On Tue, Feb 27, 2018 at 5:47 AM, wm4 <nfx...@googlemail.com> wrote:

> On Mon, 26 Feb 2018 17:15:26 -0500
> Bjorn Roche <bj...@giphy.com> wrote:
>
> > Okay, thanks Nicolas.
> >
> > I already submitted a patch to the mailing list a few months ago, I was
> > just hoping for an easier way to keep it fresh since it's gone stale,
> and I
> > had some more fixes for it.
>
> Just ping it a few times or resend it. It's pretty easy for patches to
> get lost/ignored, but we don't use the github mirror's PR system at
> all. Github merely doesn't let us disable it.


There was a fair bit of very helpful discussion, so it was not ignored, but
the relevant maintainer on that code never commented. I emailed him
privately and got nothing, nor have I seen him on the mailing list. I was
just hoping you guys now accepted PRs so it would be easier for us to keep
it fresh.

bjorn

-- 


Bjorn Roche

Sr. Video Pipeline Engineer

bj...@giphy.com
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] Pull requests

2018-02-26 Thread Bjorn Roche
Okay, thanks Nicolas.

I already submitted a patch to the mailing list a few months ago, I was
just hoping for an easier way to keep it fresh since it's gone stale, and I
had some more fixes for it.

bjorn

On Mon, Feb 26, 2018 at 4:49 PM, Nicolas George <geo...@nsup.org> wrote:

> Bjorn Roche (2018-02-26):
> > - Committing changes to a git clone, for example on github.com or
> > gitorious.org. And asking us to merge these changes.
>
> Note that it does not say how you are supposed to "ask". You are
> supposed to ask on the mailing-list.
>
> > I have a patch I'd like to submit -- can I submit a PR on GitHub, or no?
>
> No. Reviews happen on the mailing list.
>
> Regards,
>
> --
>   Nicolas George
>
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
>


-- 


Bjorn Roche

Sr. Video Pipeline Engineer

bj...@giphy.com
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] Pull requests

2018-02-26 Thread Bjorn Roche
Hey there,

Your docs (https://ffmpeg.org/developer.html) say:

There are 3 ways by which code gets into FFmpeg.

- Submitting patches to the main developer mailing list. See Submitting
patches for details.
- Directly committing changes to the main tree.
- Committing changes to a git clone, for example on github.com or
gitorious.org. And asking us to merge these changes.

The third method appears to be new (Hooray!) but I noticed that the GitHub
repo here

https://github.com/FFmpeg/FFmpeg/pulls

still has a single PR that says

"WARNING: PULL REQUESTS ON THIS REPOSITORY ARE IGNORED"

I have a patch I'd like to submit -- can I submit a PR on GitHub, or no?

Thanks,

bjorn

-- 


Bjorn Roche

Sr. Video Pipeline Engineer

bj...@giphy.com
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] fix for transparencies in animated gifs

2018-01-16 Thread Bjorn Roche
Hey all,

I'm just reviewing this and noticing that the patch is stale and no longer
compiles. I am happy to update, but is there someone to review it if I do
so? I'd love to get this patch in. Thanks,

bjorn


On Thu, Dec 7, 2017 at 5:56 PM, Bjorn Roche <bj...@giphy.com> wrote:

> Hey all,
>
> Just wondering what else is needed to get this merged? Is there anything
> else I can do?
>
> Thanks,
>
> bjorn
>
> On Thu, Nov 30, 2017 at 12:33 PM, Bjorn Roche <bj...@giphy.com> wrote:
>
>> We've done a bit more testing on this and it looks good here.
>>
>> On Thu, Nov 30, 2017 at 12:26 PM, Bjorn Roche <bj...@giphy.com> wrote:
>>
>>>
>>>
>>> On Mon, Nov 27, 2017 at 7:12 PM, Carl Eugen Hoyos <ceffm...@gmail.com>
>>> wrote:
>>>
>>>> 2017-11-28 1:07 GMT+01:00 Bjorn Roche <bj...@giphy.com>:
>>>> > On Mon, Nov 27, 2017 at 5:41 PM, Carl Eugen Hoyos <ceffm...@gmail.com
>>>> >
>>>> > wrote:
>>>>
>>>> >> >> Does remuxing animated gif with transparency work with your patch?
>>>> >> >
>>>> >> > A command like this:
>>>> >> >
>>>> >> > ffmpeg -i in.gif out.gif
>>>> >> >
>>>> >> > seems to produce the same output as before: transparency replaces
>>>> >> > with opacity.
>>>> >>
>>>> >> remuxing == -vcodec copy
>>>> >>
>>>> >> What about ffmpeg -i in.gif -vcodec copy out.gif ?
>>>> >>
>>>> >
>>>> > That doesn't work. Weather I use my patch or not it aborts:
>>>>
>>>> Of course, ticket #6640.
>>>
>>>
>>> I'm going to see if this is something I can tackle separately.
>>>
>>> bjorn
>>>
>>>
>>> --
>>>
>>>
>>> Bjorn Roche
>>>
>>> Sr. Video Pipeline Engineer
>>>
>>> bj...@giphy.com
>>>
>>
>>
>>
>> --
>>
>>
>> Bjorn Roche
>>
>> Sr. Video Pipeline Engineer
>>
>> bj...@giphy.com
>>
>
>
>
> --
>
>
> Bjorn Roche
>
> Sr. Video Pipeline Engineer
>
> bj...@giphy.com
>



-- 


Bjorn Roche

Sr. Video Pipeline Engineer

bj...@giphy.com
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] fix for transparencies in animated gifs

2017-12-07 Thread Bjorn Roche
Hey all,

Just wondering what else is needed to get this merged? Is there anything
else I can do?

Thanks,

bjorn

On Thu, Nov 30, 2017 at 12:33 PM, Bjorn Roche <bj...@giphy.com> wrote:

> We've done a bit more testing on this and it looks good here.
>
> On Thu, Nov 30, 2017 at 12:26 PM, Bjorn Roche <bj...@giphy.com> wrote:
>
>>
>>
>> On Mon, Nov 27, 2017 at 7:12 PM, Carl Eugen Hoyos <ceffm...@gmail.com>
>> wrote:
>>
>>> 2017-11-28 1:07 GMT+01:00 Bjorn Roche <bj...@giphy.com>:
>>> > On Mon, Nov 27, 2017 at 5:41 PM, Carl Eugen Hoyos <ceffm...@gmail.com>
>>> > wrote:
>>>
>>> >> >> Does remuxing animated gif with transparency work with your patch?
>>> >> >
>>> >> > A command like this:
>>> >> >
>>> >> > ffmpeg -i in.gif out.gif
>>> >> >
>>> >> > seems to produce the same output as before: transparency replaces
>>> >> > with opacity.
>>> >>
>>> >> remuxing == -vcodec copy
>>> >>
>>> >> What about ffmpeg -i in.gif -vcodec copy out.gif ?
>>> >>
>>> >
>>> > That doesn't work. Weather I use my patch or not it aborts:
>>>
>>> Of course, ticket #6640.
>>
>>
>> I'm going to see if this is something I can tackle separately.
>>
>> bjorn
>>
>>
>> --
>>
>>
>> Bjorn Roche
>>
>> Sr. Video Pipeline Engineer
>>
>> bj...@giphy.com
>>
>
>
>
> --
>
>
> Bjorn Roche
>
> Sr. Video Pipeline Engineer
>
> bj...@giphy.com
>



-- 


Bjorn Roche

Sr. Video Pipeline Engineer

bj...@giphy.com
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] fix for transparencies in animated gifs

2017-11-30 Thread Bjorn Roche
We've done a bit more testing on this and it looks good here.

On Thu, Nov 30, 2017 at 12:26 PM, Bjorn Roche <bj...@giphy.com> wrote:

>
>
> On Mon, Nov 27, 2017 at 7:12 PM, Carl Eugen Hoyos <ceffm...@gmail.com>
> wrote:
>
>> 2017-11-28 1:07 GMT+01:00 Bjorn Roche <bj...@giphy.com>:
>> > On Mon, Nov 27, 2017 at 5:41 PM, Carl Eugen Hoyos <ceffm...@gmail.com>
>> > wrote:
>>
>> >> >> Does remuxing animated gif with transparency work with your patch?
>> >> >
>> >> > A command like this:
>> >> >
>> >> > ffmpeg -i in.gif out.gif
>> >> >
>> >> > seems to produce the same output as before: transparency replaces
>> >> > with opacity.
>> >>
>> >> remuxing == -vcodec copy
>> >>
>> >> What about ffmpeg -i in.gif -vcodec copy out.gif ?
>> >>
>> >
>> > That doesn't work. Weather I use my patch or not it aborts:
>>
>> Of course, ticket #6640.
>
>
> I'm going to see if this is something I can tackle separately.
>
> bjorn
>
>
> --
>
>
> Bjorn Roche
>
> Sr. Video Pipeline Engineer
>
> bj...@giphy.com
>



-- 


Bjorn Roche

Sr. Video Pipeline Engineer

bj...@giphy.com
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] fix for transparencies in animated gifs

2017-11-30 Thread Bjorn Roche
On Mon, Nov 27, 2017 at 7:12 PM, Carl Eugen Hoyos <ceffm...@gmail.com>
wrote:

> 2017-11-28 1:07 GMT+01:00 Bjorn Roche <bj...@giphy.com>:
> > On Mon, Nov 27, 2017 at 5:41 PM, Carl Eugen Hoyos <ceffm...@gmail.com>
> > wrote:
>
> >> >> Does remuxing animated gif with transparency work with your patch?
> >> >
> >> > A command like this:
> >> >
> >> > ffmpeg -i in.gif out.gif
> >> >
> >> > seems to produce the same output as before: transparency replaces
> >> > with opacity.
> >>
> >> remuxing == -vcodec copy
> >>
> >> What about ffmpeg -i in.gif -vcodec copy out.gif ?
> >>
> >
> > That doesn't work. Weather I use my patch or not it aborts:
>
> Of course, ticket #6640.


I'm going to see if this is something I can tackle separately.

bjorn


-- 


Bjorn Roche

Sr. Video Pipeline Engineer

bj...@giphy.com
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] fix for transparencies in animated gifs (requires feedback)

2017-11-27 Thread Bjorn Roche
On Mon, Nov 27, 2017 at 5:35 PM, Carl Eugen Hoyos <ceffm...@gmail.com>
wrote:

> 2017-11-27 19:30 GMT+01:00 Bjorn Roche <bj...@giphy.com>:
> >
>
> > The only way I can see is to move some functionality between the mixer
> and
> > the encoder. It's not a clear line between the codec and the container in
> > GIF, so I wouldn't object to an approach different from the one I took.
>
> (Just a question!)
>
> Does remuxing (animated) gif to gif work now? (I believe it does.)
> Does it work with your patch?


I think this would require changes to the reader. AFAICT, it only outputs
BGRA. Something I can look into if that seems right to you.


-- 


Bjorn Roche

Sr. Video Pipeline Engineer

bj...@giphy.com
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] fix for transparencies in animated gifs

2017-11-27 Thread Bjorn Roche
On Mon, Nov 27, 2017 at 5:41 PM, Carl Eugen Hoyos <ceffm...@gmail.com>
wrote:

> 2017-11-27 18:50 GMT+01:00 Bjorn Roche <bj...@giphy.com>:
> > Sorry for the very delayed response, Carl:
> >
> > On Tue, Nov 21, 2017 at 6:55 PM, Carl Eugen Hoyos <ceffm...@gmail.com>
> > wrote:
> >
> >> 2017-11-21 18:53 GMT+01:00 Bjorn Roche <bj...@giphy.com>:
> >> > Support for transparencies in animated gifs requires modifying both
> >> > libavcodec/gif.c and libavformat/gif.c because both the graphics
> >> > control extension (handled by libavformat/gif.c) and the raw frame
> data
> >> > (handled by libavcodec/gif.c) must be changed.
> >>
> >> Does remuxing animated gif with transparency work with your patch?
> >
> > A command like this:
> >
> > ffmpeg -i in.gif out.gif
> >
> > seems to produce the same output as before: transparency replaces
> > with opacity.
>
> remuxing == -vcodec copy
>
> What about ffmpeg -i in.gif -vcodec copy out.gif ?
>

That doesn't work. Weather I use my patch or not it aborts:

Assertion video_par->format == AV_PIX_FMT_PAL8 failed at
libavformat/gif.c:132

As far as I can tell, the gif decoder (which I haven't touched) outputs
BGRA, but the gif writer requires PAL8.

> However a command like this:
> >
> > ffmpeg -i in.gif  -vf palettegen -y /tmp/pal.png && ffmpeg -i in.gif
> > -i /tmp/pal.png -lavfi paletteuse -y -f gif out.gif
> >
> > produces an output that looks like the input (including transparency).
> >
> > I believe this is a problem with the decoder, however, since
> >
> > ffmpeg -i /Users/bjorn/Desktop/smoketrail.gif
> > /Users/bjorn/Desktop/smoketrail-out%d.png
>
> This produces transparent images here for the output
> file of ticket #6813.


./ffmpeg -i transparency.apng out.gif

Produces the expected results (you don't see previous images "behind" the
current image).

bjorn

-- 


Bjorn Roche

Sr. Video Pipeline Engineer

bj...@giphy.com
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] fix for transparencies in animated gifs (requires feedback)

2017-11-27 Thread Bjorn Roche
Thanks Moritz and Carl for your help with fate. This email was stuck in my
drafts :(

Comments below:

On Fri, Nov 3, 2017 at 8:11 PM, Carl Eugen Hoyos <ceffm...@gmail.com> wrote:

> 2017-10-24 18:40 GMT+02:00 Bjorn Roche <bj...@giphy.com>:
>
> > - I don’t know if/how to update the FATE tests.
>
> A quick way (that needs some double-checking) is:
> $ make GEN=1 SAMPLES=fate-suite fate
>
> (This overwrites all values with the new output.)
>

Thanks. I ended up doing it manually to be sure, but this is useful!


> Is the new side-data unavoidable?
> (Would the only alternative be to merge the muxer into the
> encoder?)
>

The only way I can see is to move some functionality between the mixer and
the encoder. It's not a clear line between the codec and the container in
GIF, so I wouldn't object to an approach different from the one I took.

bjorn


-- 


Bjorn Roche

Sr. Video Pipeline Engineer

bj...@giphy.com
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] fix for transparencies in animated gifs

2017-11-27 Thread Bjorn Roche
Sorry for the very delayed response, Carl:

On Tue, Nov 21, 2017 at 6:55 PM, Carl Eugen Hoyos <ceffm...@gmail.com>
wrote:

> 2017-11-21 18:53 GMT+01:00 Bjorn Roche <bj...@giphy.com>:
> > Support for transparencies in animated gifs requires modifying both
> > libavcodec/gif.c and libavformat/gif.c because both the graphics
> > control extension (handled by libavformat/gif.c) and the raw frame data
> > (handled by libavcodec/gif.c) must be changed.
>
> Does remuxing animated gif with transparency work with your patch?
>

A command like this:

ffmpeg -i in.gif out.gif

seems to produce the same output as before: transparency replaces with
opacity. However a command like this:

ffmpeg -i in.gif  -vf palettegen -y /tmp/pal.png && ffmpeg -i in.gif
-i /tmp/pal.png -lavfi paletteuse -y -f gif out.gif


produces an output that looks like the input (including transparency).


I believe this is a problem with the decoder, however, since


ffmpeg -i /Users/bjorn/Desktop/smoketrail.gif
/Users/bjorn/Desktop/smoketrail-out%d.png


produces opaque images as well.

-- 


Bjorn Roche

Sr. Video Pipeline Engineer

bj...@giphy.com
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] fix for transparencies in animated gifs (requires feedback)

2017-11-02 Thread Bjorn Roche
> - I don’t know if/how to update the FATE tests.


Can anyone comment on this? Do I update the tests in the same patch or
separate that?

-- 


Bjorn Roche

Sr. Video Pipeline Engineer

bj...@giphy.com
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] lavfi/paletteuse: fix to support transparency

2017-11-02 Thread Bjorn Roche
On Sat, Oct 28, 2017 at 11:18 AM, Clément Bœsch <u...@pkh.me> wrote:

> On Mon, Oct 23, 2017 at 07:12:57PM -0400, Bjorn Roche wrote:
> > This patch enables paletteuse to identify the transparency in incoming
> > video and tag transparent pixels on outgoing video with the correct
> > index from the palette.
> >
> > This requires tracking the transparency index in the palette,
> > establishing an alpha threshold below which a pixel is considered
> > transparent and above which the pixel is considered opaque, and
> > additional changes to track the alpha value throughout the conversion
> > process.
> >
> > This change is a partial fix for https://trac.ffmpeg.org/ticket/4443
> > However, animated GIFs are still output incorrectly due to a bug
> > in gif optimization which does not correctly handle transparency.
> > ---
> >  doc/filters.texi|   7 ++
> >  libavfilter/vf_paletteuse.c | 195 --
> --
>
> patch applied. I took the liberty to make the following changes before
> pushing:
>
> - fix spacing issues around () you forgot to fix
>

Sorry. It's the exact opposite of how I usually do it, so I can't even see
it :(


> - rename "threshold" into "alpha_threshold"
>

Much better.


> - move the option documentation in the appropriate place (it was between
>   diff_mode and one of its constant)
>

Cool. Thanks.


>
> Thanks for the patch, and sorry about the delay.
>

Thanks for everyone's help and feedback!

bjorn

-- 


Bjorn Roche

Sr. Video Pipeline Engineer

bj...@giphy.com
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] Support for decoding animated WebP images

2017-10-26 Thread Bjorn Roche
On Thu, Oct 26, 2017 at 11:21 AM, Carl Eugen Hoyos <ceffm...@gmail.com>
wrote:

> 2017-10-26 17:16 GMT+02:00 Bjorn Roche <bj...@giphy.com>:
> > Hey there,
> >
> > Has anyone been working on this ticket: https://trac.ffmpeg.org/
> ticket/4907
>
> Given that the ticket has seen no activity for two years, this
> isn't very likely.
>
> To make sure, feel free to add yourself as owner.
>
> > "Support decoding animated WebP images"
> >
> > I'd be interested in working on it, especially if it's not an enormous
> > project. Any guidance or hints, however vague, would be helpful. e.g., is
> > this a problem with the codec or the muxer? Is something wrong with the
> > underlying library? Which files should I look at first? Any idea/guess
> > about what the problem might be?
>
> Our webp decoder does not understand the ANIM and ANMF chunks.
>

Thanks, that's very helpful. On quick inspection of the spec it looks
similar to some things in GIF that I'm intimately familiar with. I'll need
to read a bit more, before I commit, but I think I can tackle this.

bjorn


-- 


Bjorn Roche

Sr. Video Pipeline Engineer

bj...@giphy.com
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] Support for decoding animated WebP images

2017-10-26 Thread Bjorn Roche
Hey there,

Has anyone been working on this ticket: https://trac.ffmpeg.org/ticket/4907

"Support decoding animated WebP images"

I'd be interested in working on it, especially if it's not an enormous
project. Any guidance or hints, however vague, would be helpful. e.g., is
this a problem with the codec or the muxer? Is something wrong with the
underlying library? Which files should I look at first? Any idea/guess
about what the problem might be?

Thanks so much!

bjorn

-- 


Bjorn Roche

Sr. Video Pipeline Engineer

bj...@giphy.com
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] fix for transparencies in animated gifs (requires feedback)

2017-10-25 Thread Bjorn Roche
On Tue, Oct 24, 2017 at 8:56 PM, Michael Niedermayer <mich...@niedermayer.cc
> wrote:

> On Tue, Oct 24, 2017 at 12:40:22PM -0400, Bjorn Roche wrote:
> > Support for transparencies in animated gifs requires modifying both
> > libavcodec/gif.c and libavformat/gif.c because both the graphics
> > control extension (handled by libavformat/gif.c) and the raw frame data
> > (handled by libavcodec/gif.c) must be changed. This is because
> > transparencies in GIF can be used both to create a transparent image,
> > and to provide optimization.
> >
> > How transparencies are interpreted in a given frame is controlled by
> > the “disposal method”, which must be set appropriately in the graphics
> > control extension.
> >
> >  The “in place” disposal method is used when transparency indicates
> > optimization, and the “background” disposal method is used when
> > transparency is intended to be preserved. In order to support both
> > disposal methods, libavcodec/gif.c must signal to libavformat/gif.c
> > which disposal method is required for every frame. This is done with a
> > new side data type: AV_PKT_DATA_GIF_FRAME_DISPOSAL. This requires a
> > change to avcodec.h
> >
> > Unfortunately, the addition of a new side data type causes some of the
> > FATE tests to fail. This is not addressed here.
> >
> > This patch assumes paletteuse has already been patched to support
> > transparency. (e.g. lavfi/paletteuse: fix to support transparency)
> >
> > Feedback I definitely need:
> > - I’ve done a fair bit of testing, but I’m sure I missed some important
> > cases.
> > - I don’t know if/how to update the FATE tests.
> > ---
> >  libavcodec/avcodec.h |   6 ++
> >  libavcodec/gif.c | 196 ++
> +++--
> >  libavformat/gif.c|  16 -
> >  3 files changed, 212 insertions(+), 6 deletions(-)
> >
> > diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
> > index 52cc5b0ca0..82a5328ce1 100644
> > --- a/libavcodec/avcodec.h
> > +++ b/libavcodec/avcodec.h
> > @@ -1599,6 +1599,12 @@ enum AVPacketSideDataType {
> >   */
> >  AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
> >
> > +/**
> > + * The disposal method that should be used with the frame. If
> missing,
> > + * the frame will not be disposed. This contains exactly one byte.
> > + */
> > +AV_PKT_DATA_GIF_FRAME_DISPOSAL,
> > +
> >  /**
> >   * ATSC A53 Part 4 Closed Captions. This metadata should be
> associated with
> >   * a video stream. A53 CC bitstream is stored as uint8_t in
> AVPacketSideData.data.
>
> you cannot add values in the middle of a public enum, that would
> change the ABI
>

Ah, thanks -- I thought that was internal only. Is it safe to add to the
end?

bjorn


-- 


Bjorn Roche

Sr. Video Pipeline Engineer

bj...@giphy.com
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] fix for transparencies in animated gifs (requires feedback)

2017-10-24 Thread Bjorn Roche
On Tue, Oct 24, 2017 at 4:24 PM, Carl Eugen Hoyos <ceffm...@gmail.com>
wrote:

> 2017-10-24 18:40 GMT+02:00 Bjorn Roche <bj...@giphy.com>:
>
> > This patch assumes paletteuse has already been patched to support
> > transparency. (e.g. lavfi/paletteuse: fix to support transparency)
>
> Which should - imo - be unrelated to this patch and indeed, transcoding
> a pal8 apng (produced with your paletteuse patch) produces a good gif
> with this patch.
> I don't know if this is the best approach though.
>

Ah, okay, then my comment is wrong -- I just didn't see a way to test it
without paletteuse being fixed, but a pal8 apng makes sense.

bjorn

-- 


Bjorn Roche

Sr. Video Pipeline Engineer

bj...@giphy.com
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] Fix for paletteuse to support transparency

2017-10-24 Thread Bjorn Roche
On Mon, Oct 23, 2017 at 7:17 PM, Bjorn Roche <bj...@giphy.com> wrote:

> On Sat, Oct 21, 2017 at 4:00 PM, Clément Bœsch <u...@pkh.me> wrote:
>
>> On Sat, Oct 21, 2017 at 09:47:47PM +0200, Carl Eugen Hoyos wrote:
>> > 2017-10-21 21:43 GMT+02:00 Clément Bœsch <u...@pkh.me>:
>> > > On Sat, Oct 21, 2017 at 09:37:06PM +0200, Carl Eugen Hoyos wrote:
>> > >> 2017-10-21 18:40 GMT+02:00 Clément Bœsch <u...@pkh.me>:
>> > >>
>> > >> > Aside from these nitpicks, I'm still concerned about how it's going
>> > >> > to conflict with GIF encoding where the transparent color is
>> actually
>> > >> > used as a mean of not updating pixels from previous frames.
>> > >>
>> > >> But is this really related to this patch?
>> > >
>> > > Maybe not, but we need to keep that in mind and not make a
>> > > hasty decision wrt how we handle the transparency, because
>> > > it might makes future related development much harder.
>> >
>> > Given that this is a libavfilter-only patch and we can reproduce
>> > the issue without using libavfilter, I am not completely
>> > convinced, but this is of course your decision.
>> >
>>
>> Yes it should be fine, I just want to be sure that using
>> palettegen/paletteuse will not create input streams that the limited GIF
>> encoder does not handle well because it doesn't make a difference between
>> "transparency flavours". If paletteuse starts inserting transparent colors
>> that are not meant to be used for the frame-diff system it could become a
>> problem.
>>
>
> There is a bug in the GIF encoder. I have a fix for that issue as well.
>

Okay, I've submitted that as well. Still need some feedback, but I believe
it's close.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH] fix for transparencies in animated gifs (requires feedback)

2017-10-24 Thread Bjorn Roche
Support for transparencies in animated gifs requires modifying both
libavcodec/gif.c and libavformat/gif.c because both the graphics
control extension (handled by libavformat/gif.c) and the raw frame data
(handled by libavcodec/gif.c) must be changed. This is because
transparencies in GIF can be used both to create a transparent image,
and to provide optimization.

How transparencies are interpreted in a given frame is controlled by
the “disposal method”, which must be set appropriately in the graphics
control extension.

 The “in place” disposal method is used when transparency indicates
optimization, and the “background” disposal method is used when
transparency is intended to be preserved. In order to support both
disposal methods, libavcodec/gif.c must signal to libavformat/gif.c
which disposal method is required for every frame. This is done with a
new side data type: AV_PKT_DATA_GIF_FRAME_DISPOSAL. This requires a
change to avcodec.h

Unfortunately, the addition of a new side data type causes some of the
FATE tests to fail. This is not addressed here.

This patch assumes paletteuse has already been patched to support
transparency. (e.g. lavfi/paletteuse: fix to support transparency)

Feedback I definitely need:
- I’ve done a fair bit of testing, but I’m sure I missed some important
cases.
- I don’t know if/how to update the FATE tests.
---
 libavcodec/avcodec.h |   6 ++
 libavcodec/gif.c | 196 +--
 libavformat/gif.c|  16 -
 3 files changed, 212 insertions(+), 6 deletions(-)

diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 52cc5b0ca0..82a5328ce1 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -1599,6 +1599,12 @@ enum AVPacketSideDataType {
  */
 AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
 
+/**
+ * The disposal method that should be used with the frame. If missing,
+ * the frame will not be disposed. This contains exactly one byte.
+ */
+AV_PKT_DATA_GIF_FRAME_DISPOSAL,
+
 /**
  * ATSC A53 Part 4 Closed Captions. This metadata should be associated with
  * a video stream. A53 CC bitstream is stored as uint8_t in 
AVPacketSideData.data.
diff --git a/libavcodec/gif.c b/libavcodec/gif.c
index d9c99d52cf..6c839d99d2 100644
--- a/libavcodec/gif.c
+++ b/libavcodec/gif.c
@@ -74,11 +74,35 @@ static int pick_palette_entry(const uint8_t *buf, int 
linesize, int w, int h)
 return -1;
 }
 
-static int gif_image_write_image(AVCodecContext *avctx,
- uint8_t **bytestream, uint8_t *end,
- const uint32_t *palette,
- const uint8_t *buf, const int linesize,
- AVPacket *pkt)
+// returns true if any of the pixels are transparent
+static int is_image_translucent(AVCodecContext *avctx,
+const uint32_t *palette,
+const uint8_t *buf, const int linesize)
+{
+GIFContext *s = avctx->priv_data;
+int trans = s->transparent_index;
+int p;
+const int m = avctx->width * avctx->height ;
+
+if (trans < 0) {
+return 0;
+}
+
+for (p=0; ppriv_data;
 int len = 0, height = avctx->height, width = avctx->width, x, y;
@@ -137,6 +161,11 @@ static int gif_image_write_image(AVCodecContext *avctx,
width, height, x_start, y_start, avctx->width, avctx->height);
 }
 
+uint8_t *frame_disposal = av_packet_new_side_data(pkt, 
AV_PKT_DATA_GIF_FRAME_DISPOSAL, 1);
+if (!frame_disposal)
+return AVERROR(ENOMEM);
+*frame_disposal = GCE_DISPOSAL_INPLACE;
+
 /* image block */
 bytestream_put_byte(bytestream, GIF_IMAGE_SEPARATOR);
 bytestream_put_le16(bytestream, x_start);
@@ -214,6 +243,163 @@ static int gif_image_write_image(AVCodecContext *avctx,
 return 0;
 }
 
+// wrtites an image that may contain transparency
+// this should work for opaque images as well, but will be less optimized.
+static int gif_image_write_translucent(AVCodecContext *avctx,
+   uint8_t **bytestream, uint8_t *end,
+   const uint32_t *palette,
+   const uint8_t *buf, const int linesize,
+   AVPacket *pkt)
+{
+GIFContext *s = avctx->priv_data;
+int len = 0, height = 

Re: [FFmpeg-devel] [PATCH] Fix for paletteuse to support transparency

2017-10-23 Thread Bjorn Roche
On Sat, Oct 21, 2017 at 4:00 PM, Clément Bœsch <u...@pkh.me> wrote:

> On Sat, Oct 21, 2017 at 09:47:47PM +0200, Carl Eugen Hoyos wrote:
> > 2017-10-21 21:43 GMT+02:00 Clément Bœsch <u...@pkh.me>:
> > > On Sat, Oct 21, 2017 at 09:37:06PM +0200, Carl Eugen Hoyos wrote:
> > >> 2017-10-21 18:40 GMT+02:00 Clément Bœsch <u...@pkh.me>:
> > >>
> > >> > Aside from these nitpicks, I'm still concerned about how it's going
> > >> > to conflict with GIF encoding where the transparent color is
> actually
> > >> > used as a mean of not updating pixels from previous frames.
> > >>
> > >> But is this really related to this patch?
> > >
> > > Maybe not, but we need to keep that in mind and not make a
> > > hasty decision wrt how we handle the transparency, because
> > > it might makes future related development much harder.
> >
> > Given that this is a libavfilter-only patch and we can reproduce
> > the issue without using libavfilter, I am not completely
> > convinced, but this is of course your decision.
> >
>
> Yes it should be fine, I just want to be sure that using
> palettegen/paletteuse will not create input streams that the limited GIF
> encoder does not handle well because it doesn't make a difference between
> "transparency flavours". If paletteuse starts inserting transparent colors
> that are not meant to be used for the frame-diff system it could become a
> problem.
>

There is a bug in the GIF encoder. I have a fix for that issue as well.

In the meantime, I have submitted another patch to address the concerns
that are specific to this fix.

bjorn

-- 


Bjorn Roche

Sr. Video Pipeline Engineer

bj...@giphy.com
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH] lavfi/paletteuse: fix to support transparency

2017-10-23 Thread Bjorn Roche
This patch enables paletteuse to identify the transparency in incoming
video and tag transparent pixels on outgoing video with the correct
index from the palette.

This requires tracking the transparency index in the palette,
establishing an alpha threshold below which a pixel is considered
transparent and above which the pixel is considered opaque, and
additional changes to track the alpha value throughout the conversion
process.

This change is a partial fix for https://trac.ffmpeg.org/ticket/4443
However, animated GIFs are still output incorrectly due to a bug
in gif optimization which does not correctly handle transparency.
---
 doc/filters.texi|   7 ++
 libavfilter/vf_paletteuse.c | 195 
 2 files changed, 131 insertions(+), 71 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index 57189c77b0..690a60f569 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -11531,6 +11531,13 @@ The option must be an integer value in the range 
[0,5]. Default is @var{2}.
 @item diff_mode
 If set, define the zone to process
 
+@item threshold
+Sets the alpha threshold for transparency. Alpha values above this threshold
+will be treated as completely opaque, and values below this threshold will be
+treated as completely transparent.
+
+The option must be an integer value in the range [0,255]. Default is 128.
+
 @table @samp
 @item rectangle
 Only the changing rectangle will be reprocessed. This is similar to GIF
diff --git a/libavfilter/vf_paletteuse.c b/libavfilter/vf_paletteuse.c
index 79a0672891..40ec3b2a78 100644
--- a/libavfilter/vf_paletteuse.c
+++ b/libavfilter/vf_paletteuse.c
@@ -56,7 +56,7 @@ enum diff_mode {
 };
 
 struct color_node {
-uint8_t val[3];
+uint8_t val[4];
 uint8_t palette_id;
 int split;
 int left_id, right_id;
@@ -86,6 +86,8 @@ typedef struct PaletteUseContext {
 struct cache_node cache[CACHE_SIZE];/* lookup cache */
 struct color_node map[AVPALETTE_COUNT]; /* 3D-Tree (KD-Tree with K=3) for 
reverse colormap */
 uint32_t palette[AVPALETTE_COUNT];
+int transparency_index; /* index in the palette of transparency. -1 if 
there is no transparency in the palette. */
+int trans_thresh;
 int palette_loaded;
 int dither;
 int new;
@@ -116,6 +118,7 @@ static const AVOption paletteuse_options[] = {
 { "bayer_scale", "set scale for bayer dithering", OFFSET(bayer_scale), 
AV_OPT_TYPE_INT, {.i64=2}, 0, 5, FLAGS },
 { "diff_mode",   "set frame difference mode", OFFSET(diff_mode),   
AV_OPT_TYPE_INT, {.i64=DIFF_MODE_NONE}, 0, NB_DIFF_MODE-1, FLAGS, "diff_mode" },
 { "rectangle", "process smallest different rectangle", 0, 
AV_OPT_TYPE_CONST, {.i64=DIFF_MODE_RECTANGLE}, INT_MIN, INT_MAX, FLAGS, 
"diff_mode" },
+{ "threshold", "set the alpha threshold for transparency.", 
OFFSET(trans_thresh), AV_OPT_TYPE_INT, {.i64=128}, 0, 255, },
 
 /* following are the debug options, not part of the official API */
 { "debug_kdtree", "save Graphviz graph of the kdtree in specified file", 
OFFSET(dot_filename), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, 
FLAGS },
@@ -157,34 +160,43 @@ static int query_formats(AVFilterContext *ctx)
 
 static av_always_inline int dither_color(uint32_t px, int er, int eg, int eb, 
int scale, int shift)
 {
-return av_clip_uint8((px >> 16 & 0xff) + ((er * scale) / (1<> 24  ) << 24
+ | av_clip_uint8((px >> 16 & 0xff) + ((er * scale) / (1<>  8 & 0xff) + ((eg * scale) / (1<= trans_thresh && c2[0] >= trans_thresh) {
+return dr*dr + dg*dg + db*db;
+} else {
+return 255*255 + 255*255 + 255*255;
+}
 }
 
-static av_always_inline uint8_t colormap_nearest_bruteforce(const uint32_t 
*palette, const uint8_t *rgb)
+static av_always_inline uint8_t colormap_nearest_bruteforce(const uint32_t 
*palette, const uint8_t *argb, const int trans_thresh)
 {
 int i, pal_id = -1, min_dist = INT_MAX;
 
 for (i = 0; i < AVPALETTE_COUNT; i++) {
 const uint32_t c = palette[i];
 
-if ((c & 0xff00) == 0xff00) { // ignore transparent entry
-const uint8_t palrgb[] = {
+if ( c >> 24 >= 

[FFmpeg-devel] [PATCH] Fix for paletteuse to support transparency

2017-10-19 Thread Bjorn Roche
The palettes generated by palettegen include one transparent color.
This patch enables paletteuse to identify the transparency in incoming
video and tag transparent pixels on outgoing video.

This requires tracking the transparency index in the palette,
establishing an alpha threshold below which a pixel is considered
transparent and above which the pixel is considered opaque, and
additional changes to track the alpha value throught the conversion
process. If the format of a color variable has changed in this patch,
an effort was also made to change the variable name for clarity.

This change is a partial fix for https://trac.ffmpeg.org/ticket/4443
However, animated GIFs are still output incorrectly due to a bug
in gif optimization which does not correctly handle transparency.
---
 libavfilter/vf_paletteuse.c | 210 
 1 file changed, 132 insertions(+), 78 deletions(-)

diff --git a/libavfilter/vf_paletteuse.c b/libavfilter/vf_paletteuse.c
index 79a0672891..fa5897b7f3 100644
--- a/libavfilter/vf_paletteuse.c
+++ b/libavfilter/vf_paletteuse.c
@@ -56,7 +56,7 @@ enum diff_mode {
 };
 
 struct color_node {
-uint8_t val[3];
+uint8_t val[4];
 uint8_t palette_id;
 int split;
 int left_id, right_id;
@@ -86,6 +86,8 @@ typedef struct PaletteUseContext {
 struct cache_node cache[CACHE_SIZE];/* lookup cache */
 struct color_node map[AVPALETTE_COUNT]; /* 3D-Tree (KD-Tree with K=3) for 
reverse colormap */
 uint32_t palette[AVPALETTE_COUNT];
+int transparency_index; /* index in the palette of transparency. -1 if 
there isn't a transparency. */
+int trans_thresh;
 int palette_loaded;
 int dither;
 int new;
@@ -116,6 +118,7 @@ static const AVOption paletteuse_options[] = {
 { "bayer_scale", "set scale for bayer dithering", OFFSET(bayer_scale), 
AV_OPT_TYPE_INT, {.i64=2}, 0, 5, FLAGS },
 { "diff_mode",   "set frame difference mode", OFFSET(diff_mode),   
AV_OPT_TYPE_INT, {.i64=DIFF_MODE_NONE}, 0, NB_DIFF_MODE-1, FLAGS, "diff_mode" },
 { "rectangle", "process smallest different rectangle", 0, 
AV_OPT_TYPE_CONST, {.i64=DIFF_MODE_RECTANGLE}, INT_MIN, INT_MAX, FLAGS, 
"diff_mode" },
+{ "threshold", "set the alpha threshold for transparency. Above this 
threshold, pixels are considered opaque, below they are considered 
transparent.", OFFSET(trans_thresh), AV_OPT_TYPE_INT, {.i64=128}, 0, 255, },
 
 /* following are the debug options, not part of the official API */
 { "debug_kdtree", "save Graphviz graph of the kdtree in specified file", 
OFFSET(dot_filename), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, 
FLAGS },
@@ -157,34 +160,44 @@ static int query_formats(AVFilterContext *ctx)
 
 static av_always_inline int dither_color(uint32_t px, int er, int eg, int eb, 
int scale, int shift)
 {
-return av_clip_uint8((px >> 16 & 0xff) + ((er * scale) / (1<> 24  ) << 24
+ | av_clip_uint8((px >> 16 & 0xff) + ((er * scale) / (1<>  8 & 0xff) + ((eg * scale) / (1<= trans_thresh && c2[0] >= trans_thresh) {
+return dr*dr + dg*dg + db*db;
+} else {
+return max_diff;
+}
 }
 
-static av_always_inline uint8_t colormap_nearest_bruteforce(const uint32_t 
*palette, const uint8_t *rgb)
+static av_always_inline uint8_t colormap_nearest_bruteforce(const uint32_t 
*palette, const uint8_t *argb, const int trans_thresh)
 {
 int i, pal_id = -1, min_dist = INT_MAX;
 
 for (i = 0; i < AVPALETTE_COUNT; i++) {
 const uint32_t c = palette[i];
 
-if ((c & 0xff00) == 0xff00) { // ignore transparent entry
-const uint8_t palrgb[] = {
+if ( c >> 24 >= trans_thresh ) { // ignore transparent entry
+const uint8_t palargb[] = {
+palette[i]>>24 & 0xff,
 palette[i]>>16 & 0xff,
 palette[i]>> 8 & 0xff,
 palette[i] & 0xff,
 };
-const int d = diff(palrgb, rgb);
+const int d = diff(palargb, argb, trans_thresh);
 if (d < min_dist) {
 pal_id = i;

Re: [FFmpeg-devel] [PATCH] Fix for paletteuse to support transparency

2017-10-17 Thread Bjorn Roche
On Tue, Oct 17, 2017 at 5:27 PM, Carl Eugen Hoyos <ceffm...@gmail.com>
wrote:

> 2017-10-17 3:16 GMT+02:00 Carl Eugen Hoyos <ceffm...@gmail.com>:
> > 2017-10-10 23:41 GMT+02:00 Bjorn Roche <bj...@giphy.com>:
> >
> >> +{ "trans_threshold", "set the threshold for alpha values avoce
> which they are considered completely opaque", OFFSET(trans_thresh),
> AV_OPT_TYPE_INT, {.i64=128}, 0, 255, },
>

Looks like I somehow spelled "above" "avoce".


> > I wonder if "threshold" is enough.
> >
> > No more comments from me, thank you!
>
> Remaining comment is:
> The paletteuse filter does not work correctly on big-endian
> (my guess is the code makes wrong assumptions about the
> palette colour-space), I don't think this should delay this
> patch though.


Is this due to the patch, or was this a problem prior to the patch as well?
If it's due to the patch, I can try to gain access to a big-endian machine
and see if I can fix it.

bjorn

-- 


Bjorn Roche

Sr. Video Pipeline Engineer

bj...@giphy.com
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] Fix for paletteuse to support transparency

2017-10-17 Thread Bjorn Roche
On Mon, Oct 16, 2017 at 9:16 PM, Carl Eugen Hoyos <ceffm...@gmail.com>
wrote:

> 2017-10-10 23:41 GMT+02:00 Bjorn Roche <bj...@giphy.com>:
>
> > +{ "trans_threshold", "set the threshold for alpha values avoce
> which they are considered completely opaque", OFFSET(trans_thresh),
> AV_OPT_TYPE_INT, {.i64=128}, 0, 255, },
>
> I wonder if "threshold" is enough.
>

That would be fine with me. I can submit another patch if I get any further
feedback.

bjorn

-- 


Bjorn Roche

Sr. Video Pipeline Engineer

bj...@giphy.com
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH] Fix for paletteuse to support transparency

2017-10-06 Thread Bjorn Roche
---
 libavfilter/vf_paletteuse.c | 175 
 1 file changed, 112 insertions(+), 63 deletions(-)

diff --git a/libavfilter/vf_paletteuse.c b/libavfilter/vf_paletteuse.c
index ffd37bf1da..4203543843 100644
--- a/libavfilter/vf_paletteuse.c
+++ b/libavfilter/vf_paletteuse.c
@@ -56,7 +56,7 @@ enum diff_mode {
 };
 
 struct color_node {
-uint8_t val[3];
+uint8_t val[4];
 uint8_t palette_id;
 int split;
 int left_id, right_id;
@@ -86,6 +86,7 @@ typedef struct PaletteUseContext {
 struct cache_node cache[CACHE_SIZE];/* lookup cache */
 struct color_node map[AVPALETTE_COUNT]; /* 3D-Tree (KD-Tree with K=3) for 
reverse colormap */
 uint32_t palette[AVPALETTE_COUNT];
+int transparency_index; /* index in the palette of transparency. -1 if 
there isn't a transparency. */
 int palette_loaded;
 int dither;
 int new;
@@ -108,6 +109,7 @@ typedef struct PaletteUseContext {
 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
 static const AVOption paletteuse_options[] = {
 { "dither", "select dithering mode", OFFSET(dither), AV_OPT_TYPE_INT, 
{.i64=DITHERING_SIERRA2_4A}, 0, NB_DITHERING-1, FLAGS, "dithering_mode" },
+{ "none","no dither",  
0, AV_OPT_TYPE_CONST, {.i64=DITHERING_NONE},
INT_MIN, INT_MAX, FLAGS, "dithering_mode" },
 { "bayer",   "ordered 8x8 bayer dithering (deterministic)",
0, AV_OPT_TYPE_CONST, {.i64=DITHERING_BAYER},   
INT_MIN, INT_MAX, FLAGS, "dithering_mode" },
 { "heckbert","dithering as defined by Paul Heckbert in 1982 
(simple error diffusion)", 0, AV_OPT_TYPE_CONST, {.i64=DITHERING_HECKBERT}, 
   INT_MIN, INT_MAX, FLAGS, "dithering_mode" },
 { "floyd_steinberg", "Floyd and Steingberg dithering (error 
diffusion)",   0, AV_OPT_TYPE_CONST, 
{.i64=DITHERING_FLOYD_STEINBERG}, INT_MIN, INT_MAX, FLAGS, "dithering_mode" },
@@ -157,7 +159,8 @@ static int query_formats(AVFilterContext *ctx)
 
 static av_always_inline int dither_color(uint32_t px, int er, int eg, int eb, 
int scale, int shift)
 {
-return av_clip_uint8((px >> 16 & 0xff) + ((er * scale) / (1<> 24 & 0xff)  ) << 24
+ | av_clip_uint8((px >> 16 & 0xff) + ((er * scale) / (1<>  8 & 0xff) + ((eg * scale) / (1<>24 & 0xff,
 palette[i]>>16 & 0xff,
 palette[i]>> 8 & 0xff,
 palette[i] & 0xff,
 };
-const int d = diff(palrgb, rgb);
+const int d = diff(palargb, rgb);
 if (d < min_dist) {
 pal_id = i;
 min_dist = d;
 }
 }
 }
+
 return pal_id;
 }
 
@@ -325,14 +338,15 @@ end:
  * Note: r, g, and b are the component of c but are passed as well to avoid
  * recomputing them (they are generally computed by the caller for other uses).
  */
-static av_always_inline int color_get(struct cache_node *cache, uint32_t color,
-  uint8_t r, uint8_t g, uint8_t b,
+static av_always_inline int color_get(struct cache_node *cache, uint32_t argb,
+  uint8_t a, uint8_t r, uint8_t g, uint8_t 
b,
+  int transparency_index,
   const struct color_node *map,
   const uint32_t *palette,
   const enum color_search_method 
search_method)
 {
 int i;
-

Re: [FFmpeg-devel] [PATCH 0/7] Fix for transparent gif creation

2017-10-05 Thread Bjorn Roche
On Wed, Oct 4, 2017 at 2:50 AM, Clément Bœsch <u...@pkh.me> wrote:

> On Mon, Oct 02, 2017 at 01:24:32PM -0400, Bjorn Roche wrote:
> [...]
> > Bjorn Roche (7):
> >   First pass at fixing paletteuse
> >   Fix for dithering.
> >   Removing some debugging
> >   First pass at making the gif support transparency with the right
> > disposal methods. Needs more optimization.
> >   Reimplement optimization for transparency
> >   cleanup
> >   Fix for detecting opaque correctly.
>
> Please organize your patches in atomic changes instead of your
> chronological construction:
>
> - a patch should ideally change only one thing
> - each patch should be applicable without breaking anything
> - changes that do not belong at the end of the patchset should not be
>   present in the middle of the history unless technically required (your
>   debug logs don't).
>

Thank you Clement. I cleaned it up and sent a separate patch just for
paletteuse in response to a similar request from Carl Eugen.


bjorn

-- 


Bjorn Roche

Sr. Video Pipeline Engineer

bj...@giphy.com
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH 3/7] Removing some debugging

2017-10-05 Thread Bjorn Roche
On Tue, Oct 3, 2017 at 4:02 AM, Carl Eugen Hoyos <ceffm...@gmail.com> wrote:

> 2017-10-03 1:52 GMT+02:00 Bjorn Roche <bj...@giphy.com>:
>
> > Attached is a patch for paletteuse only.
>
> I tested the following with and without your patch:
> $ ffmpeg -i fate-suite/lena.pnm -vf palettegen pal.png
> $ ffmpeg -i fate-suite/lena.pnm -i pal.png -lavfi paletteuse out.png
>
> out.png changes with your patch: Is that intended?
>

Not intended, but not unexpected -- the ordering of colors in the palette
changed to make it easier to deal with transparency. However, there are
visual differences, so that's obviously a bug. I've supplied a new patch
(below) that fixes that bug, and maintains the order so it's easier to test
for that.


> The input frame contains no transparency.
>
> Your patch still contains printfs that should be removed
> (change them to av_log(DEBUG) if you think they are
> useful) and a new warning is shown at compilation:
> libavfilter/vf_paletteuse.c: In function ‘colormap_nearest_recursive’:
> libavfilter/vf_paletteuse.c:242:5: warning: ISO C90 forbids mixed
> declarations and code
>
> Please fix the style: Space after "if", no space after "if ("
>

Thank you for your attention. This should also be resolved in the attached
patch.

I have tested fate, all dithering (including none, which I added) and all
color search algorithms.
diff --git a/libavfilter/vf_paletteuse.c b/libavfilter/vf_paletteuse.c
index ffd37bf1da..7cb5a3db02 100644
--- a/libavfilter/vf_paletteuse.c
+++ b/libavfilter/vf_paletteuse.c
@@ -56,7 +56,7 @@ enum diff_mode {
 };
 
 struct color_node {
-uint8_t val[3];
+uint8_t val[4];
 uint8_t palette_id;
 int split;
 int left_id, right_id;
@@ -86,6 +86,7 @@ typedef struct PaletteUseContext {
 struct cache_node cache[CACHE_SIZE];/* lookup cache */
 struct color_node map[AVPALETTE_COUNT]; /* 3D-Tree (KD-Tree with K=3) for 
reverse colormap */
 uint32_t palette[AVPALETTE_COUNT];
+int transparency_index; /* index in the palette of transparency. -1 if 
there isn't a transparency. */
 int palette_loaded;
 int dither;
 int new;
@@ -108,6 +109,7 @@ typedef struct PaletteUseContext {
 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
 static const AVOption paletteuse_options[] = {
 { "dither", "select dithering mode", OFFSET(dither), AV_OPT_TYPE_INT, 
{.i64=DITHERING_SIERRA2_4A}, 0, NB_DITHERING-1, FLAGS, "dithering_mode" },
+{ "none","no dither",  
0, AV_OPT_TYPE_CONST, {.i64=DITHERING_NONE},
INT_MIN, INT_MAX, FLAGS, "dithering_mode" },
 { "bayer",   "ordered 8x8 bayer dithering (deterministic)",
0, AV_OPT_TYPE_CONST, {.i64=DITHERING_BAYER},   
INT_MIN, INT_MAX, FLAGS, "dithering_mode" },
 { "heckbert","dithering as defined by Paul Heckbert in 1982 
(simple error diffusion)", 0, AV_OPT_TYPE_CONST, {.i64=DITHERING_HECKBERT}, 
   INT_MIN, INT_MAX, FLAGS, "dithering_mode" },
 { "floyd_steinberg", "Floyd and Steingberg dithering (error 
diffusion)",   0, AV_OPT_TYPE_CONST, 
{.i64=DITHERING_FLOYD_STEINBERG}, INT_MIN, INT_MAX, FLAGS, "dithering_mode" },
@@ -157,7 +159,8 @@ static int query_formats(AVFilterContext *ctx)
 
 static av_always_inline int dither_color(uint32_t px, int er, int eg, int eb, 
int scale, int shift)
 {
-return av_clip_uint8((px >> 16 & 0xff) + ((er * scale) / (1<<shift))) << 16
+return av_clip_uint8((px >> 24 & 0xff)  ) << 24
+ | av_clip_uint8((px >> 16 & 0xff) + ((er * scale) / (1<<shift))) << 16
  | av_clip_uint8((px >>  8 & 0xff) + ((eg * scale) / (1<<shift))) <<  8
  | av_clip_uint8((px   & 0xff) + ((eb * scale) / (1<<shift)));
 }
@@ -165,10 +168,18 @@ static av_always_inline int dither_color(uint32_t px, int 
er, int eg, int eb, in
 static av_always_inline int diff(const uint8_t *c1, const uint8_t *c2)
 {
 // XXX: try L*a*b with CIE76 (dL*dL + da*da + db*db)
-const int dr = c1[0] - c2[0];
-const int dg = c1[1] - c2[1];
-const int db = c1[2] - c2[2];
-return dr*dr + dg*dg + db*db;
+const static int max_diff = 255*255 + 255*255 + 255*255;
+const int dr = c1[1] - c2[1];
+const int dg = c1[2] - c2[2];
+const int db = c1[3] - c2[3];
+
+if (c1[0] == 0 && c2[0] == 0) {
+return 0;
+} else if (c1[0] == c2[0]) {
+return dr*dr + dg*dg + db*db;
+} else {
+return max_diff;
+}
 }
 
 static av_always_inline uint8_t colormap_nearest_brut

Re: [FFmpeg-devel] [PATCH 3/7] Removing some debugging

2017-10-02 Thread Bjorn Roche
On Mon, Oct 2, 2017 at 4:19 PM, Carl Eugen Hoyos <ceffm...@gmail.com> wrote:

> 2017-10-02 20:44 GMT+02:00 Bjorn Roche <bj...@giphy.com>:
> > I submitted a complete patch separately
>
> No.
>
> What I wrote in my last email was (please
> do not top-post here):
> >> Instead please merge your paletteuse patches
> >> into one patch, I believe the new patch should
> >> allow to encode a single RGBA frame with
> >> transparency into pal8 png or similar.
>
> The earlier patch you sent did not only change
> the paletteuse filter.
>
>
Attached is a patch for paletteuse only. It produces broken animated gifs
when a transparent video is input, but it produces correct stills.

bjorn

-- 


Bjorn Roche

Sr. Video Pipeline Engineer

bj...@giphy.com


paletteuse.patch
Description: Binary data
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH 3/7] Removing some debugging

2017-10-02 Thread Bjorn Roche
I submitted a complete patch separately (
http://ffmpeg.org/pipermail/ffmpeg-devel/2017-September/216793.html), but
this is how git-email formatted things. How would you like me to proceed?

On Mon, Oct 2, 2017 at 2:13 PM, Carl Eugen Hoyos <ceffm...@gmail.com> wrote:

> 2017-10-02 19:24 GMT+02:00 Bjorn Roche <bj...@giphy.com>:
> > From: Bjorn Roche <bj...@xowave.com>
>
> > -printf( "alpha 1, 2: %d, %d\n", c1[0], c2[0] );
>
> Instead please merge your paletteuse patches
> into one patch, I believe the new patch should
> allow to encode a single RGBA frame with
> transparency into pal8 png or similar.
>
> Carl Eugen
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>



-- 


Bjorn Roche

Sr. Video Pipeline Engineer

bj...@giphy.com
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 6/7] cleanup

2017-10-02 Thread Bjorn Roche
From: Bjorn Roche <bj...@xowave.com>

---
 libavcodec/gif.c  | 14 +-
 libavformat/gif.c |  2 +-
 2 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/libavcodec/gif.c b/libavcodec/gif.c
index 3838aa7592..3ced6d4d45 100644
--- a/libavcodec/gif.c
+++ b/libavcodec/gif.c
@@ -265,7 +265,7 @@ static int gif_image_write_translucent(AVCodecContext 
*avctx,
 int x_end = w - 1,
 y_end = h - 1;
 
-// top
+// crop top
 while (y_start < y_end) {
 int i;
 int is_trans = 1;
@@ -280,7 +280,7 @@ static int gif_image_write_translucent(AVCodecContext 
*avctx,
 ++y_start;
 }
 
-// bottom
+// crop bottom
 while (y_end < h) {
 int i;
 int is_trans = 1;
@@ -295,7 +295,7 @@ static int gif_image_write_translucent(AVCodecContext 
*avctx,
 --y_end;
 }
 
-// left
+// crop left
 while (x_start < x_end) {
 int i;
 int is_trans = 1;
@@ -310,7 +310,7 @@ static int gif_image_write_translucent(AVCodecContext 
*avctx,
 ++x_start;
 }
 
-// right
+// crop right
 while (x_end < w) {
 int i;
 int is_trans = 1;
@@ -326,15 +326,11 @@ static int gif_image_write_translucent(AVCodecContext 
*avctx,
 }
 
 height = y_end + 1 - y_start;
-width = x_end + 1 - x_start;
+width  = x_end + 1 - x_start;
 av_log(avctx, AV_LOG_DEBUG,"%dx%d image at pos (%d;%d) [area:%dx%d]\n",
width, height, x_start, y_start, avctx->width, avctx->height);
 }
 
-// for( int i=0; iwidth*avctx->height; ++i ) {
-// ((uint8_t *)buf)[i] = 120;
-// }
-
 
 uint8_t *frame_disposal = av_packet_new_side_data(pkt, 
AV_PKT_DATA_GIF_FRAME_DISPOSAL, 1);
 if (!frame_disposal)
diff --git a/libavformat/gif.c b/libavformat/gif.c
index 853e84430e..4662720049 100644
--- a/libavformat/gif.c
+++ b/libavformat/gif.c
@@ -176,7 +176,7 @@ static int flush_packet(AVFormatContext *s, AVPacket *new)
 } else {
 packed = 1<<2 | (bcid >= 0);
 }
-//FIXME: if disposal == 2, make sure backgrdoun color is specified 
appropriately.
+
 avio_w8(pb, 0x21);
 avio_w8(pb, 0xf9);
 avio_w8(pb, 0x04); /* block size */
-- 
2.14.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 4/7] First pass at making the gif support transparency with the right disposal methods. Needs more optimization.

2017-10-02 Thread Bjorn Roche
From: Bjorn Roche <bj...@xowave.com>

---
 libavcodec/avcodec.h |   6 ++
 libavcodec/gif.c | 177 +--
 libavformat/gif.c|  16 -
 3 files changed, 193 insertions(+), 6 deletions(-)

diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 5c84974e03..3c64e8f7ee 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -1599,6 +1599,12 @@ enum AVPacketSideDataType {
  */
 AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
 
+/**
+ * The disposal method that should be used with the frame. If missing,
+ * the frame will not be disposed. This contains exactly one byte.
+ */
+AV_PKT_DATA_GIF_FRAME_DISPOSAL,
+
 /**
  * The number of side data elements (in fact a bit more than it).
  * This is not part of the public API/ABI in the sense that it may
diff --git a/libavcodec/gif.c b/libavcodec/gif.c
index d9c99d52cf..db2193a718 100644
--- a/libavcodec/gif.c
+++ b/libavcodec/gif.c
@@ -74,11 +74,36 @@ static int pick_palette_entry(const uint8_t *buf, int 
linesize, int w, int h)
 return -1;
 }
 
-static int gif_image_write_image(AVCodecContext *avctx,
- uint8_t **bytestream, uint8_t *end,
- const uint32_t *palette,
- const uint8_t *buf, const int linesize,
- AVPacket *pkt)
+// returns true if any of the pixels are transparent
+static int is_image_translucent(AVCodecContext *avctx,
+const uint32_t *palette,
+const uint8_t *buf, const int linesize)
+{
+GIFContext *s = avctx->priv_data;
+int trans = s->transparent_index;
+int p;
+const int m = avctx->width * avctx->height ;
+
+if( trans < 0 ) {
+return 0;
+}
+
+// FIXME: this might be faster with strchr
+for( p=0; p<m; ++p ) {
+if( buf[p] == trans ) {
+return 1;
+}
+}
+return 0;
+}
+
+// writes an opaque image. ie an image with no transparency.
+// it also works, and should be used, for a first image.
+static int gif_image_write_opaque(AVCodecContext *avctx,
+  uint8_t **bytestream, uint8_t *end,
+  const uint32_t *palette,
+  const uint8_t *buf, const int linesize,
+  AVPacket *pkt)
 {
 GIFContext *s = avctx->priv_data;
 int len = 0, height = avctx->height, width = avctx->width, x, y;
@@ -86,6 +111,7 @@ static int gif_image_write_image(AVCodecContext *avctx,
 int honor_transparency = (s->flags & GF_TRANSDIFF) && s->last_frame && 
!palette;
 const uint8_t *ptr;
 
+
 /* Crop image */
 if ((s->flags & GF_OFFSETTING) && s->last_frame && !palette) {
 const uint8_t *ref = s->last_frame->data[0];
@@ -137,6 +163,11 @@ static int gif_image_write_image(AVCodecContext *avctx,
width, height, x_start, y_start, avctx->width, avctx->height);
 }
 
+uint8_t *frame_disposal = av_packet_new_side_data(pkt, 
AV_PKT_DATA_GIF_FRAME_DISPOSAL, 1);
+if (!frame_disposal)
+return AVERROR(ENOMEM);
+*frame_disposal = GCE_DISPOSAL_INPLACE;
+
 /* image block */
 bytestream_put_byte(bytestream, GIF_IMAGE_SEPARATOR);
 bytestream_put_le16(bytestream, x_start);
@@ -214,6 +245,142 @@ static int gif_image_write_image(AVCodecContext *avctx,
 return 0;
 }
 
+// wrtites an image that may contain transparency
+// this might work for opaque images as well, but will be less optimized.
+static int gif_image_write_translucent(AVCodecContext *avctx,
+   uint8_t **bytestream, uint8_t *end,
+   const uint32_t *palette,
+   const uint8_t *buf, const int linesize,
+   AVPacket *pkt)
+{
+GIFContext *s = avctx->priv_data;
+int len = 0, height = avctx->height, width = avctx->width, x, y;
+int x_start = 0, y_start = 0, trans = s->transparent_index;
+int honor_transparency = (s->flags & GF_TRANSDIFF) && s->last_frame && 
!palette;
+const uint8_t *ptr;
+
+// /* Crop image */
+// if ((s->flags & GF_OFFSETTING) && s->last_frame && !palette) {
+// const uint8_t *ref = s->last_frame->data[0];
+// const int ref_linesize = s->last_frame->linesize[0];
+// int x_end = avctx->width  - 1,
+// y_end = avctx->height - 1;
+
+// /* skip common lines */
+// while (y_start < y_end) {
+// if (memcmp(ref + y_start*ref_linesize, buf + y_start*linesize, 
width))
+// break;
+// y_start++;
+// }
+// while (y_end > y_star

[FFmpeg-devel] [PATCH 0/7] Fix for transparent gif creation

2017-10-02 Thread Bjorn Roche
These series of patches fixes transparent gifs.

See issue: https://trac.ffmpeg.org/ticket/4443

The paletteuse function had to be patched to support transparency, and the gif 
encoder had to be patched so that support for transparent gifs worked with 
animated gifs, not just single frames.

In addition, the side channel data has to change to support this, so the 
automated tests must be updated. I don't know how to do this. I give further 
explination of that here: 
http://ffmpeg.org/pipermail/ffmpeg-devel/2017-September/216863.html


Bjorn Roche (7):
  First pass at fixing paletteuse
  Fix for dithering.
  Removing some debugging
  First pass at making the gif support transparency with the right
disposal methods. Needs more optimization.
  Reimplement optimization for transparency
  cleanup
  Fix for detecting opaque correctly.

 libavcodec/avcodec.h|   6 ++
 libavcodec/gif.c| 198 ++--
 libavfilter/vf_paletteuse.c | 184 +---
 libavformat/gif.c   |  16 +++-
 4 files changed, 329 insertions(+), 75 deletions(-)

-- 
2.14.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 5/7] Reimplement optimization for transparency

2017-10-02 Thread Bjorn Roche
From: Bjorn Roche <bj...@xowave.com>

---
 libavcodec/gif.c | 131 +--
 1 file changed, 78 insertions(+), 53 deletions(-)

diff --git a/libavcodec/gif.c b/libavcodec/gif.c
index db2193a718..3838aa7592 100644
--- a/libavcodec/gif.c
+++ b/libavcodec/gif.c
@@ -80,7 +80,7 @@ static int is_image_translucent(AVCodecContext *avctx,
 const uint8_t *buf, const int linesize)
 {
 GIFContext *s = avctx->priv_data;
-int trans = s->transparent_index;
+uint8_t trans = s->transparent_index;
 int p;
 const int m = avctx->width * avctx->height ;
 
@@ -88,7 +88,6 @@ static int is_image_translucent(AVCodecContext *avctx,
 return 0;
 }
 
-// FIXME: this might be faster with strchr
 for( p=0; p<m; ++p ) {
 if( buf[p] == trans ) {
 return 1;
@@ -254,60 +253,86 @@ static int gif_image_write_translucent(AVCodecContext 
*avctx,
AVPacket *pkt)
 {
 GIFContext *s = avctx->priv_data;
-int len = 0, height = avctx->height, width = avctx->width, x, y;
+int len = 0, height = avctx->height, width = avctx->width, y;
 int x_start = 0, y_start = 0, trans = s->transparent_index;
-int honor_transparency = (s->flags & GF_TRANSDIFF) && s->last_frame && 
!palette;
+//int honor_transparency = (s->flags & GF_TRANSDIFF) && s->last_frame && 
!palette;
 const uint8_t *ptr;
 
-// /* Crop image */
-// if ((s->flags & GF_OFFSETTING) && s->last_frame && !palette) {
-// const uint8_t *ref = s->last_frame->data[0];
-// const int ref_linesize = s->last_frame->linesize[0];
-// int x_end = avctx->width  - 1,
-// y_end = avctx->height - 1;
-
-// /* skip common lines */
-// while (y_start < y_end) {
-// if (memcmp(ref + y_start*ref_linesize, buf + y_start*linesize, 
width))
-// break;
-// y_start++;
-// }
-// while (y_end > y_start) {
-// if (memcmp(ref + y_end*ref_linesize, buf + y_end*linesize, 
width))
-// break;
-// y_end--;
-// }
-// height = y_end + 1 - y_start;
-
-// /* skip common columns */
-// while (x_start < x_end) {
-// int same_column = 1;
-// for (y = y_start; y <= y_end; y++) {
-// if (ref[y*ref_linesize + x_start] != buf[y*linesize + 
x_start]) {
-// same_column = 0;
-// break;
-// }
-// }
-// if (!same_column)
-// break;
-// x_start++;
-// }
-// while (x_end > x_start) {
-// int same_column = 1;
-// for (y = y_start; y <= y_end; y++) {
-// if (ref[y*ref_linesize + x_end] != buf[y*linesize + x_end]) 
{
-// same_column = 0;
-// break;
-// }
-// }
-// if (!same_column)
-// break;
-// x_end--;
-// }
-// width = x_end + 1 - x_start;
-
-// av_log(avctx, AV_LOG_DEBUG,"%dx%d image at pos (%d;%d) 
[area:%dx%d]\n",
-//width, height, x_start, y_start, avctx->width, 
avctx->height);
+/* Crop Image */
+if ( (s->flags & GF_OFFSETTING) && trans >=0 ) {
+const int w = avctx->width;
+const int h = avctx->height;
+int x_end = w - 1,
+y_end = h - 1;
+
+// top
+while (y_start < y_end) {
+int i;
+int is_trans = 1;
+for( i=0; i<w; ++i ) {
+if( buf[w*y_start+i] != trans ) {
+is_trans = 0;
+break;
+}
+}
+if( !is_trans )
+break;
+++y_start;
+}
+
+// bottom
+while (y_end < h) {
+int i;
+int is_trans = 1;
+for( i=0; i<w; ++i ) {
+if( buf[w*y_end+i] != trans ) {
+is_trans = 0;
+break;
+}
+}
+if( !is_trans )
+break;
+--y_end;
+}
+
+// left
+while (x_start < x_end) {
+int i;
+int is_trans = 1;
+for( i=y_start; i<y_end; ++i ) {
+if( buf[w*i+x_start] != trans ) {
+is_trans = 0;
+break;
+}
+}
+if( !is_trans )
+break;
+++x_start;
+}
+
+// right
+while (x_end < w) {
+int i;
+int is_trans = 1;
+

[FFmpeg-devel] [PATCH 7/7] Fix for detecting opaque correctly.

2017-10-02 Thread Bjorn Roche
From: Bjorn Roche <bj...@xowave.com>

---
 libavcodec/gif.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavcodec/gif.c b/libavcodec/gif.c
index 3ced6d4d45..758e16b83d 100644
--- a/libavcodec/gif.c
+++ b/libavcodec/gif.c
@@ -80,7 +80,7 @@ static int is_image_translucent(AVCodecContext *avctx,
 const uint8_t *buf, const int linesize)
 {
 GIFContext *s = avctx->priv_data;
-uint8_t trans = s->transparent_index;
+int trans = s->transparent_index;
 int p;
 const int m = avctx->width * avctx->height ;
 
-- 
2.14.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 3/7] Removing some debugging

2017-10-02 Thread Bjorn Roche
From: Bjorn Roche <bj...@xowave.com>

---
 libavfilter/vf_paletteuse.c | 65 -
 1 file changed, 11 insertions(+), 54 deletions(-)

diff --git a/libavfilter/vf_paletteuse.c b/libavfilter/vf_paletteuse.c
index abee1b3735..21870c22f5 100644
--- a/libavfilter/vf_paletteuse.c
+++ b/libavfilter/vf_paletteuse.c
@@ -172,14 +172,11 @@ static av_always_inline int diff(const uint8_t *c1, const 
uint8_t *c2)
 const int dg = c1[2] - c2[2];
 const int db = c1[3] - c2[3];
 
-printf( "alpha 1, 2: %d, %d\n", c1[0], c2[0] );
-
 return ( c1[0] == 0 && c2[0] == 0 ) ? 0 : ( (c1[0] == c2[0]) ? (dr*dr + 
dg*dg + db*db) : (max_diff) ) ;
 }
 
 static av_always_inline uint8_t colormap_nearest_bruteforce(const uint32_t 
*palette, const uint8_t *rgb)
 {
-printf( "colormap_nearest_bruteforce\n" );
 int i, pal_id = -1, min_dist = INT_MAX;
 
 for (i = 0; i < AVPALETTE_COUNT; i++) {
@@ -214,7 +211,6 @@ static void colormap_nearest_node(const struct color_node 
*map,
   const uint8_t *target,
   struct nearest_color *nearest)
 {
-printf( "colormap_nearest_node\n" );
 const struct color_node *kd = map + node_pos;
 const int s = kd->split;
 int dx, nearer_kd_id, further_kd_id;
@@ -255,7 +251,6 @@ struct stack_node {
 
 static av_always_inline uint8_t colormap_nearest_iterative(const struct 
color_node *root, const uint8_t *target)
 {
-printf( "colormap_nearest_iterative\n" );
 int pos = 0, best_node_id = -1, best_dist = INT_MAX, cur_color_id = 0;
 struct stack_node nodes[16];
 struct stack_node *node = [0];
@@ -266,14 +261,11 @@ static av_always_inline uint8_t 
colormap_nearest_iterative(const struct color_no
 const uint8_t *current = kd->val;
 const int current_to_target = diff(target, current);
 
-printf( "%d-%d-%d-%d, %d, %d-%d-%d-%d\n", target[0], target[1], 
target[2], target[3], current_to_target, current[0], current[1], current[2], 
current[3] );
-
 /* Compare current color node to the target and update our best node if
  * it's actually better. */
 if (current_to_target < best_dist) {
 best_node_id = cur_color_id;
 if (!current_to_target) {
-printf( "exact\n");
 goto end; // exact match, we can return immediately
 }
 best_dist = current_to_target;
@@ -282,7 +274,6 @@ static av_always_inline uint8_t 
colormap_nearest_iterative(const struct color_no
 /* Check if it's not a leaf */
 if (kd->left_id != -1 || kd->right_id != -1) {
 const int split = kd->split;
-printf( "split %d\n", split );
 const int dx = target[split-1] - current[split-1];
 int nearer_kd_id, further_kd_id;
 
@@ -317,10 +308,8 @@ static av_always_inline uint8_t 
colormap_nearest_iterative(const struct color_no
 /* Unstack as much as we can, typically as long as the least probable
  * branch aren't actually probable. */
 do {
-if (--pos < 0) {
-printf( "pos < 0\n");
+if (--pos < 0)
 goto end;
-}
 node--;
 } while (node->dx2 >= best_dist);
 
@@ -351,7 +340,6 @@ static av_always_inline int color_get(struct cache_node 
*cache, uint32_t argb,
   const uint32_t *palette,
   const enum color_search_method 
search_method)
 {
-printf("color_get\n");
 int i;
 const uint8_t argb_elts[] = {a, r, g, b};
 const uint8_t rhash = r & ((1<<NBITS)-1);
@@ -360,15 +348,11 @@ static av_always_inline int color_get(struct cache_node 
*cache, uint32_t argb,
 const unsigned hash = rhash<<(NBITS*2) | ghash<= 0 ) {
-printf( "trans %d %d %d %d\n", a, r, g, b );
 return transparency_index;
 }
-printf( "opaque %d %d %d %d\n", a, r, g, b );
 
 for (i = 0; i < node->nb_entries; i++) {
 e = >entries[i];
@@ -397,7 +381,6 @@ static av_always_inline int get_dst_color_err(struct 
cache_node *cache,
 const uint8_t r = argb >> 16 & 0xff;
 const uint8_t g = argb >>  8 & 0xff;
 const uint8_t b = argb   & 0xff;
-printf( "get_dst_color_err %d %d %d %d %d\n", argb, a, r, g, b );
 const int dstx = color_get(cache, argb, a, r, g, b, transparency_index, 
map, palette, search_method);
 const uint32_t dstc = palette[dstx];
 *er = r - (dstc >> 16 & 0xff);
@@ -412,7 +395,6 @@ static av_always_inline int set_frame(PaletteUseContext *s, 
AVFrame *out, AVFram
   const enum color_search_method 
search_method)
 {
 int x, y;
-

[FFmpeg-devel] [PATCH 1/7] First pass at fixing paletteuse

2017-10-02 Thread Bjorn Roche
From: Bjorn Roche <bj...@xowave.com>

Dithering doesn’t work, and only iterative and brute force color
mapping work.
---
 libavfilter/vf_paletteuse.c | 265 +++-
 1 file changed, 185 insertions(+), 80 deletions(-)

diff --git a/libavfilter/vf_paletteuse.c b/libavfilter/vf_paletteuse.c
index ffd37bf1da..e62503c8ea 100644
--- a/libavfilter/vf_paletteuse.c
+++ b/libavfilter/vf_paletteuse.c
@@ -56,7 +56,7 @@ enum diff_mode {
 };
 
 struct color_node {
-uint8_t val[3];
+uint8_t val[4];
 uint8_t palette_id;
 int split;
 int left_id, right_id;
@@ -86,6 +86,7 @@ typedef struct PaletteUseContext {
 struct cache_node cache[CACHE_SIZE];/* lookup cache */
 struct color_node map[AVPALETTE_COUNT]; /* 3D-Tree (KD-Tree with K=3) for 
reverse colormap */
 uint32_t palette[AVPALETTE_COUNT];
+int transparency_index; /* index in the palette of transparency. -1 if 
there isn't a transparency. */
 int palette_loaded;
 int dither;
 int new;
@@ -162,29 +163,44 @@ static av_always_inline int dither_color(uint32_t px, int 
er, int eg, int eb, in
  | av_clip_uint8((px   & 0xff) + ((eb * scale) / (1<<shift)));
 }
 
-static av_always_inline int diff(const uint8_t *c1, const uint8_t *c2)
+static av_always_inline int diffAlpha(const uint8_t *c1, const uint8_t *c2)
 {
 // XXX: try L*a*b with CIE76 (dL*dL + da*da + db*db)
-const int dr = c1[0] - c2[0];
-const int dg = c1[1] - c2[1];
-const int db = c1[2] - c2[2];
-return dr*dr + dg*dg + db*db;
+const static int max_diff = 255*255 + 255*255 + 255*255;
+const int dr = c1[1] - c2[1];
+const int dg = c1[2] - c2[2];
+const int db = c1[3] - c2[3];
+
+printf( "alpha 1, 2: %d, %d\n", c1[0], c2[0] );
+
+return ( c1[0] == 0 && c2[0] == 0 ) ? 0 : ( (c1[0] == c2[0]) ? (dr*dr + 
dg*dg + db*db) : (max_diff) ) ;
 }
 
+// static av_always_inline int diff3(const uint8_t *c1, const uint8_t *c2)
+// {
+// // XXX: try L*a*b with CIE76 (dL*dL + da*da + db*db)
+// const int dr = c1[1] - c2[1];
+// const int dg = c1[2] - c2[2];
+// const int db = c1[3] - c2[3];
+// return dr*dr + dg*dg + db*db;
+// }
+
 static av_always_inline uint8_t colormap_nearest_bruteforce(const uint32_t 
*palette, const uint8_t *rgb)
 {
+printf( "colormap_nearest_bruteforce\n" );
 int i, pal_id = -1, min_dist = INT_MAX;
 
 for (i = 0; i < AVPALETTE_COUNT; i++) {
 const uint32_t c = palette[i];
 
-if ((c & 0xff00) == 0xff00) { // ignore transparent entry
-const uint8_t palrgb[] = {
+if ((c & 0xff00) == 0xff00) {
+const uint8_t palargb[] = {
+palette[i]>>24 & 0xff,
 palette[i]>>16 & 0xff,
 palette[i]>> 8 & 0xff,
 palette[i] & 0xff,
 };
-const int d = diff(palrgb, rgb);
+const int d = diffAlpha(palargb, rgb);
 if (d < min_dist) {
 pal_id = i;
 min_dist = d;
@@ -195,6 +211,7 @@ static av_always_inline uint8_t 
colormap_nearest_bruteforce(const uint32_t *pale
 }
 
 /* Recursive form, simpler but a bit slower. Kept for reference. */
+/* may not work with transparency */
 struct nearest_color {
 int node_pos;
 int dist_sqd;
@@ -205,11 +222,12 @@ static void colormap_nearest_node(const struct color_node 
*map,
   const uint8_t *target,
   struct nearest_color *nearest)
 {
+printf( "colormap_nearest_node\n" );
 const struct color_node *kd = map + node_pos;
-const int s = kd->split;
+const int s = kd->split; //FIXME: spliut is one more than it was before
 int dx, nearer_kd_id, further_kd_id;
 const uint8_t *current = kd->val;
-const int current_to_target = diff(target, current);
+const int current_to_target = diffAlpha(target, current);
 
 if (current_to_target < nearest->dist_sqd) {
 nearest->node_pos = node_pos;
@@ -232,6 +250,7 @@ static void colormap_nearest_node(const struct color_node 
*map,
 
 static av_always_inline uint8_t colormap_nearest_recursive(const struct 
color_node *node, const uint8_t *rgb)
 {
+printf( "colormap_nearest_recursive\n" );
 struct nearest_color res = {.dist_sqd = INT_MAX, .node_pos = -1};
 colormap_nearest_node(node, 0, rgb, );
 return node[res.node_pos].palette_id;
@@ -244,6 +263,7 @@ struct stack_node {
 
 static av_always_inline uint8_t colormap_nearest_iterative(const struct 
color_node *root, const uint8_t *target)
 {
+printf( "colormap_nearest_iterative\n" );
 int pos = 0, best_node_id = -1, best_dist = INT_MAX, cur_color_id = 0;
 struct stack_node nodes[16];
 struct stack_node *node = [0];
@@ -252,21 +272,26 @@ static av_always_inline uint8_

[FFmpeg-devel] [PATCH 2/7] Fix for dithering.

2017-10-02 Thread Bjorn Roche
From: Bjorn Roche <bj...@xowave.com>

---
 libavfilter/vf_paletteuse.c | 52 -
 1 file changed, 18 insertions(+), 34 deletions(-)

diff --git a/libavfilter/vf_paletteuse.c b/libavfilter/vf_paletteuse.c
index e62503c8ea..abee1b3735 100644
--- a/libavfilter/vf_paletteuse.c
+++ b/libavfilter/vf_paletteuse.c
@@ -158,12 +158,13 @@ static int query_formats(AVFilterContext *ctx)
 
 static av_always_inline int dither_color(uint32_t px, int er, int eg, int eb, 
int scale, int shift)
 {
-return av_clip_uint8((px >> 16 & 0xff) + ((er * scale) / (1<<shift))) << 16
+return (px & 0xff00)
+ | av_clip_uint8((px >> 16 & 0xff) + ((er * scale) / (1<<shift))) << 16
  | av_clip_uint8((px >>  8 & 0xff) + ((eg * scale) / (1<<shift))) <<  8
  | av_clip_uint8((px   & 0xff) + ((eb * scale) / (1<<shift)));
 }
 
-static av_always_inline int diffAlpha(const uint8_t *c1, const uint8_t *c2)
+static av_always_inline int diff(const uint8_t *c1, const uint8_t *c2)
 {
 // XXX: try L*a*b with CIE76 (dL*dL + da*da + db*db)
 const static int max_diff = 255*255 + 255*255 + 255*255;
@@ -176,15 +177,6 @@ static av_always_inline int diffAlpha(const uint8_t *c1, 
const uint8_t *c2)
 return ( c1[0] == 0 && c2[0] == 0 ) ? 0 : ( (c1[0] == c2[0]) ? (dr*dr + 
dg*dg + db*db) : (max_diff) ) ;
 }
 
-// static av_always_inline int diff3(const uint8_t *c1, const uint8_t *c2)
-// {
-// // XXX: try L*a*b with CIE76 (dL*dL + da*da + db*db)
-// const int dr = c1[1] - c2[1];
-// const int dg = c1[2] - c2[2];
-// const int db = c1[3] - c2[3];
-// return dr*dr + dg*dg + db*db;
-// }
-
 static av_always_inline uint8_t colormap_nearest_bruteforce(const uint32_t 
*palette, const uint8_t *rgb)
 {
 printf( "colormap_nearest_bruteforce\n" );
@@ -200,7 +192,7 @@ static av_always_inline uint8_t 
colormap_nearest_bruteforce(const uint32_t *pale
 palette[i]>> 8 & 0xff,
 palette[i] & 0xff,
 };
-const int d = diffAlpha(palargb, rgb);
+const int d = diff(palargb, rgb);
 if (d < min_dist) {
 pal_id = i;
 min_dist = d;
@@ -211,7 +203,7 @@ static av_always_inline uint8_t 
colormap_nearest_bruteforce(const uint32_t *pale
 }
 
 /* Recursive form, simpler but a bit slower. Kept for reference. */
-/* may not work with transparency */
+/* has not been updated for transparency */
 struct nearest_color {
 int node_pos;
 int dist_sqd;
@@ -224,10 +216,10 @@ static void colormap_nearest_node(const struct color_node 
*map,
 {
 printf( "colormap_nearest_node\n" );
 const struct color_node *kd = map + node_pos;
-const int s = kd->split; //FIXME: spliut is one more than it was before
+const int s = kd->split;
 int dx, nearer_kd_id, further_kd_id;
 const uint8_t *current = kd->val;
-const int current_to_target = diffAlpha(target, current);
+const int current_to_target = diff(target, current);
 
 if (current_to_target < nearest->dist_sqd) {
 nearest->node_pos = node_pos;
@@ -272,7 +264,7 @@ static av_always_inline uint8_t 
colormap_nearest_iterative(const struct color_no
 
 const struct color_node *kd = [cur_color_id];
 const uint8_t *current = kd->val;
-const int current_to_target = diffAlpha(target, current);
+const int current_to_target = diff(target, current);
 
 printf( "%d-%d-%d-%d, %d, %d-%d-%d-%d\n", target[0], target[1], 
target[2], target[3], current_to_target, current[0], current[1], current[2], 
current[3] );
 
@@ -360,7 +352,7 @@ static av_always_inline int color_get(struct cache_node 
*cache, uint32_t argb,
   const enum color_search_method 
search_method)
 {
 printf("color_get\n");
-//int i;
+int i;
 const uint8_t argb_elts[] = {a, r, g, b};
 const uint8_t rhash = r & ((1<<NBITS)-1);
 const uint8_t ghash = g & ((1<<NBITS)-1);
@@ -378,19 +370,18 @@ static av_always_inline int color_get(struct cache_node 
*cache, uint32_t argb,
 }
 printf( "opaque %d %d %d %d\n", a, r, g, b );
 
-// FIXME
-// for (i = 0; i < node->nb_entries; i++) {
-// e = >entries[i];
-// if (e->color == rgb)
-// return e->pal_entry;
-// }
+for (i = 0; i < node->nb_entries; i++) {
+e = >entries[i];
+if (e->color == argb)
+return e->pal_entry;
+}
 
 e = av_dynarray2_add((void**)>entries, >nb_entries,
  sizeof(*node->entries), NULL);
 if (!e)
 return AVERROR(ENOMEM);
 e->color = argb;
-// FIXME
+
 e->pal_entry = COLORMAP_NEAREST(search_method, palette, map, arg

Re: [FFmpeg-devel] Frame CRC muxer

2017-09-26 Thread Bjorn Roche
On Mon, Sep 25, 2017 at 4:03 PM, Carl Eugen Hoyos <ceffm...@gmail.com>
wrote:

> 2017-09-25 20:49 GMT+02:00 Bjorn Roche <bj...@xowave.com>:
>
> > In the meantime, I've attached the patch if anyone wants to look at it.
>
> Can you explain why you had to patch the gif encoder?
> I thought it is able to encode transparency, no?


Sure, and thanks for taking a look at it!

Unfortunately, while the gif encoder does support transparency, it only
works correctly for a single frame. After that, it produces incorrect
results because the pixels from the previous frame "show through"
transparent pixels instead of being replaced.

This is because the encoder preserves transparency from the incoming frame
to the saved image, which works fine in some cases, such as in the first
(or only) frame or if the disposal method supports it, but the disposal
method the muxer was using did not support it.

The solution I came up with was to have the codec signal the muxer using
the side data about which disposal method it should use. That way, it can
use the best optimization for the situation, but still support transparency.

An alternative would be to move the code that writes the disposal method
from the muxer to the codec, which, IMO is where it belongs, but when I
started to do that it looked like many changes were required to make that
work.

bjorn


-- 
Bjorn Roche
@shimmeoapp
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] Frame CRC muxer

2017-09-26 Thread Bjorn Roche
On Mon, Sep 25, 2017 at 3:12 PM, James Almer <jamr...@gmail.com> wrote:

> On 9/25/2017 3:49 PM, Bjorn Roche wrote:
> > Hi there,
> >
> > I have a patch for this issue:
> >
> > https://trac.ffmpeg.org/ticket/4443
> >
> > However, when running the automated ("fate") tests, I get the error
> pasted
> > below. I'm not sure what's going on since the output formats look
> different
> > when running a the test vs when I run the same command with my built-in
> > FFmpeg. e.g.:
> >
> > my compiled ffmpeg:
> >
> > 0,  2,  2,1,  438, 0x4776d352, S=1, 1024,
> > 0xcfc8799f
> >
> >
> > built-in ffmpeg:
> >
> >
> > 0,  2,  2,1,  438, 0x4776d352, S=2,1,
> > 0x00010001, 1024, 0xcfc8799f
> >
> >
> > Neither format looks like this:
> > https://ffmpeg.org/ffmpeg-formats.html#framecrc-1. (I don't know what
> the
> > S=X. means, so I am not sure what it's telling me has changed, if
> > anything.)
>
> The S stands for side data, and the X is the amount of side data
> elements embedded in the packet. Values after that are size and crc
> checksum of each side data element.
>

Ah, excellent, that makes sense. Thanks for your response!

bjorn

-- 
Bjorn Roche
@shimmeoapp
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] Frame CRC muxer

2017-09-25 Thread Bjorn Roche
Hi there,

I have a patch for this issue:

https://trac.ffmpeg.org/ticket/4443

However, when running the automated ("fate") tests, I get the error pasted
below. I'm not sure what's going on since the output formats look different
when running a the test vs when I run the same command with my built-in
FFmpeg. e.g.:

my compiled ffmpeg:

0,  2,  2,1,  438, 0x4776d352, S=1, 1024,
0xcfc8799f


built-in ffmpeg:


0,  2,  2,1,  438, 0x4776d352, S=2,1,
0x00010001, 1024, 0xcfc8799f


Neither format looks like this:
https://ffmpeg.org/ffmpeg-formats.html#framecrc-1. (I don't know what the
S=X. means, so I am not sure what it's telling me has changed, if
anything.)

In the meantime, I've attached the patch if anyone wants to look at it.

bjorn

-- 
-----
Bjorn Roche
bjornroche.com
@bjornroche


./tests/fate-run.sh fate-gifenc-rgb8 "../fate-suite/" ""
"/Users/bjorn/Code/FFmpeg" 'framecrc -i ../fate-suite//gif/tc217.gif -c:v
gif -pix_fmt rgb8' '' '' '' '8' '' '' '' '' '' '' '' '' ''

 /Users/bjorn/Code/FFmpeg/ffmpeg -nostdin -nostats -cpuflags all -hwaccel
none -threads 8 -thread_type frame+slice -i ../fate-suite//gif/tc217.gif
-c:v gif -pix_fmt rgb8 -flags +bitexact -fflags +bitexact -f framecrc -

--- ./tests/ref/fate/gifenc-rgb8 2017-09-15 12:37:50.0 -0400

+++ tests/data/fate/gifenc-rgb8 2017-09-25 13:39:06.0 -0400

@@ -3,176 +3,176 @@

 #codec_id 0: gif

 #dimensions 0: 217x217

 #sar 0: 0/1

-0,  0,  0,1,  552, 0x47602c6c

-0,  1,  1,1,  297, 0x49dd8847, S=1, 1024,
0xcfc8799f

-0,  2,  2,1,  438, 0x4776d352, S=1, 1024,
0xcfc8799f

-0,  3,  3,1,  450, 0x2254d187, S=1, 1024,
0xcfc8799f

-0,  4,  4,1,  547, 0xe16104bc, S=1, 1024,
0xcfc8799f

-0,  5,  5,1,  614, 0x0fdc2027, S=1, 1024,
0xcfc8799f

-0,  6,  6,1,  642, 0xa0af1edf, S=1, 1024,
0xcfc8799f

-0,  7,  7,1,  660, 0xd0763931, S=1, 1024,
0xcfc8799f

-0,  8,  8,1,  821, 0xc38f7fac, S=1, 1024,
0xcfc8799f

-0,  9,  9,1, 1157, 0x4c112ecd, S=1, 1024,
0xcfc8799f

-0, 10, 10,1,  179, 0x0690541c, S=1, 1024,
0xcfc8799f

-0, 11, 11,1, 1333, 0x216f70a7, S=1, 1024,
0xcfc8799f

-0, 12, 12,1, 1638, 0x901c093d, S=1, 1024,
0xcfc8799f

-0, 13, 13,1, 1531, 0xc9bae5ff, S=1, 1024,
0xcfc8799f

-0, 14, 14,1, 1720, 0xce854743, S=1, 1024,
0xcfc8799f

-0, 15, 15,1, 1910, 0x2690866d, S=1, 1024,
0xcfc8799f

-0, 16, 16,1, 2124, 0xa586dad0, S=1, 1024,
0xcfc8799f

-0, 17, 17,1, 2248, 0x9ddc2a88, S=1, 1024,
0xcfc8799f

-0, 18, 18,1, 2311, 0xd64235af, S=1, 1024,
0xcfc8799f

-0, 19, 19,1, 2408, 0xe2a66cc9, S=1, 1024,
0xcfc8799f

-0, 20, 20,1, 2601, 0xeab6c267, S=1, 1024,
0xcfc8799f

-0, 21, 21,1, 2687, 0xfe1d0311, S=1, 1024,
0xcfc8799f

-0, 22, 22,1, 2784, 0xca600dee, S=1, 1024,
0xcfc8799f

-0, 23, 23,1, 2884, 0xc7134b99, S=1, 1024,
0xcfc8799f

-0, 24, 24,1, 2982, 0x0b1e7825, S=1, 1024,
0xcfc8799f

-0, 25, 25,1, 3101, 0x3e029e0e, S=1, 1024,
0xcfc8799f

-0, 26, 26,1, 3253, 0x846af678, S=1, 1024,
0xcfc8799f

-0, 27, 27,1, 3329, 0x29a81b71, S=1, 1024,
0xcfc8799f

-0, 28, 28,1, 3572, 0xa3e08a52, S=1, 1024,
0xcfc8799f

-0, 29, 29,1, 3807, 0x18e1fed2, S=1, 1024,
0xcfc8799f

-0, 30, 30,1, 2750, 0xff6e1f9e, S=1, 1024,
0xcfc8799f

-0, 31, 31,1, 4031, 0x6d4f7329, S=1, 1024,
0xcfc8799f

-0, 32, 32,1, 3025, 0xb43c9e94, S=1, 1024,
0xcfc8799f

-0, 33, 33,1, 4295, 0xc1850a80, S=1, 1024,
0xcfc8799f

-0, 34, 34,1, 2044, 0x0440c072, S=1, 1024,
0xcfc8799f

-0, 35, 35,1, 3212, 0xe91af08f, S=1, 1024,
0xcfc8799f

-0, 36, 36,1, 2292, 0x6765633e, S=1, 1024,
0xcfc8799f

-0, 37, 37,1, 3633, 0xac779aa3, S=1, 1024,
0xcfc8799f

-0, 38, 38,1, 3552, 0xed2c75b2, S=1, 1024,
0xcfc8799f

-0, 39, 39,1, 3690, 0x2020dd0d, S=1, 1024

[FFmpeg-devel] Gif from transparent video

2017-09-20 Thread Bjorn Roche
Hey all!

I’m working on this: https://trac.ffmpeg.org/ticket/4443, which relates to
creating a GIF from an image with transparency support. I have modified
paletteuse, so that I can generate a transparent gif just fine — but only a
single frame. Multiple frames cause problems with the gif encoding’s
optimizations, so I can’t successfully create an animated gif with
transparencies.

I am pretty familiar with the Gif format, but I’m confused about how FFmpeg
handles incoming transparencies. Does anyone know if libavcodec/gif.c is
even designed to handle this situation?I guess what I'm looking for is a
hint (if anyone has one) about if this is an issue with writing gifs, or if
I've still got something wrong in my palettes modifications, or something
else.

Thanks,

bjorn

-- 
-
Bjorn Roche
bjornroche.com
@bjornroche
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel