DASH Media Packaging SDK
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator
webm_muxer.cc
1 // Copyright 2015 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/formats/webm/webm_muxer.h"
8 
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"
16 
17 namespace shaka {
18 namespace media {
19 namespace webm {
20 
21 WebMMuxer::WebMMuxer(const MuxerOptions& options) : Muxer(options) {}
22 WebMMuxer::~WebMMuxer() {}
23 
24 Status WebMMuxer::InitializeMuxer() {
25  CHECK_EQ(streams().size(), 1U);
26 
27  if (crypto_period_duration_in_seconds() > 0) {
28  NOTIMPLEMENTED() << "Key rotation is not implemented for WebM";
29  return Status(error::UNIMPLEMENTED,
30  "Key rotation is not implemented for WebM");
31  }
32 
33  if (encryption_key_source() && (protection_scheme() != FOURCC_cenc)) {
34  NOTIMPLEMENTED()
35  << "WebM does not support protection scheme other than 'cenc'.";
36  return Status(error::UNIMPLEMENTED,
37  "WebM does not support protection scheme other than 'cenc'.");
38  }
39 
40  std::unique_ptr<MkvWriter> writer(new MkvWriter);
41  Status status = writer->Open(options().output_file_name);
42  if (!status.ok())
43  return status;
44 
45  if (!options().segment_template.empty()) {
46  segmenter_.reset(new MultiSegmentSegmenter(options()));
47  } else {
48  segmenter_.reset(new TwoPassSingleSegmentSegmenter(options()));
49  }
50 
51  Status initialized = segmenter_->Initialize(
52  std::move(writer), streams()[0].get(), progress_listener(),
53  muxer_listener(), encryption_key_source(), max_sd_pixels(),
54  max_hd_pixels(), max_uhd1_pixels(), clear_lead_in_seconds());
55 
56  if (!initialized.ok())
57  return initialized;
58 
59  FireOnMediaStartEvent();
60  return Status::OK;
61 }
62 
63 Status WebMMuxer::Finalize() {
64  DCHECK(segmenter_);
65  Status segmenter_finalized = segmenter_->Finalize();
66 
67  if (!segmenter_finalized.ok())
68  return segmenter_finalized;
69 
70  FireOnMediaEndEvent();
71  LOG(INFO) << "WEBM file '" << options().output_file_name << "' finalized.";
72  return Status::OK;
73 }
74 
75 Status WebMMuxer::AddSample(size_t stream_id,
76  std::shared_ptr<MediaSample> sample) {
77  DCHECK(segmenter_);
78  DCHECK_EQ(stream_id, 0u);
79  return segmenter_->AddSample(sample);
80 }
81 
82 Status WebMMuxer::FinalizeSegment(size_t stream_id,
83  std::shared_ptr<SegmentInfo> segment_info) {
84  DCHECK(segmenter_);
85  DCHECK_EQ(stream_id, 0u);
86  return segmenter_->FinalizeSegment(segment_info->start_timestamp,
87  segment_info->duration,
88  segment_info->is_subsegment);
89 }
90 
91 void WebMMuxer::FireOnMediaStartEvent() {
92  if (!muxer_listener())
93  return;
94 
95  DCHECK(!streams().empty()) << "Media started without a stream.";
96 
97  const uint32_t timescale = streams().front()->time_scale();
98  muxer_listener()->OnMediaStart(options(), *streams().front(), timescale,
99  MuxerListener::kContainerWebM);
100 }
101 
102 void WebMMuxer::FireOnMediaEndEvent() {
103  if (!muxer_listener())
104  return;
105 
106  uint64_t init_range_start = 0;
107  uint64_t init_range_end = 0;
108  const bool has_init_range =
109  segmenter_->GetInitRangeStartAndEnd(&init_range_start, &init_range_end);
110 
111  uint64_t index_range_start = 0;
112  uint64_t index_range_end = 0;
113  const bool has_index_range = segmenter_->GetIndexRangeStartAndEnd(
114  &index_range_start, &index_range_end);
115 
116  const float duration_seconds = segmenter_->GetDuration();
117 
118  const int64_t file_size =
119  File::GetFileSize(options().output_file_name.c_str());
120  if (file_size <= 0) {
121  LOG(ERROR) << "Invalid file size: " << file_size;
122  return;
123  }
124 
125  muxer_listener()->OnMediaEnd(has_init_range, init_range_start, init_range_end,
126  has_index_range, index_range_start,
127  index_range_end, duration_seconds, file_size);
128 }
129 
130 } // namespace webm
131 } // namespace media
132 } // namespace shaka
virtual void OnMediaEnd(bool has_init_range, uint64_t init_range_start, uint64_t init_range_end, bool has_index_range, uint64_t index_range_start, uint64_t index_range_end, float duration_seconds, uint64_t file_size)=0
This structure contains the list of configuration options for Muxer.
Definition: muxer_options.h:18
static int64_t GetFileSize(const char *file_name)
Definition: file.cc:176
virtual void OnMediaStart(const MuxerOptions &muxer_options, const StreamInfo &stream_info, uint32_t time_scale, ContainerType container_type)=0
WebMMuxer(const MuxerOptions &options)
Create a WebMMuxer object from MuxerOptions.
Definition: webm_muxer.cc:21