diff mbox series

[FFmpeg-devel,01/20] swscale/output: add missing yuv2packed1 and yuv2packed2 support for VUY{X, A}

Message ID 20241007122955.309-1-jamrial@gmail.com
State New
Headers show
Series [FFmpeg-devel,01/20] swscale/output: add missing yuv2packed1 and yuv2packed2 support for VUY{X, A} | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 success Make fate finished

Commit Message

James Almer Oct. 7, 2024, 12:29 p.m. UTC
Signed-off-by: James Almer <jamrial@gmail.com>
---
FATE tests don't seem to trigger this.

 libswscale/output.c | 106 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 106 insertions(+)

Comments

Michael Niedermayer Oct. 7, 2024, 8:43 p.m. UTC | #1
On Mon, Oct 07, 2024 at 09:29:48AM -0300, James Almer wrote:
> There's no need to keep using a custom decoder for this pixel format.
> 
> Signed-off-by: James Almer <jamrial@gmail.com>
> ---
>  libavcodec/raw.c                         | 1 +
>  libavformat/riff.c                       | 2 +-
>  tests/ref/fate/filter-pixdesc-vyu444     | 2 +-
>  tests/ref/fate/filter-pixfmts-copy       | 2 +-
>  tests/ref/fate/filter-pixfmts-crop       | 2 +-
>  tests/ref/fate/filter-pixfmts-field      | 2 +-
>  tests/ref/fate/filter-pixfmts-fieldorder | 2 +-
>  tests/ref/fate/filter-pixfmts-hflip      | 2 +-
>  tests/ref/fate/filter-pixfmts-il         | 2 +-
>  tests/ref/fate/filter-pixfmts-null       | 2 +-
>  tests/ref/fate/filter-pixfmts-pad        | 2 +-
>  tests/ref/fate/filter-pixfmts-scale      | 2 +-
>  tests/ref/fate/filter-pixfmts-transpose  | 2 +-
>  tests/ref/fate/filter-pixfmts-vflip      | 2 +-
>  14 files changed, 14 insertions(+), 13 deletions(-)

breaks fate here (but i had conflicts in this patchset)

TEST    vsynth1-v308
--- ./tests/ref/vsynth/vsynth1-v308	2024-09-26 22:49:42.026891952 +0200
+++ tests/data/fate/vsynth1-v308	2024-10-07 22:42:35.915229512 +0200
@@ -1,4 +1,4 @@
-5d868b73c554a9a2422d6c8a18ce9c02 *tests/data/fate/vsynth1-v308.avi
+5c0b18a7a404b8eabd4a40092331191a *tests/data/fate/vsynth1-v308.avi
 15213252 tests/data/fate/vsynth1-v308.avi
-10fb42f1abf40a289c3edafc0390482c *tests/data/fate/vsynth1-v308.out.rawvideo
-stddev:    2.67 PSNR: 39.60 MAXDIFF:   43 bytes:  7603200/  7603200
+0ad01683d6ee3af89b5e25f07139a2b6 *tests/data/fate/vsynth1-v308.out.rawvideo
+stddev:   39.07 PSNR: 16.29 MAXDIFF:  131 bytes:  7603200/  7603200
Test vsynth1-v308 failed. Look at tests/data/fate/vsynth1-v308.err for details.
make: *** [tests/Makefile:312: fate-vsynth1-v308] Error 1

[...]
James Almer Oct. 7, 2024, 9:32 p.m. UTC | #2
On 10/7/2024 5:43 PM, Michael Niedermayer wrote:
> On Mon, Oct 07, 2024 at 09:29:48AM -0300, James Almer wrote:
>> There's no need to keep using a custom decoder for this pixel format.
>>
>> Signed-off-by: James Almer <jamrial@gmail.com>
>> ---
>>   libavcodec/raw.c                         | 1 +
>>   libavformat/riff.c                       | 2 +-
>>   tests/ref/fate/filter-pixdesc-vyu444     | 2 +-
>>   tests/ref/fate/filter-pixfmts-copy       | 2 +-
>>   tests/ref/fate/filter-pixfmts-crop       | 2 +-
>>   tests/ref/fate/filter-pixfmts-field      | 2 +-
>>   tests/ref/fate/filter-pixfmts-fieldorder | 2 +-
>>   tests/ref/fate/filter-pixfmts-hflip      | 2 +-
>>   tests/ref/fate/filter-pixfmts-il         | 2 +-
>>   tests/ref/fate/filter-pixfmts-null       | 2 +-
>>   tests/ref/fate/filter-pixfmts-pad        | 2 +-
>>   tests/ref/fate/filter-pixfmts-scale      | 2 +-
>>   tests/ref/fate/filter-pixfmts-transpose  | 2 +-
>>   tests/ref/fate/filter-pixfmts-vflip      | 2 +-
>>   14 files changed, 14 insertions(+), 13 deletions(-)
> 
> breaks fate here (but i had conflicts in this patchset)

