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/stream_info.h"
12 #include "packager/media/formats/webm/mkv_writer.h"
13 #include "packager/media/formats/webm/multi_segment_segmenter.h"
14 #include "packager/media/formats/webm/single_segment_segmenter.h"
15 #include "packager/media/formats/webm/two_pass_single_segment_segmenter.h"
22 WebMMuxer::~WebMMuxer() {}
24 Status WebMMuxer::InitializeMuxer() {
25 CHECK_EQ(streams().size(), 1U);
27 if (streams()[0]->is_encrypted() &&
28 streams()[0]->encryption_config().protection_scheme != FOURCC_cenc) {
29 LOG(ERROR) <<
"WebM does not support protection scheme other than 'cenc'.";
30 return Status(error::INVALID_ARGUMENT,
31 "WebM does not support protection scheme other than 'cenc'.");
34 if (!options().segment_template.empty()) {
35 segmenter_.reset(
new MultiSegmentSegmenter(options()));
37 segmenter_.reset(
new TwoPassSingleSegmentSegmenter(options()));
40 Status initialized = segmenter_->Initialize(
41 streams()[0].
get(), progress_listener(), muxer_listener());
42 if (!initialized.ok())
45 FireOnMediaStartEvent();
49 Status WebMMuxer::Finalize() {
51 Status segmenter_finalized = segmenter_->Finalize();
53 if (!segmenter_finalized.ok())
54 return segmenter_finalized;
56 FireOnMediaEndEvent();
61 Status WebMMuxer::AddSample(
size_t stream_id,
62 std::shared_ptr<MediaSample> sample) {
64 DCHECK_EQ(stream_id, 0u);
65 return segmenter_->AddSample(sample);
68 Status WebMMuxer::FinalizeSegment(
size_t stream_id,
69 std::shared_ptr<SegmentInfo> segment_info) {
71 DCHECK_EQ(stream_id, 0u);
73 if (segment_info->key_rotation_encryption_config) {
74 NOTIMPLEMENTED() <<
"Key rotation is not implemented for WebM.";
75 return Status(error::UNIMPLEMENTED,
76 "Key rotation is not implemented for WebM");
78 return segmenter_->FinalizeSegment(segment_info->start_timestamp,
79 segment_info->duration,
80 segment_info->is_subsegment);
83 void WebMMuxer::FireOnMediaStartEvent() {
84 if (!muxer_listener())
87 DCHECK(!streams().empty()) <<
"Media started without a stream.";
89 const uint32_t timescale = streams().front()->time_scale();
90 muxer_listener()->
OnMediaStart(options(), *streams().front(), timescale,
91 MuxerListener::kContainerWebM);
94 void WebMMuxer::FireOnMediaEndEvent() {
95 if (!muxer_listener())
98 uint64_t init_range_start = 0;
99 uint64_t init_range_end = 0;
100 const bool has_init_range =
101 segmenter_->GetInitRangeStartAndEnd(&init_range_start, &init_range_end);
103 uint64_t index_range_start = 0;
104 uint64_t index_range_end = 0;
105 const bool has_index_range = segmenter_->GetIndexRangeStartAndEnd(
106 &index_range_start, &index_range_end);
108 const float duration_seconds = segmenter_->GetDurationInSeconds();
110 const int64_t file_size =
112 if (file_size <= 0) {
113 LOG(ERROR) <<
"Invalid file size: " << file_size;
117 muxer_listener()->
OnMediaEnd(has_init_range, init_range_start, init_range_end,
118 has_index_range, index_range_start,
119 index_range_end, duration_seconds, file_size);