DASH Media Packaging SDK
 All Classes Namespaces Functions Variables Typedefs 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/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"
17 
18 namespace edash_packager {
19 namespace media {
20 namespace webm {
21 
22 WebMMuxer::WebMMuxer(const MuxerOptions& options) : Muxer(options) {}
23 WebMMuxer::~WebMMuxer() {}
24 
25 Status WebMMuxer::Initialize() {
26  CHECK_EQ(streams().size(), 1U);
27 
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");
32  }
33 
34  if (encryption_key_source() && (protection_scheme() != FOURCC_cenc)) {
35  NOTIMPLEMENTED()
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'.");
39  }
40 
41  scoped_ptr<MkvWriter> writer(new MkvWriter);
42  Status status = writer->Open(options().output_file_name);
43  if (!status.ok())
44  return status;
45 
46  if (!options().single_segment) {
47  segmenter_.reset(new MultiSegmentSegmenter(options()));
48  } else if (writer->Seekable()) {
49  segmenter_.reset(new SingleSegmentSegmenter(options()));
50  } else {
51  segmenter_.reset(new TwoPassSingleSegmentSegmenter(options()));
52  }
53 
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());
58 
59  if (!initialized.ok())
60  return initialized;
61 
62  FireOnMediaStartEvent();
63  return Status::OK;
64 }
65 
66 Status WebMMuxer::Finalize() {
67  DCHECK(segmenter_);
68  Status segmenter_finalized = segmenter_->Finalize();
69 
70  if (!segmenter_finalized.ok())
71  return segmenter_finalized;
72 
73  FireOnMediaEndEvent();
74  LOG(INFO) << "WEBM file '" << options().output_file_name << "' finalized.";
75  return Status::OK;
76 }
77 
78 Status WebMMuxer::DoAddSample(const MediaStream* stream,
79  scoped_refptr<MediaSample> sample) {
80  DCHECK(segmenter_);
81  DCHECK(stream == streams()[0]);
82  return segmenter_->AddSample(sample);
83 }
84 
85 void WebMMuxer::FireOnMediaStartEvent() {
86  if (!muxer_listener())
87  return;
88 
89  DCHECK(!streams().empty()) << "Media started without a stream.";
90 
91  const uint32_t timescale = streams().front()->info()->time_scale();
92  muxer_listener()->OnMediaStart(options(), *streams().front()->info(),
93  timescale, MuxerListener::kContainerWebM);
94 }
95 
96 void WebMMuxer::FireOnMediaEndEvent() {
97  if (!muxer_listener())
98  return;
99 
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);
104 
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);
109 
110  const float duration_seconds = segmenter_->GetDuration();
111 
112  const int64_t file_size =
113  File::GetFileSize(options().output_file_name.c_str());
114  if (file_size <= 0) {
115  LOG(ERROR) << "Invalid file size: " << file_size;
116  return;
117  }
118 
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);
122 }
123 
124 } // namespace webm
125 } // namespace media
126 } // namespace edash_packager
WebMMuxer(const MuxerOptions &options)
Create a WebMMuxer object from MuxerOptions.
Definition: webm_muxer.cc:22
virtual void OnMediaStart(const MuxerOptions &muxer_options, const StreamInfo &stream_info, uint32_t time_scale, ContainerType container_type)=0
This structure contains the list of configuration options for Muxer.
Definition: muxer_options.h:18
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
static int64_t GetFileSize(const char *file_name)
Definition: file.cc:175