Niklas pushed a set that made extensive changes to libswscale/input.c, 
so i guess that's why you had conflicts.

> 
> TEST    vsynth1-v308
> --- ./tests/ref/vsynth/vsynth1-v308	2024-09-26 22:49:42.026891952 +0200
> +++ tests/data/fate/vsynth1-v308	2024-10-07 22:42:35.915229512 +0200
> @@ -1,4 +1,4 @@
> -5d868b73c554a9a2422d6c8a18ce9c02 *tests/data/fate/vsynth1-v308.avi
> +5c0b18a7a404b8eabd4a40092331191a *tests/data/fate/vsynth1-v308.avi
>   15213252 tests/data/fate/vsynth1-v308.avi
> -10fb42f1abf40a289c3edafc0390482c *tests/data/fate/vsynth1-v308.out.rawvideo
> -stddev:    2.67 PSNR: 39.60 MAXDIFF:   43 bytes:  7603200/  7603200
> +0ad01683d6ee3af89b5e25f07139a2b6 *tests/data/fate/vsynth1-v308.out.rawvideo
> +stddev:   39.07 PSNR: 16.29 MAXDIFF:  131 bytes:  7603200/  7603200
> Test vsynth1-v308 failed. Look at tests/data/fate/vsynth1-v308.err for details.
> make: *** [tests/Makefile:312: fate-vsynth1-v308] Error 1

Will send a new version.

> 
> [...]
> 
> 
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
Michael Niedermayer Oct. 8, 2024, 8:01 p.m. UTC | #3
On Mon, Oct 07, 2024 at 09:29:36AM -0300, James Almer wrote:
> Signed-off-by: James Almer <jamrial@gmail.com>
> ---
> FATE tests don't seem to trigger this.
> 
>  libswscale/output.c | 106 ++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 106 insertions(+)

should be ok if tested

thx

[...]
James Almer Oct. 8, 2024, 8:14 p.m. UTC | #4
On 10/8/2024 5:01 PM, Michael Niedermayer wrote:
> On Mon, Oct 07, 2024 at 09:29:36AM -0300, James Almer wrote:
>> Signed-off-by: James Almer <jamrial@gmail.com>
>> ---
>> FATE tests don't seem to trigger this.
>>
>>   libswscale/output.c | 106 ++++++++++++++++++++++++++++++++++++++++++++
>>   1 file changed, 106 insertions(+)
> 
> should be ok if tested

How can i trigger these paths? FATE pixfmt/pixdesc tests don't seem to 
do it.
Michael Niedermayer Oct. 8, 2024, 8:20 p.m. UTC | #5
On Tue, Oct 08, 2024 at 05:14:23PM -0300, James Almer wrote:
> On 10/8/2024 5:01 PM, Michael Niedermayer wrote:
> > On Mon, Oct 07, 2024 at 09:29:36AM -0300, James Almer wrote:
> > > Signed-off-by: James Almer <jamrial@gmail.com>
> > > ---
> > > FATE tests don't seem to trigger this.
> > > 
> > >   libswscale/output.c | 106 ++++++++++++++++++++++++++++++++++++++++++++
> > >   1 file changed, 106 insertions(+)
> > 
> > should be ok if tested
> 
> How can i trigger these paths? FATE pixfmt/pixdesc tests don't seem to do
> it.

the 2 stuff should be used for bilinear upscaling
some flags might need to be set correctly, i would have to check the code myself

thx

[...]
James Almer Oct. 8, 2024, 8:48 p.m. UTC | #6
On 10/8/2024 5:20 PM, Michael Niedermayer wrote:
> On Tue, Oct 08, 2024 at 05:14:23PM -0300, James Almer wrote:
>> On 10/8/2024 5:01 PM, Michael Niedermayer wrote:
>>> On Mon, Oct 07, 2024 at 09:29:36AM -0300, James Almer wrote:
>>>> Signed-off-by: James Almer <jamrial@gmail.com>
>>>> ---
>>>> FATE tests don't seem to trigger this.
>>>>
>>>>    libswscale/output.c | 106 ++++++++++++++++++++++++++++++++++++++++++++
>>>>    1 file changed, 106 insertions(+)
>>>
>>> should be ok if tested
>>
>> How can i trigger these paths? FATE pixfmt/pixdesc tests don't seem to do
>> it.
> 
> the 2 stuff should be used for bilinear upscaling
> some flags might need to be set correctly, i would have to check the code myself
> 
> thx

