Shaka Packager SDK
Loading...
Searching...
No Matches
simple_mpd_notifier.cc
1// Copyright 2015 Google LLC. 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/mpd/base/simple_mpd_notifier.h>
8
9#include <absl/log/check.h>
10#include <absl/log/log.h>
11
12#include <packager/mpd/base/adaptation_set.h>
13#include <packager/mpd/base/mpd_builder.h>
14#include <packager/mpd/base/mpd_notifier_util.h>
15#include <packager/mpd/base/mpd_utils.h>
16#include <packager/mpd/base/period.h>
17#include <packager/mpd/base/representation.h>
18
19namespace shaka {
20
21SimpleMpdNotifier::SimpleMpdNotifier(const MpdOptions& mpd_options)
22 : MpdNotifier(mpd_options),
23 output_path_(mpd_options.mpd_params.mpd_output),
24 mpd_builder_(new MpdBuilder(mpd_options)),
25 content_protection_in_adaptation_set_(
26 mpd_options.mpd_params.generate_dash_if_iop_compliant_mpd) {
27 for (const std::string& base_url : mpd_options.mpd_params.base_urls)
28 mpd_builder_->AddBaseUrl(base_url);
29}
30
31SimpleMpdNotifier::~SimpleMpdNotifier() {}
32
33bool SimpleMpdNotifier::Init() {
34 return true;
35}
36
37bool SimpleMpdNotifier::NotifyNewContainer(const MediaInfo& media_info,
38 uint32_t* container_id) {
39 DCHECK(container_id);
40
41 ContentType content_type = GetContentType(media_info);
42 if (content_type == kContentTypeUnknown)
43 return false;
44
45 MediaInfo adjusted_media_info(media_info);
46 MpdBuilder::MakePathsRelativeToMpd(output_path_, &adjusted_media_info);
47
48 absl::MutexLock auto_lock(&lock_);
49 const double kPeriodStartTimeSeconds = 0.0;
50 Period* period = mpd_builder_->GetOrCreatePeriod(kPeriodStartTimeSeconds);
51 DCHECK(period);
52 AdaptationSet* adaptation_set = period->GetOrCreateAdaptationSet(
53 media_info, content_protection_in_adaptation_set_);
54 DCHECK(adaptation_set);
55 if (!adaptation_set->has_id())
56 adaptation_set->set_id(next_adaptation_set_id_++);
57 Representation* representation =
58 adaptation_set->AddRepresentation(adjusted_media_info);
59 if (!representation)
60 return false;
61
62 *container_id = representation->id();
63 if (content_protection_in_adaptation_set_) {
64 // ContentProtection elements are already added to AdaptationSet above.
65 // Use RepresentationId to AdaptationSet map to update ContentProtection
66 // in AdaptationSet in NotifyEncryptionUpdate.
67 representation_id_to_adaptation_set_[representation->id()] = adaptation_set;
68 } else {
69 AddContentProtectionElements(media_info, representation);
70 }
71 representation_map_[representation->id()] = representation;
72 return true;
73}
74
75bool SimpleMpdNotifier::NotifyAvailabilityTimeOffset(uint32_t container_id) {
76 absl::MutexLock lock(&lock_);
77 auto it = representation_map_.find(container_id);
78 if (it == representation_map_.end()) {
79 LOG(ERROR) << "Unexpected container_id: " << container_id;
80 return false;
81 }
82 it->second->SetAvailabilityTimeOffset();
83 return true;
84}
85
86bool SimpleMpdNotifier::NotifySampleDuration(uint32_t container_id,
87 int32_t sample_duration) {
88 absl::MutexLock lock(&lock_);
89 auto it = representation_map_.find(container_id);
90 if (it == representation_map_.end()) {
91 LOG(ERROR) << "Unexpected container_id: " << container_id;
92 return false;
93 }
94 it->second->SetSampleDuration(sample_duration);
95 return true;
96}
97
98bool SimpleMpdNotifier::NotifySegmentDuration(uint32_t container_id) {
99 absl::MutexLock lock(&lock_);
100 auto it = representation_map_.find(container_id);
101 if (it == representation_map_.end()) {
102 LOG(ERROR) << "Unexpected container_id: " << container_id;
103 return false;
104 }
105 it->second->SetSegmentDuration();
106 return true;
107}
108
109bool SimpleMpdNotifier::NotifyNewSegment(uint32_t container_id,
110 int64_t start_time,
111 int64_t duration,
112 uint64_t size,
113 int64_t segment_number) {
114 absl::MutexLock lock(&lock_);
115 auto it = representation_map_.find(container_id);
116 if (it == representation_map_.end()) {
117 LOG(ERROR) << "Unexpected container_id: " << container_id;
118 return false;
119 }
120 it->second->AddNewSegment(start_time, duration, size, segment_number);
121 return true;
122}
123
124bool SimpleMpdNotifier::NotifyCompletedSegment(uint32_t container_id,
125 int64_t duration,
126 uint64_t size) {
127 absl::MutexLock lock(&lock_);
128 auto it = representation_map_.find(container_id);
129 if (it == representation_map_.end()) {
130 LOG(ERROR) << "Unexpected container_id: " << container_id;
131 return false;
132 }
133 it->second->UpdateCompletedSegment(duration, size);
134 return true;
135}
136
137bool SimpleMpdNotifier::NotifyCueEvent(uint32_t container_id,
138 int64_t timestamp) {
139 absl::MutexLock lock(&lock_);
140 auto it = representation_map_.find(container_id);
141 if (it == representation_map_.end()) {
142 LOG(ERROR) << "Unexpected container_id: " << container_id;
143 return false;
144 }
145 Representation* original_representation = it->second;
146 AdaptationSet* original_adaptation_set =
147 representation_id_to_adaptation_set_[container_id];
148
149 const MediaInfo& media_info = original_representation->GetMediaInfo();
150 const double period_start_time_seconds =
151 static_cast<double>(timestamp) / media_info.reference_time_scale();
152
153 Period* period = mpd_builder_->GetOrCreatePeriod(period_start_time_seconds);
154 DCHECK(period);
155 AdaptationSet* adaptation_set = period->GetOrCreateAdaptationSet(
156 media_info, content_protection_in_adaptation_set_);
157 DCHECK(adaptation_set);
158 if (!adaptation_set->has_id()) {
159 adaptation_set->set_id(original_adaptation_set->id());
160 } else {
161 DCHECK_EQ(adaptation_set->id(), original_adaptation_set->id());
162 }
163
164 Representation* representation =
165 adaptation_set->CopyRepresentation(*original_representation);
166 if (!representation)
167 return false;
168
169 if (content_protection_in_adaptation_set_) {
170 // ContentProtection elements are already added to AdaptationSet above.
171 // Use RepresentationId to AdaptationSet map to update ContentProtection
172 // in AdaptationSet in NotifyEncryptionUpdate.
173 representation_id_to_adaptation_set_[representation->id()] = adaptation_set;
174 } else {
175 AddContentProtectionElements(media_info, representation);
176 }
177 representation_map_[representation->id()] = representation;
178 return true;
179}
180
181bool SimpleMpdNotifier::NotifyEncryptionUpdate(
182 uint32_t container_id,
183 const std::string& drm_uuid,
184 const std::vector<uint8_t>& new_key_id,
185 const std::vector<uint8_t>& new_pssh) {
186 absl::MutexLock lock(&lock_);
187 auto it = representation_map_.find(container_id);
188 if (it == representation_map_.end()) {
189 LOG(ERROR) << "Unexpected container_id: " << container_id;
190 return false;
191 }
192
193 if (content_protection_in_adaptation_set_) {
194 AdaptationSet* adaptation_set_for_representation =
195 representation_id_to_adaptation_set_[it->second->id()];
196 adaptation_set_for_representation->UpdateContentProtectionPssh(
197 drm_uuid, Uint8VectorToBase64(new_pssh));
198 } else {
199 it->second->UpdateContentProtectionPssh(drm_uuid,
200 Uint8VectorToBase64(new_pssh));
201 }
202 return true;
203}
204
205bool SimpleMpdNotifier::NotifyMediaInfoUpdate(uint32_t container_id,
206 const MediaInfo& media_info) {
207 absl::MutexLock lock(&lock_);
208 auto it = representation_map_.find(container_id);
209 if (it == representation_map_.end()) {
210 LOG(ERROR) << "Unexpected container_id: " << container_id;
211 return false;
212 }
213
214 MediaInfo adjusted_media_info(media_info);
215 MpdBuilder::MakePathsRelativeToMpd(output_path_, &adjusted_media_info);
216
217 it->second->set_media_info(adjusted_media_info);
218 return true;
219}
220
221bool SimpleMpdNotifier::Flush() {
222 absl::MutexLock lock(&lock_);
223 return WriteMpdToFile(output_path_, mpd_builder_.get());
224}
225
226} // namespace shaka
virtual Representation * AddRepresentation(const MediaInfo &media_info)
virtual Representation * CopyRepresentation(const Representation &representation)
virtual void UpdateContentProtectionPssh(const std::string &drm_uuid, const std::string &pssh)
void set_id(uint32_t id)
virtual AdaptationSet * GetOrCreateAdaptationSet(const MediaInfo &media_info, bool content_protection_in_adaptation_set)
Definition period.cc:75
virtual const MediaInfo & GetMediaInfo() const
uint32_t id() const
All the methods that are virtual are virtual for mocking.
std::string Uint8VectorToBase64(const std::vector< uint8_t > &input)
Converts uint8 vector into base64 encoded string.
ContentType GetContentType(const MediaInfo &media_info)
bool WriteMpdToFile(const std::string &output_path, MpdBuilder *mpd_builder)
void AddContentProtectionElements(const MediaInfo &media_info, Representation *parent)
Definition mpd_utils.cc:523