[FFmpeg-devel] Patch for Cast128 algorithm implementation

supraja reddy supraja0493 at gmail.com
Wed Oct 15 23:55:42 CEST 2014


Extremely sorry for resending the patch . There was a trailing whitespace
which I hadn't corrected .
All the changes are done .
Please let me if any changes needed further .

Thanks ,
Supraja

On Thu, Oct 16, 2014 at 2:28 AM, supraja reddy <supraja0493 at gmail.com>
wrote:

> Hello ,
>
> I hadn't rebased my branch . This is after the sync . Apologies for the
> error .
>
> Thanks ,
>
> Supraja
>
> On Thu, Oct 16, 2014 at 12:50 AM, supraja reddy <supraja0493 at gmail.com>
> wrote:
>
>> I have updated the changes as requested .  Please look into the attached
>> patch and let me know if there is anything else you wish me to change.
>>
>> Thanks ,
>>
>> Supraja
>>
>> On Sun, Oct 12, 2014 at 8:38 PM, Giorgio Vazzana <mywing81 at gmail.com>
>> wrote:
>>
>>> 2014-10-12 13:59 GMT+02:00 supraja reddy <supraja0493 at gmail.com>:
>>> > Hello ,
>>> >
>>> > I , Supraja , am interested to work with ffmpeg as a part of OPW
>>> internship
>>> > . As a part of the qualification task , I have taken up the
>>> implementation
>>> > of Cast 128 algorithm implementation . I have written the code for the
>>> same
>>> > and have attached the patch of the same with this mail . It is
>>> currently
>>> > written for ecb mode . It takes keysizes of 40 , 80 and 128 bits for
>>> now .
>>> >
>>> > Please let me know if there are any further changes or suggestions .
>>>
>>> Hello,
>>>
>>> thanks for your patch! Please make sure to run tools/patcheck as
>>> Michael suggested and fix the reported problems.
>>> Some preliminary comments below, hopefully I'll have more time to
>>> test/review the patch in the following days.
>>>
>>> > From b7aab16b09db2a3ca16144221f1516f7fec8a7a2 Mon Sep 17 00:00:00 2001
>>> > From: Myra <supraja0493 at gmail.com>
>>>
>>> Make sure your name and email address are configured correctly in git.
>>>
>>> > Date: Sun, 12 Oct 2014 11:39:24 +0530
>>> > Subject: [PATCH] Added cast128 algorithm for ecb mode
>>> >
>>> > Signed-off-by: Myra <supraja0493 at gmail.com>
>>> > ---
>>> >  libavutil/Makefile |   3 +
>>> >  libavutil/cast5.c  | 521
>>> +++++++++++++++++++++++++++++++++++++++++++++++++++++
>>> >  libavutil/cast5.h  |  37 ++++
>>> >  3 files changed, 561 insertions(+)
>>> >  create mode 100644 libavutil/cast5.c
>>> >  create mode 100644 libavutil/cast5.h
>>> >
>>> > diff --git a/libavutil/Makefile b/libavutil/Makefile
>>> > index 65c6b53..22d345e 100644
>>> > --- a/libavutil/Makefile
>>> > +++ b/libavutil/Makefile
>>> > @@ -15,6 +15,7 @@ HEADERS = adler32.h
>>>                    \
>>> >            bprint.h
>>>   \
>>> >            bswap.h
>>>    \
>>> >            buffer.h
>>>   \
>>> > +          cast5.c
>>>    \
>>> >            channel_layout.h
>>>   \
>>> >            common.h
>>>   \
>>> >            cpu.h
>>>    \
>>> > @@ -82,6 +83,7 @@ OBJS = adler32.o
>>>                     \
>>> >         blowfish.o
>>>    \
>>> >         bprint.o
>>>    \
>>> >         buffer.o
>>>    \
>>>
>>> > +       cast5.o
>>>  \
>>>
>>> You need to add one more space after cast5.o to align the '\'.
>>>
>>> >         channel_layout.o
>>>    \
>>> >         cpu.o
>>>   \
>>> >         crc.o
>>>   \
>>> > @@ -151,6 +153,7 @@ TESTPROGS = adler32
>>>                      \
>>> >              base64
>>>   \
>>> >              blowfish
>>>   \
>>> >              bprint
>>>   \
>>>
>>> > +            cast5
>>>   \
>>>
>>> Same here, one more space is needed.
>>>
>>> >              cpu
>>>    \
>>> >              crc
>>>    \
>>> >              des
>>>    \
>>> > diff --git a/libavutil/cast5.c b/libavutil/cast5.c
>>> > new file mode 100644
>>> > index 0000000..ca7200c
>>> > --- /dev/null
>>> > +++ b/libavutil/cast5.c
>>> > @@ -0,0 +1,521 @@
>>> > +#include "cast5.h"
>>> > +#include "common.h"
>>> > +#include "intreadwrite.h"
>>>
>>> > +#include "timer.h"
>>>
>>> I don't think we need timer.h
>>>
>>> > +/*
>>> > + * An implementation of the CAST128 algorithm
>>>
>>> Maybe add a note mentioning the RFC2144.
>>>
>>> > + * Copyright (c) 2014 Supraja Meedinti
>>> > + *
>>> > + * This file is part of FFmpeg.
>>> > + *
>>> > + * FFmpeg is free software; you can redistribute it and/or
>>> > + * modify it under the terms of the GNU Lesser General Public
>>> > + * License as published by the Free Software Foundation; either
>>> > + * version 2.1 of the License, or (at your option) any later version.
>>> > + *
>>> > + * FFmpeg is distributed in the hope that it will be useful,
>>> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>>> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>>> > + * Lesser General Public License for more details.
>>> > + *
>>> > + * You should have received a copy of the GNU Lesser General Public
>>> > + * License along with FFmpeg; if not, write to the Free Software
>>> > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
>>> 02110-1301 USA
>>> > + */
>>> > +
>>> > +#define IA(x) ((x>>24) & 0xff)
>>> > +#define IB(x) ((x>>16) & 0xff)
>>> > +#define IC(x) ((x>>8) & 0xff)
>>> > +#define ID(x) (x & 0xff)
>>>
>>> I'd also suggest to add a macro for circular left shift (left
>>> rotation) and use it throughout the code:
>>>
>>> #define LR(x, c) ((x) << (c) | (x) >> (32 - (c)))
>>>
>>> > +
>>> > +typedef struct AVCAST5 {
>>> > +    uint32_t Km[17];
>>> > +    uint32_t Kr[17];
>>> > +    int rounds;
>>> > +} AVCAST5;
>>> > +
>>>
>>> > +
>>> > +
>>> > +static uint32_t func(uint32_t D, uint32_t Km, uint32_t Kr, int rnum)
>>> > +{
>>> > +    uint32_t I,t,val;
>>> > +    switch(rnum%3){
>>> > +        case 0:
>>> > +            t=(Km-D);
>>> > +            I=(t<<Kr)|(t>>(32-Kr));
>>> > +            val=((S1[IA(I)]+S2[IB(I)])^S3[IC(I)])-S4[ID(I)];
>>> > +            break;
>>>
>>> You can probably eliminate t, something like:
>>>
>>> I = LR(Km - D, Kr);
>>>
>>> > +        case 1:
>>> > +            t=Km+D;
>>> > +            I=(t<<Kr)|(t>>(32-Kr));
>>> > +            val=((S1[IA(I)]^S2[IB(I)])-S3[IC(I)])+S4[ID(I)];
>>> > +            break;
>>> > +        case 2:
>>> > +            t=(Km^D);
>>> > +            I=(t<<Kr)|(t>>(32-Kr));
>>> > +            val=((S1[IA(I)]-S2[IB(I)])+S3[IC(I)])^S4[ID(I)];
>>> > +            break;
>>> > +    }
>>> > +    return val;
>>> > +}
>>> > +
>>> > +static void GenerateRoundKeys(int rnds,uint32_t* K, uint32_t* q,
>>> uint32_t* p)
>>>
>>> We could call q->x and p->z to use the same names used in the RFC, and
>>> define:
>>>
>>> static void generate_round_keys(int rounds, uint32_t *K, uint32_t
>>> x[4], uint32_t z[4])
>>>
>>> > +{
>>>
>>> > +
>>> p[0]=q[0]^S5[IB(q[3])]^S6[ID(q[3])]^S7[IA(q[3])]^S8[IC(q[3])]^S7[IA(q[2])];
>>> > +
>>> p[1]=q[2]^S5[IA(p[0])]^S6[IC(p[0])]^S7[IB(p[0])]^S8[ID(p[0])]^S8[IC(q[2])];
>>> > +
>>> p[2]=q[3]^S5[ID(p[1])]^S6[IC(p[1])]^S7[IB(p[1])]^S8[IA(p[1])]^S5[IB(q[2])];
>>> > +
>>> p[3]=q[1]^S5[IC(p[2])]^S6[IB(p[2])]^S7[ID(p[2])]^S8[IA(p[2])]^S6[ID(q[2])];
>>>
>>> The block above computes p[] from (p[],q[]) and will be repeated
>>> later, it could be defined as a macro.
>>>
>>> > +
>>> > +
>>> K[1]=S5[IA(p[2])]^S6[IB(p[2])]^S7[ID(p[1])]^S8[IC(p[1])]^S5[IC(p[0])];
>>> > +
>>> K[2]=S5[IC(p[2])]^S6[ID(p[2])]^S7[IB(p[1])]^S8[IA(p[1])]^S6[IC(p[1])];
>>> > +
>>> K[3]=S5[IA(p[3])]^S6[IB(p[3])]^S7[ID(p[0])]^S8[IC(p[0])]^S7[IB(p[2])];
>>> > +
>>> K[4]=S5[IC(p[3])]^S6[ID(p[3])]^S7[IB(p[0])]^S8[IA(p[0])]^S8[IA(p[3])];
>>> > +
>>>
>>> > +
>>> q[0]=p[2]^S5[IB(p[1])]^S6[ID(p[1])]^S7[IA(p[1])]^S8[IC(p[1])]^S7[IA(p[0])];
>>> > +
>>> q[1]=p[0]^S5[IA(q[0])]^S6[IC(q[0])]^S7[IB(q[0])]^S8[ID(q[0])]^S8[IC(p[0])];
>>> > +
>>> q[2]=p[1]^S5[ID(q[1])]^S6[IC(q[1])]^S7[IB(q[1])]^S8[IA(q[1])]^S5[IB(p[0])];
>>> > +
>>> q[3]=p[3]^S5[IC(q[2])]^S6[IB(q[2])]^S7[ID(q[2])]^S8[IA(q[2])]^S6[ID(p[0])];
>>>
>>> Same here, the block above computes q[] from (p[],q[]) and will be
>>> repeated later, you could define a macro.
>>>
>>> > +
>>> > +
>>> K[5]=S5[ID(q[0])]^S6[IC(q[0])]^S7[IA(q[3])]^S8[IB(q[3])]^S5[IA(q[2])];
>>> > +
>>> K[6]=S5[IB(q[0])]^S6[IA(q[0])]^S7[IC(q[3])]^S8[ID(q[3])]^S6[IB(q[3])];
>>> > +
>>> K[7]=S5[ID(q[1])]^S6[IC(q[1])]^S7[IA(q[2])]^S8[IB(q[2])]^S7[ID(q[0])];
>>> > +
>>> K[8]=S5[IB(q[1])]^S6[IA(q[1])]^S7[IC(q[2])]^S8[ID(q[2])]^S8[ID(q[1])];
>>> > +
>>> > +
>>> p[0]=q[0]^S5[IB(q[3])]^S6[ID(q[3])]^S7[IA(q[3])]^S8[IC(q[3])]^S7[IA(q[2])];
>>> > +
>>> p[1]=q[2]^S5[IA(p[0])]^S6[IC(p[0])]^S7[IB(p[0])]^S8[ID(p[0])]^S8[IC(q[2])];
>>> > +
>>> p[2]=q[3]^S5[ID(p[1])]^S6[IC(p[1])]^S7[IB(p[1])]^S8[IA(p[1])]^S5[IB(q[2])];
>>> > +
>>> p[3]=q[1]^S5[IC(p[2])]^S6[IB(p[2])]^S7[ID(p[2])]^S8[IA(p[2])]^S6[ID(q[2])];
>>> > +
>>> > +
>>> K[9]=S5[ID(p[0])]^S6[IC(p[0])]^S7[IA(p[3])]^S8[IB(p[3])]^S5[IB(p[2])];
>>> > +
>>> K[10]=S5[IB(p[0])]^S6[IA(p[0])]^S7[IC(p[3])]^S8[ID(p[3])]^S6[IA(p[3])];
>>> > +
>>> K[11]=S5[ID(p[1])]^S6[IC(p[1])]^S7[IA(p[2])]^S8[IB(p[2])]^S7[IC(p[0])];
>>> > +
>>> K[12]=S5[IB(p[1])]^S6[IA(p[1])]^S7[IC(p[2])]^S8[ID(p[2])]^S8[IC(p[1])];
>>> > +
>>> > +
>>> q[0]=p[2]^S5[IB(p[1])]^S6[ID(p[1])]^S7[IA(p[1])]^S8[IC(p[1])]^S7[IA(p[0])];
>>> > +
>>> q[1]=p[0]^S5[IA(q[0])]^S6[IC(q[0])]^S7[IB(q[0])]^S8[ID(q[0])]^S8[IC(p[0])];
>>> > +
>>> q[2]=p[1]^S5[ID(q[1])]^S6[IC(q[1])]^S7[IB(q[1])]^S8[IA(q[1])]^S5[IB(p[0])];
>>> > +
>>> q[3]=p[3]^S5[IC(q[2])]^S6[IB(q[2])]^S7[ID(q[2])]^S8[IA(q[2])]^S6[ID(p[0])];
>>> > +
>>> > +    if(rnds==16) {
>>> > +
>>> K[13]=S5[IA(q[2])]^S6[IB(q[2])]^S7[ID(q[1])]^S8[IC(q[1])]^S5[ID(q[0])];
>>> > +
>>> K[14]=S5[IC(q[2])]^S6[ID(q[2])]^S7[IB(q[1])]^S8[IA(q[1])]^S6[ID(q[1])];
>>> > +
>>> K[15]=S5[IA(q[3])]^S6[IB(q[3])]^S7[ID(q[0])]^S8[IC(q[0])]^S7[IA(q[2])];
>>> > +
>>> K[16]=S5[IC(q[3])]^S6[ID(q[3])]^S7[IB(q[0])]^S8[IA(q[0])]^S8[IB(q[3])];
>>> > +    }
>>> > +}
>>> > +
>>> > +int av_cast5_init(AVCAST5* cs, const uint8_t *key, int key_bits)
>>> > +{
>>> > +    uint8_t newKey[16];
>>> > +    int i;
>>> > +    uint32_t p[4],q[4];
>>>
>>> We need:
>>>
>>> memset(newKey, 0, sizeof(newKey));
>>>
>>> > +    if(key_bits%8!=0||key_bits<40||key_bits>128)
>>>
>>> if (key_bits % 8 || key_bits < 40 || key_bits > 128)
>>>
>>> > +        return -1;
>>> > +    memcpy(newKey,key,16*sizeof(key[0]));
>>>
>>> memcpy(newKey, key, key_bits / 8);
>>>
>>> > +    if (key_bits!=128) {
>>> > +        for(i=15;i>=key_bits/8;i--)
>>> > +            newKey[i]=0x00;
>>> > +    }
>>>
>>> This if() is not needed anymore, since we used memset() on newKey.
>>>
>>> > +    if(key_bits==128){
>>> > +        cs->rounds=16;
>>> > +    } else {
>>> > +        cs->rounds=12;
>>> > +    }
>>>
>>> cs->rounds = key_bits <= 80 ? 12 : 16;
>>>
>>> > +    for(i=0;i<4;i++)
>>> > +        q[i]=AV_RB32(newKey+(4*i));
>>> > +    GenerateRoundKeys(cs->rounds,cs->Km,q,p);
>>> > +    GenerateRoundKeys(cs->rounds,cs->Kr,q,p);
>>> > +    for(i=0;i<cs->rounds;i++)
>>> > +        cs->Kr[i]=cs->Kr[i]&0x1f;
>>> > +    return 0;
>>> > +}
>>> > +
>>> > +static void encipher(AVCAST5* cs,uint8_t* dst,const uint8_t* src)
>>> > +{
>>> > +    int i;
>>> > +    uint32_t temp,sdst[2];
>>> > +    sdst[0]=AV_RB32(src);
>>> > +    sdst[1]=AV_RB32(src+4);
>>> > +    for(i=1;i<=cs->rounds;i++){
>>> > +        temp=sdst[1];
>>> > +        sdst[1]=sdst[0]^(func(sdst[1],cs->Km[i],cs->Kr[i],i));
>>> > +        sdst[0]=temp;
>>> > +    }
>>> > +    AV_WB32(dst,sdst[1]);
>>> > +    AV_WB32(dst+4,sdst[0]);
>>> > +}
>>> > +
>>> > +static void decipher(AVCAST5* cs,uint8_t* dst,const uint8_t* src)
>>> > +{
>>> > +    int i;
>>> > +    uint32_t temp,sdst[2];
>>> > +    sdst[0]=AV_RB32(src);
>>> > +    sdst[1]=AV_RB32(src+4);
>>> > +    for(i=cs->rounds;i>0;i--){
>>> > +        temp=sdst[1];
>>> > +        sdst[1]=sdst[0]^(func(sdst[1],cs->Km[i],cs->Kr[i],i));
>>> > +        sdst[0]=temp;
>>> > +    }
>>> > +    AV_WB32(dst,sdst[1]);
>>> > +    AV_WB32(dst+4,sdst[0]);
>>> > +}
>>> > +
>>> > +void av_cast5_crypt(AVCAST5* cs, uint8_t* dst, const uint8_t* src,
>>> int count, int decrypt)
>>> > +{
>>> > +    while(count--)
>>> > +    {
>>> > +        if(decrypt){
>>> > +            decipher(cs,dst,src);
>>> > +        } else {
>>> > +            encipher(cs,dst,src);
>>> > +        }
>>> > +        src=src+8;
>>> > +        dst=dst+8;
>>> > +    }
>>> > +}
>>> > +
>>> > +#include<stdio.h>
>>> > +#include<stdlib.h>
>>> > +#include"log.h"
>>>
>>> > +#include"lfg.h"
>>>
>>> Not sure we need lfg.h?
>>>
>>> > +
>>> > +#ifdef TEST
>>> > +int main(int argc, char** argv)
>>> > +{
>>> > +    AVCAST5 cs;
>>> > +    uint8_t
>>> Key[3][16]={{0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9a},
>>> > +        {0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,0x23,0x45},
>>> > +        {0x01,0x23,0x45,0x67,0x12}};
>>> > +    uint8_t rpt[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
>>> > +    uint8_t rct[3][8]={{0x23,0x8b,0x4f,0xe5,0x84,0x7e,0x44,0xb2},
>>> > +        {0xeb,0x6a,0x71,0x1a,0x2c,0x02,0x27,0x1b},
>>> > +        {0x7a,0xc8,0x16,0xd1,0x6e,0x9b,0x30,0x2e}};
>>> > +    int i,err=0;
>>> > +    uint8_t temp[8];
>>> > +    av_log_set_level(AV_LOG_DEBUG);
>>> > +    av_cast5_init(&cs,Key[0],128);
>>> > +    av_cast5_crypt(&cs,temp,rpt,1,0);
>>> > +    for(i=0;i<8;i++){
>>> > +        if(rct[0][i]!=temp[i]){
>>> > +            av_log(NULL,AV_LOG_ERROR,"%d %02x
>>> %02x\n",i,rct[0][i],temp[i]);
>>> > +            err=1;
>>> > +        }
>>> > +    }
>>> > +    av_cast5_crypt(&cs,temp,rct[0],1,1);
>>> > +    for(i=0;i<8;i++){
>>> > +        if(rpt[i]!=temp[i]){
>>> > +            av_log(NULL,AV_LOG_ERROR,"%d %02x
>>> %02x\n",i,rpt[i],temp[i]);
>>> > +            err=1;
>>> > +        }
>>> > +    }
>>> > +    av_cast5_init(&cs,Key[1],80);
>>> > +    av_cast5_crypt(&cs,temp,rpt,1,0);
>>> > +    for(i=0;i<8;i++){
>>> > +        if(rct[1][i]!=temp[i]){
>>> > +            av_log(NULL,AV_LOG_ERROR,"%d %02x
>>> %02x\n",i,rct[1][i],temp[i]);
>>> > +            err=1;
>>> > +        }
>>> > +    }
>>> > +    av_cast5_crypt(&cs,temp,rct[1],1,1);
>>> > +    for(i=0;i<8;i++){
>>> > +        if(rpt[i]!=temp[i]){
>>> > +            av_log(NULL,AV_LOG_ERROR,"%d %02x
>>> %02x\n",i,rpt[i],temp[i]);
>>> > +            err=1;
>>> > +        }
>>> > +    }
>>> > +    av_cast5_init(&cs,Key[2],40);
>>> > +    av_cast5_crypt(&cs,temp,rpt,1,0);
>>> > +    for(i=0;i<8;i++){
>>> > +        if(rct[2][i]!=temp[i]){
>>> > +            av_log(NULL,AV_LOG_ERROR,"%d %02x
>>> %02x\n",i,rct[2][i],temp[i]);
>>> > +            err=1;
>>> > +        }
>>> > +    }
>>> > +    av_cast5_crypt(&cs,temp,rct[2],1,1);
>>> > +    for(i=0;i<8;i++){
>>> > +        if(rpt[i]!=temp[i]){
>>> > +            av_log(NULL,AV_LOG_ERROR,"%d %02x
>>> %02x\n",i,rpt[i],temp[i]);
>>> > +            err=1;
>>> > +        }
>>> > +    }
>>> > +    return err;
>>> > +}
>>> > +
>>> > +#endif
>>> > +
>>> > +
>>> > +
>>> > +
>>> > +
>>> > +
>>> > diff --git a/libavutil/cast5.h b/libavutil/cast5.h
>>> > new file mode 100644
>>> > index 0000000..d2196b9
>>> > --- /dev/null
>>> > +++ b/libavutil/cast5.h
>>> > @@ -0,0 +1,37 @@
>>> > +/*
>>> > + * An implementation of the CAST128 algorithm
>>> > + * Copyright (c) 2014 Supraja Meedinti
>>> > + *
>>> > + * This file is part of FFmpeg.
>>> > + *
>>> > + * FFmpeg is free software; you can redistribute it and/or
>>> > + * modify it under the terms of the GNU Lesser General Public
>>> > + * License as published by the Free Software Foundation; either
>>> > + * version 2.1 of the License, or (at your option) any later version.
>>> > + *
>>> > + * FFmpeg is distributed in the hope that it will be useful,
>>> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>>> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>>> > + * Lesser General Public License for more details.
>>> > + *
>>> > + * You should have received a copy of the GNU Lesser General Public
>>> > + * License along with FFmpeg; if not, write to the Free Software
>>> > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
>>> 02110-1301 USA
>>> > + */
>>> > +
>>> > +#ifndef AVUTIL_CAST5_H
>>> > +#define AVUTIL_CAST5_H
>>> > +
>>> > +#include <stdint.h>
>>> > +
>>> > +#include "attributes.h"
>>> > +#include "version.h"
>>> > +
>>> > +struct AVCAST5;
>>> > +
>>> > +int av_cast5_init(struct AVCAST5 *a, const uint8_t *key, int
>>> key_bits);
>>> > +
>>> > +void av_cast5_crypt(struct AVCAST5 *a, uint8_t *dst, const uint8_t
>>> *src, int count,int decrypt);
>>> > +
>>> > +
>>> > +#endif
>>> > --
>>> > 1.8.3.2
>>> >
>>> _______________________________________________
>>> ffmpeg-devel mailing list
>>> ffmpeg-devel at ffmpeg.org
>>> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>>>
>>
>>
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Add-CAST128-symmetric-block-cipher-to-libavutil-n-nO.patch
Type: text/x-patch
Size: 39842 bytes
Desc: not available
URL: <https://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20141016/61512662/attachment.bin>


More information about the ffmpeg-devel mailing list