Adding sws_flags bilinear did the trick.
James Almer Oct. 8, 2024, 8:52 p.m. UTC | #7
On 10/8/2024 5:50 PM, Michael Niedermayer wrote:
> On Mon, Oct 07, 2024 at 11:54:00PM -0300, James Almer wrote:
>> Signed-off-by: James Almer <jamrial@gmail.com>
>> ---
>>   libswscale/input.c | 26 ++++++++++++++++++++++++++
>>   libswscale/utils.c |  1 +
>>   2 files changed, 27 insertions(+)
>>
>> diff --git a/libswscale/input.c b/libswscale/input.c
>> index 7237333e56..3d97c555a3 100644
>> --- a/libswscale/input.c
>> +++ b/libswscale/input.c
>> @@ -764,6 +764,26 @@ static void vyuToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *unused0, cons
>>       }
>>   }
>>   
>> +static void read_v30xle_Y_c(uint8_t *dst, const uint8_t *src, const uint8_t *unused0, const uint8_t *unused1, int width,
>> +                               uint32_t *unused2, void *opq)
>> +{
>> +    int i;
>> +    for (i = 0; i < width; i++)
>> +        AV_WN16(dst + i * 2, (AV_RL32(src + i * 4) >> 12) & 0x3FFu);
>> +}
>> +
>> +
>> +static void read_v30xle_UV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *unused0, const uint8_t *src,
>> +                               const uint8_t *unused1, int width, uint32_t *unused2, void *opq)
>> +{
>> +    int i;
>> +    for (i = 0; i < width; i++) {
>> +        uint32_t pixel = AV_RL32(src + i * 4);
>> +        AV_WN16(dstU + i * 2, (pixel >>  2) & 0x3FFu);
>> +        AV_WN16(dstV + i * 2, (pixel >> 22) & 0x3FFu);
>> +    }
>> +}
> 
> on ppc:
> 
> src/libswscale/input.c: In function ‘read_v30xle_UV_c’:
> src/libswscale/input.c:781:18: error: two or more data types in declaration specifiers
>           uint32_t pixel = AV_RL32(src + i * 4);

Is pixel a #define in this toolchain?
Michael Niedermayer Oct. 8, 2024, 10:35 p.m. UTC | #8
On Tue, Oct 08, 2024 at 07:13:27PM -0300, James Almer wrote:
> On 10/8/2024 7:06 PM, Michael Niedermayer wrote:
> > On Mon, Oct 07, 2024 at 09:29:44AM -0300, James Almer wrote:
> > > Signed-off-by: James Almer <jamrial@gmail.com>
> > > ---
> > >   libswscale/output.c                      | 56 ++++++++++++++++++++++++
> > >   libswscale/utils.c                       |  2 +-
> > >   tests/ref/fate/filter-pixdesc-uyva       |  1 +
> > >   tests/ref/fate/filter-pixfmts-copy       |  1 +
> > >   tests/ref/fate/filter-pixfmts-crop       |  1 +
> > >   tests/ref/fate/filter-pixfmts-field      |  1 +
> > >   tests/ref/fate/filter-pixfmts-fieldorder |  1 +
> > >   tests/ref/fate/filter-pixfmts-hflip      |  1 +
> > >   tests/ref/fate/filter-pixfmts-il         |  1 +
> > >   tests/ref/fate/filter-pixfmts-null       |  1 +
> > >   tests/ref/fate/filter-pixfmts-pad        |  1 +
> > >   tests/ref/fate/filter-pixfmts-scale      |  1 +
> > >   tests/ref/fate/filter-pixfmts-transpose  |  1 +
> > >   tests/ref/fate/filter-pixfmts-vflip      |  1 +
> > >   14 files changed, 69 insertions(+), 1 deletion(-)
> > >   create mode 100644 tests/ref/fate/filter-pixdesc-uyva
> > 
> > seems breaking this:
> > 
> > TEST    filter-pixfmts-scale
> > --- ./tests/ref/fate/filter-pixfmts-scale	2024-10-09 00:03:04.066341619 +0200
> > +++ tests/data/fate/filter-pixfmts-scale	2024-10-09 00:03:24.594518771 +0200
> > @@ -97,7 +97,7 @@
> >   rgba                85bb5d03cea1c6e8002ced3373904336
> >   rgba64be            ee73e57923af984b31cc7795d13929da
> >   rgba64le            783d2779adfafe3548bdb671ec0de69e
> > -uyva                ee83c7ba25cfc997de70a4e5b3eb398f
> > +uyva                1337927982389ee952714a91decd1474
> >   uyvy422             aeb4ba4f9f003ae21f6d18089198244f
> >   vuya                ffa817e283bf6a0b6fba21b07523ccaa
> >   vuyx                a6ff68f46c6b4b7595ec91b2a497df8e
> > Test filter-pixfmts-scale failed. Look at tests/data/fate/filter-pixfmts-scale.err for details.
> > make: *** [tests/Makefile:312: fate-filter-pixfmts-scale] Error 1
> 
> I can't reproduce, i get ee83c7ba25cfc997de70a4e5b3eb398f at this point in
> the set.

