Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(50)

Side by Side Diff: media/webm/webm_cluster_parser.cc

Issue 11088047: Support encrypted audio stream in demuxer. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/webm/webm_cluster_parser.h ('k') | media/webm/webm_cluster_parser_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_cluster_parser.h" 5 #include "media/webm/webm_cluster_parser.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/sys_byteorder.h" 10 #include "base/sys_byteorder.h"
11 #include "media/base/data_buffer.h" 11 #include "media/base/data_buffer.h"
12 #include "media/base/decrypt_config.h" 12 #include "media/base/decrypt_config.h"
13 #include "media/webm/webm_constants.h" 13 #include "media/webm/webm_constants.h"
14 14
15 namespace media { 15 namespace media {
16 16
17 // Generates a 16 byte CTR counter block. The CTR counter block format is a 17 // Generates a 16 byte CTR counter block. The CTR counter block format is a
18 // CTR IV appended with a CTR block counter. |iv| is an 8 byte CTR IV. 18 // CTR IV appended with a CTR block counter. |iv| is an 8 byte CTR IV.
19 // Returns a string of kDecryptionKeySize bytes. 19 // Returns a string of kDecryptionKeySize bytes.
20 static std::string GenerateCounterBlock(uint64 iv) { 20 static std::string GenerateCounterBlock(uint64 iv) {
21 std::string counter_block(reinterpret_cast<char*>(&iv), sizeof(iv)); 21 std::string counter_block(reinterpret_cast<char*>(&iv), sizeof(iv));
22 counter_block.append(DecryptConfig::kDecryptionKeySize - sizeof(iv), 0); 22 counter_block.append(DecryptConfig::kDecryptionKeySize - sizeof(iv), 0);
23 return counter_block; 23 return counter_block;
24 } 24 }
25 25
26 WebMClusterParser::WebMClusterParser(int64 timecode_scale, 26 WebMClusterParser::WebMClusterParser(int64 timecode_scale,
27 int audio_track_num, 27 int audio_track_num,
28 int video_track_num, 28 int video_track_num,
29 const std::string& audio_encryption_key_id,
29 const std::string& video_encryption_key_id) 30 const std::string& video_encryption_key_id)
30 : timecode_multiplier_(timecode_scale / 1000.0), 31 : timecode_multiplier_(timecode_scale / 1000.0),
32 audio_encryption_key_id_(audio_encryption_key_id),
31 video_encryption_key_id_(video_encryption_key_id), 33 video_encryption_key_id_(video_encryption_key_id),
32 parser_(kWebMIdCluster, this), 34 parser_(kWebMIdCluster, this),
33 last_block_timecode_(-1), 35 last_block_timecode_(-1),
34 block_data_size_(-1), 36 block_data_size_(-1),
35 block_duration_(-1), 37 block_duration_(-1),
36 cluster_timecode_(-1), 38 cluster_timecode_(-1),
37 cluster_start_time_(kNoTimestamp()), 39 cluster_start_time_(kNoTimestamp()),
38 cluster_ended_(false), 40 cluster_ended_(false),
39 audio_(audio_track_num), 41 audio_(audio_track_num),
40 video_(video_track_num) { 42 video_(video_track_num) {
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 if (timecode < 0) { 193 if (timecode < 0) {
192 DVLOG(1) << "Got a block with negative timecode offset " << timecode; 194 DVLOG(1) << "Got a block with negative timecode offset " << timecode;
193 return false; 195 return false;
194 } 196 }
195 197
196 if (last_block_timecode_ != -1 && timecode < last_block_timecode_) { 198 if (last_block_timecode_ != -1 && timecode < last_block_timecode_) {
197 DVLOG(1) << "Got a block with a timecode before the previous block."; 199 DVLOG(1) << "Got a block with a timecode before the previous block.";
198 return false; 200 return false;
199 } 201 }
200 202
203 Track* track = NULL;
204 std::string encryption_key_id;
205 if (track_num == audio_.track_num()) {
206 track = &audio_;
207 encryption_key_id = audio_encryption_key_id_;
208 } else if (track_num == video_.track_num()) {
209 track = &video_;
210 encryption_key_id = video_encryption_key_id_;
211 } else {
212 DVLOG(1) << "Unexpected track number " << track_num;
213 return false;
214 }
215
201 last_block_timecode_ = timecode; 216 last_block_timecode_ = timecode;
202 217
203 base::TimeDelta timestamp = base::TimeDelta::FromMicroseconds( 218 base::TimeDelta timestamp = base::TimeDelta::FromMicroseconds(
204 (cluster_timecode_ + timecode) * timecode_multiplier_); 219 (cluster_timecode_ + timecode) * timecode_multiplier_);
205 220
206 // Every encrypted Block has a signal byte and IV prepended to it. Current
207 // encrypted WebM request for comments specification is here
208 // http://wiki.webmproject.org/encryption/webm-encryption-rfc
209 bool is_track_encrypted =
210 track_num == video_.track_num() && !video_encryption_key_id_.empty();
211
212 // The first bit of the flags is set when the block contains only keyframes. 221 // The first bit of the flags is set when the block contains only keyframes.
213 // http://www.matroska.org/technical/specs/index.html 222 // http://www.matroska.org/technical/specs/index.html
214 bool is_keyframe = (flags & 0x80) != 0; 223 bool is_keyframe = (flags & 0x80) != 0;
215 scoped_refptr<StreamParserBuffer> buffer = 224 scoped_refptr<StreamParserBuffer> buffer =
216 StreamParserBuffer::CopyFrom(data, size, is_keyframe); 225 StreamParserBuffer::CopyFrom(data, size, is_keyframe);
217 226
218 if (is_track_encrypted) { 227 // Every encrypted Block has a signal byte and IV prepended to it. Current
228 // encrypted WebM request for comments specification is here
229 // http://wiki.webmproject.org/encryption/webm-encryption-rfc
230 if (!encryption_key_id.empty()) {
219 uint8 signal_byte = data[0]; 231 uint8 signal_byte = data[0];
220 int data_offset = sizeof(signal_byte); 232 int data_offset = sizeof(signal_byte);
221 233
222 // Setting the DecryptConfig object of the buffer while leaving the 234 // Setting the DecryptConfig object of the buffer while leaving the
223 // initialization vector empty will tell the decryptor that the frame is 235 // initialization vector empty will tell the decryptor that the frame is
224 // unencrypted. 236 // unencrypted.
225 std::string counter_block; 237 std::string counter_block;
226 238
227 if (signal_byte & kWebMFlagEncryptedFrame) { 239 if (signal_byte & kWebMFlagEncryptedFrame) {
228 uint64 network_iv; 240 uint64 network_iv;
229 memcpy(&network_iv, data + data_offset, sizeof(network_iv)); 241 memcpy(&network_iv, data + data_offset, sizeof(network_iv));
230 const uint64 iv = base::NetToHost64(network_iv); 242 data_offset += sizeof(network_iv);
231 counter_block = GenerateCounterBlock(iv); 243 counter_block = GenerateCounterBlock(base::NetToHost64(network_iv));
232 data_offset += sizeof(iv);
233 } 244 }
234 245
235 // TODO(fgalligan): Revisit if DecryptConfig needs to be set on unencrypted 246 // TODO(fgalligan): Revisit if DecryptConfig needs to be set on unencrypted
236 // frames after the CDM API is finalized. 247 // frames after the CDM API is finalized.
237 // Unencrypted frames of potentially encrypted streams currently set 248 // Unencrypted frames of potentially encrypted streams currently set
238 // DecryptConfig. 249 // DecryptConfig.
239 buffer->SetDecryptConfig(scoped_ptr<DecryptConfig>(new DecryptConfig( 250 buffer->SetDecryptConfig(scoped_ptr<DecryptConfig>(new DecryptConfig(
240 video_encryption_key_id_, 251 encryption_key_id,
241 counter_block, 252 counter_block,
242 data_offset, 253 data_offset,
243 std::vector<SubsampleEntry>()))); 254 std::vector<SubsampleEntry>())));
244 } 255 }
245 256
246 buffer->SetTimestamp(timestamp); 257 buffer->SetTimestamp(timestamp);
247 if (cluster_start_time_ == kNoTimestamp()) 258 if (cluster_start_time_ == kNoTimestamp())
248 cluster_start_time_ = timestamp; 259 cluster_start_time_ = timestamp;
249 260
250 if (block_duration >= 0) { 261 if (block_duration >= 0) {
251 buffer->SetDuration(base::TimeDelta::FromMicroseconds( 262 buffer->SetDuration(base::TimeDelta::FromMicroseconds(
252 block_duration * timecode_multiplier_)); 263 block_duration * timecode_multiplier_));
253 } 264 }
254 265
255 if (track_num == audio_.track_num()) { 266 return track->AddBuffer(buffer);
256 return audio_.AddBuffer(buffer);
257 } else if (track_num == video_.track_num()) {
258 return video_.AddBuffer(buffer);
259 }
260
261 DVLOG(1) << "Unexpected track number " << track_num;
262 return false;
263 } 267 }
264 268
265 WebMClusterParser::Track::Track(int track_num) 269 WebMClusterParser::Track::Track(int track_num)
266 : track_num_(track_num) { 270 : track_num_(track_num) {
267 } 271 }
268 272
269 WebMClusterParser::Track::~Track() {} 273 WebMClusterParser::Track::~Track() {}
270 274
271 bool WebMClusterParser::Track::AddBuffer( 275 bool WebMClusterParser::Track::AddBuffer(
272 const scoped_refptr<StreamParserBuffer>& buffer) { 276 const scoped_refptr<StreamParserBuffer>& buffer) {
273 DVLOG(2) << "AddBuffer() : " << track_num_ 277 DVLOG(2) << "AddBuffer() : " << track_num_
274 << " ts " << buffer->GetTimestamp().InSecondsF() 278 << " ts " << buffer->GetTimestamp().InSecondsF()
275 << " dur " << buffer->GetDuration().InSecondsF() 279 << " dur " << buffer->GetDuration().InSecondsF()
276 << " kf " << buffer->IsKeyframe() 280 << " kf " << buffer->IsKeyframe()
277 << " size " << buffer->GetDataSize(); 281 << " size " << buffer->GetDataSize();
278 282
279 buffers_.push_back(buffer); 283 buffers_.push_back(buffer);
280 return true; 284 return true;
281 } 285 }
282 286
283 void WebMClusterParser::Track::Reset() { 287 void WebMClusterParser::Track::Reset() {
284 buffers_.clear(); 288 buffers_.clear();
285 } 289 }
286 290
287 } // namespace media 291 } // namespace media
OLDNEW
« no previous file with comments | « media/webm/webm_cluster_parser.h ('k') | media/webm/webm_cluster_parser_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698