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 "base/bind.h" | 5 #include "base/bind.h" |
6 #include "base/command_line.h" | 6 #include "base/command_line.h" |
7 #include "base/debug/trace_event.h" | 7 #include "base/debug/trace_event.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
122 DCHECK_EQ(message_loop_, MessageLoop::current()); | 122 DCHECK_EQ(message_loop_, MessageLoop::current()); |
123 | 123 |
124 DVLOG(4) << "Mapping new input buffer id: " << bitstream_buffer.id() | 124 DVLOG(4) << "Mapping new input buffer id: " << bitstream_buffer.id() |
125 << " size: " << (int)bitstream_buffer.size(); | 125 << " size: " << (int)bitstream_buffer.size(); |
126 | 126 |
127 scoped_ptr<base::SharedMemory> shm( | 127 scoped_ptr<base::SharedMemory> shm( |
128 new base::SharedMemory(bitstream_buffer.handle(), true)); | 128 new base::SharedMemory(bitstream_buffer.handle(), true)); |
129 RETURN_AND_NOTIFY_ON_FAILURE(shm->Map(bitstream_buffer.size()), | 129 RETURN_AND_NOTIFY_ON_FAILURE(shm->Map(bitstream_buffer.size()), |
130 "Failed to map input buffer", UNREADABLE_INPUT,); | 130 "Failed to map input buffer", UNREADABLE_INPUT,); |
131 | 131 |
132 base::AutoLock auto_lock(lock_); | |
Ami GONE FROM CHROMIUM
2012/08/03 20:38:16
This change isn't strictly necessary b/c the extra
piman
2012/08/03 21:05:02
This change is absolutely necessary (we found the
Ami GONE FROM CHROMIUM
2012/08/03 21:06:41
Good point!
| |
133 | |
132 // Set up a new input buffer and queue it for later. | 134 // Set up a new input buffer and queue it for later. |
133 linked_ptr<InputBuffer> input_buffer(new InputBuffer()); | 135 linked_ptr<InputBuffer> input_buffer(new InputBuffer()); |
134 input_buffer->shm.reset(shm.release()); | 136 input_buffer->shm.reset(shm.release()); |
135 input_buffer->id = bitstream_buffer.id(); | 137 input_buffer->id = bitstream_buffer.id(); |
136 input_buffer->size = bitstream_buffer.size(); | 138 input_buffer->size = bitstream_buffer.size(); |
137 | 139 |
138 base::AutoLock auto_lock(lock_); | |
139 input_buffers_.push(input_buffer); | 140 input_buffers_.push(input_buffer); |
140 input_ready_.Signal(); | 141 input_ready_.Signal(); |
141 } | 142 } |
142 | 143 |
143 void VaapiVideoDecodeAccelerator::InitialDecodeTask() { | 144 void VaapiVideoDecodeAccelerator::InitialDecodeTask() { |
144 DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current()); | 145 DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current()); |
145 | 146 |
146 // Since multiple Decode()'s can be in flight at once, it's possible that a | 147 // Since multiple Decode()'s can be in flight at once, it's possible that a |
147 // Decode() that seemed like an initial one is actually later in the stream | 148 // Decode() that seemed like an initial one is actually later in the stream |
148 // and we're already kDecoding. Let the normal DecodeTask take over in that | 149 // and we're already kDecoding. Let the normal DecodeTask take over in that |
149 // case. | 150 // case. |
150 { | 151 { |
151 base::AutoLock auto_lock(lock_); | 152 base::AutoLock auto_lock(lock_); |
152 if (state_ != kInitialized && state_ != kIdle) | 153 if (state_ != kInitialized && state_ != kIdle) |
153 return; | 154 return; |
154 } | 155 } |
155 | 156 |
156 // Try to initialize or resume playback after reset. | 157 // Try to initialize or resume playback after reset. |
157 for (;;) { | 158 for (;;) { |
158 if (!GetInputBuffer()) | 159 if (!GetInputBuffer()) |
159 return; | 160 return; |
160 DCHECK(curr_input_buffer_.get()); | |
161 | 161 |
162 VaapiH264Decoder::DecResult res = decoder_.DecodeInitial( | 162 int32 id = 0; |
163 curr_input_buffer_->id); | 163 { |
164 base::AutoLock auto_lock(lock_); | |
165 DCHECK(curr_input_buffer_.get()); | |
166 id = curr_input_buffer_->id; | |
167 } | |
168 | |
169 VaapiH264Decoder::DecResult res = decoder_.DecodeInitial(id); | |
164 switch (res) { | 170 switch (res) { |
165 case VaapiH264Decoder::kReadyToDecode: | 171 case VaapiH264Decoder::kReadyToDecode: |
166 if (state_ == kInitialized) { | 172 if (state_ == kInitialized) { |
167 base::AutoLock auto_lock(lock_); | 173 base::AutoLock auto_lock(lock_); |
168 state_ = kPicturesRequested; | 174 state_ = kPicturesRequested; |
169 int num_pics = decoder_.GetRequiredNumOfPictures(); | 175 int num_pics = decoder_.GetRequiredNumOfPictures(); |
170 gfx::Size size(decoder_.pic_width(), decoder_.pic_height()); | 176 gfx::Size size(decoder_.pic_width(), decoder_.pic_height()); |
171 DVLOG(1) << "Requesting " << num_pics << " pictures of size: " | 177 DVLOG(1) << "Requesting " << num_pics << " pictures of size: " |
172 << size.width() << "x" << size.height(); | 178 << size.width() << "x" << size.height(); |
173 message_loop_->PostTask(FROM_HERE, base::Bind( | 179 message_loop_->PostTask(FROM_HERE, base::Bind( |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
240 curr_input_buffer_->size); | 246 curr_input_buffer_->size); |
241 return true; | 247 return true; |
242 | 248 |
243 default: | 249 default: |
244 // We got woken up due to being destroyed/reset, ignore any already | 250 // We got woken up due to being destroyed/reset, ignore any already |
245 // queued inputs. | 251 // queued inputs. |
246 return false; | 252 return false; |
247 } | 253 } |
248 } | 254 } |
249 | 255 |
250 void VaapiVideoDecodeAccelerator::ReturnCurrInputBuffer() { | 256 void VaapiVideoDecodeAccelerator::ReturnCurrInputBufferLocked() { |
257 lock_.AssertAcquired(); | |
251 DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current()); | 258 DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current()); |
259 DCHECK(curr_input_buffer_.get()); | |
252 | 260 |
253 base::AutoLock auto_lock(lock_); | |
254 DCHECK(curr_input_buffer_.get()); | |
255 int32 id = curr_input_buffer_->id; | 261 int32 id = curr_input_buffer_->id; |
256 curr_input_buffer_.reset(); | 262 curr_input_buffer_.reset(); |
257 DVLOG(4) << "End of input buffer " << id; | 263 DVLOG(4) << "End of input buffer " << id; |
258 message_loop_->PostTask(FROM_HERE, base::Bind( | 264 message_loop_->PostTask(FROM_HERE, base::Bind( |
259 &Client::NotifyEndOfBitstreamBuffer, client_, id)); | 265 &Client::NotifyEndOfBitstreamBuffer, client_, id)); |
260 } | 266 } |
261 | 267 |
268 void VaapiVideoDecodeAccelerator::ReturnCurrInputBuffer() { | |
269 base::AutoLock auto_lock(lock_); | |
270 ReturnCurrInputBufferLocked(); | |
271 } | |
272 | |
262 bool VaapiVideoDecodeAccelerator::GetOutputBuffers() { | 273 bool VaapiVideoDecodeAccelerator::GetOutputBuffers() { |
263 DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current()); | 274 DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current()); |
264 | 275 |
265 base::AutoLock auto_lock(lock_); | 276 base::AutoLock auto_lock(lock_); |
266 | 277 |
267 while (output_buffers_.empty() && | 278 while (output_buffers_.empty() && |
268 (state_ == kDecoding || state_ == kFlushing)) { | 279 (state_ == kDecoding || state_ == kFlushing)) { |
269 output_ready_.Wait(); | 280 output_ready_.Wait(); |
270 } | 281 } |
271 | 282 |
(...skipping 13 matching lines...) Expand all Loading... | |
285 | 296 |
286 // Main decode task. | 297 // Main decode task. |
287 DVLOG(4) << "Decode task"; | 298 DVLOG(4) << "Decode task"; |
288 | 299 |
289 // Try to decode what stream data is (still) in the decoder until we run out | 300 // Try to decode what stream data is (still) in the decoder until we run out |
290 // of it. | 301 // of it. |
291 for (;;) { | 302 for (;;) { |
292 if (!GetInputBuffer()) | 303 if (!GetInputBuffer()) |
293 // Early exit requested. | 304 // Early exit requested. |
294 return; | 305 return; |
295 DCHECK(curr_input_buffer_.get()); | |
296 | 306 |
297 VaapiH264Decoder::DecResult res = | 307 int32 id = 0; |
298 decoder_.DecodeOneFrame(curr_input_buffer_->id); | 308 { |
309 base::AutoLock auto_lock(lock_); | |
310 DCHECK(curr_input_buffer_.get()); | |
311 id = curr_input_buffer_->id; | |
312 } | |
313 | |
314 VaapiH264Decoder::DecResult res = decoder_.DecodeOneFrame(id); | |
299 switch (res) { | 315 switch (res) { |
300 case VaapiH264Decoder::kNeedMoreStreamData: | 316 case VaapiH264Decoder::kNeedMoreStreamData: |
301 ReturnCurrInputBuffer(); | 317 ReturnCurrInputBuffer(); |
302 break; | 318 break; |
303 | 319 |
304 case VaapiH264Decoder::kDecodedFrame: | 320 case VaapiH264Decoder::kDecodedFrame: |
305 // May still have more stream data, continue decoding. | 321 // May still have more stream data, continue decoding. |
306 break; | 322 break; |
307 | 323 |
308 case VaapiH264Decoder::kNoOutputAvailable: | 324 case VaapiH264Decoder::kNoOutputAvailable: |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
447 } | 463 } |
448 | 464 |
449 void VaapiVideoDecodeAccelerator::ResetTask() { | 465 void VaapiVideoDecodeAccelerator::ResetTask() { |
450 DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current()); | 466 DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current()); |
451 | 467 |
452 // All the decoding tasks from before the reset request from client are done | 468 // All the decoding tasks from before the reset request from client are done |
453 // by now, as this task was scheduled after them and client is expected not | 469 // by now, as this task was scheduled after them and client is expected not |
454 // to call Decode() after Reset() and before NotifyResetDone. | 470 // to call Decode() after Reset() and before NotifyResetDone. |
455 decoder_.Reset(); | 471 decoder_.Reset(); |
456 | 472 |
473 base::AutoLock auto_lock(lock_); | |
474 | |
457 // Return current input buffer, if present. | 475 // Return current input buffer, if present. |
458 if (curr_input_buffer_.get()) | 476 if (curr_input_buffer_.get()) |
459 ReturnCurrInputBuffer(); | 477 ReturnCurrInputBufferLocked(); |
460 | 478 |
461 // And let client know that we are done with reset. | 479 // And let client know that we are done with reset. |
462 message_loop_->PostTask(FROM_HERE, base::Bind( | 480 message_loop_->PostTask(FROM_HERE, base::Bind( |
463 &VaapiVideoDecodeAccelerator::FinishReset, weak_this_)); | 481 &VaapiVideoDecodeAccelerator::FinishReset, weak_this_)); |
464 } | 482 } |
465 | 483 |
466 void VaapiVideoDecodeAccelerator::Reset() { | 484 void VaapiVideoDecodeAccelerator::Reset() { |
467 DCHECK_EQ(message_loop_, MessageLoop::current()); | 485 DCHECK_EQ(message_loop_, MessageLoop::current()); |
468 DVLOG(1) << "Got reset request"; | 486 DVLOG(1) << "Got reset request"; |
469 | 487 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
543 "Input id", input_id, "Picture id", output_id); | 561 "Input id", input_id, "Picture id", output_id); |
544 DVLOG(4) << "Outputting picture, input id: " << input_id | 562 DVLOG(4) << "Outputting picture, input id: " << input_id |
545 << " output id: " << output_id; | 563 << " output id: " << output_id; |
546 | 564 |
547 // Forward the request to the main thread. | 565 // Forward the request to the main thread. |
548 DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current()); | 566 DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current()); |
549 message_loop_->PostTask(FROM_HERE, base::Bind( | 567 message_loop_->PostTask(FROM_HERE, base::Bind( |
550 &VaapiVideoDecodeAccelerator::SyncAndNotifyPictureReady, weak_this_, | 568 &VaapiVideoDecodeAccelerator::SyncAndNotifyPictureReady, weak_this_, |
551 input_id, output_id)); | 569 input_id, output_id)); |
552 } | 570 } |
OLD | NEW |