diff options
author | Jan Gerber <j@v2v.cc> | 2013-11-15 19:00:37 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2014-01-07 03:05:29 +0100 |
commit | 95b5496dce829615ad7fac7dcdf6c781a72bcb8c (patch) | |
tree | eba459f8a80133a89bf0b41fdae09141d2763bce | |
parent | 3ffd1c2e40b6ef1c80669a180b6c74105e0569eb (diff) | |
download | ffmpeg-95b5496dce829615ad7fac7dcdf6c781a72bcb8c.tar.gz |
lavf/matroska*: add support for signed integers
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit d03eea36b2c329241f63c8aca2d6adbb6ea81d9c)
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 0ed8316dd9..6bc6d23243 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 671e01ee61..021098bd8c 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); |