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

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

Issue 297553002: Add callback in VideoDecoder and AudioDecoder to return decoded frames. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 6 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"
(...skipping 14 matching lines...) Expand all
25 : task_runner_(task_runner), 25 : task_runner_(task_runner),
26 state_(kUninitialized), 26 state_(kUninitialized),
27 set_decryptor_ready_cb_(set_decryptor_ready_cb), 27 set_decryptor_ready_cb_(set_decryptor_ready_cb),
28 decryptor_(NULL), 28 decryptor_(NULL),
29 key_added_while_decode_pending_(false), 29 key_added_while_decode_pending_(false),
30 trace_id_(0), 30 trace_id_(0),
31 weak_factory_(this) {} 31 weak_factory_(this) {}
32 32
33 void DecryptingVideoDecoder::Initialize(const VideoDecoderConfig& config, 33 void DecryptingVideoDecoder::Initialize(const VideoDecoderConfig& config,
34 bool live_mode, 34 bool live_mode,
35 const PipelineStatusCB& status_cb) { 35 const PipelineStatusCB& status_cb,
36 const OutputCB& output_cb) {
36 DVLOG(2) << "Initialize()"; 37 DVLOG(2) << "Initialize()";
37 DCHECK(task_runner_->BelongsToCurrentThread()); 38 DCHECK(task_runner_->BelongsToCurrentThread());
38 DCHECK(state_ == kUninitialized || 39 DCHECK(state_ == kUninitialized ||
39 state_ == kIdle || 40 state_ == kIdle ||
40 state_ == kDecodeFinished) << state_; 41 state_ == kDecodeFinished) << state_;
41 DCHECK(decode_cb_.is_null()); 42 DCHECK(decode_cb_.is_null());
42 DCHECK(reset_cb_.is_null()); 43 DCHECK(reset_cb_.is_null());
43 DCHECK(config.IsValidConfig()); 44 DCHECK(config.IsValidConfig());
44 DCHECK(config.is_encrypted()); 45 DCHECK(config.is_encrypted());
45 46
46 init_cb_ = BindToCurrentLoop(status_cb); 47 init_cb_ = BindToCurrentLoop(status_cb);
48 output_cb_ = BindToCurrentLoop(output_cb);
47 weak_this_ = weak_factory_.GetWeakPtr(); 49 weak_this_ = weak_factory_.GetWeakPtr();
48 config_ = config; 50 config_ = config;
49 51
50 if (state_ == kUninitialized) { 52 if (state_ == kUninitialized) {
51 state_ = kDecryptorRequested; 53 state_ = kDecryptorRequested;
52 set_decryptor_ready_cb_.Run(BindToCurrentLoop(base::Bind( 54 set_decryptor_ready_cb_.Run(BindToCurrentLoop(base::Bind(
53 &DecryptingVideoDecoder::SetDecryptor, weak_this_))); 55 &DecryptingVideoDecoder::SetDecryptor, weak_this_)));
54 return; 56 return;
55 } 57 }
56 58
(...skipping 10 matching lines...) Expand all
67 DCHECK(task_runner_->BelongsToCurrentThread()); 69 DCHECK(task_runner_->BelongsToCurrentThread());
68 DCHECK(state_ == kIdle || 70 DCHECK(state_ == kIdle ||
69 state_ == kDecodeFinished || 71 state_ == kDecodeFinished ||
70 state_ == kError) << state_; 72 state_ == kError) << state_;
71 DCHECK(!decode_cb.is_null()); 73 DCHECK(!decode_cb.is_null());
72 CHECK(decode_cb_.is_null()) << "Overlapping decodes are not supported."; 74 CHECK(decode_cb_.is_null()) << "Overlapping decodes are not supported.";
73 75
74 decode_cb_ = BindToCurrentLoop(decode_cb); 76 decode_cb_ = BindToCurrentLoop(decode_cb);
75 77
76 if (state_ == kError) { 78 if (state_ == kError) {
77 base::ResetAndReturn(&decode_cb_).Run(kDecodeError, NULL); 79 base::ResetAndReturn(&decode_cb_).Run(kDecodeError);
78 return; 80 return;
79 } 81 }
80 82
81 // Return empty frames if decoding has finished. 83 // Return empty frames if decoding has finished.
82 if (state_ == kDecodeFinished) { 84 if (state_ == kDecodeFinished) {
83 base::ResetAndReturn(&decode_cb_).Run(kOk, VideoFrame::CreateEOSFrame()); 85 output_cb_.Run(VideoFrame::CreateEOSFrame());
86 base::ResetAndReturn(&decode_cb_).Run(kOk);
84 return; 87 return;
85 } 88 }
86 89
87 pending_buffer_to_decode_ = buffer; 90 pending_buffer_to_decode_ = buffer;
88 state_ = kPendingDecode; 91 state_ = kPendingDecode;
89 DecodePendingBuffer(); 92 DecodePendingBuffer();
90 } 93 }
91 94
92 void DecryptingVideoDecoder::Reset(const base::Closure& closure) { 95 void DecryptingVideoDecoder::Reset(const base::Closure& closure) {
93 DVLOG(2) << "Reset() - state: " << state_; 96 DVLOG(2) << "Reset() - state: " << state_;
(...skipping 15 matching lines...) Expand all
109 // after the decode callback is fired - see DecryptAndDecodeBuffer() and 112 // after the decode callback is fired - see DecryptAndDecodeBuffer() and
110 // DeliverFrame(). 113 // DeliverFrame().
111 if (state_ == kPendingDecode) { 114 if (state_ == kPendingDecode) {
112 DCHECK(!decode_cb_.is_null()); 115 DCHECK(!decode_cb_.is_null());
113 return; 116 return;
114 } 117 }
115 118
116 if (state_ == kWaitingForKey) { 119 if (state_ == kWaitingForKey) {
117 DCHECK(!decode_cb_.is_null()); 120 DCHECK(!decode_cb_.is_null());
118 pending_buffer_to_decode_ = NULL; 121 pending_buffer_to_decode_ = NULL;
119 base::ResetAndReturn(&decode_cb_).Run(kAborted, NULL); 122 base::ResetAndReturn(&decode_cb_).Run(kAborted);
120 } 123 }
121 124
122 DCHECK(decode_cb_.is_null()); 125 DCHECK(decode_cb_.is_null());
123 DoReset(); 126 DoReset();
124 } 127 }
125 128
126 void DecryptingVideoDecoder::Stop() { 129 void DecryptingVideoDecoder::Stop() {
127 DCHECK(task_runner_->BelongsToCurrentThread()); 130 DCHECK(task_runner_->BelongsToCurrentThread());
128 DVLOG(2) << "Stop() - state: " << state_; 131 DVLOG(2) << "Stop() - state: " << state_;
129 132
130 // Invalidate all weak pointers so that pending callbacks won't be fired into 133 // Invalidate all weak pointers so that pending callbacks won't be fired into
131 // this object. 134 // this object.
132 weak_factory_.InvalidateWeakPtrs(); 135 weak_factory_.InvalidateWeakPtrs();
133 136
134 // At this point the render thread is likely paused (in WebMediaPlayerImpl's 137 // At this point the render thread is likely paused (in WebMediaPlayerImpl's
135 // Destroy()), so running |closure| can't wait for anything that requires the 138 // Destroy()), so running |closure| can't wait for anything that requires the
136 // render thread to be processing messages to complete (such as PPAPI 139 // render thread to be processing messages to complete (such as PPAPI
137 // callbacks). 140 // callbacks).
138 if (decryptor_) { 141 if (decryptor_) {
139 decryptor_->DeinitializeDecoder(Decryptor::kVideo); 142 decryptor_->DeinitializeDecoder(Decryptor::kVideo);
140 decryptor_ = NULL; 143 decryptor_ = NULL;
141 } 144 }
142 if (!set_decryptor_ready_cb_.is_null()) 145 if (!set_decryptor_ready_cb_.is_null())
143 base::ResetAndReturn(&set_decryptor_ready_cb_).Run(DecryptorReadyCB()); 146 base::ResetAndReturn(&set_decryptor_ready_cb_).Run(DecryptorReadyCB());
144 pending_buffer_to_decode_ = NULL; 147 pending_buffer_to_decode_ = NULL;
145 if (!init_cb_.is_null()) 148 if (!init_cb_.is_null())
146 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); 149 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
147 if (!decode_cb_.is_null()) 150 if (!decode_cb_.is_null())
148 base::ResetAndReturn(&decode_cb_).Run(kAborted, NULL); 151 base::ResetAndReturn(&decode_cb_).Run(kAborted);
149 if (!reset_cb_.is_null()) 152 if (!reset_cb_.is_null())
150 base::ResetAndReturn(&reset_cb_).Run(); 153 base::ResetAndReturn(&reset_cb_).Run();
151 154
152 state_ = kStopped; 155 state_ = kStopped;
153 } 156 }
154 157
155 DecryptingVideoDecoder::~DecryptingVideoDecoder() { 158 DecryptingVideoDecoder::~DecryptingVideoDecoder() {
156 DCHECK(state_ == kUninitialized || state_ == kStopped) << state_; 159 DCHECK(state_ == kUninitialized || state_ == kStopped) << state_;
157 } 160 }
158 161
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 "media", "DecryptingVideoDecoder::DecodePendingBuffer", trace_id_); 237 "media", "DecryptingVideoDecoder::DecodePendingBuffer", trace_id_);
235 238
236 bool need_to_try_again_if_nokey_is_returned = key_added_while_decode_pending_; 239 bool need_to_try_again_if_nokey_is_returned = key_added_while_decode_pending_;
237 key_added_while_decode_pending_ = false; 240 key_added_while_decode_pending_ = false;
238 241
239 scoped_refptr<DecoderBuffer> scoped_pending_buffer_to_decode = 242 scoped_refptr<DecoderBuffer> scoped_pending_buffer_to_decode =
240 pending_buffer_to_decode_; 243 pending_buffer_to_decode_;
241 pending_buffer_to_decode_ = NULL; 244 pending_buffer_to_decode_ = NULL;
242 245
243 if (!reset_cb_.is_null()) { 246 if (!reset_cb_.is_null()) {
244 base::ResetAndReturn(&decode_cb_).Run(kAborted, NULL); 247 base::ResetAndReturn(&decode_cb_).Run(kAborted);
245 DoReset(); 248 DoReset();
246 return; 249 return;
247 } 250 }
248 251
249 DCHECK_EQ(status == Decryptor::kSuccess, frame.get() != NULL); 252 DCHECK_EQ(status == Decryptor::kSuccess, frame.get() != NULL);
250 253
251 if (status == Decryptor::kError) { 254 if (status == Decryptor::kError) {
252 DVLOG(2) << "DeliverFrame() - kError"; 255 DVLOG(2) << "DeliverFrame() - kError";
253 state_ = kError; 256 state_ = kError;
254 base::ResetAndReturn(&decode_cb_).Run(kDecodeError, NULL); 257 base::ResetAndReturn(&decode_cb_).Run(kDecodeError);
255 return; 258 return;
256 } 259 }
257 260
258 if (status == Decryptor::kNoKey) { 261 if (status == Decryptor::kNoKey) {
259 DVLOG(2) << "DeliverFrame() - kNoKey"; 262 DVLOG(2) << "DeliverFrame() - kNoKey";
260 // Set |pending_buffer_to_decode_| back as we need to try decoding the 263 // Set |pending_buffer_to_decode_| back as we need to try decoding the
261 // pending buffer again when new key is added to the decryptor. 264 // pending buffer again when new key is added to the decryptor.
262 pending_buffer_to_decode_ = scoped_pending_buffer_to_decode; 265 pending_buffer_to_decode_ = scoped_pending_buffer_to_decode;
263 266
264 if (need_to_try_again_if_nokey_is_returned) { 267 if (need_to_try_again_if_nokey_is_returned) {
265 // The |state_| is still kPendingDecode. 268 // The |state_| is still kPendingDecode.
266 DecodePendingBuffer(); 269 DecodePendingBuffer();
267 return; 270 return;
268 } 271 }
269 272
270 state_ = kWaitingForKey; 273 state_ = kWaitingForKey;
271 return; 274 return;
272 } 275 }
273 276
274 if (status == Decryptor::kNeedMoreData) { 277 if (status == Decryptor::kNeedMoreData) {
275 DVLOG(2) << "DeliverFrame() - kNeedMoreData"; 278 DVLOG(2) << "DeliverFrame() - kNeedMoreData";
276 if (scoped_pending_buffer_to_decode->end_of_stream()) { 279 if (scoped_pending_buffer_to_decode->end_of_stream()) {
277 state_ = kDecodeFinished; 280 state_ = kDecodeFinished;
278 base::ResetAndReturn(&decode_cb_).Run( 281 output_cb_.Run(media::VideoFrame::CreateEOSFrame());
279 kOk, media::VideoFrame::CreateEOSFrame()); 282 } else {
280 return; 283 state_ = kIdle;
281 } 284 }
282 285 base::ResetAndReturn(&decode_cb_).Run(kOk);
283 state_ = kIdle;
284 base::ResetAndReturn(&decode_cb_).Run(kNotEnoughData, NULL);
285 return; 286 return;
286 } 287 }
287 288
288 DCHECK_EQ(status, Decryptor::kSuccess); 289 DCHECK_EQ(status, Decryptor::kSuccess);
289 // No frame returned with kSuccess should be end-of-stream frame. 290 // No frame returned with kSuccess should be end-of-stream frame.
290 DCHECK(!frame->end_of_stream()); 291 DCHECK(!frame->end_of_stream());
291 state_ = kIdle; 292 state_ = kIdle;
292 base::ResetAndReturn(&decode_cb_).Run(kOk, frame); 293 output_cb_.Run(frame);
294 base::ResetAndReturn(&decode_cb_).Run(kOk);
293 } 295 }
294 296
295 void DecryptingVideoDecoder::OnKeyAdded() { 297 void DecryptingVideoDecoder::OnKeyAdded() {
296 DVLOG(2) << "OnKeyAdded()"; 298 DVLOG(2) << "OnKeyAdded()";
297 DCHECK(task_runner_->BelongsToCurrentThread()); 299 DCHECK(task_runner_->BelongsToCurrentThread());
298 300
299 if (state_ == kPendingDecode) { 301 if (state_ == kPendingDecode) {
300 key_added_while_decode_pending_ = true; 302 key_added_while_decode_pending_ = true;
301 return; 303 return;
302 } 304 }
303 305
304 if (state_ == kWaitingForKey) { 306 if (state_ == kWaitingForKey) {
305 state_ = kPendingDecode; 307 state_ = kPendingDecode;
306 DecodePendingBuffer(); 308 DecodePendingBuffer();
307 } 309 }
308 } 310 }
309 311
310 void DecryptingVideoDecoder::DoReset() { 312 void DecryptingVideoDecoder::DoReset() {
311 DCHECK(init_cb_.is_null()); 313 DCHECK(init_cb_.is_null());
312 DCHECK(decode_cb_.is_null()); 314 DCHECK(decode_cb_.is_null());
313 state_ = kIdle; 315 state_ = kIdle;
314 base::ResetAndReturn(&reset_cb_).Run(); 316 base::ResetAndReturn(&reset_cb_).Run();
315 } 317 }
316 318
317 } // namespace media 319 } // 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