comparison matroskaenc.c @ 2489:3ef5728030da libavformat

Calculate the size of key EBML master elements beforehand so only just enough size is reserved for the size
author conrad
date Wed, 05 Sep 2007 00:24:56 +0000
parents 7420572a8d72
children 06d0bb96139a
comparison
equal deleted inserted replaced
2488:7420572a8d72 2489:3ef5728030da
23 #include "md5.h" 23 #include "md5.h"
24 #include "riff.h" 24 #include "riff.h"
25 #include "xiph.h" 25 #include "xiph.h"
26 #include "matroska.h" 26 #include "matroska.h"
27 27
28 typedef struct ebml_master {
29 offset_t pos; ///< absolute offset in the file where the master's elements start
30 int sizebytes; ///< how many bytes were reserved for the size
31 } ebml_master;
32
28 typedef struct mkv_seekhead_entry { 33 typedef struct mkv_seekhead_entry {
29 unsigned int elementid; 34 unsigned int elementid;
30 uint64_t segmentpos; 35 uint64_t segmentpos;
31 } mkv_seekhead_entry; 36 } mkv_seekhead_entry;
32 37
50 mkv_cuepoint *entries; 55 mkv_cuepoint *entries;
51 int num_entries; 56 int num_entries;
52 } mkv_cues; 57 } mkv_cues;
53 58
54 typedef struct MatroskaMuxContext { 59 typedef struct MatroskaMuxContext {
55 offset_t segment; 60 ebml_master segment;
56 offset_t segment_offset; 61 offset_t segment_offset;
57 offset_t segment_uid; 62 offset_t segment_uid;
58 offset_t cluster; 63 ebml_master cluster;
59 offset_t cluster_pos; ///< file offset of the current cluster 64 offset_t cluster_pos; ///< file offset of the current cluster
60 uint64_t cluster_pts; 65 uint64_t cluster_pts;
61 offset_t duration_offset; 66 offset_t duration_offset;
62 uint64_t duration; 67 uint64_t duration;
63 mkv_seekhead *main_seekhead; 68 mkv_seekhead *main_seekhead;
64 mkv_seekhead *cluster_seekhead; 69 mkv_seekhead *cluster_seekhead;
65 mkv_cues *cues; 70 mkv_cues *cues;
66 71
67 struct AVMD5 *md5_ctx; 72 struct AVMD5 *md5_ctx;
68 } MatroskaMuxContext; 73 } MatroskaMuxContext;
74
75
76 // 2 bytes * 3 for EBML IDs, 3 1-byte EBML lengths, 8 bytes for 64 bit offset, 4 bytes for target EBML ID
77 #define MAX_SEEKENTRY_SIZE 21
78
79 // per-cuepoint-track - 3 1-byte EBML IDs, 3 1-byte EBML sizes, 2 8-byte uint max
80 #define MAX_CUETRACKPOS_SIZE 22
81
82 // per-cuepoint - 2 1-byte EBML IDs, 2 1-byte EBML sizes, 8-byte uint max
83 #define MAX_CUEPOINT_SIZE(num_tracks) 12 + MAX_CUETRACKPOS_SIZE*num_tracks
84
69 85
70 static int ebml_id_size(unsigned int id) 86 static int ebml_id_size(unsigned int id)
71 { 87 {
72 return (av_log2(id+1)-1)/7+1; 88 return (av_log2(id+1)-1)/7+1;
73 } 89 }
192 else 208 else
193 put_ebml_size(pb, size-9, 8); 209 put_ebml_size(pb, size-9, 8);
194 url_fseek(pb, currentpos + size, SEEK_SET); 210 url_fseek(pb, currentpos + size, SEEK_SET);
195 } 211 }
196 212
197 static offset_t start_ebml_master(ByteIOContext *pb, unsigned int elementid) 213 static ebml_master start_ebml_master(ByteIOContext *pb, unsigned int elementid, uint64_t expectedsize)
198 { 214 {
215 int bytes = expectedsize ? ebml_size_bytes(expectedsize) : 8;
199 put_ebml_id(pb, elementid); 216 put_ebml_id(pb, elementid);
200 // XXX: this always reserves the maximum needed space to store any size value 217 put_ebml_size_unknown(pb, bytes);
201 // we should be smarter (additional parameter for expected size?) 218 return (ebml_master){ url_ftell(pb), bytes };
202 put_ebml_size_unknown(pb, 8); 219 }
203 return url_ftell(pb); 220
204 } 221 static void end_ebml_master(ByteIOContext *pb, ebml_master master)
205
206 static void end_ebml_master(ByteIOContext *pb, offset_t start)
207 { 222 {
208 offset_t pos = url_ftell(pb); 223 offset_t pos = url_ftell(pb);
209 224
210 url_fseek(pb, start - 8, SEEK_SET); 225 url_fseek(pb, master.pos - master.sizebytes, SEEK_SET);
211 put_ebml_size(pb, pos - start, 8); 226 put_ebml_size(pb, pos - master.pos, master.sizebytes);
212 url_fseek(pb, pos, SEEK_SET); 227 url_fseek(pb, pos, SEEK_SET);
213 } 228 }
214 229
215 static void put_xiph_size(ByteIOContext *pb, int size) 230 static void put_xiph_size(ByteIOContext *pb, int size)
216 { 231 {
239 254
240 if (numelements > 0) { 255 if (numelements > 0) {
241 new_seekhead->filepos = url_ftell(pb); 256 new_seekhead->filepos = url_ftell(pb);
242 // 21 bytes max for a seek entry, 10 bytes max for the SeekHead ID and size, 257 // 21 bytes max for a seek entry, 10 bytes max for the SeekHead ID and size,
243 // and 3 bytes to guarantee that an EBML void element will fit afterwards 258 // and 3 bytes to guarantee that an EBML void element will fit afterwards
244 // XXX: 28 bytes right now because begin_ebml_master() reserves more than necessary 259 new_seekhead->reserved_size = numelements * MAX_SEEKENTRY_SIZE + 13;
245 new_seekhead->reserved_size = numelements * 28 + 13;
246 new_seekhead->max_entries = numelements; 260 new_seekhead->max_entries = numelements;
247 put_ebml_void(pb, new_seekhead->reserved_size); 261 put_ebml_void(pb, new_seekhead->reserved_size);
248 } 262 }
249 return new_seekhead; 263 return new_seekhead;
250 } 264 }
278 * 292 *
279 * @return the file offset where the seekhead was written 293 * @return the file offset where the seekhead was written
280 */ 294 */
281 static offset_t mkv_write_seekhead(ByteIOContext *pb, mkv_seekhead *seekhead) 295 static offset_t mkv_write_seekhead(ByteIOContext *pb, mkv_seekhead *seekhead)
282 { 296 {
283 offset_t metaseek, seekentry, currentpos; 297 ebml_master metaseek, seekentry;
298 offset_t currentpos;
284 int i; 299 int i;
285 300
286 currentpos = url_ftell(pb); 301 currentpos = url_ftell(pb);
287 302
288 if (seekhead->reserved_size > 0) 303 if (seekhead->reserved_size > 0)
289 url_fseek(pb, seekhead->filepos, SEEK_SET); 304 url_fseek(pb, seekhead->filepos, SEEK_SET);
290 305
291 metaseek = start_ebml_master(pb, MATROSKA_ID_SEEKHEAD); 306 metaseek = start_ebml_master(pb, MATROSKA_ID_SEEKHEAD, seekhead->reserved_size);
292 for (i = 0; i < seekhead->num_entries; i++) { 307 for (i = 0; i < seekhead->num_entries; i++) {
293 mkv_seekhead_entry *entry = &seekhead->entries[i]; 308 mkv_seekhead_entry *entry = &seekhead->entries[i];
294 309
295 seekentry = start_ebml_master(pb, MATROSKA_ID_SEEKENTRY); 310 seekentry = start_ebml_master(pb, MATROSKA_ID_SEEKENTRY, MAX_SEEKENTRY_SIZE);
296 311
297 put_ebml_id(pb, MATROSKA_ID_SEEKID); 312 put_ebml_id(pb, MATROSKA_ID_SEEKID);
298 put_ebml_size(pb, ebml_id_size(entry->elementid), 0); 313 put_ebml_size(pb, ebml_id_size(entry->elementid), 0);
299 put_ebml_id(pb, entry->elementid); 314 put_ebml_id(pb, entry->elementid);
300 315
342 cues->entries = entries; 357 cues->entries = entries;
343 cues->num_entries++; 358 cues->num_entries++;
344 return 0; 359 return 0;
345 } 360 }
346 361
347 static offset_t mkv_write_cues(ByteIOContext *pb, mkv_cues *cues) 362 static offset_t mkv_write_cues(ByteIOContext *pb, mkv_cues *cues, int num_tracks)
348 { 363 {
349 offset_t currentpos, cues_element; 364 ebml_master cues_element;
365 offset_t currentpos;
350 int i, j; 366 int i, j;
351 367
352 currentpos = url_ftell(pb); 368 currentpos = url_ftell(pb);
353 cues_element = start_ebml_master(pb, MATROSKA_ID_CUES); 369 cues_element = start_ebml_master(pb, MATROSKA_ID_CUES, 0);
354 370
355 for (i = 0; i < cues->num_entries; i++) { 371 for (i = 0; i < cues->num_entries; i++) {
356 offset_t cuepoint, track_positions; 372 ebml_master cuepoint, track_positions;
357 mkv_cuepoint *entry = &cues->entries[i]; 373 mkv_cuepoint *entry = &cues->entries[i];
358 uint64_t pts = entry->pts; 374 uint64_t pts = entry->pts;
359 375
360 cuepoint = start_ebml_master(pb, MATROSKA_ID_POINTENTRY); 376 cuepoint = start_ebml_master(pb, MATROSKA_ID_POINTENTRY, MAX_CUEPOINT_SIZE(num_tracks));
361 put_ebml_uint(pb, MATROSKA_ID_CUETIME, pts); 377 put_ebml_uint(pb, MATROSKA_ID_CUETIME, pts);
362 378
363 // put all the entries from different tracks that have the exact same 379 // put all the entries from different tracks that have the exact same
364 // timestamp into the same CuePoint 380 // timestamp into the same CuePoint
365 for (j = 0; j < cues->num_entries - i && entry[j].pts == pts; j++) { 381 for (j = 0; j < cues->num_entries - i && entry[j].pts == pts; j++) {
366 track_positions = start_ebml_master(pb, MATROSKA_ID_CUETRACKPOSITION); 382 track_positions = start_ebml_master(pb, MATROSKA_ID_CUETRACKPOSITION, MAX_CUETRACKPOS_SIZE);
367 put_ebml_uint(pb, MATROSKA_ID_CUETRACK , entry[j].tracknum ); 383 put_ebml_uint(pb, MATROSKA_ID_CUETRACK , entry[j].tracknum );
368 put_ebml_uint(pb, MATROSKA_ID_CUECLUSTERPOSITION, entry[j].cluster_pos); 384 put_ebml_uint(pb, MATROSKA_ID_CUECLUSTERPOSITION, entry[j].cluster_pos);
369 end_ebml_master(pb, track_positions); 385 end_ebml_master(pb, track_positions);
370 } 386 }
371 i += j - 1; 387 i += j - 1;
378 return currentpos; 394 return currentpos;
379 } 395 }
380 396
381 static int put_xiph_codecpriv(ByteIOContext *pb, AVCodecContext *codec) 397 static int put_xiph_codecpriv(ByteIOContext *pb, AVCodecContext *codec)
382 { 398 {
383 offset_t codecprivate; 399 ebml_master codecprivate;
384 uint8_t *header_start[3]; 400 uint8_t *header_start[3];
385 int header_len[3]; 401 int header_len[3];
386 int first_header_size; 402 int first_header_size;
387 int j; 403 int j;
388 404
395 first_header_size, header_start, header_len) < 0) { 411 first_header_size, header_start, header_len) < 0) {
396 av_log(codec, AV_LOG_ERROR, "Extradata corrupt.\n"); 412 av_log(codec, AV_LOG_ERROR, "Extradata corrupt.\n");
397 return -1; 413 return -1;
398 } 414 }
399 415
400 codecprivate = start_ebml_master(pb, MATROSKA_ID_CODECPRIVATE); 416 codecprivate = start_ebml_master(pb, MATROSKA_ID_CODECPRIVATE, 0);
401 put_byte(pb, 2); // number packets - 1 417 put_byte(pb, 2); // number packets - 1
402 for (j = 0; j < 2; j++) { 418 for (j = 0; j < 2; j++) {
403 put_xiph_size(pb, header_len[j]); 419 put_xiph_size(pb, header_len[j]);
404 } 420 }
405 for (j = 0; j < 3; j++) 421 for (j = 0; j < 3; j++)
411 427
412 #define FLAC_STREAMINFO_SIZE 34 428 #define FLAC_STREAMINFO_SIZE 34
413 429
414 static int put_flac_codecpriv(ByteIOContext *pb, AVCodecContext *codec) 430 static int put_flac_codecpriv(ByteIOContext *pb, AVCodecContext *codec)
415 { 431 {
416 offset_t codecpriv = start_ebml_master(pb, MATROSKA_ID_CODECPRIVATE); 432 ebml_master codecpriv = start_ebml_master(pb, MATROSKA_ID_CODECPRIVATE, 0);
417 433
418 // if the extradata_size is greater than FLAC_STREAMINFO_SIZE, 434 // if the extradata_size is greater than FLAC_STREAMINFO_SIZE,
419 // assume that it's in Matroska's format already 435 // assume that it's in Matroska's format already
420 if (codec->extradata_size < FLAC_STREAMINFO_SIZE) { 436 if (codec->extradata_size < FLAC_STREAMINFO_SIZE) {
421 av_log(codec, AV_LOG_ERROR, "Invalid FLAC extradata\n"); 437 av_log(codec, AV_LOG_ERROR, "Invalid FLAC extradata\n");
464 480
465 static int mkv_write_tracks(AVFormatContext *s) 481 static int mkv_write_tracks(AVFormatContext *s)
466 { 482 {
467 MatroskaMuxContext *mkv = s->priv_data; 483 MatroskaMuxContext *mkv = s->priv_data;
468 ByteIOContext *pb = &s->pb; 484 ByteIOContext *pb = &s->pb;
469 offset_t tracks; 485 ebml_master tracks;
470 int i, j; 486 int i, j;
471 487
472 if (mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_TRACKS, url_ftell(pb)) < 0) 488 if (mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_TRACKS, url_ftell(pb)) < 0)
473 return -1; 489 return -1;
474 490
475 tracks = start_ebml_master(pb, MATROSKA_ID_TRACKS); 491 tracks = start_ebml_master(pb, MATROSKA_ID_TRACKS, 0);
476 for (i = 0; i < s->nb_streams; i++) { 492 for (i = 0; i < s->nb_streams; i++) {
477 AVStream *st = s->streams[i]; 493 AVStream *st = s->streams[i];
478 AVCodecContext *codec = st->codec; 494 AVCodecContext *codec = st->codec;
479 offset_t subinfo, track; 495 ebml_master subinfo, track;
480 int native_id = 0; 496 int native_id = 0;
481 int bit_depth = av_get_bits_per_sample(codec->codec_id); 497 int bit_depth = av_get_bits_per_sample(codec->codec_id);
482 int sample_rate = codec->sample_rate; 498 int sample_rate = codec->sample_rate;
483 int output_sample_rate = 0; 499 int output_sample_rate = 0;
484 500
485 if (codec->codec_id == CODEC_ID_AAC) 501 if (codec->codec_id == CODEC_ID_AAC)
486 get_aac_sample_rates(codec, &sample_rate, &output_sample_rate); 502 get_aac_sample_rates(codec, &sample_rate, &output_sample_rate);
487 503
488 track = start_ebml_master(pb, MATROSKA_ID_TRACKENTRY); 504 track = start_ebml_master(pb, MATROSKA_ID_TRACKENTRY, 0);
489 put_ebml_uint (pb, MATROSKA_ID_TRACKNUMBER , i + 1); 505 put_ebml_uint (pb, MATROSKA_ID_TRACKNUMBER , i + 1);
490 put_ebml_uint (pb, MATROSKA_ID_TRACKUID , i + 1); 506 put_ebml_uint (pb, MATROSKA_ID_TRACKUID , i + 1);
491 put_ebml_uint (pb, MATROSKA_ID_TRACKFLAGLACING , 0); // no lacing (yet) 507 put_ebml_uint (pb, MATROSKA_ID_TRACKFLAGLACING , 0); // no lacing (yet)
492 508
493 if (st->language[0]) 509 if (st->language[0])
519 switch (codec->codec_type) { 535 switch (codec->codec_type) {
520 case CODEC_TYPE_VIDEO: 536 case CODEC_TYPE_VIDEO:
521 put_ebml_uint(pb, MATROSKA_ID_TRACKTYPE, MATROSKA_TRACK_TYPE_VIDEO); 537 put_ebml_uint(pb, MATROSKA_ID_TRACKTYPE, MATROSKA_TRACK_TYPE_VIDEO);
522 538
523 if (!native_id) { 539 if (!native_id) {
524 offset_t bmp_header; 540 ebml_master bmp_header;
525 // if there is no mkv-specific codec id, use VFW mode 541 // if there is no mkv-specific codec id, use VFW mode
526 if (!codec->codec_tag) 542 if (!codec->codec_tag)
527 codec->codec_tag = codec_get_tag(codec_bmp_tags, codec->codec_id); 543 codec->codec_tag = codec_get_tag(codec_bmp_tags, codec->codec_id);
528 544
529 put_ebml_string(pb, MATROSKA_ID_CODECID, MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC); 545 put_ebml_string(pb, MATROSKA_ID_CODECID, MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC);
530 bmp_header = start_ebml_master(pb, MATROSKA_ID_CODECPRIVATE); 546 bmp_header = start_ebml_master(pb, MATROSKA_ID_CODECPRIVATE, 0);
531 put_bmp_header(pb, codec, codec_bmp_tags, 0); 547 put_bmp_header(pb, codec, codec_bmp_tags, 0);
532 end_ebml_master(pb, bmp_header); 548 end_ebml_master(pb, bmp_header);
533 } 549 }
534 subinfo = start_ebml_master(pb, MATROSKA_ID_TRACKVIDEO); 550 subinfo = start_ebml_master(pb, MATROSKA_ID_TRACKVIDEO, 0);
535 // XXX: interlace flag? 551 // XXX: interlace flag?
536 put_ebml_uint (pb, MATROSKA_ID_VIDEOPIXELWIDTH , codec->width); 552 put_ebml_uint (pb, MATROSKA_ID_VIDEOPIXELWIDTH , codec->width);
537 put_ebml_uint (pb, MATROSKA_ID_VIDEOPIXELHEIGHT, codec->height); 553 put_ebml_uint (pb, MATROSKA_ID_VIDEOPIXELHEIGHT, codec->height);
538 if (codec->sample_aspect_ratio.num) { 554 if (codec->sample_aspect_ratio.num) {
539 put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYWIDTH , codec->sample_aspect_ratio.num); 555 put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYWIDTH , codec->sample_aspect_ratio.num);
544 560
545 case CODEC_TYPE_AUDIO: 561 case CODEC_TYPE_AUDIO:
546 put_ebml_uint(pb, MATROSKA_ID_TRACKTYPE, MATROSKA_TRACK_TYPE_AUDIO); 562 put_ebml_uint(pb, MATROSKA_ID_TRACKTYPE, MATROSKA_TRACK_TYPE_AUDIO);
547 563
548 if (!native_id) { 564 if (!native_id) {
549 offset_t wav_header; 565 ebml_master wav_header;
550 // no mkv-specific ID, use ACM mode 566 // no mkv-specific ID, use ACM mode
551 codec->codec_tag = codec_get_tag(codec_wav_tags, codec->codec_id); 567 codec->codec_tag = codec_get_tag(codec_wav_tags, codec->codec_id);
552 if (!codec->codec_tag) { 568 if (!codec->codec_tag) {
553 av_log(s, AV_LOG_ERROR, "no codec id found for stream %d", i); 569 av_log(s, AV_LOG_ERROR, "no codec id found for stream %d", i);
554 return -1; 570 return -1;
555 } 571 }
556 572
557 put_ebml_string(pb, MATROSKA_ID_CODECID, MATROSKA_CODEC_ID_AUDIO_ACM); 573 put_ebml_string(pb, MATROSKA_ID_CODECID, MATROSKA_CODEC_ID_AUDIO_ACM);
558 wav_header = start_ebml_master(pb, MATROSKA_ID_CODECPRIVATE); 574 wav_header = start_ebml_master(pb, MATROSKA_ID_CODECPRIVATE, 0);
559 put_wav_header(pb, codec); 575 put_wav_header(pb, codec);
560 end_ebml_master(pb, wav_header); 576 end_ebml_master(pb, wav_header);
561 } 577 }
562 subinfo = start_ebml_master(pb, MATROSKA_ID_TRACKAUDIO); 578 subinfo = start_ebml_master(pb, MATROSKA_ID_TRACKAUDIO, 0);
563 put_ebml_uint (pb, MATROSKA_ID_AUDIOCHANNELS , codec->channels); 579 put_ebml_uint (pb, MATROSKA_ID_AUDIOCHANNELS , codec->channels);
564 put_ebml_float (pb, MATROSKA_ID_AUDIOSAMPLINGFREQ, sample_rate); 580 put_ebml_float (pb, MATROSKA_ID_AUDIOSAMPLINGFREQ, sample_rate);
565 if (output_sample_rate) 581 if (output_sample_rate)
566 put_ebml_float(pb, MATROSKA_ID_AUDIOOUTSAMPLINGFREQ, output_sample_rate); 582 put_ebml_float(pb, MATROSKA_ID_AUDIOOUTSAMPLINGFREQ, output_sample_rate);
567 if (bit_depth) 583 if (bit_depth)
587 603
588 static int mkv_write_header(AVFormatContext *s) 604 static int mkv_write_header(AVFormatContext *s)
589 { 605 {
590 MatroskaMuxContext *mkv = s->priv_data; 606 MatroskaMuxContext *mkv = s->priv_data;
591 ByteIOContext *pb = &s->pb; 607 ByteIOContext *pb = &s->pb;
592 offset_t ebml_header, segment_info; 608 ebml_master ebml_header, segment_info;
593 609
594 mkv->md5_ctx = av_mallocz(av_md5_size); 610 mkv->md5_ctx = av_mallocz(av_md5_size);
595 av_md5_init(mkv->md5_ctx); 611 av_md5_init(mkv->md5_ctx);
596 612
597 ebml_header = start_ebml_master(pb, EBML_ID_HEADER); 613 ebml_header = start_ebml_master(pb, EBML_ID_HEADER, 0);
598 put_ebml_uint (pb, EBML_ID_EBMLVERSION , 1); 614 put_ebml_uint (pb, EBML_ID_EBMLVERSION , 1);
599 put_ebml_uint (pb, EBML_ID_EBMLREADVERSION , 1); 615 put_ebml_uint (pb, EBML_ID_EBMLREADVERSION , 1);
600 put_ebml_uint (pb, EBML_ID_EBMLMAXIDLENGTH , 4); 616 put_ebml_uint (pb, EBML_ID_EBMLMAXIDLENGTH , 4);
601 put_ebml_uint (pb, EBML_ID_EBMLMAXSIZELENGTH , 8); 617 put_ebml_uint (pb, EBML_ID_EBMLMAXSIZELENGTH , 8);
602 put_ebml_string (pb, EBML_ID_DOCTYPE , "matroska"); 618 put_ebml_string (pb, EBML_ID_DOCTYPE , "matroska");
603 put_ebml_uint (pb, EBML_ID_DOCTYPEVERSION , 2); 619 put_ebml_uint (pb, EBML_ID_DOCTYPEVERSION , 2);
604 put_ebml_uint (pb, EBML_ID_DOCTYPEREADVERSION , 2); 620 put_ebml_uint (pb, EBML_ID_DOCTYPEREADVERSION , 2);
605 end_ebml_master(pb, ebml_header); 621 end_ebml_master(pb, ebml_header);
606 622
607 mkv->segment = start_ebml_master(pb, MATROSKA_ID_SEGMENT); 623 mkv->segment = start_ebml_master(pb, MATROSKA_ID_SEGMENT, 0);
608 mkv->segment_offset = url_ftell(pb); 624 mkv->segment_offset = url_ftell(pb);
609 625
610 // we write 2 seek heads - one at the end of the file to point to each cluster, and 626 // we write 2 seek heads - one at the end of the file to point to each cluster, and
611 // one at the beginning to point to all other level one elements (including the seek 627 // one at the beginning to point to all other level one elements (including the seek
612 // head at the end of the file), which isn't more than 10 elements if we only write one 628 // head at the end of the file), which isn't more than 10 elements if we only write one
615 mkv->cluster_seekhead = mkv_start_seekhead(pb, mkv->segment_offset, 0); 631 mkv->cluster_seekhead = mkv_start_seekhead(pb, mkv->segment_offset, 0);
616 632
617 if (mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_INFO, url_ftell(pb)) < 0) 633 if (mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_INFO, url_ftell(pb)) < 0)
618 return -1; 634 return -1;
619 635
620 segment_info = start_ebml_master(pb, MATROSKA_ID_INFO); 636 segment_info = start_ebml_master(pb, MATROSKA_ID_INFO, 0);
621 put_ebml_uint(pb, MATROSKA_ID_TIMECODESCALE, 1000000); 637 put_ebml_uint(pb, MATROSKA_ID_TIMECODESCALE, 1000000);
622 if (strlen(s->title)) 638 if (strlen(s->title))
623 put_ebml_string(pb, MATROSKA_ID_TITLE, s->title); 639 put_ebml_string(pb, MATROSKA_ID_TITLE, s->title);
624 if (!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) { 640 if (!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) {
625 put_ebml_string(pb, MATROSKA_ID_MUXINGAPP , LIBAVFORMAT_IDENT); 641 put_ebml_string(pb, MATROSKA_ID_MUXINGAPP , LIBAVFORMAT_IDENT);
641 657
642 if (mkv_add_seekhead_entry(mkv->cluster_seekhead, MATROSKA_ID_CLUSTER, url_ftell(pb)) < 0) 658 if (mkv_add_seekhead_entry(mkv->cluster_seekhead, MATROSKA_ID_CLUSTER, url_ftell(pb)) < 0)
643 return -1; 659 return -1;
644 660
645 mkv->cluster_pos = url_ftell(pb); 661 mkv->cluster_pos = url_ftell(pb);
646 mkv->cluster = start_ebml_master(pb, MATROSKA_ID_CLUSTER); 662 mkv->cluster = start_ebml_master(pb, MATROSKA_ID_CLUSTER, 0);
647 put_ebml_uint(pb, MATROSKA_ID_CLUSTERTIMECODE, 0); 663 put_ebml_uint(pb, MATROSKA_ID_CLUSTERTIMECODE, 0);
648 mkv->cluster_pts = 0; 664 mkv->cluster_pts = 0;
649 665
650 mkv->cues = mkv_start_cues(mkv->segment_offset); 666 mkv->cues = mkv_start_cues(mkv->segment_offset);
651 if (mkv->cues == NULL) 667 if (mkv->cues == NULL)
652 return -1; 668 return -1;
653 669
654 return 0; 670 return 0;
671 }
672
673 static int mkv_block_size(AVPacket *pkt)
674 {
675 int size = 4; // track num + timecode + flags
676 return size + pkt->size;
677 }
678
679 static int mkv_blockgroup_size(AVPacket *pkt)
680 {
681 int size = mkv_block_size(pkt);
682 size += ebml_size_bytes(size);
683 size += 2; // EBML ID for block and block duration
684 size += 8; // max size of block duration
685 size += ebml_size_bytes(size);
686 size += 1; // blockgroup EBML ID
687 return size;
655 } 688 }
656 689
657 static void mkv_write_block(AVFormatContext *s, unsigned int blockid, AVPacket *pkt, int flags) 690 static void mkv_write_block(AVFormatContext *s, unsigned int blockid, AVPacket *pkt, int flags)
658 { 691 {
659 MatroskaMuxContext *mkv = s->priv_data; 692 MatroskaMuxContext *mkv = s->priv_data;
660 ByteIOContext *pb = &s->pb; 693 ByteIOContext *pb = &s->pb;
661 694
662 av_log(s, AV_LOG_DEBUG, "Writing block at offset %llu, size %d, pts %lld, dts %lld, duration %d, flags %d\n", 695 av_log(s, AV_LOG_DEBUG, "Writing block at offset %llu, size %d, pts %lld, dts %lld, duration %d, flags %d\n",
663 url_ftell(pb), pkt->size, pkt->pts, pkt->dts, pkt->duration, flags); 696 url_ftell(pb), pkt->size, pkt->pts, pkt->dts, pkt->duration, flags);
664 put_ebml_id(pb, blockid); 697 put_ebml_id(pb, blockid);
665 put_ebml_size(pb, pkt->size + 4, 0); 698 put_ebml_size(pb, mkv_block_size(pkt), 0);
666 put_byte(pb, 0x80 | (pkt->stream_index + 1)); // this assumes stream_index is less than 126 699 put_byte(pb, 0x80 | (pkt->stream_index + 1)); // this assumes stream_index is less than 126
667 put_be16(pb, pkt->pts - mkv->cluster_pts); 700 put_be16(pb, pkt->pts - mkv->cluster_pts);
668 put_byte(pb, flags); 701 put_byte(pb, flags);
669 put_buffer(pb, pkt->data, pkt->size); 702 put_buffer(pb, pkt->data, pkt->size);
670 } 703 }
683 716
684 if (mkv_add_seekhead_entry(mkv->cluster_seekhead, MATROSKA_ID_CLUSTER, url_ftell(pb)) < 0) 717 if (mkv_add_seekhead_entry(mkv->cluster_seekhead, MATROSKA_ID_CLUSTER, url_ftell(pb)) < 0)
685 return -1; 718 return -1;
686 719
687 mkv->cluster_pos = url_ftell(pb); 720 mkv->cluster_pos = url_ftell(pb);
688 mkv->cluster = start_ebml_master(pb, MATROSKA_ID_CLUSTER); 721 mkv->cluster = start_ebml_master(pb, MATROSKA_ID_CLUSTER, 0);
689 put_ebml_uint(pb, MATROSKA_ID_CLUSTERTIMECODE, pkt->pts); 722 put_ebml_uint(pb, MATROSKA_ID_CLUSTERTIMECODE, pkt->pts);
690 mkv->cluster_pts = pkt->pts; 723 mkv->cluster_pts = pkt->pts;
691 av_md5_update(mkv->md5_ctx, pkt->data, FFMIN(200, pkt->size)); 724 av_md5_update(mkv->md5_ctx, pkt->data, FFMIN(200, pkt->size));
692 } 725 }
693 726
694 if (codec->codec_type != CODEC_TYPE_SUBTITLE) { 727 if (codec->codec_type != CODEC_TYPE_SUBTITLE) {
695 mkv_write_block(s, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe << 7); 728 mkv_write_block(s, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe << 7);
696 } else { 729 } else {
697 offset_t blockgroup = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP); 730 ebml_master blockgroup = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP, mkv_blockgroup_size(pkt));
698 mkv_write_block(s, MATROSKA_ID_BLOCK, pkt, 0); 731 mkv_write_block(s, MATROSKA_ID_BLOCK, pkt, 0);
699 put_ebml_uint(pb, MATROSKA_ID_DURATION, pkt->duration); 732 put_ebml_uint(pb, MATROSKA_ID_DURATION, pkt->duration);
700 end_ebml_master(pb, blockgroup); 733 end_ebml_master(pb, blockgroup);
701 } 734 }
702 735
715 ByteIOContext *pb = &s->pb; 748 ByteIOContext *pb = &s->pb;
716 offset_t currentpos, second_seekhead, cuespos; 749 offset_t currentpos, second_seekhead, cuespos;
717 750
718 end_ebml_master(pb, mkv->cluster); 751 end_ebml_master(pb, mkv->cluster);
719 752
720 cuespos = mkv_write_cues(pb, mkv->cues); 753 cuespos = mkv_write_cues(pb, mkv->cues, s->nb_streams);
721 second_seekhead = mkv_write_seekhead(pb, mkv->cluster_seekhead); 754 second_seekhead = mkv_write_seekhead(pb, mkv->cluster_seekhead);
722 755
723 mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_CUES , cuespos); 756 mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_CUES , cuespos);
724 mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_SEEKHEAD, second_seekhead); 757 mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_SEEKHEAD, second_seekhead);
725 mkv_write_seekhead(pb, mkv->main_seekhead); 758 mkv_write_seekhead(pb, mkv->main_seekhead);