avformat/matroskaenc: Refactor writing EBML lengths

This commit factors the ability to write ordinary EBML numbers out of
the functions for writing EBML lengths. This is in preparation for
future commits.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
This commit is contained in:
Andreas Rheinhardt
2020-04-15 04:05:09 +02:00
parent 40d038a635
commit 112afaccdf

View File

@@ -189,18 +189,37 @@ static void put_ebml_size_unknown(AVIOContext *pb, int bytes)
ffio_fill(pb, 0xff, bytes - 1); ffio_fill(pb, 0xff, bytes - 1);
} }
/**
* Returns how many bytes are needed to represent a number
* as EBML variable length integer.
*/
static int ebml_num_size(uint64_t num)
{
int bytes = 0;
do {
bytes++;
} while (num >>= 7);
return bytes;
}
/** /**
* Calculate how many bytes are needed to represent the length field * Calculate how many bytes are needed to represent the length field
* of an EBML element whose payload has a given length. * of an EBML element whose payload has a given length.
*/ */
static int ebml_length_size(uint64_t length) static int ebml_length_size(uint64_t length)
{ {
int bytes = 0; return ebml_num_size(length + 1);
length++; }
do {
bytes++; /**
} while (length >>= 7); * Write a number as EBML variable length integer on `bytes` bytes.
return bytes; * `bytes` is taken literally without checking.
*/
static void put_ebml_num(AVIOContext *pb, uint64_t num, int bytes)
{
num |= 1ULL << bytes * 7;
for (int i = bytes - 1; i >= 0; i--)
avio_w8(pb, (uint8_t)(num >> i * 8));
} }
/** /**
@@ -211,7 +230,7 @@ static int ebml_length_size(uint64_t length)
*/ */
static void put_ebml_length(AVIOContext *pb, uint64_t length, int bytes) static void put_ebml_length(AVIOContext *pb, uint64_t length, int bytes)
{ {
int i, needed_bytes = ebml_length_size(length); int needed_bytes = ebml_length_size(length);
// sizes larger than this are currently undefined in EBML // sizes larger than this are currently undefined in EBML
av_assert0(length < (1ULL << 56) - 1); av_assert0(length < (1ULL << 56) - 1);
@@ -221,10 +240,7 @@ static void put_ebml_length(AVIOContext *pb, uint64_t length, int bytes)
// The bytes needed to write the given size must not exceed // The bytes needed to write the given size must not exceed
// the bytes that we ought to use. // the bytes that we ought to use.
av_assert0(bytes >= needed_bytes); av_assert0(bytes >= needed_bytes);
put_ebml_num(pb, length, bytes);
length |= 1ULL << bytes * 7;
for (i = bytes - 1; i >= 0; i--)
avio_w8(pb, (uint8_t)(length >> i * 8));
} }
/** /**