7 #include "packager/media/formats/webm/webm_muxer.h"
9 #include "packager/media/base/fourccs.h"
10 #include "packager/media/base/media_sample.h"
11 #include "packager/media/base/media_stream.h"
12 #include "packager/media/base/stream_info.h"
13 #include "packager/media/formats/webm/mkv_writer.h"
14 #include "packager/media/formats/webm/multi_segment_segmenter.h"
15 #include "packager/media/formats/webm/single_segment_segmenter.h"
16 #include "packager/media/formats/webm/two_pass_single_segment_segmenter.h"
18 namespace edash_packager {
23 WebMMuxer::~WebMMuxer() {}
25 Status WebMMuxer::Initialize() {
26 CHECK_EQ(streams().size(), 1U);
28 if (crypto_period_duration_in_seconds() > 0) {
29 NOTIMPLEMENTED() <<
"Key rotation is not implemented for WebM";
30 return Status(error::UNIMPLEMENTED,
31 "Key rotation is not implemented for WebM");
34 if (encryption_key_source() && (protection_scheme() != FOURCC_cenc)) {
36 <<
"WebM does not support protection scheme other than 'cenc'.";
37 return Status(error::UNIMPLEMENTED,
38 "WebM does not support protection scheme other than 'cenc'.");
41 scoped_ptr<MkvWriter> writer(
new MkvWriter);
42 Status status = writer->Open(options().output_file_name);
47 segmenter_.reset(
new MultiSegmentSegmenter(options()));
48 }
else if (writer->Seekable()) {
49 segmenter_.reset(
new SingleSegmentSegmenter(options()));
51 segmenter_.reset(
new TwoPassSingleSegmentSegmenter(options()));
54 Status initialized = segmenter_->Initialize(
55 writer.Pass(), streams()[0]->info().get(), progress_listener(),
56 muxer_listener(), encryption_key_source(), max_sd_pixels(),
57 clear_lead_in_seconds());
59 if (!initialized.ok())
62 FireOnMediaStartEvent();
66 Status WebMMuxer::Finalize() {
68 Status segmenter_finalized = segmenter_->Finalize();
70 if (!segmenter_finalized.ok())
71 return segmenter_finalized;
73 FireOnMediaEndEvent();
78 Status WebMMuxer::DoAddSample(
const MediaStream* stream,
79 scoped_refptr<MediaSample> sample) {
81 DCHECK(stream == streams()[0]);
82 return segmenter_->AddSample(sample);
85 void WebMMuxer::FireOnMediaStartEvent() {
86 if (!muxer_listener())
89 DCHECK(!streams().empty()) <<
"Media started without a stream.";
91 const uint32_t timescale = streams().front()->info()->time_scale();
92 muxer_listener()->
OnMediaStart(options(), *streams().front()->info(),
93 timescale, MuxerListener::kContainerWebM);
96 void WebMMuxer::FireOnMediaEndEvent() {
97 if (!muxer_listener())
100 uint32_t init_range_start = 0;
101 uint32_t init_range_end = 0;
102 const bool has_init_range =
103 segmenter_->GetInitRangeStartAndEnd(&init_range_start, &init_range_end);
105 uint32_t index_range_start = 0;
106 uint32_t index_range_end = 0;
107 const bool has_index_range = segmenter_->GetIndexRangeStartAndEnd(
108 &index_range_start, &index_range_end);
110 const float duration_seconds = segmenter_->GetDuration();
112 const int64_t file_size =
114 if (file_size <= 0) {
115 LOG(ERROR) <<
"Invalid file size: " << file_size;
119 muxer_listener()->
OnMediaEnd(has_init_range, init_range_start, init_range_end,
120 has_index_range, index_range_start,
121 index_range_end, duration_seconds, file_size);