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

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

Issue 65803002: Replace MessageLoopProxy with SingleThreadTaskRunner for media/filters/ + associated code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years 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/filters/decrypting_video_decoder.h ('k') | media/filters/fake_demuxer_stream.h » ('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/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/single_thread_task_runner.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/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 DecryptingVideoDecoder::DecryptingVideoDecoder( 22 DecryptingVideoDecoder::DecryptingVideoDecoder(
23 const scoped_refptr<base::MessageLoopProxy>& message_loop, 23 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
24 const SetDecryptorReadyCB& set_decryptor_ready_cb) 24 const SetDecryptorReadyCB& set_decryptor_ready_cb)
25 : message_loop_(message_loop), 25 : task_runner_(task_runner),
26 weak_factory_(this), 26 weak_factory_(this),
27 state_(kUninitialized), 27 state_(kUninitialized),
28 set_decryptor_ready_cb_(set_decryptor_ready_cb), 28 set_decryptor_ready_cb_(set_decryptor_ready_cb),
29 decryptor_(NULL), 29 decryptor_(NULL),
30 key_added_while_decode_pending_(false), 30 key_added_while_decode_pending_(false),
31 trace_id_(0) { 31 trace_id_(0) {
32 } 32 }
33 33
34 void DecryptingVideoDecoder::Initialize(const VideoDecoderConfig& config, 34 void DecryptingVideoDecoder::Initialize(const VideoDecoderConfig& config,
35 const PipelineStatusCB& status_cb) { 35 const PipelineStatusCB& status_cb) {
36 DVLOG(2) << "Initialize()"; 36 DVLOG(2) << "Initialize()";
37 DCHECK(message_loop_->BelongsToCurrentThread()); 37 DCHECK(task_runner_->BelongsToCurrentThread());
38 DCHECK(state_ == kUninitialized || 38 DCHECK(state_ == kUninitialized ||
39 state_ == kIdle || 39 state_ == kIdle ||
40 state_ == kDecodeFinished) << state_; 40 state_ == kDecodeFinished) << state_;
41 DCHECK(decode_cb_.is_null()); 41 DCHECK(decode_cb_.is_null());
42 DCHECK(reset_cb_.is_null()); 42 DCHECK(reset_cb_.is_null());
43 DCHECK(config.IsValidConfig()); 43 DCHECK(config.IsValidConfig());
44 DCHECK(config.is_encrypted()); 44 DCHECK(config.is_encrypted());
45 45
46 init_cb_ = BindToCurrentLoop(status_cb); 46 init_cb_ = BindToCurrentLoop(status_cb);
47 weak_this_ = weak_factory_.GetWeakPtr(); 47 weak_this_ = weak_factory_.GetWeakPtr();
48 config_ = config; 48 config_ = config;
49 49
50 if (state_ == kUninitialized) { 50 if (state_ == kUninitialized) {
51 state_ = kDecryptorRequested; 51 state_ = kDecryptorRequested;
52 set_decryptor_ready_cb_.Run(BindToCurrentLoop(base::Bind( 52 set_decryptor_ready_cb_.Run(BindToCurrentLoop(base::Bind(
53 &DecryptingVideoDecoder::SetDecryptor, weak_this_))); 53 &DecryptingVideoDecoder::SetDecryptor, weak_this_)));
54 return; 54 return;
55 } 55 }
56 56
57 // Reinitialization. 57 // Reinitialization.
58 decryptor_->DeinitializeDecoder(Decryptor::kVideo); 58 decryptor_->DeinitializeDecoder(Decryptor::kVideo);
59 state_ = kPendingDecoderInit; 59 state_ = kPendingDecoderInit;
60 decryptor_->InitializeVideoDecoder(config, BindToCurrentLoop(base::Bind( 60 decryptor_->InitializeVideoDecoder(config, BindToCurrentLoop(base::Bind(
61 &DecryptingVideoDecoder::FinishInitialization, weak_this_))); 61 &DecryptingVideoDecoder::FinishInitialization, weak_this_)));
62 } 62 }
63 63
64 void DecryptingVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer, 64 void DecryptingVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer,
65 const DecodeCB& decode_cb) { 65 const DecodeCB& decode_cb) {
66 DVLOG(3) << "Decode()"; 66 DVLOG(3) << "Decode()";
67 DCHECK(message_loop_->BelongsToCurrentThread()); 67 DCHECK(task_runner_->BelongsToCurrentThread());
68 DCHECK(state_ == kIdle || 68 DCHECK(state_ == kIdle ||
69 state_ == kDecodeFinished || 69 state_ == kDecodeFinished ||
70 state_ == kError) << state_; 70 state_ == kError) << state_;
71 DCHECK(!decode_cb.is_null()); 71 DCHECK(!decode_cb.is_null());
72 CHECK(decode_cb_.is_null()) << "Overlapping decodes are not supported."; 72 CHECK(decode_cb_.is_null()) << "Overlapping decodes are not supported.";
73 73
74 decode_cb_ = BindToCurrentLoop(decode_cb); 74 decode_cb_ = BindToCurrentLoop(decode_cb);
75 75
76 if (state_ == kError) { 76 if (state_ == kError) {
77 base::ResetAndReturn(&decode_cb_).Run(kDecodeError, NULL); 77 base::ResetAndReturn(&decode_cb_).Run(kDecodeError, NULL);
78 return; 78 return;
79 } 79 }
80 80
81 // Return empty frames if decoding has finished. 81 // Return empty frames if decoding has finished.
82 if (state_ == kDecodeFinished) { 82 if (state_ == kDecodeFinished) {
83 base::ResetAndReturn(&decode_cb_).Run(kOk, VideoFrame::CreateEOSFrame()); 83 base::ResetAndReturn(&decode_cb_).Run(kOk, VideoFrame::CreateEOSFrame());
84 return; 84 return;
85 } 85 }
86 86
87 pending_buffer_to_decode_ = buffer; 87 pending_buffer_to_decode_ = buffer;
88 state_ = kPendingDecode; 88 state_ = kPendingDecode;
89 DecodePendingBuffer(); 89 DecodePendingBuffer();
90 } 90 }
91 91
92 void DecryptingVideoDecoder::Reset(const base::Closure& closure) { 92 void DecryptingVideoDecoder::Reset(const base::Closure& closure) {
93 DVLOG(2) << "Reset() - state: " << state_; 93 DVLOG(2) << "Reset() - state: " << state_;
94 DCHECK(message_loop_->BelongsToCurrentThread()); 94 DCHECK(task_runner_->BelongsToCurrentThread());
95 DCHECK(state_ == kIdle || 95 DCHECK(state_ == kIdle ||
96 state_ == kPendingDecode || 96 state_ == kPendingDecode ||
97 state_ == kWaitingForKey || 97 state_ == kWaitingForKey ||
98 state_ == kDecodeFinished || 98 state_ == kDecodeFinished ||
99 state_ == kError) << state_; 99 state_ == kError) << state_;
100 DCHECK(init_cb_.is_null()); // No Reset() during pending initialization. 100 DCHECK(init_cb_.is_null()); // No Reset() during pending initialization.
101 DCHECK(reset_cb_.is_null()); 101 DCHECK(reset_cb_.is_null());
102 102
103 reset_cb_ = BindToCurrentLoop(closure); 103 reset_cb_ = BindToCurrentLoop(closure);
104 104
(...skipping 12 matching lines...) Expand all
117 DCHECK(!decode_cb_.is_null()); 117 DCHECK(!decode_cb_.is_null());
118 pending_buffer_to_decode_ = NULL; 118 pending_buffer_to_decode_ = NULL;
119 base::ResetAndReturn(&decode_cb_).Run(kOk, NULL); 119 base::ResetAndReturn(&decode_cb_).Run(kOk, NULL);
120 } 120 }
121 121
122 DCHECK(decode_cb_.is_null()); 122 DCHECK(decode_cb_.is_null());
123 DoReset(); 123 DoReset();
124 } 124 }
125 125
126 void DecryptingVideoDecoder::Stop(const base::Closure& closure) { 126 void DecryptingVideoDecoder::Stop(const base::Closure& closure) {
127 DCHECK(message_loop_->BelongsToCurrentThread()); 127 DCHECK(task_runner_->BelongsToCurrentThread());
128 DVLOG(2) << "Stop() - state: " << state_; 128 DVLOG(2) << "Stop() - state: " << state_;
129 129
130 // At this point the render thread is likely paused (in WebMediaPlayerImpl's 130 // At this point the render thread is likely paused (in WebMediaPlayerImpl's
131 // Destroy()), so running |closure| can't wait for anything that requires the 131 // Destroy()), so running |closure| can't wait for anything that requires the
132 // render thread to be processing messages to complete (such as PPAPI 132 // render thread to be processing messages to complete (such as PPAPI
133 // callbacks). 133 // callbacks).
134 if (decryptor_) { 134 if (decryptor_) {
135 decryptor_->RegisterNewKeyCB(Decryptor::kVideo, Decryptor::NewKeyCB()); 135 decryptor_->RegisterNewKeyCB(Decryptor::kVideo, Decryptor::NewKeyCB());
136 decryptor_->DeinitializeDecoder(Decryptor::kVideo); 136 decryptor_->DeinitializeDecoder(Decryptor::kVideo);
137 decryptor_ = NULL; 137 decryptor_ = NULL;
(...skipping 10 matching lines...) Expand all
148 state_ = kStopped; 148 state_ = kStopped;
149 BindToCurrentLoop(closure).Run(); 149 BindToCurrentLoop(closure).Run();
150 } 150 }
151 151
152 DecryptingVideoDecoder::~DecryptingVideoDecoder() { 152 DecryptingVideoDecoder::~DecryptingVideoDecoder() {
153 DCHECK(state_ == kUninitialized || state_ == kStopped) << state_; 153 DCHECK(state_ == kUninitialized || state_ == kStopped) << state_;
154 } 154 }
155 155
156 void DecryptingVideoDecoder::SetDecryptor(Decryptor* decryptor) { 156 void DecryptingVideoDecoder::SetDecryptor(Decryptor* decryptor) {
157 DVLOG(2) << "SetDecryptor()"; 157 DVLOG(2) << "SetDecryptor()";
158 DCHECK(message_loop_->BelongsToCurrentThread()); 158 DCHECK(task_runner_->BelongsToCurrentThread());
159 159
160 if (state_ == kStopped) 160 if (state_ == kStopped)
161 return; 161 return;
162 162
163 DCHECK_EQ(state_, kDecryptorRequested) << state_; 163 DCHECK_EQ(state_, kDecryptorRequested) << state_;
164 DCHECK(!init_cb_.is_null()); 164 DCHECK(!init_cb_.is_null());
165 DCHECK(!set_decryptor_ready_cb_.is_null()); 165 DCHECK(!set_decryptor_ready_cb_.is_null());
166 set_decryptor_ready_cb_.Reset(); 166 set_decryptor_ready_cb_.Reset();
167 167
168 if (!decryptor) { 168 if (!decryptor) {
169 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); 169 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
170 state_ = kStopped; 170 state_ = kStopped;
171 return; 171 return;
172 } 172 }
173 173
174 decryptor_ = decryptor; 174 decryptor_ = decryptor;
175 175
176 state_ = kPendingDecoderInit; 176 state_ = kPendingDecoderInit;
177 decryptor_->InitializeVideoDecoder( 177 decryptor_->InitializeVideoDecoder(
178 config_, 178 config_,
179 BindToCurrentLoop(base::Bind( 179 BindToCurrentLoop(base::Bind(
180 &DecryptingVideoDecoder::FinishInitialization, weak_this_))); 180 &DecryptingVideoDecoder::FinishInitialization, weak_this_)));
181 } 181 }
182 182
183 void DecryptingVideoDecoder::FinishInitialization(bool success) { 183 void DecryptingVideoDecoder::FinishInitialization(bool success) {
184 DVLOG(2) << "FinishInitialization()"; 184 DVLOG(2) << "FinishInitialization()";
185 DCHECK(message_loop_->BelongsToCurrentThread()); 185 DCHECK(task_runner_->BelongsToCurrentThread());
186 186
187 if (state_ == kStopped) 187 if (state_ == kStopped)
188 return; 188 return;
189 189
190 DCHECK_EQ(state_, kPendingDecoderInit) << state_; 190 DCHECK_EQ(state_, kPendingDecoderInit) << state_;
191 DCHECK(!init_cb_.is_null()); 191 DCHECK(!init_cb_.is_null());
192 DCHECK(reset_cb_.is_null()); // No Reset() before initialization finished. 192 DCHECK(reset_cb_.is_null()); // No Reset() before initialization finished.
193 DCHECK(decode_cb_.is_null()); // No Decode() before initialization finished. 193 DCHECK(decode_cb_.is_null()); // No Decode() before initialization finished.
194 194
195 if (!success) { 195 if (!success) {
196 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); 196 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
197 state_ = kStopped; 197 state_ = kStopped;
198 return; 198 return;
199 } 199 }
200 200
201 decryptor_->RegisterNewKeyCB(Decryptor::kVideo, BindToCurrentLoop( 201 decryptor_->RegisterNewKeyCB(Decryptor::kVideo, BindToCurrentLoop(
202 base::Bind(&DecryptingVideoDecoder::OnKeyAdded, weak_this_))); 202 base::Bind(&DecryptingVideoDecoder::OnKeyAdded, weak_this_)));
203 203
204 // Success! 204 // Success!
205 state_ = kIdle; 205 state_ = kIdle;
206 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); 206 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK);
207 } 207 }
208 208
209 209
210 void DecryptingVideoDecoder::DecodePendingBuffer() { 210 void DecryptingVideoDecoder::DecodePendingBuffer() {
211 DCHECK(message_loop_->BelongsToCurrentThread()); 211 DCHECK(task_runner_->BelongsToCurrentThread());
212 DCHECK_EQ(state_, kPendingDecode) << state_; 212 DCHECK_EQ(state_, kPendingDecode) << state_;
213 TRACE_EVENT_ASYNC_BEGIN0( 213 TRACE_EVENT_ASYNC_BEGIN0(
214 "media", "DecryptingVideoDecoder::DecodePendingBuffer", ++trace_id_); 214 "media", "DecryptingVideoDecoder::DecodePendingBuffer", ++trace_id_);
215 215
216 int buffer_size = 0; 216 int buffer_size = 0;
217 if (!pending_buffer_to_decode_->end_of_stream()) { 217 if (!pending_buffer_to_decode_->end_of_stream()) {
218 buffer_size = pending_buffer_to_decode_->data_size(); 218 buffer_size = pending_buffer_to_decode_->data_size();
219 } 219 }
220 220
221 decryptor_->DecryptAndDecodeVideo( 221 decryptor_->DecryptAndDecodeVideo(
222 pending_buffer_to_decode_, BindToCurrentLoop(base::Bind( 222 pending_buffer_to_decode_, BindToCurrentLoop(base::Bind(
223 &DecryptingVideoDecoder::DeliverFrame, weak_this_, buffer_size))); 223 &DecryptingVideoDecoder::DeliverFrame, weak_this_, buffer_size)));
224 } 224 }
225 225
226 void DecryptingVideoDecoder::DeliverFrame( 226 void DecryptingVideoDecoder::DeliverFrame(
227 int buffer_size, 227 int buffer_size,
228 Decryptor::Status status, 228 Decryptor::Status status,
229 const scoped_refptr<VideoFrame>& frame) { 229 const scoped_refptr<VideoFrame>& frame) {
230 DVLOG(3) << "DeliverFrame() - status: " << status; 230 DVLOG(3) << "DeliverFrame() - status: " << status;
231 DCHECK(message_loop_->BelongsToCurrentThread()); 231 DCHECK(task_runner_->BelongsToCurrentThread());
232 TRACE_EVENT_ASYNC_END0( 232 TRACE_EVENT_ASYNC_END0(
233 "media", "DecryptingVideoDecoder::DecodePendingBuffer", trace_id_); 233 "media", "DecryptingVideoDecoder::DecodePendingBuffer", trace_id_);
234 234
235 if (state_ == kStopped) 235 if (state_ == kStopped)
236 return; 236 return;
237 237
238 DCHECK_EQ(state_, kPendingDecode) << state_; 238 DCHECK_EQ(state_, kPendingDecode) << state_;
239 DCHECK(!decode_cb_.is_null()); 239 DCHECK(!decode_cb_.is_null());
240 DCHECK(pending_buffer_to_decode_.get()); 240 DCHECK(pending_buffer_to_decode_.get());
241 241
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 293
294 DCHECK_EQ(status, Decryptor::kSuccess); 294 DCHECK_EQ(status, Decryptor::kSuccess);
295 // No frame returned with kSuccess should be end-of-stream frame. 295 // No frame returned with kSuccess should be end-of-stream frame.
296 DCHECK(!frame->end_of_stream()); 296 DCHECK(!frame->end_of_stream());
297 state_ = kIdle; 297 state_ = kIdle;
298 base::ResetAndReturn(&decode_cb_).Run(kOk, frame); 298 base::ResetAndReturn(&decode_cb_).Run(kOk, frame);
299 } 299 }
300 300
301 void DecryptingVideoDecoder::OnKeyAdded() { 301 void DecryptingVideoDecoder::OnKeyAdded() {
302 DVLOG(2) << "OnKeyAdded()"; 302 DVLOG(2) << "OnKeyAdded()";
303 DCHECK(message_loop_->BelongsToCurrentThread()); 303 DCHECK(task_runner_->BelongsToCurrentThread());
304 304
305 if (state_ == kPendingDecode) { 305 if (state_ == kPendingDecode) {
306 key_added_while_decode_pending_ = true; 306 key_added_while_decode_pending_ = true;
307 return; 307 return;
308 } 308 }
309 309
310 if (state_ == kWaitingForKey) { 310 if (state_ == kWaitingForKey) {
311 state_ = kPendingDecode; 311 state_ = kPendingDecode;
312 DecodePendingBuffer(); 312 DecodePendingBuffer();
313 } 313 }
314 } 314 }
315 315
316 void DecryptingVideoDecoder::DoReset() { 316 void DecryptingVideoDecoder::DoReset() {
317 DCHECK(init_cb_.is_null()); 317 DCHECK(init_cb_.is_null());
318 DCHECK(decode_cb_.is_null()); 318 DCHECK(decode_cb_.is_null());
319 state_ = kIdle; 319 state_ = kIdle;
320 base::ResetAndReturn(&reset_cb_).Run(); 320 base::ResetAndReturn(&reset_cb_).Run();
321 } 321 }
322 322
323 } // namespace media 323 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/decrypting_video_decoder.h ('k') | media/filters/fake_demuxer_stream.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698