ok, ignore it then, ill retest in the next iteration, quite possible i mixed something up

thx

[...]
James Almer Oct. 8, 2024, 10:51 p.m. UTC | #9
On 10/8/2024 7:35 PM, Michael Niedermayer wrote:
> On Tue, Oct 08, 2024 at 07:13:27PM -0300, James Almer wrote:
>> On 10/8/2024 7:06 PM, Michael Niedermayer wrote:
>>> On Mon, Oct 07, 2024 at 09:29:44AM -0300, James Almer wrote:
>>>> Signed-off-by: James Almer <jamrial@gmail.com>
>>>> ---
>>>>    libswscale/output.c                      | 56 ++++++++++++++++++++++++
>>>>    libswscale/utils.c                       |  2 +-
>>>>    tests/ref/fate/filter-pixdesc-uyva       |  1 +
>>>>    tests/ref/fate/filter-pixfmts-copy       |  1 +
>>>>    tests/ref/fate/filter-pixfmts-crop       |  1 +
>>>>    tests/ref/fate/filter-pixfmts-field      |  1 +
>>>>    tests/ref/fate/filter-pixfmts-fieldorder |  1 +
>>>>    tests/ref/fate/filter-pixfmts-hflip      |  1 +
>>>>    tests/ref/fate/filter-pixfmts-il         |  1 +
>>>>    tests/ref/fate/filter-pixfmts-null       |  1 +
>>>>    tests/ref/fate/filter-pixfmts-pad        |  1 +
>>>>    tests/ref/fate/filter-pixfmts-scale      |  1 +
>>>>    tests/ref/fate/filter-pixfmts-transpose  |  1 +
>>>>    tests/ref/fate/filter-pixfmts-vflip      |  1 +
>>>>    14 files changed, 69 insertions(+), 1 deletion(-)
>>>>    create mode 100644 tests/ref/fate/filter-pixdesc-uyva
>>>
>>> seems breaking this:
>>>
>>> TEST    filter-pixfmts-scale
>>> --- ./tests/ref/fate/filter-pixfmts-scale	2024-10-09 00:03:04.066341619 +0200
>>> +++ tests/data/fate/filter-pixfmts-scale	2024-10-09 00:03:24.594518771 +0200
>>> @@ -97,7 +97,7 @@
>>>    rgba                85bb5d03cea1c6e8002ced3373904336
>>>    rgba64be            ee73e57923af984b31cc7795d13929da
>>>    rgba64le            783d2779adfafe3548bdb671ec0de69e
>>> -uyva                ee83c7ba25cfc997de70a4e5b3eb398f
>>> +uyva                1337927982389ee952714a91decd1474
>>>    uyvy422             aeb4ba4f9f003ae21f6d18089198244f
>>>    vuya                ffa817e283bf6a0b6fba21b07523ccaa
>>>    vuyx                a6ff68f46c6b4b7595ec91b2a497df8e
>>> Test filter-pixfmts-scale failed. Look at tests/data/fate/filter-pixfmts-scale.err for details.
>>> make: *** [tests/Makefile:312: fate-filter-pixfmts-scale] Error 1
>>
>> I can't reproduce, i get ee83c7ba25cfc997de70a4e5b3eb398f at this point in
>> the set.
> 
> ok, ignore it then, ill retest in the next iteration, quite possible i mixed something up

