[x264-devel] commit: mkv: Write SimpleBlock instead of Block for frame headers ( Alexander Strange )

git version control git at videolan.org
Mon Feb 15 10:07:47 CET 2010


x264 | branch: master | Alexander Strange <astrange at ithinksw.com> | Sat Feb 13 01:41:41 2010 -0500| [f3de1741f1e38c6b0d4262e6290a20b3e35f6692] | committer: Jason Garrett-Glaser 

mkv: Write SimpleBlock instead of Block for frame headers

mkvtoolnix writes these by default since 2009/04/13.
Slightly simplifies muxer and allows 'mkvinfo -s' to show B-frames
as 'B' (but not B-ref frames).

> http://git.videolan.org/gitweb.cgi/x264.git/?a=commit;h=f3de1741f1e38c6b0d4262e6290a20b3e35f6692
---

 output/matroska.c      |    2 +-
 output/matroska_ebml.c |   80 ++++++++----------------------------------------
 output/matroska_ebml.h |    2 +-
 3 files changed, 15 insertions(+), 69 deletions(-)

diff --git a/output/matroska.c b/output/matroska.c
index 8e84f52..db7639c 100644
--- a/output/matroska.c
+++ b/output/matroska.c
@@ -185,7 +185,7 @@ static int write_frame( hnd_t handle, uint8_t *p_nalu, int i_size, x264_picture_
 
     p_mkv->b_writing_frame = 0;
 
-    if( mk_set_frame_flags( p_mkv->w, i_stamp, p_picture->b_keyframe ) < 0 )
+    if( mk_set_frame_flags( p_mkv->w, i_stamp, p_picture->b_keyframe, p_picture->i_type == X264_TYPE_B ) < 0 )
         return -1;
 
     return i_size;
diff --git a/output/matroska_ebml.c b/output/matroska_ebml.c
index d1c6e13..7265909 100644
--- a/output/matroska_ebml.c
+++ b/output/matroska_ebml.c
@@ -53,9 +53,9 @@ struct mk_writer
     int64_t def_duration;
     int64_t timescale;
     int64_t cluster_tc_scaled;
-    int64_t frame_tc, prev_frame_tc_scaled, max_frame_tc;
+    int64_t frame_tc, max_frame_tc;
 
-    char wrote_header, in_frame, keyframe;
+    char wrote_header, in_frame, keyframe, skippable;
 };
 
 static mk_context *mk_create_context( mk_writer *w, mk_context *parent, unsigned id )
@@ -258,23 +258,6 @@ static int mk_write_uint( mk_context *c, unsigned id, int64_t ui )
     return 0;
 }
 
-static int mk_write_sint( mk_context *c, unsigned id, int64_t si )
-{
-    unsigned char c_si[8] = { si >> 56, si >> 48, si >> 40, si >> 32, si >> 24, si >> 16, si >> 8, si };
-    unsigned i = 0;
-
-    CHECK( mk_write_id( c, id ) );
-    if( si < 0 )
-        while( i < 7 && c_si[i] == 0xff && c_si[i+1] & 0x80 )
-            ++i;
-    else
-        while( i < 7 && c_si[i] == 0 && !(c_si[i+1] & 0x80 ) )
-            ++i;
-    CHECK( mk_write_size( c, 8 - i ) );
-    CHECK( mk_append_context_data( c, c_si+i, 8 - i ) );
-    return 0;
-}
-
 static int mk_write_float_raw( mk_context *c, float f )
 {
     union
@@ -301,34 +284,6 @@ static int mk_write_float( mk_context *c, unsigned id, float f )
     return 0;
 }
 
