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

Side by Side Diff: media/filters/decrypting_video_decoder.cc

Issue 16274005: Separate DemuxerStream and VideoDecoder. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix win64 Created 7 years, 5 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
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/filters/decrypting_video_decoder.h" 5 #include "media/filters/decrypting_video_decoder.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback_helpers.h" 8 #include "base/callback_helpers.h"
9 #include "base/debug/trace_event.h" 9 #include "base/debug/trace_event.h"
10 #include "base/location.h" 10 #include "base/location.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/message_loop/message_loop_proxy.h" 12 #include "base/message_loop/message_loop_proxy.h"
13 #include "media/base/bind_to_loop.h" 13 #include "media/base/bind_to_loop.h"
14 #include "media/base/decoder_buffer.h" 14 #include "media/base/decoder_buffer.h"
15 #include "media/base/decryptor.h" 15 #include "media/base/decryptor.h"
16 #include "media/base/demuxer_stream.h"
17 #include "media/base/pipeline.h" 16 #include "media/base/pipeline.h"
18 #include "media/base/video_decoder_config.h" 17 #include "media/base/video_decoder_config.h"
19 #include "media/base/video_frame.h" 18 #include "media/base/video_frame.h"
20 19
21 namespace media { 20 namespace media {
22 21
23 DecryptingVideoDecoder::DecryptingVideoDecoder( 22 DecryptingVideoDecoder::DecryptingVideoDecoder(
24 const scoped_refptr<base::MessageLoopProxy>& message_loop, 23 const scoped_refptr<base::MessageLoopProxy>& message_loop,
25 const SetDecryptorReadyCB& set_decryptor_ready_cb) 24 const SetDecryptorReadyCB& set_decryptor_ready_cb)
26 : message_loop_(message_loop), 25 : message_loop_(message_loop),
27 weak_factory_(this), 26 weak_factory_(this),
28 state_(kUninitialized), 27 state_(kUninitialized),
29 demuxer_stream_(NULL),
30 set_decryptor_ready_cb_(set_decryptor_ready_cb), 28 set_decryptor_ready_cb_(set_decryptor_ready_cb),
31 decryptor_(NULL), 29 decryptor_(NULL),
32 key_added_while_decode_pending_(false), 30 key_added_while_decode_pending_(false),
33 trace_id_(0) { 31 trace_id_(0) {
34 } 32 }
35 33
36 void DecryptingVideoDecoder::Initialize( 34 void DecryptingVideoDecoder::Initialize(
37 DemuxerStream* stream, 35 const VideoDecoderConfig& config,
38 const PipelineStatusCB& status_cb, 36 const PipelineStatusCB& status_cb,
39 const StatisticsCB& statistics_cb) { 37 const StatisticsCB& statistics_cb) {
40 DVLOG(2) << "Initialize()"; 38 DVLOG(2) << "Initialize()";
41 DCHECK(message_loop_->BelongsToCurrentThread()); 39 DCHECK(message_loop_->BelongsToCurrentThread());
42 DCHECK(state_ == kUninitialized || 40 DCHECK(state_ == kUninitialized ||
43 state_ == kIdle || 41 state_ == kIdle ||
44 state_ == kDecodeFinished) << state_; 42 state_ == kDecodeFinished) << state_;
45 DCHECK(read_cb_.is_null()); 43 DCHECK(read_cb_.is_null());
46 DCHECK(reset_cb_.is_null()); 44 DCHECK(reset_cb_.is_null());
47 DCHECK(stream); 45 DCHECK(config.IsValidConfig());
46 DCHECK(config.is_encrypted());
48 47
49 init_cb_ = BindToCurrentLoop(status_cb); 48 init_cb_ = BindToCurrentLoop(status_cb);
50 weak_this_ = weak_factory_.GetWeakPtr(); 49 weak_this_ = weak_factory_.GetWeakPtr();
51 demuxer_stream_ = stream; 50 config_ = config;
52 statistics_cb_ = statistics_cb; 51 statistics_cb_ = statistics_cb;
53 52
54 const VideoDecoderConfig& config = demuxer_stream_->video_decoder_config();
55 DCHECK(config.IsValidConfig());
56 DCHECK(config.is_encrypted());
57
58 if (state_ == kUninitialized) { 53 if (state_ == kUninitialized) {
59 state_ = kDecryptorRequested; 54 state_ = kDecryptorRequested;
60 set_decryptor_ready_cb_.Run(BindToCurrentLoop(base::Bind( 55 set_decryptor_ready_cb_.Run(BindToCurrentLoop(base::Bind(
61 &DecryptingVideoDecoder::SetDecryptor, weak_this_))); 56 &DecryptingVideoDecoder::SetDecryptor, weak_this_)));
62 return; 57 return;
63 } 58 }
64 59
65 // Reinitialization. 60 // Reinitialization.
66 decryptor_->DeinitializeDecoder(Decryptor::kVideo); 61 decryptor_->DeinitializeDecoder(Decryptor::kVideo);
67 state_ = kPendingDecoderInit; 62 state_ = kPendingDecoderInit;
68 decryptor_->InitializeVideoDecoder(config, BindToCurrentLoop(base::Bind( 63 decryptor_->InitializeVideoDecoder(config, BindToCurrentLoop(base::Bind(
69 &DecryptingVideoDecoder::FinishInitialization, weak_this_))); 64 &DecryptingVideoDecoder::FinishInitialization, weak_this_)));
70 } 65 }
71 66
72 void DecryptingVideoDecoder::Read(const ReadCB& read_cb) { 67 void DecryptingVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer,
73 DVLOG(3) << "Read()"; 68 const ReadCB& read_cb) {
69 DVLOG(3) << "Decode()";
74 DCHECK(message_loop_->BelongsToCurrentThread()); 70 DCHECK(message_loop_->BelongsToCurrentThread());
75 DCHECK(state_ == kIdle || 71 DCHECK(state_ == kIdle ||
76 state_ == kDecodeFinished || 72 state_ == kDecodeFinished ||
77 state_ == kError) << state_; 73 state_ == kError) << state_;
78 DCHECK(!read_cb.is_null()); 74 DCHECK(!read_cb.is_null());
79 CHECK(read_cb_.is_null()) << "Overlapping decodes are not supported."; 75 CHECK(read_cb_.is_null()) << "Overlapping decodes are not supported.";
76
80 read_cb_ = BindToCurrentLoop(read_cb); 77 read_cb_ = BindToCurrentLoop(read_cb);
81 78
82 if (state_ == kError) { 79 if (state_ == kError) {
83 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL); 80 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL);
84 return; 81 return;
85 } 82 }
86 83
87 // Return empty frames if decoding has finished. 84 // Return empty frames if decoding has finished.
88 if (state_ == kDecodeFinished) { 85 if (state_ == kDecodeFinished) {
89 base::ResetAndReturn(&read_cb_).Run(kOk, VideoFrame::CreateEmptyFrame()); 86 base::ResetAndReturn(&read_cb_).Run(kOk, VideoFrame::CreateEmptyFrame());
90 return; 87 return;
91 } 88 }
92 89
93 state_ = kPendingDemuxerRead; 90 pending_buffer_to_decode_ = buffer;
94 ReadFromDemuxerStream(); 91 state_ = kPendingDecode;
92 DecodePendingBuffer();
95 } 93 }
96 94
97 void DecryptingVideoDecoder::Reset(const base::Closure& closure) { 95 void DecryptingVideoDecoder::Reset(const base::Closure& closure) {
98 DVLOG(2) << "Reset() - state: " << state_; 96 DVLOG(2) << "Reset() - state: " << state_;
99 DCHECK(message_loop_->BelongsToCurrentThread()); 97 DCHECK(message_loop_->BelongsToCurrentThread());
100 DCHECK(state_ == kIdle || 98 DCHECK(state_ == kIdle ||
101 state_ == kPendingDemuxerRead ||
102 state_ == kPendingDecode || 99 state_ == kPendingDecode ||
103 state_ == kWaitingForKey || 100 state_ == kWaitingForKey ||
104 state_ == kDecodeFinished || 101 state_ == kDecodeFinished ||
105 state_ == kError) << state_; 102 state_ == kError) << state_;
106 DCHECK(init_cb_.is_null()); // No Reset() during pending initialization. 103 DCHECK(init_cb_.is_null()); // No Reset() during pending initialization.
107 DCHECK(reset_cb_.is_null()); 104 DCHECK(reset_cb_.is_null());
108 105
109 reset_cb_ = BindToCurrentLoop(closure); 106 reset_cb_ = BindToCurrentLoop(closure);
110 107
111 decryptor_->ResetDecoder(Decryptor::kVideo); 108 decryptor_->ResetDecoder(Decryptor::kVideo);
112 109
113 // Reset() cannot complete if the read callback is still pending. 110 // Reset() cannot complete if the read callback is still pending.
114 // Defer the resetting process in this case. The |reset_cb_| will be fired 111 // Defer the resetting process in this case. The |reset_cb_| will be fired
115 // after the read callback is fired - see DecryptAndDecodeBuffer() and 112 // after the read callback is fired - see DecryptAndDecodeBuffer() and
116 // DeliverFrame(). 113 // DeliverFrame().
117 if (state_ == kPendingDemuxerRead || state_ == kPendingDecode) { 114 if (state_ == kPendingDecode) {
118 DCHECK(!read_cb_.is_null()); 115 DCHECK(!read_cb_.is_null());
119 return; 116 return;
120 } 117 }
121 118
122 if (state_ == kWaitingForKey) { 119 if (state_ == kWaitingForKey) {
123 DCHECK(!read_cb_.is_null()); 120 DCHECK(!read_cb_.is_null());
124 pending_buffer_to_decode_ = NULL; 121 pending_buffer_to_decode_ = NULL;
125 base::ResetAndReturn(&read_cb_).Run(kOk, NULL); 122 base::ResetAndReturn(&read_cb_).Run(kOk, NULL);
126 } 123 }
127 124
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 if (!decryptor) { 171 if (!decryptor) {
175 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); 172 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
176 state_ = kStopped; 173 state_ = kStopped;
177 return; 174 return;
178 } 175 }
179 176
180 decryptor_ = decryptor; 177 decryptor_ = decryptor;
181 178
182 state_ = kPendingDecoderInit; 179 state_ = kPendingDecoderInit;
183 decryptor_->InitializeVideoDecoder( 180 decryptor_->InitializeVideoDecoder(
184 demuxer_stream_->video_decoder_config(), BindToCurrentLoop(base::Bind( 181 config_,
182 BindToCurrentLoop(base::Bind(
185 &DecryptingVideoDecoder::FinishInitialization, weak_this_))); 183 &DecryptingVideoDecoder::FinishInitialization, weak_this_)));
186 } 184 }
187 185
188 void DecryptingVideoDecoder::FinishInitialization(bool success) { 186 void DecryptingVideoDecoder::FinishInitialization(bool success) {
189 DVLOG(2) << "FinishInitialization()"; 187 DVLOG(2) << "FinishInitialization()";
190 DCHECK(message_loop_->BelongsToCurrentThread()); 188 DCHECK(message_loop_->BelongsToCurrentThread());
191 189
192 if (state_ == kStopped) 190 if (state_ == kStopped)
193 return; 191 return;
194 192
195 DCHECK_EQ(state_, kPendingDecoderInit) << state_; 193 DCHECK_EQ(state_, kPendingDecoderInit) << state_;
196 DCHECK(!init_cb_.is_null()); 194 DCHECK(!init_cb_.is_null());
197 DCHECK(reset_cb_.is_null()); // No Reset() before initialization finished. 195 DCHECK(reset_cb_.is_null()); // No Reset() before initialization finished.
198 DCHECK(read_cb_.is_null()); // No Read() before initialization finished. 196 DCHECK(read_cb_.is_null()); // No Read() before initialization finished.
199 197
200 if (!success) { 198 if (!success) {
201 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); 199 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
202 state_ = kStopped; 200 state_ = kStopped;
203 return; 201 return;
204 } 202 }
205 203
206 decryptor_->RegisterNewKeyCB(Decryptor::kVideo, BindToCurrentLoop( 204 decryptor_->RegisterNewKeyCB(Decryptor::kVideo, BindToCurrentLoop(
207 base::Bind(&DecryptingVideoDecoder::OnKeyAdded, weak_this_))); 205 base::Bind(&DecryptingVideoDecoder::OnKeyAdded, weak_this_)));
208 206
209 // Success! 207 // Success!
210 state_ = kIdle; 208 state_ = kIdle;
211 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); 209 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK);
212 } 210 }
213 211
214 void DecryptingVideoDecoder::ReadFromDemuxerStream() {
215 DCHECK(message_loop_->BelongsToCurrentThread());
216 DCHECK_EQ(state_, kPendingDemuxerRead) << state_;
217 DCHECK(!read_cb_.is_null());
218
219 demuxer_stream_->Read(
220 base::Bind(&DecryptingVideoDecoder::DecryptAndDecodeBuffer, weak_this_));
221 }
222
223 void DecryptingVideoDecoder::DecryptAndDecodeBuffer(
224 DemuxerStream::Status status,
225 const scoped_refptr<DecoderBuffer>& buffer) {
226 DVLOG(3) << "DecryptAndDecodeBuffer()";
227 DCHECK(message_loop_->BelongsToCurrentThread());
228
229 if (state_ == kStopped)
230 return;
231
232 DCHECK_EQ(state_, kPendingDemuxerRead) << state_;
233 DCHECK(!read_cb_.is_null());
234 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status;
235
236 if (!reset_cb_.is_null()) {
237 base::ResetAndReturn(&read_cb_).Run(kOk, NULL);
238 DoReset();
239 return;
240 }
241
242 if (status == DemuxerStream::kAborted) {
243 DVLOG(2) << "DecryptAndDecodeBuffer() - kAborted";
244 state_ = kIdle;
245 base::ResetAndReturn(&read_cb_).Run(kOk, NULL);
246 return;
247 }
248
249 // VideoFrameStream ensures no kConfigChanged is passed to VideoDecoders.
250 DCHECK_EQ(status, DemuxerStream::kOk) << status;
251 pending_buffer_to_decode_ = buffer;
252 state_ = kPendingDecode;
253 DecodePendingBuffer();
254 }
255 212
256 void DecryptingVideoDecoder::DecodePendingBuffer() { 213 void DecryptingVideoDecoder::DecodePendingBuffer() {
257 DCHECK(message_loop_->BelongsToCurrentThread()); 214 DCHECK(message_loop_->BelongsToCurrentThread());
258 DCHECK_EQ(state_, kPendingDecode) << state_; 215 DCHECK_EQ(state_, kPendingDecode) << state_;
259 TRACE_EVENT_ASYNC_BEGIN0( 216 TRACE_EVENT_ASYNC_BEGIN0(
260 "eme", "DecryptingVideoDecoder::DecodePendingBuffer", ++trace_id_); 217 "eme", "DecryptingVideoDecoder::DecodePendingBuffer", ++trace_id_);
261 218
262 int buffer_size = 0; 219 int buffer_size = 0;
263 if (!pending_buffer_to_decode_->IsEndOfStream()) { 220 if (!pending_buffer_to_decode_->IsEndOfStream()) {
264 buffer_size = pending_buffer_to_decode_->GetDataSize(); 221 buffer_size = pending_buffer_to_decode_->GetDataSize();
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 289
333 if (status == Decryptor::kNeedMoreData) { 290 if (status == Decryptor::kNeedMoreData) {
334 DVLOG(2) << "DeliverFrame() - kNeedMoreData"; 291 DVLOG(2) << "DeliverFrame() - kNeedMoreData";
335 if (scoped_pending_buffer_to_decode->IsEndOfStream()) { 292 if (scoped_pending_buffer_to_decode->IsEndOfStream()) {
336 state_ = kDecodeFinished; 293 state_ = kDecodeFinished;
337 base::ResetAndReturn(&read_cb_).Run( 294 base::ResetAndReturn(&read_cb_).Run(
338 kOk, media::VideoFrame::CreateEmptyFrame()); 295 kOk, media::VideoFrame::CreateEmptyFrame());
339 return; 296 return;
340 } 297 }
341 298
342 state_ = kPendingDemuxerRead; 299 state_ = kIdle;
343 ReadFromDemuxerStream(); 300 base::ResetAndReturn(&read_cb_).Run(kNotEnoughData, NULL);
344 return; 301 return;
345 } 302 }
346 303
347 DCHECK_EQ(status, Decryptor::kSuccess); 304 DCHECK_EQ(status, Decryptor::kSuccess);
348 // No frame returned with kSuccess should be end-of-stream frame. 305 // No frame returned with kSuccess should be end-of-stream frame.
349 DCHECK(!frame->IsEndOfStream()); 306 DCHECK(!frame->IsEndOfStream());
350 state_ = kIdle; 307 state_ = kIdle;
351 base::ResetAndReturn(&read_cb_).Run(kOk, frame); 308 base::ResetAndReturn(&read_cb_).Run(kOk, frame);
352 } 309 }
353 310
(...skipping 13 matching lines...) Expand all
367 } 324 }
368 325
369 void DecryptingVideoDecoder::DoReset() { 326 void DecryptingVideoDecoder::DoReset() {
370 DCHECK(init_cb_.is_null()); 327 DCHECK(init_cb_.is_null());
371 DCHECK(read_cb_.is_null()); 328 DCHECK(read_cb_.is_null());
372 state_ = kIdle; 329 state_ = kIdle;
373 base::ResetAndReturn(&reset_cb_).Run(); 330 base::ResetAndReturn(&reset_cb_).Run();
374 } 331 }
375 332
376 } // namespace media 333 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/decrypting_video_decoder.h ('k') | media/filters/decrypting_video_decoder_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698