shithub: libvpx

Download patch

ref: c156a68d06ace37b87d91c97774e06c05bee1f08
parent: 587ca06da9d652d60309679c14a1c0b310c93c66
author: Yunqing Wang <yunqingwang@google.com>
date: Tue Jul 12 10:34:51 EDT 2011

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

--- 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 @@
 
     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_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 @@
     }
 
     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 @@
     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)
--- 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);
 /////
 
--- a/libmkv/WebMElement.c
+++ b/libmkv/WebMElement.c
@@ -35,11 +35,11 @@
     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);
--- a/vpxenc.c
+++ b/vpxenc.c
@@ -501,16 +501,43 @@
     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 @@
 {
     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_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 @@
 
     /* 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 @@
 
     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)