Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(181)

Side by Side Diff: patched-ffmpeg-mt/libavformat/matroskaenc.c

Issue 789004: ffmpeg roll of source to mar 9 version... (Closed) Base URL: svn://chrome-svn/chrome/trunk/deps/third_party/ffmpeg/
Patch Set: '' Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Matroska muxer 2 * Matroska muxer
3 * Copyright (c) 2007 David Conrad 3 * Copyright (c) 2007 David Conrad
4 * 4 *
5 * This file is part of FFmpeg. 5 * This file is part of FFmpeg.
6 * 6 *
7 * FFmpeg is free software; you can redistribute it and/or 7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public 8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version. 10 * version 2.1 of the License, or (at your option) any later version.
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 int tracknum; 54 int tracknum;
55 int64_t cluster_pos; ///< file offset of the cluster containi ng the block 55 int64_t cluster_pos; ///< file offset of the cluster containi ng the block
56 } mkv_cuepoint; 56 } mkv_cuepoint;
57 57
58 typedef struct { 58 typedef struct {
59 int64_t segment_offset; 59 int64_t segment_offset;
60 mkv_cuepoint *entries; 60 mkv_cuepoint *entries;
61 int num_entries; 61 int num_entries;
62 } mkv_cues; 62 } mkv_cues;
63 63
64 typedef struct {
65 int write_dts;
66 } mkv_track;
67
64 typedef struct MatroskaMuxContext { 68 typedef struct MatroskaMuxContext {
69 ByteIOContext *dyn_bc;
65 ebml_master segment; 70 ebml_master segment;
66 int64_t segment_offset; 71 int64_t segment_offset;
67 int64_t segment_uid; 72 int64_t segment_uid;
68 ebml_master cluster; 73 ebml_master cluster;
69 int64_t cluster_pos; ///< file offset of the current cluster 74 int64_t cluster_pos; ///< file offset of the current cluster
70 uint64_t cluster_pts; 75 int64_t cluster_pts;
71 int64_t duration_offset; 76 int64_t duration_offset;
72 uint64_t duration; 77 int64_t duration;
73 mkv_seekhead *main_seekhead; 78 mkv_seekhead *main_seekhead;
74 mkv_seekhead *cluster_seekhead; 79 mkv_seekhead *cluster_seekhead;
75 mkv_cues *cues; 80 mkv_cues *cues;
81 mkv_track *tracks;
76 82
77 struct AVMD5 *md5_ctx; 83 struct AVMD5 *md5_ctx;
78 } MatroskaMuxContext; 84 } MatroskaMuxContext;
79 85
80 86
81 /** 2 bytes * 3 for EBML IDs, 3 1-byte EBML lengths, 8 bytes for 64 bit 87 /** 2 bytes * 3 for EBML IDs, 3 1-byte EBML lengths, 8 bytes for 64 bit
82 * offset, 4 bytes for target EBML ID */ 88 * offset, 4 bytes for target EBML ID */
83 #define MAX_SEEKENTRY_SIZE 21 89 #define MAX_SEEKENTRY_SIZE 21
84 90
85 /** per-cuepoint-track - 3 1-byte EBML IDs, 3 1-byte EBML sizes, 2 91 /** per-cuepoint-track - 3 1-byte EBML IDs, 3 1-byte EBML sizes, 2
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 int bytes = expectedsize ? ebml_num_size(expectedsize) : 8; 217 int bytes = expectedsize ? ebml_num_size(expectedsize) : 8;
212 put_ebml_id(pb, elementid); 218 put_ebml_id(pb, elementid);
213 put_ebml_size_unknown(pb, bytes); 219 put_ebml_size_unknown(pb, bytes);
214 return (ebml_master){ url_ftell(pb), bytes }; 220 return (ebml_master){ url_ftell(pb), bytes };
215 } 221 }
216 222
217 static void end_ebml_master(ByteIOContext *pb, ebml_master master) 223 static void end_ebml_master(ByteIOContext *pb, ebml_master master)
218 { 224 {
219 int64_t pos = url_ftell(pb); 225 int64_t pos = url_ftell(pb);
220 226
221 // leave the unknown size for masters when streaming 227 if (url_fseek(pb, master.pos - master.sizebytes, SEEK_SET) < 0)
222 if (url_is_streamed(pb))
223 return; 228 return;
224
225 url_fseek(pb, master.pos - master.sizebytes, SEEK_SET);
226 put_ebml_num(pb, pos - master.pos, master.sizebytes); 229 put_ebml_num(pb, pos - master.pos, master.sizebytes);
227 url_fseek(pb, pos, SEEK_SET); 230 url_fseek(pb, pos, SEEK_SET);
228 } 231 }
229 232
230 static void put_xiph_size(ByteIOContext *pb, int size) 233 static void put_xiph_size(ByteIOContext *pb, int size)
231 { 234 {
232 int i; 235 int i;
233 for (i = 0; i < size / 255; i++) 236 for (i = 0; i < size / 255; i++)
234 put_byte(pb, 255); 237 put_byte(pb, 255);
235 put_byte(pb, size % 255); 238 put_byte(pb, size % 255);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 seekhead->entries = entries; 287 seekhead->entries = entries;
285 return 0; 288 return 0;
286 } 289 }
287 290
288 /** 291 /**
289 * Write the seek head to the file and free it. If a maximum number of 292 * Write the seek head to the file and free it. If a maximum number of
290 * elements was specified to mkv_start_seekhead(), the seek head will 293 * elements was specified to mkv_start_seekhead(), the seek head will
291 * be written at the location reserved for it. Otherwise, it is written 294 * be written at the location reserved for it. Otherwise, it is written
292 * at the current location in the file. 295 * at the current location in the file.
293 * 296 *
294 * @return The file offset where the seekhead was written. 297 * @return The file offset where the seekhead was written,
298 * -1 if an error occurred.
295 */ 299 */
296 static int64_t mkv_write_seekhead(ByteIOContext *pb, mkv_seekhead *seekhead) 300 static int64_t mkv_write_seekhead(ByteIOContext *pb, mkv_seekhead *seekhead)
297 { 301 {
298 ebml_master metaseek, seekentry; 302 ebml_master metaseek, seekentry;
299 int64_t currentpos; 303 int64_t currentpos;
300 int i; 304 int i;
301 305
302 currentpos = url_ftell(pb); 306 currentpos = url_ftell(pb);
303 307
304 if (seekhead->reserved_size > 0) 308 if (seekhead->reserved_size > 0)
305 url_fseek(pb, seekhead->filepos, SEEK_SET); 309 if (url_fseek(pb, seekhead->filepos, SEEK_SET) < 0)
310 return -1;
306 311
307 metaseek = start_ebml_master(pb, MATROSKA_ID_SEEKHEAD, seekhead->reserved_si ze); 312 metaseek = start_ebml_master(pb, MATROSKA_ID_SEEKHEAD, seekhead->reserved_si ze);
308 for (i = 0; i < seekhead->num_entries; i++) { 313 for (i = 0; i < seekhead->num_entries; i++) {
309 mkv_seekhead_entry *entry = &seekhead->entries[i]; 314 mkv_seekhead_entry *entry = &seekhead->entries[i];
310 315
311 seekentry = start_ebml_master(pb, MATROSKA_ID_SEEKENTRY, MAX_SEEKENTRY_S IZE); 316 seekentry = start_ebml_master(pb, MATROSKA_ID_SEEKENTRY, MAX_SEEKENTRY_S IZE);
312 317
313 put_ebml_id(pb, MATROSKA_ID_SEEKID); 318 put_ebml_id(pb, MATROSKA_ID_SEEKID);
314 put_ebml_num(pb, ebml_id_size(entry->elementid), 0); 319 put_ebml_num(pb, ebml_id_size(entry->elementid), 0);
315 put_ebml_id(pb, entry->elementid); 320 put_ebml_id(pb, entry->elementid);
(...skipping 19 matching lines...) Expand all
335 static mkv_cues * mkv_start_cues(int64_t segment_offset) 340 static mkv_cues * mkv_start_cues(int64_t segment_offset)
336 { 341 {
337 mkv_cues *cues = av_mallocz(sizeof(mkv_cues)); 342 mkv_cues *cues = av_mallocz(sizeof(mkv_cues));
338 if (cues == NULL) 343 if (cues == NULL)
339 return NULL; 344 return NULL;
340 345
341 cues->segment_offset = segment_offset; 346 cues->segment_offset = segment_offset;
342 return cues; 347 return cues;
343 } 348 }
344 349
345 static int mkv_add_cuepoint(mkv_cues *cues, AVPacket *pkt, int64_t cluster_pos) 350 static int mkv_add_cuepoint(mkv_cues *cues, int stream, int64_t ts, int64_t clus ter_pos)
346 { 351 {
347 mkv_cuepoint *entries = cues->entries; 352 mkv_cuepoint *entries = cues->entries;
348 353
349 entries = av_realloc(entries, (cues->num_entries + 1) * sizeof(mkv_cuepoint) ); 354 entries = av_realloc(entries, (cues->num_entries + 1) * sizeof(mkv_cuepoint) );
350 if (entries == NULL) 355 if (entries == NULL)
351 return AVERROR(ENOMEM); 356 return AVERROR(ENOMEM);
352 357
353 entries[cues->num_entries ].pts = pkt->pts; 358 if (ts < 0)
354 entries[cues->num_entries ].tracknum = pkt->stream_index + 1; 359 return 0;
360
361 entries[cues->num_entries ].pts = ts;
362 entries[cues->num_entries ].tracknum = stream + 1;
355 entries[cues->num_entries++].cluster_pos = cluster_pos - cues->segment_offse t; 363 entries[cues->num_entries++].cluster_pos = cluster_pos - cues->segment_offse t;
356 364
357 cues->entries = entries; 365 cues->entries = entries;
358 return 0; 366 return 0;
359 } 367 }
360 368
361 static int64_t mkv_write_cues(ByteIOContext *pb, mkv_cues *cues, int num_tracks) 369 static int64_t mkv_write_cues(ByteIOContext *pb, mkv_cues *cues, int num_tracks)
362 { 370 {
363 ebml_master cues_element; 371 ebml_master cues_element;
364 int64_t currentpos; 372 int64_t currentpos;
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 ret = ff_isom_write_avcc(dyn_cp, codec->extradata, codec->extradata_ size); 475 ret = ff_isom_write_avcc(dyn_cp, codec->extradata, codec->extradata_ size);
468 else if (codec->extradata_size) 476 else if (codec->extradata_size)
469 put_buffer(dyn_cp, codec->extradata, codec->extradata_size); 477 put_buffer(dyn_cp, codec->extradata, codec->extradata_size);
470 } else if (codec->codec_type == CODEC_TYPE_VIDEO) { 478 } else if (codec->codec_type == CODEC_TYPE_VIDEO) {
471 if (qt_id) { 479 if (qt_id) {
472 if (!codec->codec_tag) 480 if (!codec->codec_tag)
473 codec->codec_tag = ff_codec_get_tag(codec_movvideo_tags, codec-> codec_id); 481 codec->codec_tag = ff_codec_get_tag(codec_movvideo_tags, codec-> codec_id);
474 if (codec->extradata_size) 482 if (codec->extradata_size)
475 put_buffer(dyn_cp, codec->extradata, codec->extradata_size); 483 put_buffer(dyn_cp, codec->extradata, codec->extradata_size);
476 } else { 484 } else {
477 if (!codec->codec_tag) 485 if (!codec->codec_tag)
478 codec->codec_tag = ff_codec_get_tag(ff_codec_bmp_tags, codec->codec_ id); 486 codec->codec_tag = ff_codec_get_tag(ff_codec_bmp_tags, codec->co dec_id);
479 if (!codec->codec_tag) { 487 if (!codec->codec_tag) {
480 av_log(s, AV_LOG_ERROR, "No bmp codec ID found."); 488 av_log(s, AV_LOG_ERROR, "No bmp codec ID found.");
481 ret = -1; 489 ret = -1;
482 } 490 }
483 491
484 ff_put_bmp_header(dyn_cp, codec, ff_codec_bmp_tags, 0); 492 ff_put_bmp_header(dyn_cp, codec, ff_codec_bmp_tags, 0);
485 } 493 }
486 494
487 } else if (codec->codec_type == CODEC_TYPE_AUDIO) { 495 } else if (codec->codec_type == CODEC_TYPE_AUDIO) {
488 if (!codec->codec_tag) 496 if (!codec->codec_tag)
489 codec->codec_tag = ff_codec_get_tag(ff_codec_wav_tags, codec->codec_ id); 497 codec->codec_tag = ff_codec_get_tag(ff_codec_wav_tags, codec->codec_ id);
490 if (!codec->codec_tag) { 498 if (!codec->codec_tag) {
491 av_log(s, AV_LOG_ERROR, "No wav codec ID found."); 499 av_log(s, AV_LOG_ERROR, "No wav codec ID found.");
492 ret = -1; 500 ret = -1;
493 } 501 }
494 502
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 537
530 if (codec->codec_id == CODEC_ID_AAC) 538 if (codec->codec_id == CODEC_ID_AAC)
531 get_aac_sample_rates(s, codec, &sample_rate, &output_sample_rate); 539 get_aac_sample_rates(s, codec, &sample_rate, &output_sample_rate);
532 540
533 track = start_ebml_master(pb, MATROSKA_ID_TRACKENTRY, 0); 541 track = start_ebml_master(pb, MATROSKA_ID_TRACKENTRY, 0);
534 put_ebml_uint (pb, MATROSKA_ID_TRACKNUMBER , i + 1); 542 put_ebml_uint (pb, MATROSKA_ID_TRACKNUMBER , i + 1);
535 put_ebml_uint (pb, MATROSKA_ID_TRACKUID , i + 1); 543 put_ebml_uint (pb, MATROSKA_ID_TRACKUID , i + 1);
536 put_ebml_uint (pb, MATROSKA_ID_TRACKFLAGLACING , 0); // no lacing (ye t) 544 put_ebml_uint (pb, MATROSKA_ID_TRACKFLAGLACING , 0); // no lacing (ye t)
537 put_ebml_float(pb, MATROSKA_ID_TRACKTIMECODESCALE, 1.0); 545 put_ebml_float(pb, MATROSKA_ID_TRACKTIMECODESCALE, 1.0);
538 546
539 if ((tag = av_metadata_get(st->metadata, "description", NULL, 0))) 547 if ((tag = av_metadata_get(st->metadata, "title", NULL, 0)))
540 put_ebml_string(pb, MATROSKA_ID_TRACKNAME, tag->value); 548 put_ebml_string(pb, MATROSKA_ID_TRACKNAME, tag->value);
541 tag = av_metadata_get(st->metadata, "language", NULL, 0); 549 tag = av_metadata_get(st->metadata, "language", NULL, 0);
542 put_ebml_string(pb, MATROSKA_ID_TRACKLANGUAGE, tag ? tag->value:"und"); 550 put_ebml_string(pb, MATROSKA_ID_TRACKLANGUAGE, tag ? tag->value:"und");
543 551
544 if (st->disposition) 552 if (st->disposition)
545 put_ebml_uint(pb, MATROSKA_ID_TRACKFLAGDEFAULT, !!(st->disposition & AV_DISPOSITION_DEFAULT)); 553 put_ebml_uint(pb, MATROSKA_ID_TRACKFLAGDEFAULT, !!(st->disposition & AV_DISPOSITION_DEFAULT));
546 554
547 // look for a codec ID string specific to mkv to use, 555 // look for a codec ID string specific to mkv to use,
548 // if none are found, use AVI codes 556 // if none are found, use AVI codes
549 for (j = 0; ff_mkv_codec_tags[j].id != CODEC_ID_NONE; j++) { 557 for (j = 0; ff_mkv_codec_tags[j].id != CODEC_ID_NONE; j++) {
(...skipping 11 matching lines...) Expand all
561 if (!native_id && 569 if (!native_id &&
562 ff_codec_get_tag(codec_movvideo_tags, codec->codec_id) && 570 ff_codec_get_tag(codec_movvideo_tags, codec->codec_id) &&
563 (!ff_codec_get_tag(ff_codec_bmp_tags, codec->codec_id) 571 (!ff_codec_get_tag(ff_codec_bmp_tags, codec->codec_id)
564 || codec->codec_id == CODEC_ID_SVQ1 572 || codec->codec_id == CODEC_ID_SVQ1
565 || codec->codec_id == CODEC_ID_SVQ3 573 || codec->codec_id == CODEC_ID_SVQ3
566 || codec->codec_id == CODEC_ID_CINEPAK)) 574 || codec->codec_id == CODEC_ID_CINEPAK))
567 qt_id = 1; 575 qt_id = 1;
568 576
569 if (qt_id) 577 if (qt_id)
570 put_ebml_string(pb, MATROSKA_ID_CODECID, "V_QUICKTIME"); 578 put_ebml_string(pb, MATROSKA_ID_CODECID, "V_QUICKTIME");
571 else if (!native_id) 579 else if (!native_id) {
572 // if there is no mkv-specific codec ID, use VFW mode 580 // if there is no mkv-specific codec ID, use VFW mode
573 put_ebml_string(pb, MATROSKA_ID_CODECID, "V_MS/VFW/FOURCC"); 581 put_ebml_string(pb, MATROSKA_ID_CODECID, "V_MS/VFW/FOURCC");
582 mkv->tracks[i].write_dts = 1;
583 }
574 584
575 subinfo = start_ebml_master(pb, MATROSKA_ID_TRACKVIDEO, 0); 585 subinfo = start_ebml_master(pb, MATROSKA_ID_TRACKVIDEO, 0);
576 // XXX: interlace flag? 586 // XXX: interlace flag?
577 put_ebml_uint (pb, MATROSKA_ID_VIDEOPIXELWIDTH , codec->width); 587 put_ebml_uint (pb, MATROSKA_ID_VIDEOPIXELWIDTH , codec->width);
578 put_ebml_uint (pb, MATROSKA_ID_VIDEOPIXELHEIGHT, codec->height); 588 put_ebml_uint (pb, MATROSKA_ID_VIDEOPIXELHEIGHT, codec->height);
579 if (st->sample_aspect_ratio.num) { 589 if (st->sample_aspect_ratio.num) {
580 int d_width = codec->width*av_q2d(st->sample_aspect_ratio); 590 int d_width = codec->width*av_q2d(st->sample_aspect_ratio);
581 put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYWIDTH , d_width); 591 put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYWIDTH , d_width);
582 put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYHEIGHT, codec->hei ght); 592 put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYHEIGHT, codec->hei ght);
583 } 593 }
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 static int mkv_write_header(AVFormatContext *s) 677 static int mkv_write_header(AVFormatContext *s)
668 { 678 {
669 MatroskaMuxContext *mkv = s->priv_data; 679 MatroskaMuxContext *mkv = s->priv_data;
670 ByteIOContext *pb = s->pb; 680 ByteIOContext *pb = s->pb;
671 ebml_master ebml_header, segment_info; 681 ebml_master ebml_header, segment_info;
672 AVMetadataTag *tag; 682 AVMetadataTag *tag;
673 int ret; 683 int ret;
674 684
675 mkv->md5_ctx = av_mallocz(av_md5_size); 685 mkv->md5_ctx = av_mallocz(av_md5_size);
676 av_md5_init(mkv->md5_ctx); 686 av_md5_init(mkv->md5_ctx);
687 mkv->tracks = av_mallocz(s->nb_streams * sizeof(*mkv->tracks));
677 688
678 ebml_header = start_ebml_master(pb, EBML_ID_HEADER, 0); 689 ebml_header = start_ebml_master(pb, EBML_ID_HEADER, 0);
679 put_ebml_uint (pb, EBML_ID_EBMLVERSION , 1); 690 put_ebml_uint (pb, EBML_ID_EBMLVERSION , 1);
680 put_ebml_uint (pb, EBML_ID_EBMLREADVERSION , 1); 691 put_ebml_uint (pb, EBML_ID_EBMLREADVERSION , 1);
681 put_ebml_uint (pb, EBML_ID_EBMLMAXIDLENGTH , 4); 692 put_ebml_uint (pb, EBML_ID_EBMLMAXIDLENGTH , 4);
682 put_ebml_uint (pb, EBML_ID_EBMLMAXSIZELENGTH , 8); 693 put_ebml_uint (pb, EBML_ID_EBMLMAXSIZELENGTH , 8);
683 put_ebml_string (pb, EBML_ID_DOCTYPE , "matroska"); 694 put_ebml_string (pb, EBML_ID_DOCTYPE , "matroska");
684 put_ebml_uint (pb, EBML_ID_DOCTYPEVERSION , 2); 695 put_ebml_uint (pb, EBML_ID_DOCTYPEVERSION , 2);
685 put_ebml_uint (pb, EBML_ID_DOCTYPEREADVERSION , 2); 696 put_ebml_uint (pb, EBML_ID_DOCTYPEREADVERSION , 2);
686 end_ebml_master(pb, ebml_header); 697 end_ebml_master(pb, ebml_header);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
719 mkv->duration_offset = url_ftell(pb); 730 mkv->duration_offset = url_ftell(pb);
720 put_ebml_void(pb, 11); // assumes double-precision float to be written 731 put_ebml_void(pb, 11); // assumes double-precision float to be written
721 end_ebml_master(pb, segment_info); 732 end_ebml_master(pb, segment_info);
722 733
723 ret = mkv_write_tracks(s); 734 ret = mkv_write_tracks(s);
724 if (ret < 0) return ret; 735 if (ret < 0) return ret;
725 736
726 ret = mkv_write_chapters(s); 737 ret = mkv_write_chapters(s);
727 if (ret < 0) return ret; 738 if (ret < 0) return ret;
728 739
729 ret = mkv_add_seekhead_entry(mkv->cluster_seekhead, MATROSKA_ID_CLUSTER, url _ftell(pb)); 740 if (url_is_streamed(s->pb))
730 if (ret < 0) return ret; 741 mkv_write_seekhead(pb, mkv->main_seekhead);
731
732 mkv->cluster_pos = url_ftell(pb);
733 mkv->cluster = start_ebml_master(pb, MATROSKA_ID_CLUSTER, 0);
734 put_ebml_uint(pb, MATROSKA_ID_CLUSTERTIMECODE, 0);
735 mkv->cluster_pts = 0;
736 742
737 mkv->cues = mkv_start_cues(mkv->segment_offset); 743 mkv->cues = mkv_start_cues(mkv->segment_offset);
738 if (mkv->cues == NULL) 744 if (mkv->cues == NULL)
739 return AVERROR(ENOMEM); 745 return AVERROR(ENOMEM);
740 746
741 put_flush_packet(pb); 747 put_flush_packet(pb);
742 return 0; 748 return 0;
743 } 749 }
744 750
745 static int mkv_blockgroup_size(int pkt_size) 751 static int mkv_blockgroup_size(int pkt_size)
(...skipping 13 matching lines...) Expand all
759 uint64_t start, end; 765 uint64_t start, end;
760 766
761 if (sscanf(p, "%*[^,],%d:%d:%d%*c%d,%d:%d:%d%*c%d", 767 if (sscanf(p, "%*[^,],%d:%d:%d%*c%d,%d:%d:%d%*c%d",
762 &sh, &sm, &ss, &sc, &eh, &em, &es, &ec) != 8) 768 &sh, &sm, &ss, &sc, &eh, &em, &es, &ec) != 8)
763 return 0; 769 return 0;
764 start = 3600000*sh + 60000*sm + 1000*ss + 10*sc; 770 start = 3600000*sh + 60000*sm + 1000*ss + 10*sc;
765 end = 3600000*eh + 60000*em + 1000*es + 10*ec; 771 end = 3600000*eh + 60000*em + 1000*es + 10*ec;
766 return end - start; 772 return end - start;
767 } 773 }
768 774
769 static int mkv_write_ass_blocks(AVFormatContext *s, AVPacket *pkt) 775 static int mkv_write_ass_blocks(AVFormatContext *s, ByteIOContext *pb, AVPacket *pkt)
770 { 776 {
771 MatroskaMuxContext *mkv = s->priv_data; 777 MatroskaMuxContext *mkv = s->priv_data;
772 ByteIOContext *pb = s->pb;
773 int i, layer = 0, max_duration = 0, size, line_size, data_size = pkt->size; 778 int i, layer = 0, max_duration = 0, size, line_size, data_size = pkt->size;
774 uint8_t *start, *end, *data = pkt->data; 779 uint8_t *start, *end, *data = pkt->data;
775 ebml_master blockgroup; 780 ebml_master blockgroup;
776 char buffer[2048]; 781 char buffer[2048];
777 782
778 while (data_size) { 783 while (data_size) {
779 int duration = ass_get_duration(data); 784 int duration = ass_get_duration(data);
780 max_duration = FFMAX(duration, max_duration); 785 max_duration = FFMAX(duration, max_duration);
781 end = memchr(data, '\n', data_size); 786 end = memchr(data, '\n', data_size);
782 size = line_size = end ? end-data+1 : data_size; 787 size = line_size = end ? end-data+1 : data_size;
(...skipping 22 matching lines...) Expand all
805 put_ebml_uint(pb, MATROSKA_ID_BLOCKDURATION, duration); 810 put_ebml_uint(pb, MATROSKA_ID_BLOCKDURATION, duration);
806 end_ebml_master(pb, blockgroup); 811 end_ebml_master(pb, blockgroup);
807 812
808 data += line_size; 813 data += line_size;
809 data_size -= line_size; 814 data_size -= line_size;
810 } 815 }
811 816
812 return max_duration; 817 return max_duration;
813 } 818 }
814 819
815 static void mkv_write_block(AVFormatContext *s, unsigned int blockid, AVPacket * pkt, int flags) 820 static void mkv_write_block(AVFormatContext *s, ByteIOContext *pb,
821 unsigned int blockid, AVPacket *pkt, int flags)
816 { 822 {
817 MatroskaMuxContext *mkv = s->priv_data; 823 MatroskaMuxContext *mkv = s->priv_data;
818 ByteIOContext *pb = s->pb;
819 AVCodecContext *codec = s->streams[pkt->stream_index]->codec; 824 AVCodecContext *codec = s->streams[pkt->stream_index]->codec;
820 uint8_t *data = NULL; 825 uint8_t *data = NULL;
821 int size = pkt->size; 826 int size = pkt->size;
827 int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts;
822 828
823 av_log(s, AV_LOG_DEBUG, "Writing block at offset %" PRIu64 ", size %d, " 829 av_log(s, AV_LOG_DEBUG, "Writing block at offset %" PRIu64 ", size %d, "
824 "pts %" PRId64 ", dts %" PRId64 ", duration %d, flags %d\n", 830 "pts %" PRId64 ", dts %" PRId64 ", duration %d, flags %d\n",
825 url_ftell(pb), pkt->size, pkt->pts, pkt->dts, pkt->duration, flags); 831 url_ftell(pb), pkt->size, pkt->pts, pkt->dts, pkt->duration, flags);
826 if (codec->codec_id == CODEC_ID_H264 && codec->extradata_size > 0 && 832 if (codec->codec_id == CODEC_ID_H264 && codec->extradata_size > 0 &&
827 (AV_RB24(codec->extradata) == 1 || AV_RB32(codec->extradata) == 1)) 833 (AV_RB24(codec->extradata) == 1 || AV_RB32(codec->extradata) == 1))
828 ff_avc_parse_nal_units_buf(pkt->data, &data, &size); 834 ff_avc_parse_nal_units_buf(pkt->data, &data, &size);
829 else 835 else
830 data = pkt->data; 836 data = pkt->data;
831 put_ebml_id(pb, blockid); 837 put_ebml_id(pb, blockid);
832 put_ebml_num(pb, size+4, 0); 838 put_ebml_num(pb, size+4, 0);
833 put_byte(pb, 0x80 | (pkt->stream_index + 1)); // this assumes stream_ind ex is less than 126 839 put_byte(pb, 0x80 | (pkt->stream_index + 1)); // this assumes stream_ind ex is less than 126
834 put_be16(pb, pkt->pts - mkv->cluster_pts); 840 put_be16(pb, ts - mkv->cluster_pts);
835 put_byte(pb, flags); 841 put_byte(pb, flags);
836 put_buffer(pb, data, size); 842 put_buffer(pb, data, size);
837 if (data != pkt->data) 843 if (data != pkt->data)
838 av_free(data); 844 av_free(data);
839 } 845 }
840 846
847 static void mkv_flush_dynbuf(AVFormatContext *s)
848 {
849 MatroskaMuxContext *mkv = s->priv_data;
850 int bufsize;
851 uint8_t *dyn_buf;
852
853 if (!mkv->dyn_bc)
854 return;
855
856 bufsize = url_close_dyn_buf(mkv->dyn_bc, &dyn_buf);
857 put_buffer(s->pb, dyn_buf, bufsize);
858 av_free(dyn_buf);
859 mkv->dyn_bc = NULL;
860 }
861
841 static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt) 862 static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt)
842 { 863 {
843 MatroskaMuxContext *mkv = s->priv_data; 864 MatroskaMuxContext *mkv = s->priv_data;
844 ByteIOContext *pb = s->pb; 865 ByteIOContext *pb = s->pb;
845 AVCodecContext *codec = s->streams[pkt->stream_index]->codec; 866 AVCodecContext *codec = s->streams[pkt->stream_index]->codec;
846 int keyframe = !!(pkt->flags & PKT_FLAG_KEY); 867 int keyframe = !!(pkt->flags & PKT_FLAG_KEY);
847 int duration = pkt->duration; 868 int duration = pkt->duration;
848 int ret; 869 int ret;
870 int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts;
849 871
850 // start a new cluster every 5 MB or 5 sec 872 if (ts == AV_NOPTS_VALUE) {
851 if (url_ftell(pb) > mkv->cluster_pos + 5*1024*1024 || pkt->pts > mkv->cluste r_pts + 5000) { 873 av_log(s, AV_LOG_ERROR, "Can't write packet with unknown timestamp\n");
852 av_log(s, AV_LOG_DEBUG, "Starting new cluster at offset %" PRIu64 874 return AVERROR(EINVAL);
853 " bytes, pts %" PRIu64 "\n", url_ftell(pb), pkt->pts); 875 }
854 end_ebml_master(pb, mkv->cluster);
855 876
877 if (url_is_streamed(s->pb)) {
878 if (!mkv->dyn_bc)
879 url_open_dyn_buf(&mkv->dyn_bc);
880 pb = mkv->dyn_bc;
881 }
882
883 if (!mkv->cluster_pos) {
856 ret = mkv_add_seekhead_entry(mkv->cluster_seekhead, MATROSKA_ID_CLUSTER, url_ftell(pb)); 884 ret = mkv_add_seekhead_entry(mkv->cluster_seekhead, MATROSKA_ID_CLUSTER, url_ftell(pb));
857 if (ret < 0) return ret; 885 if (ret < 0) return ret;
858 886
859 mkv->cluster_pos = url_ftell(pb); 887 mkv->cluster_pos = url_ftell(s->pb);
860 mkv->cluster = start_ebml_master(pb, MATROSKA_ID_CLUSTER, 0); 888 mkv->cluster = start_ebml_master(pb, MATROSKA_ID_CLUSTER, 0);
861 put_ebml_uint(pb, MATROSKA_ID_CLUSTERTIMECODE, pkt->pts); 889 put_ebml_uint(pb, MATROSKA_ID_CLUSTERTIMECODE, FFMAX(0, ts));
862 mkv->cluster_pts = pkt->pts; 890 mkv->cluster_pts = FFMAX(0, ts);
863 av_md5_update(mkv->md5_ctx, pkt->data, FFMIN(200, pkt->size)); 891 av_md5_update(mkv->md5_ctx, pkt->data, FFMIN(200, pkt->size));
864 } 892 }
865 893
866 if (codec->codec_type != CODEC_TYPE_SUBTITLE) { 894 if (codec->codec_type != CODEC_TYPE_SUBTITLE) {
867 mkv_write_block(s, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe << 7); 895 mkv_write_block(s, pb, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe << 7);
868 } else if (codec->codec_id == CODEC_ID_SSA) { 896 } else if (codec->codec_id == CODEC_ID_SSA) {
869 duration = mkv_write_ass_blocks(s, pkt); 897 duration = mkv_write_ass_blocks(s, pb, pkt);
870 } else { 898 } else {
871 ebml_master blockgroup = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP, m kv_blockgroup_size(pkt->size)); 899 ebml_master blockgroup = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP, m kv_blockgroup_size(pkt->size));
872 duration = pkt->convergence_duration; 900 duration = pkt->convergence_duration;
873 mkv_write_block(s, MATROSKA_ID_BLOCK, pkt, 0); 901 mkv_write_block(s, pb, MATROSKA_ID_BLOCK, pkt, 0);
874 put_ebml_uint(pb, MATROSKA_ID_BLOCKDURATION, duration); 902 put_ebml_uint(pb, MATROSKA_ID_BLOCKDURATION, duration);
875 end_ebml_master(pb, blockgroup); 903 end_ebml_master(pb, blockgroup);
876 } 904 }
877 905
878 if (codec->codec_type == CODEC_TYPE_VIDEO && keyframe) { 906 if (codec->codec_type == CODEC_TYPE_VIDEO && keyframe) {
879 ret = mkv_add_cuepoint(mkv->cues, pkt, mkv->cluster_pos); 907 ret = mkv_add_cuepoint(mkv->cues, pkt->stream_index, ts, mkv->cluster_po s);
880 if (ret < 0) return ret; 908 if (ret < 0) return ret;
881 } 909 }
882 910
883 mkv->duration = FFMAX(mkv->duration, pkt->pts + duration); 911 // start a new cluster every 5 MB or 5 sec, or 32k / 1 sec for streaming
912 if (url_is_streamed(s->pb) && (url_ftell(pb) > 32*1024 || ts > mkv->cluster_ pts + 1000)
913 || url_ftell(pb) > mkv->cluster_pos + 5*1024*1024 || ts > mkv->cluster_ pts + 5000) {
914 av_log(s, AV_LOG_DEBUG, "Starting new cluster at offset %" PRIu64
915 " bytes, pts %" PRIu64 "\n", url_ftell(pb), ts);
916 end_ebml_master(pb, mkv->cluster);
917 mkv->cluster_pos = 0;
918 if (mkv->dyn_bc)
919 mkv_flush_dynbuf(s);
920 }
921
922 mkv->duration = FFMAX(mkv->duration, ts + duration);
884 return 0; 923 return 0;
885 } 924 }
886 925
887 static int mkv_write_trailer(AVFormatContext *s) 926 static int mkv_write_trailer(AVFormatContext *s)
888 { 927 {
889 MatroskaMuxContext *mkv = s->priv_data; 928 MatroskaMuxContext *mkv = s->priv_data;
890 ByteIOContext *pb = s->pb; 929 ByteIOContext *pb = s->pb;
891 int64_t currentpos, second_seekhead, cuespos; 930 int64_t currentpos, second_seekhead, cuespos;
892 int ret; 931 int ret;
893 932
894 end_ebml_master(pb, mkv->cluster); 933 if (mkv->dyn_bc) {
934 end_ebml_master(mkv->dyn_bc, mkv->cluster);
935 mkv_flush_dynbuf(s);
936 } else if (mkv->cluster_pos) {
937 end_ebml_master(pb, mkv->cluster);
938 }
895 939
896 if (!url_is_streamed(pb)) { 940 if (!url_is_streamed(pb)) {
897 cuespos = mkv_write_cues(pb, mkv->cues, s->nb_streams); 941 cuespos = mkv_write_cues(pb, mkv->cues, s->nb_streams);
898 second_seekhead = mkv_write_seekhead(pb, mkv->cluster_seekhead); 942 second_seekhead = mkv_write_seekhead(pb, mkv->cluster_seekhead);
899 943
900 ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_CUES , c uespos); 944 ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_CUES , c uespos);
901 if (ret < 0) return ret; 945 if (ret < 0) return ret;
902 ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_SEEKHEAD, s econd_seekhead); 946 if (second_seekhead >= 0) {
903 if (ret < 0) return ret; 947 ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_SEEKHEA D, second_seekhead);
948 if (ret < 0) return ret;
949 }
904 mkv_write_seekhead(pb, mkv->main_seekhead); 950 mkv_write_seekhead(pb, mkv->main_seekhead);
905 951
906 // update the duration 952 // update the duration
907 av_log(s, AV_LOG_DEBUG, "end duration = %" PRIu64 "\n", mkv->duration); 953 av_log(s, AV_LOG_DEBUG, "end duration = %" PRIu64 "\n", mkv->duration);
908 currentpos = url_ftell(pb); 954 currentpos = url_ftell(pb);
909 url_fseek(pb, mkv->duration_offset, SEEK_SET); 955 url_fseek(pb, mkv->duration_offset, SEEK_SET);
910 put_ebml_float(pb, MATROSKA_ID_DURATION, mkv->duration); 956 put_ebml_float(pb, MATROSKA_ID_DURATION, mkv->duration);
911 957
912 // write the md5sum of some frames as the segment UID 958 // write the md5sum of some frames as the segment UID
913 if (!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) { 959 if (!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) {
914 uint8_t segment_uid[16]; 960 uint8_t segment_uid[16];
915 av_md5_final(mkv->md5_ctx, segment_uid); 961 av_md5_final(mkv->md5_ctx, segment_uid);
916 url_fseek(pb, mkv->segment_uid, SEEK_SET); 962 url_fseek(pb, mkv->segment_uid, SEEK_SET);
917 put_ebml_binary(pb, MATROSKA_ID_SEGMENTUID, segment_uid, 16); 963 put_ebml_binary(pb, MATROSKA_ID_SEGMENTUID, segment_uid, 16);
918 } 964 }
919 url_fseek(pb, currentpos, SEEK_SET); 965 url_fseek(pb, currentpos, SEEK_SET);
920 } 966 }
921 967
922 end_ebml_master(pb, mkv->segment); 968 end_ebml_master(pb, mkv->segment);
923 av_free(mkv->md5_ctx); 969 av_free(mkv->md5_ctx);
970 av_free(mkv->tracks);
924 put_flush_packet(pb); 971 put_flush_packet(pb);
925 return 0; 972 return 0;
926 } 973 }
927 974
928 AVOutputFormat matroska_muxer = { 975 AVOutputFormat matroska_muxer = {
929 "matroska", 976 "matroska",
930 NULL_IF_CONFIG_SMALL("Matroska file format"), 977 NULL_IF_CONFIG_SMALL("Matroska file format"),
931 "video/x-matroska", 978 "video/x-matroska",
932 "mkv", 979 "mkv",
933 sizeof(MatroskaMuxContext), 980 sizeof(MatroskaMuxContext),
(...skipping 14 matching lines...) Expand all
948 "mka", 995 "mka",
949 sizeof(MatroskaMuxContext), 996 sizeof(MatroskaMuxContext),
950 CODEC_ID_MP2, 997 CODEC_ID_MP2,
951 CODEC_ID_NONE, 998 CODEC_ID_NONE,
952 mkv_write_header, 999 mkv_write_header,
953 mkv_write_packet, 1000 mkv_write_packet,
954 mkv_write_trailer, 1001 mkv_write_trailer,
955 .flags = AVFMT_GLOBALHEADER, 1002 .flags = AVFMT_GLOBALHEADER,
956 .codec_tag = (const AVCodecTag* const []){ff_codec_wav_tags, 0}, 1003 .codec_tag = (const AVCodecTag* const []){ff_codec_wav_tags, 0},
957 }; 1004 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698