Applied the pixfmt additions to lavu and just sent a new set with the 
rest of the changes.
James Almer Oct. 9, 2024, 5:03 p.m. UTC | #10
On 10/8/2024 4:56 PM, Michael Niedermayer wrote:
> On Mon, Oct 07, 2024 at 09:29:45AM -0300, James Almer wrote:
>> Signed-off-by: James Almer <jamrial@gmail.com>
>> ---
>>   libswscale/output.c                      | 43 ++++++++++++++++++++++++
>>   libswscale/utils.c                       |  2 +-
>>   tests/ref/fate/filter-pixdesc-vyu444     |  1 +
>>   tests/ref/fate/filter-pixfmts-copy       |  1 +
>>   tests/ref/fate/filter-pixfmts-crop       |  1 +
>>   tests/ref/fate/filter-pixfmts-field      |  1 +
>>   tests/ref/fate/filter-pixfmts-fieldorder |  1 +
>>   tests/ref/fate/filter-pixfmts-hflip      |  1 +
>>   tests/ref/fate/filter-pixfmts-il         |  1 +
>>   tests/ref/fate/filter-pixfmts-null       |  1 +
>>   tests/ref/fate/filter-pixfmts-pad        |  1 +
>>   tests/ref/fate/filter-pixfmts-scale      |  1 +
>>   tests/ref/fate/filter-pixfmts-transpose  |  1 +
>>   tests/ref/fate/filter-pixfmts-vflip      |  1 +
>>   14 files changed, 56 insertions(+), 1 deletion(-)
>>   create mode 100644 tests/ref/fate/filter-pixdesc-vyu444
>>
>> diff --git a/libswscale/output.c b/libswscale/output.c
>> index a11bedde95..6716cfad34 100644
>> --- a/libswscale/output.c
>> +++ b/libswscale/output.c
>> @@ -2931,6 +2931,46 @@ yuv2uyva_X_c(SwsContext *c, const int16_t *lumFilter,
>>       }
>>   }
>>   
>> +static void
>> +yuv2vyu444_X_c(SwsContext *c, const int16_t *lumFilter,
>> +               const int16_t **lumSrc, int lumFilterSize,
>> +               const int16_t *chrFilter, const int16_t **chrUSrc,
>> +               const int16_t **chrVSrc, int chrFilterSize,
>> +               const int16_t **alpSrc, uint8_t *dest, int dstW, int y)
>> +{
>> +    int i;
>> +
>> +    for (i = 0; i < dstW; i++) {
>> +        int j;
>> +        int Y = 1 << 18, U = 1 << 18;
>> +        int V = 1 << 18;
>> +
>> +        for (j = 0; j < lumFilterSize; j++)
>> +            Y += lumSrc[j][i] * lumFilter[j];
>> +
>> +        for (j = 0; j < chrFilterSize; j++)
>> +            U += chrUSrc[j][i] * chrFilter[j];
>> +
>> +        for (j = 0; j < chrFilterSize; j++)
>> +            V += chrVSrc[j][i] * chrFilter[j];
>> +
>> +        Y >>= 19;
>> +        U >>= 19;
>> +        V >>= 19;
>> +
>> +        if (Y  & 0x100)
>> +            Y = av_clip_uint8(Y);
>> +        if (U  & 0x100)
>> +            U = av_clip_uint8(U);
>> +        if (V  & 0x100)
>> +            V = av_clip_uint8(V);
>> +
>> +        dest[3 * i    ] = V;
>> +        dest[3 * i + 1] = Y;
>> +        dest[3 * i + 2] = U;
>> +    }
>> +}
>> +
>>   #define output_pixel(pos, val, bits) \
>>       AV_WL16(pos, av_clip_uintp2(val >> shift, bits) << output_shift);
>>   
>> @@ -3465,6 +3505,9 @@ av_cold void ff_sws_init_output_funcs(SwsContext *c,
>>           *yuv2packed2 = yuv2uyvy422_2_c;
>>           *yuv2packedX = yuv2uyvy422_X_c;
>>           break;
>> +    case AV_PIX_FMT_VYU444:
>> +        *yuv2packedX = yuv2vyu444_X_c;
>> +        break;
> 
> does this work in the unscaled and 2 tap scaling cases ? (which would normally
> use teh other 2pointers

I tried

./ffmpeg.exe -noauto_conversion_filters -cpuflags 0 -f image2 -c:v 
pgmyuv -i ./tests/vsynth1/%02d.pgm -vf 
scale=sws_flags=bilinear,format=vyu444 -vcodec rawvideo -pix_fmt vyu444 
-frames:v 1 -y out.nut

And it works (The output looks fine with ffplay). Is there some other 
way to test that?
Michael Niedermayer Oct. 16, 2024, 11:17 p.m. UTC | #11
On Wed, Oct 09, 2024 at 02:03:28PM -0300, James Almer wrote:
> On 10/8/2024 4:56 PM, Michael Niedermayer wrote:
> > On Mon, Oct 07, 2024 at 09:29:45AM -0300, James Almer wrote:
> > > Signed-off-by: James Almer <jamrial@gmail.com>
> > > ---
> > >   libswscale/output.c                      | 43 ++++++++++++++++++++++++
> > >   libswscale/utils.c                       |  2 +-
> > >   tests/ref/fate/filter-pixdesc-vyu444     |  1 +
> > >   tests/ref/fate/filter-pixfmts-copy       |  1 +
> > >   tests/ref/fate/filter-pixfmts-crop       |  1 +
> > >   tests/ref/fate/filter-pixfmts-field      |  1 +
> > >   tests/ref/fate/filter-pixfmts-fieldorder |  1 +
> > >   tests/ref/fate/filter-pixfmts-hflip      |  1 +
> > >   tests/ref/fate/filter-pixfmts-il         |  1 +
> > >   tests/ref/fate/filter-pixfmts-null       |  1 +
> > >   tests/ref/fate/filter-pixfmts-pad        |  1 +
> > >   tests/ref/fate/filter-pixfmts-scale      |  1 +
> > >   tests/ref/fate/filter-pixfmts-transpose  |  1 +
> > >   tests/ref/fate/filter-pixfmts-vflip      |  1 +
> > >   14 files changed, 56 insertions(+), 1 deletion(-)
> > >   create mode 100644 tests/ref/fate/filter-pixdesc-vyu444
> > > 
> > > diff --git a/libswscale/output.c b/libswscale/output.c
> > > index a11bedde95..6716cfad34 100644
> > > --- a/libswscale/output.c
> > > +++ b/libswscale/output.c
> > > @@ -2931,6 +2931,46 @@ yuv2uyva_X_c(SwsContext *c, const int16_t *lumFilter,
> > >       }
> > >   }
> > > +static void
> > > +yuv2vyu444_X_c(SwsContext *c, const int16_t *lumFilter,
> > > +               const int16_t **lumSrc, int lumFilterSize,
> > > +               const int16_t *chrFilter, const int16_t **chrUSrc,
> > > +               const int16_t **chrVSrc, int chrFilterSize,
> > > +               const int16_t **alpSrc, uint8_t *dest, int dstW, int y)
> > > +{
> > > +    int i;
> > > +
> > > +    for (i = 0; i < dstW; i++) {
> > > +        int j;
> > > +        int Y = 1 << 18, U = 1 << 18;
> > > +        int V = 1 << 18;
> > > +
> > > +        for (j = 0; j < lumFilterSize; j++)
> > > +            Y += lumSrc[j][i] * lumFilter[j];
> > > +
> > > +        for (j = 0; j < chrFilterSize; j++)
> > > +            U += chrUSrc[j][i] * chrFilter[j];
> > > +
> > > +        for (j = 0; j < chrFilterSize; j++)
> > > +            V += chrVSrc[j][i] * chrFilter[j];
> > > +
> > > +        Y >>= 19;
> > > +        U >>= 19;
> > > +        V >>= 19;
> > > +
> > > +        if (Y  & 0x100)
> > > +            Y = av_clip_uint8(Y);
> > > +        if (U  & 0x100)
> > > +            U = av_clip_uint8(U);
> > > +        if (V  & 0x100)
> > > +            V = av_clip_uint8(V);
> > > +
> > > +        dest[3 * i    ] = V;
> > > +        dest[3 * i + 1] = Y;
> > > +        dest[3 * i + 2] = U;
> > > +    }
> > > +}
> > > +
> > >   #define output_pixel(pos, val, bits) \
> > >       AV_WL16(pos, av_clip_uintp2(val >> shift, bits) << output_shift);
> > > @@ -3465,6 +3505,9 @@ av_cold void ff_sws_init_output_funcs(SwsContext *c,
> > >           *yuv2packed2 = yuv2uyvy422_2_c;
> > >           *yuv2packedX = yuv2uyvy422_X_c;
> > >           break;
> > > +    case AV_PIX_FMT_VYU444:
> > > +        *yuv2packedX = yuv2vyu444_X_c;
> > > +        break;
> > 
> > does this work in the unscaled and 2 tap scaling cases ? (which would normally
> > use teh other 2pointers
> 
> I tried
> 
> ./ffmpeg.exe -noauto_conversion_filters -cpuflags 0 -f image2 -c:v pgmyuv -i
> ./tests/vsynth1/%02d.pgm -vf scale=sws_flags=bilinear,format=vyu444 -vcodec
> rawvideo -pix_fmt vyu444 -frames:v 1 -y out.nut
> 

> And it works (The output looks fine with ffplay). Is there some other way to
> test that?

is that command above actually scaling anything ? it looks like input and output
have t he same size

thx

[...]
James Almer Oct. 17, 2024, 12:18 p.m. UTC | #12
On 10/16/2024 8:17 PM, Michael Niedermayer wrote:
> On Wed, Oct 09, 2024 at 02:03:28PM -0300, James Almer wrote:
>> On 10/8/2024 4:56 PM, Michael Niedermayer wrote:
>>> On Mon, Oct 07, 2024 at 09:29:45AM -0300, James Almer wrote:
>>>> Signed-off-by: James Almer <jamrial@gmail.com>
>>>> ---
>>>>    libswscale/output.c                      | 43 ++++++++++++++++++++++++
>>>>    libswscale/utils.c                       |  2 +-
>>>>    tests/ref/fate/filter-pixdesc-vyu444     |  1 +
>>>>    tests/ref/fate/filter-pixfmts-copy       |  1 +
>>>>    tests/ref/fate/filter-pixfmts-crop       |  1 +
>>>>    tests/ref/fate/filter-pixfmts-field      |  1 +
>>>>    tests/ref/fate/filter-pixfmts-fieldorder |  1 +
>>>>    tests/ref/fate/filter-pixfmts-hflip      |  1 +
>>>>    tests/ref/fate/filter-pixfmts-il         |  1 +
>>>>    tests/ref/fate/filter-pixfmts-null       |  1 +
>>>>    tests/ref/fate/filter-pixfmts-pad        |  1 +
>>>>    tests/ref/fate/filter-pixfmts-scale      |  1 +
>>>>    tests/ref/fate/filter-pixfmts-transpose  |  1 +
>>>>    tests/ref/fate/filter-pixfmts-vflip      |  1 +
>>>>    14 files changed, 56 insertions(+), 1 deletion(-)
>>>>    create mode 100644 tests/ref/fate/filter-pixdesc-vyu444
>>>>
>>>> diff --git a/libswscale/output.c b/libswscale/output.c
>>>> index a11bedde95..6716cfad34 100644
>>>> --- a/libswscale/output.c
>>>> +++ b/libswscale/output.c
>>>> @@ -2931,6 +2931,46 @@ yuv2uyva_X_c(SwsContext *c, const int16_t *lumFilter,
>>>>        }
>>>>    }
>>>> +static void
>>>> +yuv2vyu444_X_c(SwsContext *c, const int16_t *lumFilter,
>>>> +               const int16_t **lumSrc, int lumFilterSize,
>>>> +               const int16_t *chrFilter, const int16_t **chrUSrc,
>>>> +               const int16_t **chrVSrc, int chrFilterSize,
>>>> +               const int16_t **alpSrc, uint8_t *dest, int dstW, int y)
>>>> +{
>>>> +    int i;
>>>> +
>>>> +    for (i = 0; i < dstW; i++) {
>>>> +        int j;
>>>> +        int Y = 1 << 18, U = 1 << 18;
>>>> +        int V = 1 << 18;
>>>> +
>>>> +        for (j = 0; j < lumFilterSize; j++)
>>>> +            Y += lumSrc[j][i] * lumFilter[j];
>>>> +
>>>> +        for (j = 0; j < chrFilterSize; j++)
>>>> +            U += chrUSrc[j][i] * chrFilter[j];
>>>> +
>>>> +        for (j = 0; j < chrFilterSize; j++)
>>>> +            V += chrVSrc[j][i] * chrFilter[j];
>>>> +
>>>> +        Y >>= 19;
>>>> +        U >>= 19;
>>>> +        V >>= 19;
>>>> +
>>>> +        if (Y  & 0x100)
>>>> +            Y = av_clip_uint8(Y);
>>>> +        if (U  & 0x100)
>>>> +            U = av_clip_uint8(U);
>>>> +        if (V  & 0x100)
>>>> +            V = av_clip_uint8(V);
>>>> +
>>>> +        dest[3 * i    ] = V;
>>>> +        dest[3 * i + 1] = Y;
>>>> +        dest[3 * i + 2] = U;
>>>> +    }
>>>> +}
>>>> +
>>>>    #define output_pixel(pos, val, bits) \
>>>>        AV_WL16(pos, av_clip_uintp2(val >> shift, bits) << output_shift);
>>>> @@ -3465,6 +3505,9 @@ av_cold void ff_sws_init_output_funcs(SwsContext *c,
>>>>            *yuv2packed2 = yuv2uyvy422_2_c;
>>>>            *yuv2packedX = yuv2uyvy422_X_c;
>>>>            break;
>>>> +    case AV_PIX_FMT_VYU444:
>>>> +        *yuv2packedX = yuv2vyu444_X_c;
>>>> +        break;
>>>
>>> does this work in the unscaled and 2 tap scaling cases ? (which would normally
>>> use teh other 2pointers
>>
>> I tried
>>
>> ./ffmpeg.exe -noauto_conversion_filters -cpuflags 0 -f image2 -c:v pgmyuv -i
>> ./tests/vsynth1/%02d.pgm -vf scale=sws_flags=bilinear,format=vyu444 -vcodec
>> rawvideo -pix_fmt vyu444 -frames:v 1 -y out.nut
>>
> 
>> And it works (The output looks fine with ffplay). Is there some other way to
>> test that?
> 
> is that command above actually scaling anything ? it looks like input and output
> have t he same size
> 
> thx

Tried adding s=702x573 to the scale opts and the result also looked right.
diff mbox series

Patch

diff --git a/libswscale/output.c b/libswscale/output.c
index 31921a3cce..e5d555f76f 100644
--- a/libswscale/output.c
+++ b/libswscale/output.c
@@ -2668,6 +2668,110 @@  yuv2xv36le_X_c(SwsContext *c, const int16_t *lumFilter,
     }
 }
 
+static void
+yuv2vuyX_1_c(SwsContext *c, const int16_t *buf0,
+             const int16_t *ubuf[2], const int16_t *vbuf[2],
+             const int16_t *abuf0, uint8_t *dest, int dstW,
+             int uvalpha, int y)
+{
+    int hasAlpha = !!abuf0;
+    int i;
+
+    if (uvalpha < 2048) {
+        for (i = 0; i < dstW; i++) {
+            int Y = (buf0[i] + 64) >> 7;
+            int U = (ubuf[0][i] + 64) >> 7;
+            int V = (vbuf[0][i] + 64) >> 7;
+            int A = 255;
+
+            if (Y & 0x100)
+                Y = av_clip_uint8(Y);
+            if (U & 0x100)
+                U = av_clip_uint8(U);
+            if (V & 0x100)
+                V = av_clip_uint8(V);
+
+            if (hasAlpha) {
+                A = (abuf0[i] + 64) >> 7;
+                if (A & 0x100)
+                    A = av_clip_uint8(A);
+            }
+
+            dest[i * 2    ] = Y;
+            dest[i * 2 + 1] = A;
+        }
+    } else {
+        for (i = 0; i < dstW; i++) {
+            int Y = (buf0[i] + 64) >> 7;
+            int U = (ubuf[0][i] + ubuf[1][i] + 128) >> 8;
+            int V = (vbuf[0][i] + vbuf[1][i] + 128) >> 8;
+            int A = 255;
+
+            if (Y & 0x100)
+                Y = av_clip_uint8(Y);
+            if (U & 0x100)
+                U = av_clip_uint8(U);
+            if (V & 0x100)
+                V = av_clip_uint8(V);
+
+            if (hasAlpha) {
+                A = (abuf0[i] + 64) >> 7;
+                if (A & 0x100)
+                    A = av_clip_uint8(A);
+            }
+
+            dest[4 * i    ] = V;
+            dest[4 * i + 1] = U;
+            dest[4 * i + 2] = Y;
+            dest[4 * i + 3] = A;
+        }
+    }
+}
+
+static void
+yuv2vuyX_2_c(SwsContext *c, const int16_t *buf[2],
+            const int16_t *ubuf[2], const int16_t *vbuf[2],
+            const int16_t *abuf[2], uint8_t *dest, int dstW,
+            int yalpha, int uvalpha, int y)
+{
+    int hasAlpha = abuf && abuf[0] && abuf[1];
+    const int16_t *buf0  = buf[0],  *buf1  = buf[1],
+                  *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
+                  *vbuf0 = vbuf[0], *vbuf1 = vbuf[1],
+                  *abuf0 = hasAlpha ? abuf[0] : NULL,
+                  *abuf1 = hasAlpha ? abuf[1] : NULL;
+    int yalpha1  = 4096 - yalpha;
+    int uvalpha1 = 4096 - uvalpha;
+    int i;
+
+    av_assert2(yalpha  <= 4096U);
+    av_assert2(uvalpha <= 4096U);
+
+    for (i = 0; i < dstW; i++) {
+        int Y = (buf0[i]  * yalpha1  + buf1[i]  * yalpha)  >> 19;
+        int U = (ubuf0[i] * uvalpha1 + ubuf1[i] * uvalpha) >> 19;
+        int V = (vbuf0[i] * uvalpha1 + vbuf1[i] * uvalpha) >> 19;
+        int A = 255;
+
+        if (Y & 0x100)
+            Y = av_clip_uint8(Y);
+        if (U & 0x100)
+            U = av_clip_uint8(U);
+        if (V & 0x100)
+            V = av_clip_uint8(V);
+
+        if (hasAlpha) {
+            A = (abuf0[i] * yalpha1 + abuf1[i] * yalpha) >> 19;
+            A = av_clip_uint8(A);
+        }
+
+        dest[4 * i    ] = V;
+        dest[4 * i + 1] = U;
+        dest[4 * i + 2] = Y;
+        dest[4 * i + 3] = A;
+    }
+}
+
 static void
 yuv2vuyX_X_c(SwsContext *c, const int16_t *lumFilter,
              const int16_t **lumSrc, int lumFilterSize,
@@ -3275,6 +3379,8 @@  av_cold void ff_sws_init_output_funcs(SwsContext *c,
         break;
     case AV_PIX_FMT_VUYA:
     case AV_PIX_FMT_VUYX:
+        *yuv2packed1 = yuv2vuyX_1_c;
+        *yuv2packed2 = yuv2vuyX_2_c;
         *yuv2packedX = yuv2vuyX_X_c;
         break;
     case AV_PIX_FMT_XV30LE: