Updating XTBs based on .GRDs from branch master
[chromium-blink-merge.git] / media / formats / webm / webm_content_encodings_client.cc
bloba9783ddf99d0add817533b272cf71015d058b31c
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "media/formats/webm/webm_content_encodings_client.h"
7 #include "base/logging.h"
8 #include "base/stl_util.h"
9 #include "media/formats/webm/webm_constants.h"
11 namespace media {
13 WebMContentEncodingsClient::WebMContentEncodingsClient(
14 const scoped_refptr<MediaLog>& media_log)
15 : media_log_(media_log),
16 content_encryption_encountered_(false),
17 content_encodings_ready_(false) {
20 WebMContentEncodingsClient::~WebMContentEncodingsClient() {
21 STLDeleteElements(&content_encodings_);
24 const ContentEncodings& WebMContentEncodingsClient::content_encodings() const {
25 DCHECK(content_encodings_ready_);
26 return content_encodings_;
29 WebMParserClient* WebMContentEncodingsClient::OnListStart(int id) {
30 if (id == kWebMIdContentEncodings) {
31 DCHECK(!cur_content_encoding_.get());
32 DCHECK(!content_encryption_encountered_);
33 STLDeleteElements(&content_encodings_);
34 content_encodings_ready_ = false;
35 return this;
38 if (id == kWebMIdContentEncoding) {
39 DCHECK(!cur_content_encoding_.get());
40 DCHECK(!content_encryption_encountered_);
41 cur_content_encoding_.reset(new ContentEncoding());
42 return this;
45 if (id == kWebMIdContentEncryption) {
46 DCHECK(cur_content_encoding_.get());
47 if (content_encryption_encountered_) {
48 MEDIA_LOG(ERROR, media_log_) << "Unexpected multiple ContentEncryption.";
49 return NULL;
51 content_encryption_encountered_ = true;
52 return this;
55 if (id == kWebMIdContentEncAESSettings) {
56 DCHECK(cur_content_encoding_.get());
57 return this;
60 // This should not happen if WebMListParser is working properly.
61 DCHECK(false);
62 return NULL;
65 // Mandatory occurrence restriction is checked in this function. Multiple
66 // occurrence restriction is checked in OnUInt and OnBinary.
67 bool WebMContentEncodingsClient::OnListEnd(int id) {
68 if (id == kWebMIdContentEncodings) {
69 // ContentEncoding element is mandatory. Check this!
70 if (content_encodings_.empty()) {
71 MEDIA_LOG(ERROR, media_log_) << "Missing ContentEncoding.";
72 return false;
74 content_encodings_ready_ = true;
75 return true;
78 if (id == kWebMIdContentEncoding) {
79 DCHECK(cur_content_encoding_.get());
82 // Specify default values to missing mandatory elements.
85 if (cur_content_encoding_->order() == ContentEncoding::kOrderInvalid) {
86 // Default value of encoding order is 0, which should only be used on the
87 // first ContentEncoding.
88 if (!content_encodings_.empty()) {
89 MEDIA_LOG(ERROR, media_log_) << "Missing ContentEncodingOrder.";
90 return false;
92 cur_content_encoding_->set_order(0);
95 if (cur_content_encoding_->scope() == ContentEncoding::kScopeInvalid)
96 cur_content_encoding_->set_scope(ContentEncoding::kScopeAllFrameContents);
98 if (cur_content_encoding_->type() == ContentEncoding::kTypeInvalid)
99 cur_content_encoding_->set_type(ContentEncoding::kTypeCompression);
101 // Check for elements valid in spec but not supported for now.
102 if (cur_content_encoding_->type() == ContentEncoding::kTypeCompression) {
103 MEDIA_LOG(ERROR, media_log_) << "ContentCompression not supported.";
104 return false;
107 // Enforce mandatory elements without default values.
108 DCHECK(cur_content_encoding_->type() == ContentEncoding::kTypeEncryption);
109 if (!content_encryption_encountered_) {
110 MEDIA_LOG(ERROR, media_log_) << "ContentEncodingType is encryption but"
111 << " ContentEncryption is missing.";
112 return false;
115 content_encodings_.push_back(cur_content_encoding_.release());
116 content_encryption_encountered_ = false;
117 return true;
120 if (id == kWebMIdContentEncryption) {
121 DCHECK(cur_content_encoding_.get());
122 // Specify default value for elements that are not present.
123 if (cur_content_encoding_->encryption_algo() ==
124 ContentEncoding::kEncAlgoInvalid) {
125 cur_content_encoding_->set_encryption_algo(
126 ContentEncoding::kEncAlgoNotEncrypted);
128 return true;
131 if (id == kWebMIdContentEncAESSettings) {
132 if (cur_content_encoding_->cipher_mode() ==
133 ContentEncoding::kCipherModeInvalid)
134 cur_content_encoding_->set_cipher_mode(ContentEncoding::kCipherModeCtr);
135 return true;
138 // This should not happen if WebMListParser is working properly.
139 DCHECK(false);
140 return false;
143 // Multiple occurrence restriction and range are checked in this function.
144 // Mandatory occurrence restriction is checked in OnListEnd.
145 bool WebMContentEncodingsClient::OnUInt(int id, int64 val) {
146 DCHECK(cur_content_encoding_.get());
148 if (id == kWebMIdContentEncodingOrder) {
149 if (cur_content_encoding_->order() != ContentEncoding::kOrderInvalid) {
150 MEDIA_LOG(ERROR, media_log_)
151 << "Unexpected multiple ContentEncodingOrder.";
152 return false;
155 if (val != static_cast<int64>(content_encodings_.size())) {
156 // According to the spec, encoding order starts with 0 and counts upwards.
157 MEDIA_LOG(ERROR, media_log_) << "Unexpected ContentEncodingOrder.";
158 return false;
161 cur_content_encoding_->set_order(val);
162 return true;
165 if (id == kWebMIdContentEncodingScope) {
166 if (cur_content_encoding_->scope() != ContentEncoding::kScopeInvalid) {
167 MEDIA_LOG(ERROR, media_log_)
168 << "Unexpected multiple ContentEncodingScope.";
169 return false;
172 if (val == ContentEncoding::kScopeInvalid ||
173 val > ContentEncoding::kScopeMax) {
174 MEDIA_LOG(ERROR, media_log_) << "Unexpected ContentEncodingScope.";
175 return false;
178 if (val & ContentEncoding::kScopeNextContentEncodingData) {
179 MEDIA_LOG(ERROR, media_log_) << "Encoded next ContentEncoding is not "
180 "supported.";
181 return false;
184 cur_content_encoding_->set_scope(static_cast<ContentEncoding::Scope>(val));
185 return true;
188 if (id == kWebMIdContentEncodingType) {
189 if (cur_content_encoding_->type() != ContentEncoding::kTypeInvalid) {
190 MEDIA_LOG(ERROR, media_log_)
191 << "Unexpected multiple ContentEncodingType.";
192 return false;
195 if (val == ContentEncoding::kTypeCompression) {
196 MEDIA_LOG(ERROR, media_log_) << "ContentCompression not supported.";
197 return false;
200 if (val != ContentEncoding::kTypeEncryption) {
201 MEDIA_LOG(ERROR, media_log_) << "Unexpected ContentEncodingType " << val
202 << ".";
203 return false;
206 cur_content_encoding_->set_type(static_cast<ContentEncoding::Type>(val));
207 return true;
210 if (id == kWebMIdContentEncAlgo) {
211 if (cur_content_encoding_->encryption_algo() !=
212 ContentEncoding::kEncAlgoInvalid) {
213 MEDIA_LOG(ERROR, media_log_) << "Unexpected multiple ContentEncAlgo.";
214 return false;
217 if (val < ContentEncoding::kEncAlgoNotEncrypted ||
218 val > ContentEncoding::kEncAlgoAes) {
219 MEDIA_LOG(ERROR, media_log_) << "Unexpected ContentEncAlgo " << val
220 << ".";
221 return false;
224 cur_content_encoding_->set_encryption_algo(
225 static_cast<ContentEncoding::EncryptionAlgo>(val));
226 return true;
229 if (id == kWebMIdAESSettingsCipherMode) {
230 if (cur_content_encoding_->cipher_mode() !=
231 ContentEncoding::kCipherModeInvalid) {
232 MEDIA_LOG(ERROR, media_log_)
233 << "Unexpected multiple AESSettingsCipherMode.";
234 return false;
237 if (val != ContentEncoding::kCipherModeCtr) {
238 MEDIA_LOG(ERROR, media_log_) << "Unexpected AESSettingsCipherMode " << val
239 << ".";
240 return false;
243 cur_content_encoding_->set_cipher_mode(
244 static_cast<ContentEncoding::CipherMode>(val));
245 return true;
248 // This should not happen if WebMListParser is working properly.
249 DCHECK(false);
250 return false;
253 // Multiple occurrence restriction is checked in this function. Mandatory
254 // restriction is checked in OnListEnd.
255 bool WebMContentEncodingsClient::OnBinary(int id, const uint8* data, int size) {
256 DCHECK(cur_content_encoding_.get());
257 DCHECK(data);
258 DCHECK_GT(size, 0);
260 if (id == kWebMIdContentEncKeyID) {
261 if (!cur_content_encoding_->encryption_key_id().empty()) {
262 MEDIA_LOG(ERROR, media_log_) << "Unexpected multiple ContentEncKeyID";
263 return false;
265 cur_content_encoding_->SetEncryptionKeyId(data, size);
266 return true;
269 // This should not happen if WebMListParser is working properly.
270 DCHECK(false);
271 return false;
274 } // namespace media