-static unsigned mk_ebml_size_size( unsigned s )
-{
-    if( s < 0x7f )
-        return 1;
-    if( s < 0x3fff )
-        return 2;
-    if( s < 0x1fffff )
-        return 3;
-    if( s < 0x0fffffff )
-        return 4;
-    return 5;
-}
-
-static unsigned mk_ebml_sint_size( int64_t si )
-{
-    unsigned char c_si[8] = { si >> 56, si >> 48, si >> 40, si >> 32, si >> 24, si >> 16, si >> 8, si };
-    unsigned i = 0;
-
-    if( si < 0 )
-        while( i < 7 && c_si[i] == 0xff && c_si[i+1] & 0x80 )
-            ++i;
-    else
-        while( i < 7 && c_si[i] == 0 && !(c_si[i+1] & 0x80) )
-            ++i;
-
-    return 8 - i;
-}
-
 mk_writer *mk_create_writer( const char *filename )
 {
     mk_writer *w = malloc( sizeof(*w) );
@@ -446,8 +401,8 @@ static int mk_close_cluster( mk_writer *w )
 
 static int mk_flush_frame( mk_writer *w )
 {
-    int64_t delta, ref = 0;
-    unsigned fsize, bgsize;
+    int64_t delta;
+    unsigned fsize;
     unsigned char c_delta_flags[3];
 
     if( !w->in_frame )
@@ -470,33 +425,22 @@ static int mk_flush_frame( mk_writer *w )
     }
 
     fsize = w->frame ? w->frame->d_cur : 0;
-    bgsize = fsize + 4 + mk_ebml_size_size( fsize + 4 ) + 1;
-    if( !w->keyframe )
-    {
-        ref = w->prev_frame_tc_scaled - w->cluster_tc_scaled - delta;
-        bgsize += 1 + 1 + mk_ebml_sint_size( ref );
-    }
 
-    CHECK( mk_write_id( w->cluster, 0xa0 ) ); // BlockGroup
-    CHECK( mk_write_size( w->cluster, bgsize ) );
-    CHECK( mk_write_id( w->cluster, 0xa1 ) ); // Block
+    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
 
     c_delta_flags[0] = delta >> 8;
     c_delta_flags[1] = delta;
-    c_delta_flags[2] = 0;
+    c_delta_flags[2] = (w->keyframe << 7) | w->skippable;
     CHECK( mk_append_context_data( w->cluster, c_delta_flags, 3 ) );
     if( w->frame )
     {
         CHECK( mk_append_context_data( w->cluster, w->frame->data, w->frame->d_cur ) );
         w->frame->d_cur = 0;
     }
-    if( !w->keyframe )
-        CHECK( mk_write_sint( w->cluster, 0xfb, ref ) ); // ReferenceBlock
 
     w->in_frame = 0;
-    w->prev_frame_tc_scaled = w->cluster_tc_scaled + delta;
 
     if( w->cluster->d_cur > CLSIZE )
         CHECK( mk_close_cluster( w ) );
@@ -509,19 +453,21 @@ int mk_start_frame( mk_writer *w )
     if( mk_flush_frame( w ) < 0 )
         return -1;
 
-    w->in_frame = 1;
-    w->keyframe = 0;
+    w->in_frame  = 1;
+    w->keyframe  = 0;
+    w->skippable = 0;
 
     return 0;
 }
 
-int mk_set_frame_flags( mk_writer *w, int64_t timestamp, int keyframe )
+int mk_set_frame_flags( mk_writer *w, int64_t timestamp, int keyframe, int skippable )
 {
     if( !w->in_frame )
         return -1;
 
-    w->frame_tc = timestamp;
-    w->keyframe = keyframe != 0;
+    w->frame_tc  = timestamp;
+    w->keyframe  = keyframe  != 0;
+    w->skippable = skippable != 0;
 
     if( w->max_frame_tc < timestamp )
         w->max_frame_tc = timestamp;
diff --git a/output/matroska_ebml.h b/output/matroska_ebml.h
index 252e781..56eb8cc 100644
--- a/output/matroska_ebml.h
+++ b/output/matroska_ebml.h
@@ -35,7 +35,7 @@ int mk_writeHeader( mk_writer *w, const char *writing_app,
 
 int mk_start_frame( mk_writer *w );
 int mk_add_frame_data( mk_writer *w, const void *data, unsigned size );
-int mk_set_frame_flags( mk_writer *w, int64_t timestamp, int keyframe );
+int mk_set_frame_flags( mk_writer *w, int64_t timestamp, int keyframe, int skippable );
 int mk_close( mk_writer *w, int64_t last_delta );
 
 #endif



More information about the x264-devel mailing list