]> git.sesse.net Git - x264/blobdiff - output/matroska_ebml.c
arm: Implement x264_mbtree_propagate_{cost, list}_neon
[x264] / output / matroska_ebml.c
index 7265909430c90897034f14219e346b3bb9c8f8a0..dc0d44d0a041ca817fca950f91d7921289d00ffb 100644 (file)
@@ -1,7 +1,9 @@
 /*****************************************************************************
- * matroska_ebml.c:
+ * matroska_ebml.c: matroska muxer utilities
  *****************************************************************************
- * Copyright (C) 2005 Mike Matsnev
+ * Copyright (C) 2005-2015 x264 project
+ *
+ * Authors: Mike Matsnev <mike@haali.su>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
+ *
+ * This program is also available under a commercial proprietary license.
+ * For more information, contact us at licensing@x264.com.
  *****************************************************************************/
 
-#include "muxers.h"
+#include "output.h"
 #include "matroska_ebml.h"
 
 #define CLSIZE 1048576
@@ -69,10 +74,9 @@ static mk_context *mk_create_context( mk_writer *w, mk_context *parent, unsigned
     }
     else
     {
-        c = malloc( sizeof(*c) );
+        c = calloc( 1, sizeof(mk_context) );
         if( !c )
             return NULL;
-        memset( c, 0, sizeof(*c) );
     }
 
     c->parent = parent;
