Fix vpxenc encoding incorrect webm file header on big endian machines(Issue 331)
As reported in issue 331, vpxenc encoded incorrect webm file header on big endian machines. This change fixed that. Change-Id: I31924ebd476a87f3e88b9b5424540bf781d2b86f
This commit is contained in:
parent
587ca06da9
commit
c156a68d06
@ -11,6 +11,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <limits.h>
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#define LITERALU64(n) n
|
#define LITERALU64(n) n
|
||||||
#else
|
#else
|
||||||
@ -33,7 +34,7 @@ void Ebml_WriteLen(EbmlGlobal *glob, long long val)
|
|||||||
|
|
||||||
val |= (LITERALU64(0x000000000000080) << ((size - 1) * 7));
|
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)
|
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)
|
void Ebml_WriteID(EbmlGlobal *glob, unsigned long class_id)
|
||||||
{
|
{
|
||||||
|
int len;
|
||||||
|
|
||||||
if (class_id >= 0x01000000)
|
if (class_id >= 0x01000000)
|
||||||
Ebml_Serialize(glob, (void *)&class_id, 4);
|
len = 4;
|
||||||
else if (class_id >= 0x00010000)
|
else if (class_id >= 0x00010000)
|
||||||
Ebml_Serialize(glob, (void *)&class_id, 3);
|
len = 3;
|
||||||
else if (class_id >= 0x00000100)
|
else if (class_id >= 0x00000100)
|
||||||
Ebml_Serialize(glob, (void *)&class_id, 2);
|
len = 2;
|
||||||
else
|
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)
|
void Ebml_SerializeUnsigned64(EbmlGlobal *glob, unsigned long class_id, uint64_t ui)
|
||||||
{
|
{
|
||||||
unsigned char sizeSerialized = 8 | 0x80;
|
unsigned char sizeSerialized = 8 | 0x80;
|
||||||
Ebml_WriteID(glob, class_id);
|
Ebml_WriteID(glob, class_id);
|
||||||
Ebml_Serialize(glob, &sizeSerialized, 1);
|
Ebml_Serialize(glob, &sizeSerialized, sizeof(sizeSerialized), 1);
|
||||||
Ebml_Serialize(glob, &ui, 8);
|
Ebml_Serialize(glob, &ui, sizeof(ui), 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ebml_SerializeUnsigned(EbmlGlobal *glob, unsigned long class_id, unsigned long ui)
|
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;
|
sizeSerialized = 0x80 | size;
|
||||||
Ebml_Serialize(glob, &sizeSerialized, 1);
|
Ebml_Serialize(glob, &sizeSerialized, sizeof(sizeSerialized), 1);
|
||||||
Ebml_Serialize(glob, &ui, size);
|
Ebml_Serialize(glob, &ui, sizeof(ui), size);
|
||||||
}
|
}
|
||||||
//TODO: perhaps this is a poor name for this id serializer helper function
|
//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)
|
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;
|
unsigned char len = 0x88;
|
||||||
|
|
||||||
Ebml_WriteID(glob, class_id);
|
Ebml_WriteID(glob, class_id);
|
||||||
Ebml_Serialize(glob, &len, 1);
|
Ebml_Serialize(glob, &len, sizeof(len), 1);
|
||||||
Ebml_Serialize(glob, &d, 8);
|
Ebml_Serialize(glob, &d, sizeof(d), 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ebml_WriteSigned16(EbmlGlobal *glob, short val)
|
void Ebml_WriteSigned16(EbmlGlobal *glob, short val)
|
||||||
{
|
{
|
||||||
signed long out = ((val & 0x003FFFFF) | 0x00200000) << 8;
|
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)
|
void Ebml_SerializeString(EbmlGlobal *glob, unsigned long class_id, const char *s)
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
#include "vpx/vpx_integer.h"
|
#include "vpx/vpx_integer.h"
|
||||||
|
|
||||||
typedef struct EbmlGlobal EbmlGlobal;
|
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);
|
void Ebml_Write(EbmlGlobal *glob, const void *, unsigned long);
|
||||||
/////
|
/////
|
||||||
|
|
||||||
|
@ -35,11 +35,11 @@ void writeSimpleBlock(EbmlGlobal *glob, unsigned char trackNumber, short timeCod
|
|||||||
Ebml_WriteID(glob, SimpleBlock);
|
Ebml_WriteID(glob, SimpleBlock);
|
||||||
unsigned long blockLength = 4 + dataLength;
|
unsigned long blockLength = 4 + dataLength;
|
||||||
blockLength |= 0x10000000; //TODO check length < 0x0FFFFFFFF
|
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
|
trackNumber |= 0x80; //TODO check track nubmer < 128
|
||||||
Ebml_Write(glob, &trackNumber, 1);
|
Ebml_Write(glob, &trackNumber, 1);
|
||||||
//Ebml_WriteSigned16(glob, timeCode,2); //this is 3 bytes
|
//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;
|
unsigned char flags = 0x00 | (isKeyframe ? 0x80 : 0x00) | (lacingFlag << 1) | discardable;
|
||||||
Ebml_Write(glob, &flags, 1);
|
Ebml_Write(glob, &flags, 1);
|
||||||
Ebml_Write(glob, data, dataLength);
|
Ebml_Write(glob, data, dataLength);
|
||||||
|
53
vpxenc.c
53
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));
|
if(fwrite(buffer_in, 1, len, glob->stream));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define WRITE_BUFFER(s) \
|
||||||
void Ebml_Serialize(EbmlGlobal *glob, const void *buffer_in, unsigned long len)
|
for(i = len-1; i>=0; i--)\
|
||||||
{
|
{ \
|
||||||
const unsigned char *q = (const unsigned char *)buffer_in + len - 1;
|
x = *(const s *)buffer_in >> (i * CHAR_BIT); \
|
||||||
|
Ebml_Write(glob, &x, 1); \
|
||||||
for(; len; len--)
|
|
||||||
Ebml_Write(glob, q--, 1);
|
|
||||||
}
|
}
|
||||||
|
void Ebml_Serialize(EbmlGlobal *glob, const void *buffer_in, int buffer_size, unsigned long len)
|
||||||
|
{
|
||||||
|
char x;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* 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
|
/* Need a fixed size serializer for the track ID. libmkv provdes a 64 bit
|
||||||
* one, but not a 32 bit one.
|
* 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;
|
unsigned char sizeSerialized = 4 | 0x80;
|
||||||
Ebml_WriteID(glob, class_id);
|
Ebml_WriteID(glob, class_id);
|
||||||
Ebml_Serialize(glob, &sizeSerialized, 1);
|
Ebml_Serialize(glob, &sizeSerialized, sizeof(sizeSerialized), 1);
|
||||||
Ebml_Serialize(glob, &ui, 4);
|
Ebml_Serialize(glob, &ui, sizeof(ui), 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -533,7 +560,7 @@ Ebml_StartSubElement(EbmlGlobal *glob, EbmlLoc *ebmlLoc,
|
|||||||
|
|
||||||
Ebml_WriteID(glob, class_id);
|
Ebml_WriteID(glob, class_id);
|
||||||
*ebmlLoc = ftello(glob->stream);
|
*ebmlLoc = ftello(glob->stream);
|
||||||
Ebml_Serialize(glob, &unknownLen, 8);
|
Ebml_Serialize(glob, &unknownLen, sizeof(unknownLen), 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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 */
|
/* Seek back to the beginning of the element and write the new size */
|
||||||
fseeko(glob->stream, *ebmlLoc, SEEK_SET);
|
fseeko(glob->stream, *ebmlLoc, SEEK_SET);
|
||||||
Ebml_Serialize(glob, &size, 8);
|
Ebml_Serialize(glob, &size, sizeof(size), 8);
|
||||||
|
|
||||||
/* Reset the stream pointer */
|
/* Reset the stream pointer */
|
||||||
fseeko(glob->stream, pos, SEEK_SET);
|
fseeko(glob->stream, pos, SEEK_SET);
|
||||||
@ -741,13 +768,13 @@ write_webm_block(EbmlGlobal *glob,
|
|||||||
|
|
||||||
block_length = pkt->data.frame.sz + 4;
|
block_length = pkt->data.frame.sz + 4;
|
||||||
block_length |= 0x10000000;
|
block_length |= 0x10000000;
|
||||||
Ebml_Serialize(glob, &block_length, 4);
|
Ebml_Serialize(glob, &block_length, sizeof(block_length), 4);
|
||||||
|
|
||||||
track_number = 1;
|
track_number = 1;
|
||||||
track_number |= 0x80;
|
track_number |= 0x80;
|
||||||
Ebml_Write(glob, &track_number, 1);
|
Ebml_Write(glob, &track_number, 1);
|
||||||
|
|
||||||
Ebml_Serialize(glob, &block_timecode, 2);
|
Ebml_Serialize(glob, &block_timecode, sizeof(block_timecode), 2);
|
||||||
|
|
||||||
flags = 0;
|
flags = 0;
|
||||||
if(is_keyframe)
|
if(is_keyframe)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user