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

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: VideoFrameStream ready for review. Created 7 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"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/message_loop_proxy.h" 12 #include "base/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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 165
169 DCHECK_EQ(state_, kDecryptorRequested) << state_; 166 DCHECK_EQ(state_, kDecryptorRequested) << state_;
170 DCHECK(!init_cb_.is_null()); 167 DCHECK(!init_cb_.is_null());
171 DCHECK(!set_decryptor_ready_cb_.is_null()); 168 DCHECK(!set_decryptor_ready_cb_.is_null());
172 set_decryptor_ready_cb_.Reset(); 169 set_decryptor_ready_cb_.Reset();
173 170
174 decryptor_ = decryptor; 171 decryptor_ = decryptor;
175 172
176 state_ = kPendingDecoderInit; 173 state_ = kPendingDecoderInit;
177 decryptor_->InitializeVideoDecoder( 174 decryptor_->InitializeVideoDecoder(
178 demuxer_stream_->video_decoder_config(), BindToCurrentLoop(base::Bind( 175 config_,
176 BindToCurrentLoop(base::Bind(
179 &DecryptingVideoDecoder::FinishInitialization, weak_this_))); 177 &DecryptingVideoDecoder::FinishInitialization, weak_this_)));
180 } 178 }
181 179
182 void DecryptingVideoDecoder::FinishInitialization(bool success) { 180 void DecryptingVideoDecoder::FinishInitialization(bool success) {
183 DVLOG(2) << "FinishInitialization()"; 181 DVLOG(2) << "FinishInitialization()";
184 DCHECK(message_loop_->BelongsToCurrentThread()); 182 DCHECK(message_loop_->BelongsToCurrentThread());
185 183
186 if (state_ == kStopped) 184 if (state_ == kStopped)
187 return; 185 return;
188 186
189 DCHECK_EQ(state_, kPendingDecoderInit) << state_; 187 DCHECK_EQ(state_, kPendingDecoderInit) << state_;
190 DCHECK(!init_cb_.is_null()); 188 DCHECK(!init_cb_.is_null());
191 DCHECK(reset_cb_.is_null()); // No Reset() before initialization finished. 189 DCHECK(reset_cb_.is_null()); // No Reset() before initialization finished.
192 DCHECK(read_cb_.is_null()); // No Read() before initialization finished. 190 DCHECK(read_cb_.is_null()); // No Read() before initialization finished.
193 191
194 if (!success) { 192 if (!success) {
195 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); 193 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
196 state_ = kStopped; 194 state_ = kStopped;
197 return; 195 return;
198 } 196 }
199 197
200 decryptor_->RegisterNewKeyCB(Decryptor::kVideo, BindToCurrentLoop( 198 decryptor_->RegisterNewKeyCB(Decryptor::kVideo, BindToCurrentLoop(
201 base::Bind(&DecryptingVideoDecoder::OnKeyAdded, weak_this_))); 199 base::Bind(&DecryptingVideoDecoder::OnKeyAdded, weak_this_)));
202 200
203 // Success! 201 // Success!
204 state_ = kIdle; 202 state_ = kIdle;
205 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); 203 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK);
206 } 204 }
207 205
208 void DecryptingVideoDecoder::ReadFromDemuxerStream() {
209 DCHECK(message_loop_->BelongsToCurrentThread());
210 DCHECK_EQ(state_, kPendingDemuxerRead) << state_;
211 DCHECK(!read_cb_.is_null());
212
213 demuxer_stream_->Read(
214 base::Bind(&DecryptingVideoDecoder::DecryptAndDecodeBuffer, weak_this_));
215 }
216
217 void DecryptingVideoDecoder::DecryptAndDecodeBuffer(
218 DemuxerStream::Status status,
219 const scoped_refptr<DecoderBuffer>& buffer) {
220 DVLOG(3) << "DecryptAndDecodeBuffer()";
221 DCHECK(message_loop_->BelongsToCurrentThread());
222
223 if (state_ == kStopped)
224 return;
225
226 DCHECK_EQ(state_, kPendingDemuxerRead) << state_;
227 DCHECK(!read_cb_.is_null());
228 DCHECK_EQ(buffer != NULL, status == DemuxerStream::kOk) << status;
229
230 if (!reset_cb_.is_null()) {
231 base::ResetAndReturn(&read_cb_).Run(kOk, NULL);
232 DoReset();
233 return;
234 }
235
236 if (status == DemuxerStream::kAborted) {
237 DVLOG(2) << "DecryptAndDecodeBuffer() - kAborted";
238 state_ = kIdle;
239 base::ResetAndReturn(&read_cb_).Run(kOk, NULL);
240 return;
241 }
242
243 // VideoFrameStream ensures no kConfigChanged is passed to VideoDecoders.
244 DCHECK_EQ(status, DemuxerStream::kOk) << status;
245 pending_buffer_to_decode_ = buffer;
246 state_ = kPendingDecode;
247 DecodePendingBuffer();
248 }
249 206
250 void DecryptingVideoDecoder::DecodePendingBuffer() { 207 void DecryptingVideoDecoder::DecodePendingBuffer() {
251 DCHECK(message_loop_->BelongsToCurrentThread()); 208 DCHECK(message_loop_->BelongsToCurrentThread());
252 DCHECK_EQ(state_, kPendingDecode) << state_; 209 DCHECK_EQ(state_, kPendingDecode) << state_;
253 TRACE_EVENT_ASYNC_BEGIN0( 210 TRACE_EVENT_ASYNC_BEGIN0(
254 "eme", "DecryptingVideoDecoder::DecodePendingBuffer", ++trace_id_); 211 "eme", "DecryptingVideoDecoder::DecodePendingBuffer", ++trace_id_);
255 212
256 int buffer_size = 0; 213 int buffer_size = 0;
257 if (!pending_buffer_to_decode_->IsEndOfStream()) { 214 if (!pending_buffer_to_decode_->IsEndOfStream()) {
258 buffer_size = pending_buffer_to_decode_->GetDataSize(); 215 buffer_size = pending_buffer_to_decode_->GetDataSize();
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 283
327 if (status == Decryptor::kNeedMoreData) { 284 if (status == Decryptor::kNeedMoreData) {
328 DVLOG(2) << "DeliverFrame() - kNeedMoreData"; 285 DVLOG(2) << "DeliverFrame() - kNeedMoreData";
329 if (scoped_pending_buffer_to_decode->IsEndOfStream()) { 286 if (scoped_pending_buffer_to_decode->IsEndOfStream()) {
330 state_ = kDecodeFinished; 287 state_ = kDecodeFinished;
331 base::ResetAndReturn(&read_cb_).Run( 288 base::ResetAndReturn(&read_cb_).Run(
332 kOk, media::VideoFrame::CreateEmptyFrame()); 289 kOk, media::VideoFrame::CreateEmptyFrame());
333 return; 290 return;
334 } 291 }
335 292
336 state_ = kPendingDemuxerRead; 293 state_ = kIdle;
337 ReadFromDemuxerStream(); 294 base::ResetAndReturn(&read_cb_).Run(kNotEnoughData, NULL);
338 return; 295 return;
339 } 296 }
340 297
341 DCHECK_EQ(status, Decryptor::kSuccess); 298 DCHECK_EQ(status, Decryptor::kSuccess);
342 // No frame returned with kSuccess should be end-of-stream frame. 299 // No frame returned with kSuccess should be end-of-stream frame.
343 DCHECK(!frame->IsEndOfStream()); 300 DCHECK(!frame->IsEndOfStream());
344 state_ = kIdle; 301 state_ = kIdle;
345 base::ResetAndReturn(&read_cb_).Run(kOk, frame); 302 base::ResetAndReturn(&read_cb_).Run(kOk, frame);
346 } 303 }
347 304
(...skipping 13 matching lines...) Expand all
361 } 318 }
362 319
363 void DecryptingVideoDecoder::DoReset() { 320 void DecryptingVideoDecoder::DoReset() {
364 DCHECK(init_cb_.is_null()); 321 DCHECK(init_cb_.is_null());
365 DCHECK(read_cb_.is_null()); 322 DCHECK(read_cb_.is_null());
366 state_ = kIdle; 323 state_ = kIdle;
367 base::ResetAndReturn(&reset_cb_).Run(); 324 base::ResetAndReturn(&reset_cb_).Run();
368 } 325 }
369 326
370 } // namespace media 327 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698