~ubuntu-branches/ubuntu/maverick/x264/maverick-updates

« back to all changes in this revision

Viewing changes to output/matroska_ebml.c

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2010-02-18 07:39:51 UTC
  • mto: This revision was merged to the branch mainline in revision 19.
  • Revision ID: james.westby@ubuntu.com-20100218073951-9jgsvskb976rfbvq
Tags: upstream-0.85.1442.1+git781d30
ImportĀ upstreamĀ versionĀ 0.85.1442.1+git781d30

Show diffs side-by-side

added added

removed removed

Lines of Context:
53
53
    int64_t def_duration;
54
54
    int64_t timescale;
55
55
    int64_t cluster_tc_scaled;
56
 
    int64_t frame_tc, prev_frame_tc_scaled, max_frame_tc;
 
56
    int64_t frame_tc, max_frame_tc;
57
57
 
58
 
    char wrote_header, in_frame, keyframe;
 
58
    char wrote_header, in_frame, keyframe, skippable;
59
59
};
60
60
 
61
61
static mk_context *mk_create_context( mk_writer *w, mk_context *parent, unsigned id )
258
258
    return 0;
259
259
}
260
260
 
261
 
static int mk_write_sint( mk_context *c, unsigned id, int64_t si )
262
 
{
263
 
    unsigned char c_si[8] = { si >> 56, si >> 48, si >> 40, si >> 32, si >> 24, si >> 16, si >> 8, si };
264
 
    unsigned i = 0;
265
 
 
266
 
    CHECK( mk_write_id( c, id ) );
267
 
    if( si < 0 )
268
 
        while( i < 7 && c_si[i] == 0xff && c_si[i+1] & 0x80 )
269
 
            ++i;
270
 
    else
271
 
        while( i < 7 && c_si[i] == 0 && !(c_si[i+1] & 0x80 ) )
272
 
            ++i;
273
 
    CHECK( mk_write_size( c, 8 - i ) );
274
 
    CHECK( mk_append_context_data( c, c_si+i, 8 - i ) );
275
 
    return 0;
276
 
}
277
 
 
278
261
static int mk_write_float_raw( mk_context *c, float f )
279
262
{
280
263
    union
301
284
    return 0;
302
285
}
303
286
 
304
 
static unsigned mk_ebml_size_size( unsigned s )
305
 
{
306
 
    if( s < 0x7f )
307
 
        return 1;
308
 
    if( s < 0x3fff )
309
 
        return 2;
310
 
    if( s < 0x1fffff )
311
 
        return 3;
312
 
    if( s < 0x0fffffff )
313
 
        return 4;
314
 
    return 5;
315
 
}
316
 
 
317
 
static unsigned mk_ebml_sint_size( int64_t si )
318
 
{
319
 
    unsigned char c_si[8] = { si >> 56, si >> 48, si >> 40, si >> 32, si >> 24, si >> 16, si >> 8, si };
320
 
    unsigned i = 0;
321
 
 
322
 
    if( si < 0 )
323
 
        while( i < 7 && c_si[i] == 0xff && c_si[i+1] & 0x80 )
324
 
            ++i;
325
 
    else
326
 
        while( i < 7 && c_si[i] == 0 && !(c_si[i+1] & 0x80) )
327
 
            ++i;
328
 
 
329
 
    return 8 - i;
330
 
}
331
 
 
332
287
mk_writer *mk_create_writer( const char *filename )
333
288
{
334
289
    mk_writer *w = malloc( sizeof(*w) );
446
401
 
447
402
static int mk_flush_frame( mk_writer *w )
448
403
{
449
 
    int64_t delta, ref = 0;
450
 
    unsigned fsize, bgsize;
 
404
    int64_t delta;
 
405
    unsigned fsize;
451
406
    unsigned char c_delta_flags[3];
452
407
 
453
408
    if( !w->in_frame )
470
425
    }
471
426
 
472
427
    fsize = w->frame ? w->frame->d_cur : 0;
473
 
    bgsize = fsize + 4 + mk_ebml_size_size( fsize + 4 ) + 1;
474
 
    if( !w->keyframe )
475
 
    {
476
 
        ref = w->prev_frame_tc_scaled - w->cluster_tc_scaled - delta;
477
 
        bgsize += 1 + 1 + mk_ebml_sint_size( ref );
478
 
    }
479
428
 
480
 
    CHECK( mk_write_id( w->cluster, 0xa0 ) ); // BlockGroup
481
 
    CHECK( mk_write_size( w->cluster, bgsize ) );
482
 
    CHECK( mk_write_id( w->cluster, 0xa1 ) ); // Block
 
429
    CHECK( mk_write_id( w->cluster, 0xa3 ) ); // SimpleBlock
483
430
    CHECK( mk_write_size( w->cluster, fsize + 4 ) );
484
431
    CHECK( mk_write_size( w->cluster, 1 ) ); // track number
485
432
 
486
433
    c_delta_flags[0] = delta >> 8;
487
434
    c_delta_flags[1] = delta;
488
 
    c_delta_flags[2] = 0;
 
435
    c_delta_flags[2] = (w->keyframe << 7) | w->skippable;
489
436
    CHECK( mk_append_context_data( w->cluster, c_delta_flags, 3 ) );
490
437
    if( w->frame )
491
438
    {
492
439
        CHECK( mk_append_context_data( w->cluster, w->frame->data, w->frame->d_cur ) );
493
440
        w->frame->d_cur = 0;
494
441
    }
495
 
    if( !w->keyframe )
496
 
        CHECK( mk_write_sint( w->cluster, 0xfb, ref ) ); // ReferenceBlock
497
442
 
498
443
    w->in_frame = 0;
499
 
    w->prev_frame_tc_scaled = w->cluster_tc_scaled + delta;
500
444
 
501
445
    if( w->cluster->d_cur > CLSIZE )
502
446
        CHECK( mk_close_cluster( w ) );
509
453
    if( mk_flush_frame( w ) < 0 )
510
454
        return -1;
511
455
 
512
 
    w->in_frame = 1;
513
 
    w->keyframe = 0;
 
456
    w->in_frame  = 1;
 
457
    w->keyframe  = 0;
 
458
    w->skippable = 0;
514
459
 
515
460
    return 0;
516
461
}
517
462
 
518
 
int mk_set_frame_flags( mk_writer *w, int64_t timestamp, int keyframe )
 
463
int mk_set_frame_flags( mk_writer *w, int64_t timestamp, int keyframe, int skippable )
519
464
{
520
465
    if( !w->in_frame )
521
466
        return -1;
522
467
 
523
 
    w->frame_tc = timestamp;
524
 
    w->keyframe = keyframe != 0;
 
468
    w->frame_tc  = timestamp;
 
469
    w->keyframe  = keyframe  != 0;
 
470
    w->skippable = skippable != 0;
525
471
 
526
472
    if( w->max_frame_tc < timestamp )
527
473
        w->max_frame_tc = timestamp;