diff options
author | Jan Gerber <j@v2v.cc> | 2013-11-15 19:00:37 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2013-11-15 21:38:12 +0100 |
commit | d03eea36b2c329241f63c8aca2d6adbb6ea81d9c (patch) | |
tree | 3c284e1187b4074b7a0d1d75c08b536b8767b5db | |
parent | 5592d1b741924d375a04470eda8e601715e0d04c (diff) | |
download | ffmpeg-d03eea36b2c329241f63c8aca2d6adbb6ea81d9c.tar.gz |
lavf/matroska*: add support for signed integers
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavformat/matroskadec.c | 30 | ||||
-rw-r--r-- | libavformat/matroskaenc.c | 21 |
2 files changed, 51 insertions, 0 deletions
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index f770d67af7..6bb75457cb 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -62,6 +62,7 @@ typedef enum { EBML_NEST, EBML_PASS, EBML_STOP, + EBML_SINT, EBML_TYPE_COUNT } EbmlType; @@ -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; + } + + /* 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 d8355b23cc..8db4795d8c 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); + } + + 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); |