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/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/bind_to_current_loop.h" |
8 #include "base/callback_helpers.h" | 9 #include "base/callback_helpers.h" |
9 #include "base/location.h" | 10 #include "base/location.h" |
10 #include "base/logging.h" | 11 #include "base/logging.h" |
11 #include "base/single_thread_task_runner.h" | 12 #include "base/single_thread_task_runner.h" |
12 #include "base/trace_event/trace_event.h" | 13 #include "base/trace_event/trace_event.h" |
13 #include "media/base/bind_to_current_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/pipeline.h" | 16 #include "media/base/pipeline.h" |
17 #include "media/base/video_decoder_config.h" | 17 #include "media/base/video_decoder_config.h" |
18 #include "media/base/video_frame.h" | 18 #include "media/base/video_frame.h" |
19 | 19 |
20 namespace media { | 20 namespace media { |
21 | 21 |
22 const char DecryptingVideoDecoder::kDecoderName[] = "DecryptingVideoDecoder"; | 22 const char DecryptingVideoDecoder::kDecoderName[] = "DecryptingVideoDecoder"; |
23 | 23 |
(...skipping 22 matching lines...) Expand all Loading... |
46 DVLOG(2) << "Initialize()"; | 46 DVLOG(2) << "Initialize()"; |
47 DCHECK(task_runner_->BelongsToCurrentThread()); | 47 DCHECK(task_runner_->BelongsToCurrentThread()); |
48 DCHECK(state_ == kUninitialized || | 48 DCHECK(state_ == kUninitialized || |
49 state_ == kIdle || | 49 state_ == kIdle || |
50 state_ == kDecodeFinished) << state_; | 50 state_ == kDecodeFinished) << state_; |
51 DCHECK(decode_cb_.is_null()); | 51 DCHECK(decode_cb_.is_null()); |
52 DCHECK(reset_cb_.is_null()); | 52 DCHECK(reset_cb_.is_null()); |
53 DCHECK(config.IsValidConfig()); | 53 DCHECK(config.IsValidConfig()); |
54 DCHECK(config.is_encrypted()); | 54 DCHECK(config.is_encrypted()); |
55 | 55 |
56 init_cb_ = BindToCurrentLoop(status_cb); | 56 init_cb_ = base::BindToCurrentLoop(status_cb); |
57 output_cb_ = BindToCurrentLoop(output_cb); | 57 output_cb_ = base::BindToCurrentLoop(output_cb); |
58 weak_this_ = weak_factory_.GetWeakPtr(); | 58 weak_this_ = weak_factory_.GetWeakPtr(); |
59 config_ = config; | 59 config_ = config; |
60 | 60 |
61 if (state_ == kUninitialized) { | 61 if (state_ == kUninitialized) { |
62 state_ = kDecryptorRequested; | 62 state_ = kDecryptorRequested; |
63 set_decryptor_ready_cb_.Run(BindToCurrentLoop(base::Bind( | 63 set_decryptor_ready_cb_.Run(base::BindToCurrentLoop(base::Bind( |
64 &DecryptingVideoDecoder::SetDecryptor, weak_this_))); | 64 &DecryptingVideoDecoder::SetDecryptor, weak_this_))); |
65 return; | 65 return; |
66 } | 66 } |
67 | 67 |
68 // Reinitialization. | 68 // Reinitialization. |
69 decryptor_->DeinitializeDecoder(Decryptor::kVideo); | 69 decryptor_->DeinitializeDecoder(Decryptor::kVideo); |
70 state_ = kPendingDecoderInit; | 70 state_ = kPendingDecoderInit; |
71 decryptor_->InitializeVideoDecoder(config, BindToCurrentLoop(base::Bind( | 71 decryptor_->InitializeVideoDecoder(config, base::BindToCurrentLoop(base::Bind( |
72 &DecryptingVideoDecoder::FinishInitialization, weak_this_))); | 72 &DecryptingVideoDecoder::FinishInitialization, weak_this_))); |
73 } | 73 } |
74 | 74 |
75 void DecryptingVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer, | 75 void DecryptingVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer, |
76 const DecodeCB& decode_cb) { | 76 const DecodeCB& decode_cb) { |
77 DVLOG(3) << "Decode()"; | 77 DVLOG(3) << "Decode()"; |
78 DCHECK(task_runner_->BelongsToCurrentThread()); | 78 DCHECK(task_runner_->BelongsToCurrentThread()); |
79 DCHECK(state_ == kIdle || | 79 DCHECK(state_ == kIdle || |
80 state_ == kDecodeFinished || | 80 state_ == kDecodeFinished || |
81 state_ == kError) << state_; | 81 state_ == kError) << state_; |
82 DCHECK(!decode_cb.is_null()); | 82 DCHECK(!decode_cb.is_null()); |
83 CHECK(decode_cb_.is_null()) << "Overlapping decodes are not supported."; | 83 CHECK(decode_cb_.is_null()) << "Overlapping decodes are not supported."; |
84 | 84 |
85 decode_cb_ = BindToCurrentLoop(decode_cb); | 85 decode_cb_ = base::BindToCurrentLoop(decode_cb); |
86 | 86 |
87 if (state_ == kError) { | 87 if (state_ == kError) { |
88 base::ResetAndReturn(&decode_cb_).Run(kDecodeError); | 88 base::ResetAndReturn(&decode_cb_).Run(kDecodeError); |
89 return; | 89 return; |
90 } | 90 } |
91 | 91 |
92 // Return empty frames if decoding has finished. | 92 // Return empty frames if decoding has finished. |
93 if (state_ == kDecodeFinished) { | 93 if (state_ == kDecodeFinished) { |
94 base::ResetAndReturn(&decode_cb_).Run(kOk); | 94 base::ResetAndReturn(&decode_cb_).Run(kOk); |
95 return; | 95 return; |
96 } | 96 } |
97 | 97 |
98 pending_buffer_to_decode_ = buffer; | 98 pending_buffer_to_decode_ = buffer; |
99 state_ = kPendingDecode; | 99 state_ = kPendingDecode; |
100 DecodePendingBuffer(); | 100 DecodePendingBuffer(); |
101 } | 101 } |
102 | 102 |
103 void DecryptingVideoDecoder::Reset(const base::Closure& closure) { | 103 void DecryptingVideoDecoder::Reset(const base::Closure& closure) { |
104 DVLOG(2) << "Reset() - state: " << state_; | 104 DVLOG(2) << "Reset() - state: " << state_; |
105 DCHECK(task_runner_->BelongsToCurrentThread()); | 105 DCHECK(task_runner_->BelongsToCurrentThread()); |
106 DCHECK(state_ == kIdle || | 106 DCHECK(state_ == kIdle || |
107 state_ == kPendingDecode || | 107 state_ == kPendingDecode || |
108 state_ == kWaitingForKey || | 108 state_ == kWaitingForKey || |
109 state_ == kDecodeFinished || | 109 state_ == kDecodeFinished || |
110 state_ == kError) << state_; | 110 state_ == kError) << state_; |
111 DCHECK(init_cb_.is_null()); // No Reset() during pending initialization. | 111 DCHECK(init_cb_.is_null()); // No Reset() during pending initialization. |
112 DCHECK(reset_cb_.is_null()); | 112 DCHECK(reset_cb_.is_null()); |
113 | 113 |
114 reset_cb_ = BindToCurrentLoop(closure); | 114 reset_cb_ = base::BindToCurrentLoop(closure); |
115 | 115 |
116 decryptor_->ResetDecoder(Decryptor::kVideo); | 116 decryptor_->ResetDecoder(Decryptor::kVideo); |
117 | 117 |
118 // Reset() cannot complete if the decode callback is still pending. | 118 // Reset() cannot complete if the decode callback is still pending. |
119 // Defer the resetting process in this case. The |reset_cb_| will be fired | 119 // Defer the resetting process in this case. The |reset_cb_| will be fired |
120 // after the decode callback is fired - see DecryptAndDecodeBuffer() and | 120 // after the decode callback is fired - see DecryptAndDecodeBuffer() and |
121 // DeliverFrame(). | 121 // DeliverFrame(). |
122 if (state_ == kPendingDecode) { | 122 if (state_ == kPendingDecode) { |
123 DCHECK(!decode_cb_.is_null()); | 123 DCHECK(!decode_cb_.is_null()); |
124 return; | 124 return; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 state_ = kError; | 170 state_ = kError; |
171 decryptor_attached_cb.Run(false); | 171 decryptor_attached_cb.Run(false); |
172 return; | 172 return; |
173 } | 173 } |
174 | 174 |
175 decryptor_ = decryptor; | 175 decryptor_ = decryptor; |
176 | 176 |
177 state_ = kPendingDecoderInit; | 177 state_ = kPendingDecoderInit; |
178 decryptor_->InitializeVideoDecoder( | 178 decryptor_->InitializeVideoDecoder( |
179 config_, | 179 config_, |
180 BindToCurrentLoop(base::Bind( | 180 base::BindToCurrentLoop(base::Bind( |
181 &DecryptingVideoDecoder::FinishInitialization, weak_this_))); | 181 &DecryptingVideoDecoder::FinishInitialization, weak_this_))); |
182 decryptor_attached_cb.Run(true); | 182 decryptor_attached_cb.Run(true); |
183 } | 183 } |
184 | 184 |
185 void DecryptingVideoDecoder::FinishInitialization(bool success) { | 185 void DecryptingVideoDecoder::FinishInitialization(bool success) { |
186 DVLOG(2) << "FinishInitialization()"; | 186 DVLOG(2) << "FinishInitialization()"; |
187 DCHECK(task_runner_->BelongsToCurrentThread()); | 187 DCHECK(task_runner_->BelongsToCurrentThread()); |
188 DCHECK_EQ(state_, kPendingDecoderInit) << state_; | 188 DCHECK_EQ(state_, kPendingDecoderInit) << state_; |
189 DCHECK(!init_cb_.is_null()); | 189 DCHECK(!init_cb_.is_null()); |
190 DCHECK(reset_cb_.is_null()); // No Reset() before initialization finished. | 190 DCHECK(reset_cb_.is_null()); // No Reset() before initialization finished. |
191 DCHECK(decode_cb_.is_null()); // No Decode() before initialization finished. | 191 DCHECK(decode_cb_.is_null()); // No Decode() before initialization finished. |
192 | 192 |
193 if (!success) { | 193 if (!success) { |
194 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); | 194 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); |
195 decryptor_ = NULL; | 195 decryptor_ = NULL; |
196 state_ = kError; | 196 state_ = kError; |
197 return; | 197 return; |
198 } | 198 } |
199 | 199 |
200 decryptor_->RegisterNewKeyCB( | 200 decryptor_->RegisterNewKeyCB( |
201 Decryptor::kVideo, | 201 Decryptor::kVideo, |
202 BindToCurrentLoop( | 202 base::BindToCurrentLoop( |
203 base::Bind(&DecryptingVideoDecoder::OnKeyAdded, weak_this_))); | 203 base::Bind(&DecryptingVideoDecoder::OnKeyAdded, weak_this_))); |
204 | 204 |
205 // Success! | 205 // Success! |
206 state_ = kIdle; | 206 state_ = kIdle; |
207 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); | 207 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); |
208 } | 208 } |
209 | 209 |
210 | 210 |
211 void DecryptingVideoDecoder::DecodePendingBuffer() { | 211 void DecryptingVideoDecoder::DecodePendingBuffer() { |
212 DCHECK(task_runner_->BelongsToCurrentThread()); | 212 DCHECK(task_runner_->BelongsToCurrentThread()); |
213 DCHECK_EQ(state_, kPendingDecode) << state_; | 213 DCHECK_EQ(state_, kPendingDecode) << state_; |
214 TRACE_EVENT_ASYNC_BEGIN0( | 214 TRACE_EVENT_ASYNC_BEGIN0( |
215 "media", "DecryptingVideoDecoder::DecodePendingBuffer", ++trace_id_); | 215 "media", "DecryptingVideoDecoder::DecodePendingBuffer", ++trace_id_); |
216 | 216 |
217 int buffer_size = 0; | 217 int buffer_size = 0; |
218 if (!pending_buffer_to_decode_->end_of_stream()) { | 218 if (!pending_buffer_to_decode_->end_of_stream()) { |
219 buffer_size = pending_buffer_to_decode_->data_size(); | 219 buffer_size = pending_buffer_to_decode_->data_size(); |
220 } | 220 } |
221 | 221 |
222 decryptor_->DecryptAndDecodeVideo( | 222 decryptor_->DecryptAndDecodeVideo( |
223 pending_buffer_to_decode_, BindToCurrentLoop(base::Bind( | 223 pending_buffer_to_decode_, base::BindToCurrentLoop(base::Bind( |
224 &DecryptingVideoDecoder::DeliverFrame, weak_this_, buffer_size))); | 224 &DecryptingVideoDecoder::DeliverFrame, weak_this_, buffer_size))); |
225 } | 225 } |
226 | 226 |
227 void DecryptingVideoDecoder::DeliverFrame( | 227 void DecryptingVideoDecoder::DeliverFrame( |
228 int buffer_size, | 228 int buffer_size, |
229 Decryptor::Status status, | 229 Decryptor::Status status, |
230 const scoped_refptr<VideoFrame>& frame) { | 230 const scoped_refptr<VideoFrame>& frame) { |
231 DVLOG(3) << "DeliverFrame() - status: " << status; | 231 DVLOG(3) << "DeliverFrame() - status: " << status; |
232 DCHECK(task_runner_->BelongsToCurrentThread()); | 232 DCHECK(task_runner_->BelongsToCurrentThread()); |
233 DCHECK_EQ(state_, kPendingDecode) << state_; | 233 DCHECK_EQ(state_, kPendingDecode) << state_; |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
318 } | 318 } |
319 | 319 |
320 void DecryptingVideoDecoder::DoReset() { | 320 void DecryptingVideoDecoder::DoReset() { |
321 DCHECK(init_cb_.is_null()); | 321 DCHECK(init_cb_.is_null()); |
322 DCHECK(decode_cb_.is_null()); | 322 DCHECK(decode_cb_.is_null()); |
323 state_ = kIdle; | 323 state_ = kIdle; |
324 base::ResetAndReturn(&reset_cb_).Run(); | 324 base::ResetAndReturn(&reset_cb_).Run(); |
325 } | 325 } |
326 | 326 |
327 } // namespace media | 327 } // namespace media |
OLD | NEW |