@@ -208,16 +212,16 @@ static int mk_close_context( mk_context *c, unsigned *off )
 
 static void mk_destroy_contexts( mk_writer *w )
 {
-    mk_context *cur, *next;
+    mk_context *next;
 
-    for( cur = w->freelist; cur; cur = next )
+    for( mk_context *cur = w->freelist; cur; cur = next )
     {
         next = cur->next;
         free( cur->data );
         free( cur );
     }
 
-    for( cur = w->actlist; cur; cur = next )
+    for( mk_context *cur = w->actlist; cur; cur = next )
     {
         next = cur->next;
         free( cur->data );
@@ -286,12 +290,10 @@ static int mk_write_float( mk_context *c, unsigned id, float f )
 
 mk_writer *mk_create_writer( const char *filename )
 {
-    mk_writer *w = malloc( sizeof(*w) );
+    mk_writer *w = calloc( 1, sizeof(mk_writer) );
     if( !w )
         return NULL;
 
-    memset( w, 0, sizeof(*w) );
-
     w->root = mk_create_context( w, NULL, 0 );
     if( !w->root )
     {
@@ -302,7 +304,7 @@ mk_writer *mk_create_writer( const char *filename )
     if( !strcmp( filename, "-" ) )
         w->fp = stdout;
     else
-        w->fp = fopen( filename, "wb" );
+        w->fp = x264_fopen( filename, "wb" );
     if( !w->fp )
     {
         mk_destroy_contexts( w );
@@ -315,13 +317,13 @@ mk_writer *mk_create_writer( const char *filename )
     return w;
 }
 
-int mk_writeHeader( mk_writer *w, const char *writing_app,
-                    const char *codec_id,
-                    const void *codec_private, unsigned codec_private_size,
-                    int64_t default_frame_duration,
-                    int64_t timescale,
-                    unsigned width, unsigned height,
-                    unsigned d_width, unsigned d_height )
+int mk_write_header( mk_writer *w, const char *writing_app,
+                     const char *codec_id,
+                     const void *codec_private, unsigned codec_private_size,
+                     int64_t default_frame_duration,
+                     int64_t timescale,
+                     unsigned width, unsigned height,
+                     unsigned d_width, unsigned d_height, int display_size_units, int stereo_mode )
 {
     mk_context  *c, *ti, *v;
 
@@ -338,8 +340,8 @@ int mk_writeHeader( mk_writer *w, const char *writing_app,
     CHECK( mk_write_uint( c, 0x42f2, 4 ) ); // EBMLMaxIDLength
     CHECK( mk_write_uint( c, 0x42f3, 8 ) ); // EBMLMaxSizeLength
     CHECK( mk_write_string( c, 0x4282, "matroska") ); // DocType
-    CHECK( mk_write_uint( c, 0x4287, 1 ) ); // DocTypeVersion
-    CHECK( mk_write_uint( c, 0x4285, 1 ) ); // DocTypeReadversion
+    CHECK( mk_write_uint( c, 0x4287, stereo_mode >= 0 ? 3 : 2 ) ); // DocTypeVersion
+    CHECK( mk_write_uint( c, 0x4285, 2 ) ); // DocTypeReadVersion
     CHECK( mk_close_context( c, 0 ) );
 
     if( !(c = mk_create_context( w, w->root, 0x18538067 )) ) // Segment
@@ -349,14 +351,14 @@ int mk_writeHeader( mk_writer *w, const char *writing_app,
 
     if( !(c = mk_create_context( w, w->root, 0x1549a966 )) ) // SegmentInfo
         return -1;
-    CHECK( mk_write_string( c, 0x4d80, "Haali Matroska Writer b0" ) );
-    CHECK( mk_write_string( c, 0x5741, writing_app ) );
-    CHECK( mk_write_uint( c, 0x2ad7b1, w->timescale ) );
-    CHECK( mk_write_float( c, 0x4489, 0) );
+    CHECK( mk_write_string( c, 0x4d80, "Haali Matroska Writer b0" ) ); // MuxingApp
+    CHECK( mk_write_string( c, 0x5741, writing_app ) ); // WritingApp
+    CHECK( mk_write_uint( c, 0x2ad7b1, w->timescale ) ); // TimecodeScale
+    CHECK( mk_write_float( c, 0x4489, 0) ); // Duration
     w->duration_ptr = c->d_cur - 4;
     CHECK( mk_close_context( c, &w->duration_ptr ) );
 
-    if( !(c = mk_create_context( w, w->root, 0x1654ae6b )) ) // tracks
+    if( !(c = mk_create_context( w, w->root, 0x1654ae6b )) ) // Tracks
         return -1;
     if( !(ti = mk_create_context( w, c, 0xae )) ) // TrackEntry
         return -1;
@@ -364,18 +366,21 @@ int mk_writeHeader( mk_writer *w, const char *writing_app,
     CHECK( mk_write_uint( ti, 0x73c5, 1 ) ); // TrackUID
     CHECK( mk_write_uint( ti, 0x83, 1 ) ); // TrackType
     CHECK( mk_write_uint( ti, 0x9c, 0 ) ); // FlagLacing
-    CHECK( mk_write_string( ti, 0x86, codec_id ) ); // codec_id
+    CHECK( mk_write_string( ti, 0x86, codec_id ) ); // CodecID
     if( codec_private_size )
-        CHECK( mk_write_bin( ti, 0x63a2, codec_private, codec_private_size ) ); // codec_private
+        CHECK( mk_write_bin( ti, 0x63a2, codec_private, codec_private_size ) ); // CodecPrivate
     if( default_frame_duration )
         CHECK( mk_write_uint( ti, 0x23e383, default_frame_duration ) ); // DefaultDuration
 
     if( !(v = mk_create_context( w, ti, 0xe0 ) ) ) // Video
         return -1;
-    CHECK( mk_write_uint( v, 0xb0, width ) );
-    CHECK( mk_write_uint( v, 0xba, height ) );
-    CHECK( mk_write_uint( v, 0x54b0, d_width ) );
-    CHECK( mk_write_uint( v, 0x54ba, d_height ) );
+    CHECK( mk_write_uint( v, 0xb0, width ) ); // PixelWidth
+    CHECK( mk_write_uint( v, 0xba, height ) ); // PixelHeight
+    CHECK( mk_write_uint( v, 0x54b2, display_size_units ) ); // DisplayUnit
+    CHECK( mk_write_uint( v, 0x54b0, d_width ) ); // DisplayWidth
+    CHECK( mk_write_uint( v, 0x54ba, d_height ) ); // DisplayHeight
+    if( stereo_mode >= 0 )
+        CHECK( mk_write_uint( v, 0x53b8, stereo_mode ) ); // StereoMode
     CHECK( mk_close_context( v, 0 ) );
 
     CHECK( mk_close_context( ti, 0 ) );
@@ -427,16 +432,16 @@ static int mk_flush_frame( mk_writer *w )
     fsize = w->frame ? w->frame->d_cur : 0;
 
     CHECK( mk_write_id( w->cluster, 0xa3 ) ); // SimpleBlock
-    CHECK( mk_write_size( w->cluster, fsize + 4 ) );
-    CHECK( mk_write_size( w->cluster, 1 ) ); // track number
+    CHECK( mk_write_size( w->cluster, fsize + 4 ) ); // Size
+    CHECK( mk_write_size( w->cluster, 1 ) ); // TrackNumber
 
     c_delta_flags[0] = delta >> 8;
     c_delta_flags[1] = delta;
     c_delta_flags[2] = (w->keyframe << 7) | w->skippable;
-    CHECK( mk_append_context_data( w->cluster, c_delta_flags, 3 ) );
+    CHECK( mk_append_context_data( w->cluster, c_delta_flags, 3 ) ); // Timecode, Flags
     if( w->frame )
     {
-        CHECK( mk_append_context_data( w->cluster, w->frame->data, w->frame->d_cur ) );
+        CHECK( mk_append_context_data( w->cluster, w->frame->data, w->frame->d_cur ) ); // Data
         w->frame->d_cur = 0;
     }