| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "media/webm/webm_content_encodings_client.h" | 5 #include "media/webm/webm_content_encodings_client.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
| 9 #include "media/webm/webm_constants.h" | 9 #include "media/webm/webm_constants.h" |
| 10 | 10 |
| 11 namespace media { | 11 namespace media { |
| 12 | 12 |
| 13 WebMContentEncodingsClient::WebMContentEncodingsClient() | 13 WebMContentEncodingsClient::WebMContentEncodingsClient( |
| 14 : content_encryption_encountered_(false), | 14 const ErrorLogCB& error_cb) |
| 15 : error_cb_(error_cb), |
| 16 content_encryption_encountered_(false), |
| 15 content_encodings_ready_(false) { | 17 content_encodings_ready_(false) { |
| 16 } | 18 } |
| 17 | 19 |
| 18 WebMContentEncodingsClient::~WebMContentEncodingsClient() { | 20 WebMContentEncodingsClient::~WebMContentEncodingsClient() { |
| 19 STLDeleteElements(&content_encodings_); | 21 STLDeleteElements(&content_encodings_); |
| 20 } | 22 } |
| 21 | 23 |
| 22 const ContentEncodings& WebMContentEncodingsClient::content_encodings() const { | 24 const ContentEncodings& WebMContentEncodingsClient::content_encodings() const { |
| 23 DCHECK(content_encodings_ready_); | 25 DCHECK(content_encodings_ready_); |
| 24 return content_encodings_; | 26 return content_encodings_; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 36 if (id == kWebMIdContentEncoding) { | 38 if (id == kWebMIdContentEncoding) { |
| 37 DCHECK(!cur_content_encoding_.get()); | 39 DCHECK(!cur_content_encoding_.get()); |
| 38 DCHECK(!content_encryption_encountered_); | 40 DCHECK(!content_encryption_encountered_); |
| 39 cur_content_encoding_.reset(new ContentEncoding()); | 41 cur_content_encoding_.reset(new ContentEncoding()); |
| 40 return this; | 42 return this; |
| 41 } | 43 } |
| 42 | 44 |
| 43 if (id == kWebMIdContentEncryption) { | 45 if (id == kWebMIdContentEncryption) { |
| 44 DCHECK(cur_content_encoding_.get()); | 46 DCHECK(cur_content_encoding_.get()); |
| 45 if (content_encryption_encountered_) { | 47 if (content_encryption_encountered_) { |
| 46 DVLOG(1) << "Unexpected multiple ContentEncryption."; | 48 ERROR_LOG(error_cb_) << "Unexpected multiple ContentEncryption."; |
| 47 return NULL; | 49 return NULL; |
| 48 } | 50 } |
| 49 content_encryption_encountered_ = true; | 51 content_encryption_encountered_ = true; |
| 50 return this; | 52 return this; |
| 51 } | 53 } |
| 52 | 54 |
| 53 if (id == kWebMIdContentEncAESSettings) { | 55 if (id == kWebMIdContentEncAESSettings) { |
| 54 DCHECK(cur_content_encoding_.get()); | 56 DCHECK(cur_content_encoding_.get()); |
| 55 return this; | 57 return this; |
| 56 } | 58 } |
| 57 | 59 |
| 58 // This should not happen if WebMListParser is working properly. | 60 // This should not happen if WebMListParser is working properly. |
| 59 DCHECK(false); | 61 DCHECK(false); |
| 60 return NULL; | 62 return NULL; |
| 61 } | 63 } |
| 62 | 64 |
| 63 // Mandatory occurrence restriction is checked in this function. Multiple | 65 // Mandatory occurrence restriction is checked in this function. Multiple |
| 64 // occurrence restriction is checked in OnUInt and OnBinary. | 66 // occurrence restriction is checked in OnUInt and OnBinary. |
| 65 bool WebMContentEncodingsClient::OnListEnd(int id) { | 67 bool WebMContentEncodingsClient::OnListEnd(int id) { |
| 66 if (id == kWebMIdContentEncodings) { | 68 if (id == kWebMIdContentEncodings) { |
| 67 // ContentEncoding element is mandatory. Check this! | 69 // ContentEncoding element is mandatory. Check this! |
| 68 if (content_encodings_.empty()) { | 70 if (content_encodings_.empty()) { |
| 69 DVLOG(1) << "Missing ContentEncoding."; | 71 ERROR_LOG(error_cb_) << "Missing ContentEncoding."; |
| 70 return false; | 72 return false; |
| 71 } | 73 } |
| 72 content_encodings_ready_ = true; | 74 content_encodings_ready_ = true; |
| 73 return true; | 75 return true; |
| 74 } | 76 } |
| 75 | 77 |
| 76 if (id == kWebMIdContentEncoding) { | 78 if (id == kWebMIdContentEncoding) { |
| 77 DCHECK(cur_content_encoding_.get()); | 79 DCHECK(cur_content_encoding_.get()); |
| 78 | 80 |
| 79 // | 81 // |
| 80 // Specify default values to missing mandatory elements. | 82 // Specify default values to missing mandatory elements. |
| 81 // | 83 // |
| 82 | 84 |
| 83 if (cur_content_encoding_->order() == ContentEncoding::kOrderInvalid) { | 85 if (cur_content_encoding_->order() == ContentEncoding::kOrderInvalid) { |
| 84 // Default value of encoding order is 0, which should only be used on the | 86 // Default value of encoding order is 0, which should only be used on the |
| 85 // first ContentEncoding. | 87 // first ContentEncoding. |
| 86 if (!content_encodings_.empty()) { | 88 if (!content_encodings_.empty()) { |
| 87 DVLOG(1) << "Missing ContentEncodingOrder."; | 89 ERROR_LOG(error_cb_) << "Missing ContentEncodingOrder."; |
| 88 return false; | 90 return false; |
| 89 } | 91 } |
| 90 cur_content_encoding_->set_order(0); | 92 cur_content_encoding_->set_order(0); |
| 91 } | 93 } |
| 92 | 94 |
| 93 if (cur_content_encoding_->scope() == ContentEncoding::kScopeInvalid) | 95 if (cur_content_encoding_->scope() == ContentEncoding::kScopeInvalid) |
| 94 cur_content_encoding_->set_scope(ContentEncoding::kScopeAllFrameContents); | 96 cur_content_encoding_->set_scope(ContentEncoding::kScopeAllFrameContents); |
| 95 | 97 |
| 96 if (cur_content_encoding_->type() == ContentEncoding::kTypeInvalid) | 98 if (cur_content_encoding_->type() == ContentEncoding::kTypeInvalid) |
| 97 cur_content_encoding_->set_type(ContentEncoding::kTypeCompression); | 99 cur_content_encoding_->set_type(ContentEncoding::kTypeCompression); |
| 98 | 100 |
| 99 // Check for elements valid in spec but not supported for now. | 101 // Check for elements valid in spec but not supported for now. |
| 100 if (cur_content_encoding_->type() == ContentEncoding::kTypeCompression) { | 102 if (cur_content_encoding_->type() == ContentEncoding::kTypeCompression) { |
| 101 DVLOG(1) << "ContentCompression not supported."; | 103 ERROR_LOG(error_cb_) << "ContentCompression not supported."; |
| 102 return false; | 104 return false; |
| 103 } | 105 } |
| 104 | 106 |
| 105 // Enforce mandatory elements without default values. | 107 // Enforce mandatory elements without default values. |
| 106 DCHECK(cur_content_encoding_->type() == ContentEncoding::kTypeEncryption); | 108 DCHECK(cur_content_encoding_->type() == ContentEncoding::kTypeEncryption); |
| 107 if (!content_encryption_encountered_) { | 109 if (!content_encryption_encountered_) { |
| 108 DVLOG(1) << "ContentEncodingType is encryption but ContentEncryption " | 110 ERROR_LOG(error_cb_) << "ContentEncodingType is encryption but" |
| 109 "is missing."; | 111 << " ContentEncryption is missing."; |
| 110 return false; | 112 return false; |
| 111 } | 113 } |
| 112 | 114 |
| 113 content_encodings_.push_back(cur_content_encoding_.release()); | 115 content_encodings_.push_back(cur_content_encoding_.release()); |
| 114 content_encryption_encountered_ = false; | 116 content_encryption_encountered_ = false; |
| 115 return true; | 117 return true; |
| 116 } | 118 } |
| 117 | 119 |
| 118 if (id == kWebMIdContentEncryption) { | 120 if (id == kWebMIdContentEncryption) { |
| 119 DCHECK(cur_content_encoding_.get()); | 121 DCHECK(cur_content_encoding_.get()); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 138 return false; | 140 return false; |
| 139 } | 141 } |
| 140 | 142 |
| 141 // Multiple occurrence restriction and range are checked in this function. | 143 // Multiple occurrence restriction and range are checked in this function. |
| 142 // Mandatory occurrence restriction is checked in OnListEnd. | 144 // Mandatory occurrence restriction is checked in OnListEnd. |
| 143 bool WebMContentEncodingsClient::OnUInt(int id, int64 val) { | 145 bool WebMContentEncodingsClient::OnUInt(int id, int64 val) { |
| 144 DCHECK(cur_content_encoding_.get()); | 146 DCHECK(cur_content_encoding_.get()); |
| 145 | 147 |
| 146 if (id == kWebMIdContentEncodingOrder) { | 148 if (id == kWebMIdContentEncodingOrder) { |
| 147 if (cur_content_encoding_->order() != ContentEncoding::kOrderInvalid) { | 149 if (cur_content_encoding_->order() != ContentEncoding::kOrderInvalid) { |
| 148 DVLOG(1) << "Unexpected multiple ContentEncodingOrder."; | 150 ERROR_LOG(error_cb_) << "Unexpected multiple ContentEncodingOrder."; |
| 149 return false; | 151 return false; |
| 150 } | 152 } |
| 151 | 153 |
| 152 if (val != static_cast<int64>(content_encodings_.size())) { | 154 if (val != static_cast<int64>(content_encodings_.size())) { |
| 153 // According to the spec, encoding order starts with 0 and counts upwards. | 155 // According to the spec, encoding order starts with 0 and counts upwards. |
| 154 DVLOG(1) << "Unexpected ContentEncodingOrder."; | 156 ERROR_LOG(error_cb_) << "Unexpected ContentEncodingOrder."; |
| 155 return false; | 157 return false; |
| 156 } | 158 } |
| 157 | 159 |
| 158 cur_content_encoding_->set_order(val); | 160 cur_content_encoding_->set_order(val); |
| 159 return true; | 161 return true; |
| 160 } | 162 } |
| 161 | 163 |
| 162 if (id == kWebMIdContentEncodingScope) { | 164 if (id == kWebMIdContentEncodingScope) { |
| 163 if (cur_content_encoding_->scope() != ContentEncoding::kScopeInvalid) { | 165 if (cur_content_encoding_->scope() != ContentEncoding::kScopeInvalid) { |
| 164 DVLOG(1) << "Unexpected multiple ContentEncodingScope."; | 166 ERROR_LOG(error_cb_) << "Unexpected multiple ContentEncodingScope."; |
| 165 return false; | 167 return false; |
| 166 } | 168 } |
| 167 | 169 |
| 168 if (val == ContentEncoding::kScopeInvalid || | 170 if (val == ContentEncoding::kScopeInvalid || |
| 169 val > ContentEncoding::kScopeMax) { | 171 val > ContentEncoding::kScopeMax) { |
| 170 DVLOG(1) << "Unexpected ContentEncodingScope."; | 172 ERROR_LOG(error_cb_) << "Unexpected ContentEncodingScope."; |
| 171 return false; | 173 return false; |
| 172 } | 174 } |
| 173 | 175 |
| 174 if (val & ContentEncoding::kScopeNextContentEncodingData) { | 176 if (val & ContentEncoding::kScopeNextContentEncodingData) { |
| 175 DVLOG(1) << "Encoded next ContentEncoding is not supported."; | 177 ERROR_LOG(error_cb_) << "Encoded next ContentEncoding is not supported."; |
| 176 return false; | 178 return false; |
| 177 } | 179 } |
| 178 | 180 |
| 179 cur_content_encoding_->set_scope(static_cast<ContentEncoding::Scope>(val)); | 181 cur_content_encoding_->set_scope(static_cast<ContentEncoding::Scope>(val)); |
| 180 return true; | 182 return true; |
| 181 } | 183 } |
| 182 | 184 |
| 183 if (id == kWebMIdContentEncodingType) { | 185 if (id == kWebMIdContentEncodingType) { |
| 184 if (cur_content_encoding_->type() != ContentEncoding::kTypeInvalid) { | 186 if (cur_content_encoding_->type() != ContentEncoding::kTypeInvalid) { |
| 185 DVLOG(1) << "Unexpected multiple ContentEncodingType."; | 187 ERROR_LOG(error_cb_) << "Unexpected multiple ContentEncodingType."; |
| 186 return false; | 188 return false; |
| 187 } | 189 } |
| 188 | 190 |
| 189 if (val == ContentEncoding::kTypeCompression) { | 191 if (val == ContentEncoding::kTypeCompression) { |
| 190 DVLOG(1) << "ContentCompression not supported."; | 192 ERROR_LOG(error_cb_) << "ContentCompression not supported."; |
| 191 return false; | 193 return false; |
| 192 } | 194 } |
| 193 | 195 |
| 194 if (val != ContentEncoding::kTypeEncryption) { | 196 if (val != ContentEncoding::kTypeEncryption) { |
| 195 DVLOG(1) << "Unexpected ContentEncodingType " << val << "."; | 197 ERROR_LOG(error_cb_) << "Unexpected ContentEncodingType " << val << "."; |
| 196 return false; | 198 return false; |
| 197 } | 199 } |
| 198 | 200 |
| 199 cur_content_encoding_->set_type(static_cast<ContentEncoding::Type>(val)); | 201 cur_content_encoding_->set_type(static_cast<ContentEncoding::Type>(val)); |
| 200 return true; | 202 return true; |
| 201 } | 203 } |
| 202 | 204 |
| 203 if (id == kWebMIdContentEncAlgo) { | 205 if (id == kWebMIdContentEncAlgo) { |
| 204 if (cur_content_encoding_->encryption_algo() != | 206 if (cur_content_encoding_->encryption_algo() != |
| 205 ContentEncoding::kEncAlgoInvalid) { | 207 ContentEncoding::kEncAlgoInvalid) { |
| 206 DVLOG(1) << "Unexpected multiple ContentEncAlgo."; | 208 ERROR_LOG(error_cb_) << "Unexpected multiple ContentEncAlgo."; |
| 207 return false; | 209 return false; |
| 208 } | 210 } |
| 209 | 211 |
| 210 if (val < ContentEncoding::kEncAlgoNotEncrypted || | 212 if (val < ContentEncoding::kEncAlgoNotEncrypted || |
| 211 val > ContentEncoding::kEncAlgoAes) { | 213 val > ContentEncoding::kEncAlgoAes) { |
| 212 DVLOG(1) << "Unexpected ContentEncAlgo " << val << "."; | 214 ERROR_LOG(error_cb_) << "Unexpected ContentEncAlgo " << val << "."; |
| 213 return false; | 215 return false; |
| 214 } | 216 } |
| 215 | 217 |
| 216 cur_content_encoding_->set_encryption_algo( | 218 cur_content_encoding_->set_encryption_algo( |
| 217 static_cast<ContentEncoding::EncryptionAlgo>(val)); | 219 static_cast<ContentEncoding::EncryptionAlgo>(val)); |
| 218 return true; | 220 return true; |
| 219 } | 221 } |
| 220 | 222 |
| 221 if (id == kWebMIdAESSettingsCipherMode) { | 223 if (id == kWebMIdAESSettingsCipherMode) { |
| 222 if (cur_content_encoding_->cipher_mode() != | 224 if (cur_content_encoding_->cipher_mode() != |
| 223 ContentEncoding::kCipherModeInvalid) { | 225 ContentEncoding::kCipherModeInvalid) { |
| 224 DVLOG(1) << "Unexpected multiple AESSettingsCipherMode."; | 226 ERROR_LOG(error_cb_) << "Unexpected multiple AESSettingsCipherMode."; |
| 225 return false; | 227 return false; |
| 226 } | 228 } |
| 227 | 229 |
| 228 if (val != ContentEncoding::kCipherModeCtr) { | 230 if (val != ContentEncoding::kCipherModeCtr) { |
| 229 DVLOG(1) << "Unexpected AESSettingsCipherMode " << val << "."; | 231 ERROR_LOG(error_cb_) << "Unexpected AESSettingsCipherMode " << val << "."; |
| 230 return false; | 232 return false; |
| 231 } | 233 } |
| 232 | 234 |
| 233 cur_content_encoding_->set_cipher_mode( | 235 cur_content_encoding_->set_cipher_mode( |
| 234 static_cast<ContentEncoding::CipherMode>(val)); | 236 static_cast<ContentEncoding::CipherMode>(val)); |
| 235 return true; | 237 return true; |
| 236 } | 238 } |
| 237 | 239 |
| 238 // This should not happen if WebMListParser is working properly. | 240 // This should not happen if WebMListParser is working properly. |
| 239 DCHECK(false); | 241 DCHECK(false); |
| 240 return false; | 242 return false; |
| 241 } | 243 } |
| 242 | 244 |
| 243 // Multiple occurrence restriction is checked in this function. Mandatory | 245 // Multiple occurrence restriction is checked in this function. Mandatory |
| 244 // restriction is checked in OnListEnd. | 246 // restriction is checked in OnListEnd. |
| 245 bool WebMContentEncodingsClient::OnBinary(int id, const uint8* data, int size) { | 247 bool WebMContentEncodingsClient::OnBinary(int id, const uint8* data, int size) { |
| 246 DCHECK(cur_content_encoding_.get()); | 248 DCHECK(cur_content_encoding_.get()); |
| 247 DCHECK(data); | 249 DCHECK(data); |
| 248 DCHECK_GT(size, 0); | 250 DCHECK_GT(size, 0); |
| 249 | 251 |
| 250 if (id == kWebMIdContentEncKeyID) { | 252 if (id == kWebMIdContentEncKeyID) { |
| 251 if (!cur_content_encoding_->encryption_key_id().empty()) { | 253 if (!cur_content_encoding_->encryption_key_id().empty()) { |
| 252 DVLOG(1) << "Unexpected multiple ContentEncKeyID"; | 254 ERROR_LOG(error_cb_) << "Unexpected multiple ContentEncKeyID"; |
| 253 return false; | 255 return false; |
| 254 } | 256 } |
| 255 cur_content_encoding_->SetEncryptionKeyId(data, size); | 257 cur_content_encoding_->SetEncryptionKeyId(data, size); |
| 256 return true; | 258 return true; |
| 257 } | 259 } |
| 258 | 260 |
| 259 // This should not happen if WebMListParser is working properly. | 261 // This should not happen if WebMListParser is working properly. |
| 260 DCHECK(false); | 262 DCHECK(false); |
| 261 return false; | 263 return false; |
| 262 } | 264 } |
| 263 | 265 |
| 264 } // namespace media | 266 } // namespace media |
| OLD | NEW |