[FFmpeg-devel] [PATCH] Fix linesize computation for NV formats

Ramiro Polla ramiro.polla
Thu Dec 3 04:13:57 CET 2009


On Wed, Nov 25, 2009 at 4:16 PM, Michael Niedermayer <michaelni at gmx.at> wrote:
> On Wed, Nov 25, 2009 at 03:24:03PM -0200, Ramiro Polla wrote:
>> On Tue, Nov 24, 2009 at 12:27 PM, Michael Niedermayer <michaelni at gmx.at> wrote:
>> > On Fri, Nov 20, 2009 at 02:16:44PM -0200, Ramiro Polla wrote:
>> >> On Fri, Nov 20, 2009 at 9:56 AM, Ramiro Polla <ramiro.polla at gmail.com> wrote:
>> >> > On Thu, Nov 19, 2009 at 10:54 PM, Ramiro Polla <ramiro.polla at gmail.com> wrote:
>> >> >> On Thu, Nov 19, 2009 at 10:38 PM, Stefano Sabatini
>> >> >> <stefano.sabatini-lala at poste.it> wrote:
>> >> >>> On date Thursday 2009-11-19 17:51:30 +0100, Michael Niedermayer encoded:
>> >> >>>> On Thu, Nov 19, 2009 at 01:37:03AM +0100, Stefano Sabatini wrote:
>> >> >>> [...]
>> >> >>>> > So basically all the code affected by the change is indeed code which
>> >> >>>> > is never used, my patch simply makes the linesize params semantics for
>> >> >>>> > NV formats consistent with that of all the other formats (thus
>> >> >>>> > simplifying the code if we choose to use pixdesc for ff_fill_XXX).
>> >> >>>>
>> >> >>>> if no code uses NV12 it should be removed (i dont belive this though)
>> >> >>>> if any code uses NV12 your patch will break it.
>> >> >>>
>> >> >>> ffmpeg doesn't support NV12 as input, but can convert to NV12 /
>> >> >>> NV21. So we can create a stream with pix_fmt nv12 but there is no mean
>> >> >>> to visually test it (e.g. with ffplay) or convert it back to a stream
>> >> >>> which is playable by ffmpeg, but maybe someone can suggest some way to
>> >> >>> display such a format e.g. with mplayer or vlc.
>> >> >>>
>> >> >>> Also I wonder how hard would be to add it as an input format in lsws.
>> >> >>
>> >> >> I have a device with a hardware decoder to nv12 that also displays in
>> >> >> nv12 at work. I might take a look tomorrow if I manage to find some
>> >> >> time...
>> >> >
>> >> > One more change was needed to get raw nv12 output properly. With
>> >> > attached patch I can
>> >> > ./ffmpeg_g -i input.avi -s 1280x720 -pix_fmt nv12 -f rawvideo -y output.nv12
>> >> > and then feed output.nv12 to the display frame by frame.
>> >> >
>> >> > I haven't worked on nv12 support as input to swscale yet. I'll do it
>> >> > either this afternoon or in two weeks =)
>> >>
>> >> And here is a patch to take nv12 and nv21 as input for swscale
>> >> (depends on the previous patch).
>> >>
>> >> Ramiro Polla
>> >
>> >> ?swscale.c ? ? ? ? ?| ? ?2 ++
>> >> ?swscale_template.c | ? 23 +++++++++++++++++++++++
>> >> ?2 files changed, 25 insertions(+)
>> >> 7e95c118694ad7ee4d89e948fea7e3252238d5d9 ?nv12in.diff
>> >> Index: libswscale/swscale.c
>> >> ===================================================================
>> >> --- libswscale/swscale.c ? ? ?(revis?o 29937)
>> >> +++ libswscale/swscale.c ? ? ?(c?pia de trabalho)
>> >> @@ -134,6 +134,8 @@
>> >> ? ? ? ? ?|| (x)==PIX_FMT_GRAY8 ? ? ? \
>> >> ? ? ? ? ?|| (x)==PIX_FMT_YUV410P ? ? \
>> >> ? ? ? ? ?|| (x)==PIX_FMT_YUV440P ? ? \
>> >> + ? ? ? ?|| (x)==PIX_FMT_NV12 ? ? ? ?\
>> >> + ? ? ? ?|| (x)==PIX_FMT_NV21 ? ? ? ?\
>> >> ? ? ? ? ?|| (x)==PIX_FMT_GRAY16BE ? ?\
>> >> ? ? ? ? ?|| (x)==PIX_FMT_GRAY16LE ? ?\
>> >> ? ? ? ? ?|| (x)==PIX_FMT_YUV444P ? ? \
>> >> Index: libswscale/swscale_template.c
>> >> ===================================================================
>> >> --- libswscale/swscale_template.c ? ? (revis?o 29937)
>> >> +++ libswscale/swscale_template.c ? ? (c?pia de trabalho)
>> >> @@ -1784,6 +1784,27 @@
>> >> ?#endif
>> >> ?}
>> >>
>> >> +#define NVxxToUV(U, V) ? ? ? ? ? ? ?\
>> >> + ? ?int i; ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> >> + ? ?for (i = 0; i < width; i++) { ? \
>> >> + ? ? ? ?dstU[i]= src1[2*i+U]; ? ? ? \
>> >> + ? ? ? ?dstV[i]= src1[2*i+V]; ? ? ? \
>> >> + ? ?} ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
>> >> +
>> >> +static inline void RENAME(nv12ToUV)(uint8_t *dstU, uint8_t *dstV,
>> >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?const uint8_t *src1, const uint8_t *src2,
>> >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?long width, uint32_t *unused)
>> >> +{
>> >> + ? ?NVxxToUV(0, 1);
>> >> +}
>> >> +
>> >> +static inline void RENAME(nv21ToUV)(uint8_t *dstU, uint8_t *dstV,
>> >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?const uint8_t *src1, const uint8_t *src2,
>> >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?long width, uint32_t *unused)
>> >> +{
>> >> + ? ?NVxxToUV(1, 0);
>> >> +}
>> >
>> > you need just 1 function, just exchange the 2 dst pointers
>>
>> Like in attached?
>
>> ?swscale.c ? ? ? ? ?| ? ?2 ++
>> ?swscale_template.c | ? 26 ++++++++++++++++++++++++++
>> ?2 files changed, 28 insertions(+)
>> 219c60ab14c8879cf0b3578079ced1b82df9e01f ?nv12in2.diff
>> Index: libswscale/swscale.c
>> ===================================================================
>> --- libswscale/swscale.c ? ? ?(revision 29964)
>> +++ libswscale/swscale.c ? ? ?(working copy)
>> @@ -134,6 +134,8 @@
>> ? ? ? ? ?|| (x)==PIX_FMT_GRAY8 ? ? ? \
>> ? ? ? ? ?|| (x)==PIX_FMT_YUV410P ? ? \
>> ? ? ? ? ?|| (x)==PIX_FMT_YUV440P ? ? \
>> + ? ? ? ?|| (x)==PIX_FMT_NV12 ? ? ? ?\
>> + ? ? ? ?|| (x)==PIX_FMT_NV21 ? ? ? ?\
>> ? ? ? ? ?|| (x)==PIX_FMT_GRAY16BE ? ?\
>> ? ? ? ? ?|| (x)==PIX_FMT_GRAY16LE ? ?\
>> ? ? ? ? ?|| (x)==PIX_FMT_YUV444P ? ? \
>> Index: libswscale/swscale_template.c
>> ===================================================================
>> --- libswscale/swscale_template.c ? ? (revision 29964)
>> +++ libswscale/swscale_template.c ? ? (working copy)
>> @@ -1784,6 +1784,30 @@
>> ?#endif
>> ?}
>>
>> +static inline void RENAME(nvXXtoUV)(uint8_t *dst1, uint8_t *dst2,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?const uint8_t *src, long width)
>> +{
>> + ? ?int i;
>> + ? ?for (i = 0; i < width; i++) {
>> + ? ? ? ?dst1[i]= src[2*i+0];
>> + ? ? ? ?dst2[i]= src[2*i+1];
>> + ? ?}
>> +}
>> +
>> +static inline void nv12ToUV(uint8_t *dstU, uint8_t *dstV,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?const uint8_t *src1, const uint8_t *src2,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?long width, uint32_t *unused)
>> +{
>> + ? ?RENAME(nvXXtoUV)(dstU, dstV, src1, width);
>> +}
>> +
>> +static inline void nv21ToUV(uint8_t *dstU, uint8_t *dstV,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?const uint8_t *src1, const uint8_t *src2,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?long width, uint32_t *unused)
>> +{
>> + ? ?RENAME(nvXXtoUV)(dstV, dstU, src1, width);
>> +}
>
> is the use of existing functions like yuy2ToY() slower?

Getting the smallest dezicycle count from a whole bunch of runs:

nvXXtoUV:
C   21802
MMX  7744

yuy2ToY and uyvyToY to not cause unaligned loads in MMX:
C   27653
MMX 8464

BEToUV (half the loads are always unaligned in MMX):
C   21952
MMX 10060

New patch attached with MMX nvXXtoUV as well.

Ramiro Polla
-------------- next part --------------
A non-text attachment was scrubbed...
Name: nv12inMMX.diff
Type: text/x-diff
Size: 3281 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20091203/620865ed/attachment.diff>



More information about the ffmpeg-devel mailing list