diff --git a/libmkv/EbmlWriter.c b/libmkv/EbmlWriter.c index ac70d097d1b771d2819df7001903f2bc1192d042..fbf2c66e90cf093c588233d6da46a9ba674c7471 100644 --- a/libmkv/EbmlWriter.c +++ b/libmkv/EbmlWriter.c @@ -11,6 +11,7 @@ #include <stdlib.h> #include <wchar.h> #include <string.h> +#include <limits.h> #if defined(_MSC_VER) #define LITERALU64(n) n #else @@ -33,7 +34,7 @@ void Ebml_WriteLen(EbmlGlobal *glob, long long val) val |= (LITERALU64(0x000000000000080) << ((size - 1) * 7)); - Ebml_Serialize(glob, (void *) &val, size); + Ebml_Serialize(glob, (void *) &val, sizeof(val), size); } void Ebml_WriteString(EbmlGlobal *glob, const char *str) @@ -60,21 +61,26 @@ void Ebml_WriteUTF8(EbmlGlobal *glob, const wchar_t *wstr) void Ebml_WriteID(EbmlGlobal *glob, unsigned long class_id) { + int len; + if (class_id >= 0x01000000) - Ebml_Serialize(glob, (void *)&class_id, 4); + len = 4; else if (class_id >= 0x00010000) - Ebml_Serialize(glob, (void *)&class_id, 3); + len = 3; else if (class_id >= 0x00000100) - Ebml_Serialize(glob, (void *)&class_id, 2); + len = 2; else - Ebml_Serialize(glob, (void *)&class_id, 1); + len = 1; + + Ebml_Serialize(glob, (void *)&class_id, sizeof(class_id), len); } + void Ebml_SerializeUnsigned64(EbmlGlobal *glob, unsigned long class_id, uint64_t ui) { unsigned char sizeSerialized = 8 | 0x80; Ebml_WriteID(glob, class_id); - Ebml_Serialize(glob, &sizeSerialized, 1); - Ebml_Serialize(glob, &ui, 8); + Ebml_Serialize(glob, &sizeSerialized, sizeof(sizeSerialized), 1); + Ebml_Serialize(glob, &ui, sizeof(ui), 8); } void Ebml_SerializeUnsigned(EbmlGlobal *glob, unsigned long class_id, unsigned long ui) @@ -97,8 +103,8 @@ void Ebml_SerializeUnsigned(EbmlGlobal *glob, unsigned long class_id, unsigned l } sizeSerialized = 0x80 | size; - Ebml_Serialize(glob, &sizeSerialized, 1); - Ebml_Serialize(glob, &ui, size); + Ebml_Serialize(glob, &sizeSerialized, sizeof(sizeSerialized), 1); + Ebml_Serialize(glob, &ui, sizeof(ui), size); } //TODO: perhaps this is a poor name for this id serializer helper function void Ebml_SerializeBinary(EbmlGlobal *glob, unsigned long class_id, unsigned long bin) @@ -119,14 +125,14 @@ void Ebml_SerializeFloat(EbmlGlobal *glob, unsigned long class_id, double d) unsigned char len = 0x88; Ebml_WriteID(glob, class_id); - Ebml_Serialize(glob, &len, 1); - Ebml_Serialize(glob, &d, 8); + Ebml_Serialize(glob, &len, sizeof(len), 1); + Ebml_Serialize(glob, &d, sizeof(d), 8); } void Ebml_WriteSigned16(EbmlGlobal *glob, short val) { signed long out = ((val & 0x003FFFFF) | 0x00200000) << 8; - Ebml_Serialize(glob, &out, 3); + Ebml_Serialize(glob, &out, sizeof(out), 3); } void Ebml_SerializeString(EbmlGlobal *glob, unsigned long class_id, const char *s) diff --git a/libmkv/EbmlWriter.h b/libmkv/EbmlWriter.h index 8c7fe7c666aa02992b41bd74de145adbd078a4bc..324c9bca036ff888b1c79d38a98854ede749554a 100644 --- a/libmkv/EbmlWriter.h +++ b/libmkv/EbmlWriter.h @@ -15,7 +15,7 @@ #include "vpx/vpx_integer.h" typedef struct EbmlGlobal EbmlGlobal; -void Ebml_Serialize(EbmlGlobal *glob, const void *, unsigned long); +void Ebml_Serialize(EbmlGlobal *glob, const void *, int, unsigned long); void Ebml_Write(EbmlGlobal *glob, const void *, unsigned long); ///// diff --git a/libmkv/WebMElement.c b/libmkv/WebMElement.c index 25a90249ad9fef8f60cb7394633b44b893f487b5..0ef5100bb35976af1d8836b638711ee703b93b07 100644 --- a/libmkv/WebMElement.c +++ b/libmkv/WebMElement.c @@ -35,11 +35,11 @@ void writeSimpleBlock(EbmlGlobal *glob, unsigned char trackNumber, short timeCod Ebml_WriteID(glob, SimpleBlock); unsigned long blockLength = 4 + dataLength; blockLength |= 0x10000000; //TODO check length < 0x0FFFFFFFF - Ebml_Serialize(glob, &blockLength, 4); + Ebml_Serialize(glob, &blockLength, sizeof(blockLength), 4); trackNumber |= 0x80; //TODO check track nubmer < 128 Ebml_Write(glob, &trackNumber, 1); //Ebml_WriteSigned16(glob, timeCode,2); //this is 3 bytes - Ebml_Serialize(glob, &timeCode, 2); + Ebml_Serialize(glob, &timeCode, sizeof(timeCode), 2); unsigned char flags = 0x00 | (isKeyframe ? 0x80 : 0x00) | (lacingFlag << 1) | discardable; Ebml_Write(glob, &flags, 1); Ebml_Write(glob, data, dataLength); diff --git a/vpxenc.c b/vpxenc.c index 042f07b81344993867598ace09dcfa0ba2c3c427..a3c8eadc0a9fef3ea6b920547526c4e7bbae803e 100644 --- a/vpxenc.c +++ b/vpxenc.c @@ -501,15 +501,42 @@ void Ebml_Write(EbmlGlobal *glob, const void *buffer_in, unsigned long len) if(fwrite(buffer_in, 1, len, glob->stream)); } - -void Ebml_Serialize(EbmlGlobal *glob, const void *buffer_in, unsigned long len) +#define WRITE_BUFFER(s) \ +for(i = len-1; i>=0; i--)\ +{ \ + x = *(const s *)buffer_in >> (i * CHAR_BIT); \ + Ebml_Write(glob, &x, 1); \ +} +void Ebml_Serialize(EbmlGlobal *glob, const void *buffer_in, int buffer_size, unsigned long len) { - const unsigned char *q = (const unsigned char *)buffer_in + len - 1; + char x; + int i; - for(; len; len--) - Ebml_Write(glob, q--, 1); + /* buffer_size: + * 1 - int8_t; + * 2 - int16_t; + * 3 - int32_t; + * 4 - int64_t; + */ + switch (buffer_size) + { + case 1: + WRITE_BUFFER(int8_t) + break; + case 2: + WRITE_BUFFER(int16_t) + break; + case 4: + WRITE_BUFFER(int32_t) + break; + case 8: + WRITE_BUFFER(int64_t) + break; + default: + break; + } } - +#undef WRITE_BUFFER /* Need a fixed size serializer for the track ID. libmkv provdes a 64 bit * one, but not a 32 bit one. @@ -518,8 +545,8 @@ static void Ebml_SerializeUnsigned32(EbmlGlobal *glob, unsigned long class_id, u { unsigned char sizeSerialized = 4 | 0x80; Ebml_WriteID(glob, class_id); - Ebml_Serialize(glob, &sizeSerialized, 1); - Ebml_Serialize(glob, &ui, 4); + Ebml_Serialize(glob, &sizeSerialized, sizeof(sizeSerialized), 1); + Ebml_Serialize(glob, &ui, sizeof(ui), 4); } @@ -533,7 +560,7 @@ Ebml_StartSubElement(EbmlGlobal *glob, EbmlLoc *ebmlLoc, Ebml_WriteID(glob, class_id); *ebmlLoc = ftello(glob->stream); - Ebml_Serialize(glob, &unknownLen, 8); + Ebml_Serialize(glob, &unknownLen, sizeof(unknownLen), 8); } static void @@ -551,7 +578,7 @@ Ebml_EndSubElement(EbmlGlobal *glob, EbmlLoc *ebmlLoc) /* Seek back to the beginning of the element and write the new size */ fseeko(glob->stream, *ebmlLoc, SEEK_SET); - Ebml_Serialize(glob, &size, 8); + Ebml_Serialize(glob, &size, sizeof(size), 8); /* Reset the stream pointer */ fseeko(glob->stream, pos, SEEK_SET); @@ -741,13 +768,13 @@ write_webm_block(EbmlGlobal *glob, block_length = pkt->data.frame.sz + 4; block_length |= 0x10000000; - Ebml_Serialize(glob, &block_length, 4); + Ebml_Serialize(glob, &block_length, sizeof(block_length), 4); track_number = 1; track_number |= 0x80; Ebml_Write(glob, &track_number, 1); - Ebml_Serialize(glob, &block_timecode, 2); + Ebml_Serialize(glob, &block_timecode, sizeof(block_timecode), 2); flags = 0; if(is_keyframe)