[FFmpeg-devel] lavf/matroska*: add support for signed integers

Michael Niedermayer michaelni at gmx.at
Fri Nov 15 17:42:32 CET 2013


On Fri, Nov 15, 2013 at 05:33:22PM +0100, Jan Gerber wrote:
> On 11/15/2013 04:37 PM, Michael Niedermayer wrote:
> >> +    int n = 0;
> >> +
> >> +    if (size > 8)
> >> +        return AVERROR_INVALIDDATA;
> >> +
> >> +    *num = avio_r8(pb);
> >> +    if (*num & 0x80) {
> >> +        *num = -1;
> >> +    } else {
> >> +        *num = 0;
> >> +    }
> > 
> > this discards the 7 less significant bits
> > i think these contain bits from the number to be read
> 
> indeed.
> 

>  matroskadec.c |   32 +++++++++++++++++++++++++++++++-
>  matroskaenc.c |   21 +++++++++++++++++++++
>  2 files changed, 52 insertions(+), 1 deletion(-)
> 13662a2dbf120fa0fd4fcfe6c9e45897d56fc2bd  0001-lavf-matroska-add-support-for-signed-integers.patch
> diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
> index f770d67..ad7ff4f 100644
> --- a/libavformat/matroskadec.c
> +++ b/libavformat/matroskadec.c
> @@ -62,7 +62,8 @@ typedef enum {
>      EBML_NEST,
>      EBML_PASS,
>      EBML_STOP,
> -    EBML_TYPE_COUNT
> +    EBML_TYPE_COUNT,
> +    EBML_SINT,
>  } EbmlType;
>  
>  typedef const struct EbmlSyntax {

EBML_TYPE_COUNT is the number of enum types its used as size for
some array


> @@ -759,6 +760,34 @@ static int ebml_read_uint(AVIOContext *pb, int size, uint64_t *num)
>  }
>  
>  /*
> + * Read the next element as a signed int.
> + * 0 is success, < 0 is failure.
> + */
> +static int ebml_read_sint(AVIOContext *pb, int size, int64_t *num)
> +{
> +    int n = 1;
> +
> +    if (size > 8)
> +        return AVERROR_INVALIDDATA;
> +
> +    if (size == 0) {
> +        *num = 0;
> +    } else {
> +        *num = avio_r8(pb);
> +        /* negative value */
> +        if (*num & 0x80) {
> +            *num = (-1 << 8) | *num;
> +        }

can be simplified with sign_extend()


> +
> +        /* big-endian ordering; build up number */
> +        while (n++ < size)
> +            *num = (*num << 8) | avio_r8(pb);
> +    }
> +
> +    return 0;
> +}
> +
> +/*
>   * Read the next element as a float.
>   * 0 is success, < 0 is failure.
>   */
> @@ -985,6 +1014,7 @@ static int ebml_parse_elem(MatroskaDemuxContext *matroska,
>  
>      switch (syntax->type) {
>      case EBML_UINT:  res = ebml_read_uint  (pb, length, data);  break;
> +    case EBML_SINT:  res = ebml_read_sint  (pb, length, data);  break;
>      case EBML_FLOAT: res = ebml_read_float (pb, length, data);  break;
>      case EBML_STR:
>      case EBML_UTF8:  res = ebml_read_ascii (pb, length, data);  break;
> diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
> index d8355b2..8db4795 100644
> --- a/libavformat/matroskaenc.c
> +++ b/libavformat/matroskaenc.c
> @@ -202,6 +202,27 @@ static void put_ebml_uint(AVIOContext *pb, unsigned int elementid, uint64_t val)
>          avio_w8(pb, (uint8_t)(val >> i*8));
>  }
>  
> +static void put_ebml_sint(AVIOContext *pb, unsigned int elementid, int64_t val)
> +{
> +    int i, bytes = 1;
> +    uint64_t uval = (val < 0 ? (-val - 1) << 1 : val << 1);
> +    while (uval>>=8) bytes++;
> +

> +    /* make unsigned */
> +    if (val >= 0) {
> +        uval = val;
> +    } else {
> +        uval = 0x80 << (bytes - 1);
> +        uval += val;
> +        uval |= 0x80 << (bytes - 1);
> +    }

this should not be needed
signed integers are already in twos complement, simply storing them
bytewise should work

> +
> +    put_ebml_id(pb, elementid);
> +    put_ebml_num(pb, bytes, 0);
> +    for (i = bytes - 1; i >= 0; i--)
> +        avio_w8(pb, (uint8_t)(uval >> i*8));





> +}
> +
>  static void put_ebml_float(AVIOContext *pb, unsigned int elementid, double val)
>  {
>      put_ebml_id(pb, elementid);

> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Opposition brings concord. Out of discord comes the fairest harmony.
-- Heraclitus
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20131115/96df995e/attachment.asc>


More information about the ffmpeg-devel mailing list