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 "content/common/gpu/media/omx_video_decode_accelerator.h" | 5 #include "content/common/gpu/media/omx_video_decode_accelerator.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
282 "Buffer id", bitstream_buffer.id()); | 282 "Buffer id", bitstream_buffer.id()); |
283 DCHECK_EQ(message_loop_, MessageLoop::current()); | 283 DCHECK_EQ(message_loop_, MessageLoop::current()); |
284 | 284 |
285 if (current_state_change_ == RESETTING || | 285 if (current_state_change_ == RESETTING || |
286 !queued_bitstream_buffers_.empty() || | 286 !queued_bitstream_buffers_.empty() || |
287 free_input_buffers_.empty()) { | 287 free_input_buffers_.empty()) { |
288 queued_bitstream_buffers_.push_back(bitstream_buffer); | 288 queued_bitstream_buffers_.push_back(bitstream_buffer); |
289 return; | 289 return; |
290 } | 290 } |
291 | 291 |
292 RETURN_ON_FAILURE(current_state_change_ == NO_TRANSITION && | 292 RETURN_ON_FAILURE((current_state_change_ == NO_TRANSITION || |
| 293 current_state_change_ == FLUSHING) && |
293 (client_state_ == OMX_StateIdle || | 294 (client_state_ == OMX_StateIdle || |
294 client_state_ == OMX_StateExecuting), | 295 client_state_ == OMX_StateExecuting), |
295 "Call to Decode() during invalid state or transition: " | 296 "Call to Decode() during invalid state or transition: " |
296 << current_state_change_ << ", " << client_state_, | 297 << current_state_change_ << ", " << client_state_, |
297 ILLEGAL_STATE,); | 298 ILLEGAL_STATE,); |
298 | 299 |
299 OMX_BUFFERHEADERTYPE* omx_buffer = free_input_buffers_.front(); | 300 OMX_BUFFERHEADERTYPE* omx_buffer = free_input_buffers_.front(); |
300 free_input_buffers_.pop(); | 301 free_input_buffers_.pop(); |
301 | 302 |
| 303 if (bitstream_buffer.id() == -1 && bitstream_buffer.size() == 0) { |
| 304 // Cook up an empty buffer w/ EOS set and feed it to OMX. |
| 305 omx_buffer->nFilledLen = 0; |
| 306 omx_buffer->nAllocLen = omx_buffer->nFilledLen; |
| 307 omx_buffer->nFlags |= OMX_BUFFERFLAG_EOS; |
| 308 omx_buffer->nTimeStamp = -2; |
| 309 OMX_ERRORTYPE result = OMX_EmptyThisBuffer(component_handle_, omx_buffer); |
| 310 RETURN_ON_OMX_FAILURE(result, "OMX_EmptyThisBuffer() failed", |
| 311 PLATFORM_FAILURE,); |
| 312 input_buffers_at_component_++; |
| 313 return; |
| 314 } |
| 315 |
302 // Setup |omx_buffer|. | 316 // Setup |omx_buffer|. |
303 scoped_ptr<base::SharedMemory> shm( | 317 scoped_ptr<base::SharedMemory> shm( |
304 new base::SharedMemory(bitstream_buffer.handle(), true)); | 318 new base::SharedMemory(bitstream_buffer.handle(), true)); |
305 RETURN_ON_FAILURE(shm->Map(bitstream_buffer.size()), | 319 RETURN_ON_FAILURE(shm->Map(bitstream_buffer.size()), |
306 "Failed to SharedMemory::Map()", UNREADABLE_INPUT,); | 320 "Failed to SharedMemory::Map()", UNREADABLE_INPUT,); |
307 | 321 |
308 SharedMemoryAndId* input_buffer_details = new SharedMemoryAndId(); | 322 SharedMemoryAndId* input_buffer_details = new SharedMemoryAndId(); |
309 input_buffer_details->first.reset(shm.release()); | 323 input_buffer_details->first.reset(shm.release()); |
310 input_buffer_details->second = bitstream_buffer.id(); | 324 input_buffer_details->second = bitstream_buffer.id(); |
311 DCHECK(!omx_buffer->pAppPrivate); | 325 DCHECK(!omx_buffer->pAppPrivate); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 if (!AllocateOutputBuffers()) | 371 if (!AllocateOutputBuffers()) |
358 return; | 372 return; |
359 if (!SendCommandToPort(OMX_CommandPortEnable, output_port_)) | 373 if (!SendCommandToPort(OMX_CommandPortEnable, output_port_)) |
360 return; | 374 return; |
361 } | 375 } |
362 | 376 |
363 void OmxVideoDecodeAccelerator::ReusePictureBuffer(int32 picture_buffer_id) { | 377 void OmxVideoDecodeAccelerator::ReusePictureBuffer(int32 picture_buffer_id) { |
364 TRACE_EVENT1("Video Decoder", "OVDA::ReusePictureBuffer", | 378 TRACE_EVENT1("Video Decoder", "OVDA::ReusePictureBuffer", |
365 "Picture id", picture_buffer_id); | 379 "Picture id", picture_buffer_id); |
366 DCHECK_EQ(message_loop_, MessageLoop::current()); | 380 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 381 |
367 RETURN_ON_FAILURE(CanFillBuffer(), "Can't fill buffer", ILLEGAL_STATE,); | 382 RETURN_ON_FAILURE(CanFillBuffer(), "Can't fill buffer", ILLEGAL_STATE,); |
368 | 383 |
369 OutputPictureById::iterator it = pictures_.find(picture_buffer_id); | 384 OutputPictureById::iterator it = pictures_.find(picture_buffer_id); |
370 RETURN_ON_FAILURE(it != pictures_.end(), | 385 RETURN_ON_FAILURE(it != pictures_.end(), |
371 "Missing picture buffer id: " << picture_buffer_id, | 386 "Missing picture buffer id: " << picture_buffer_id, |
372 INVALID_ARGUMENT,); | 387 INVALID_ARGUMENT,); |
373 OutputPicture& output_picture = it->second; | 388 OutputPicture& output_picture = it->second; |
374 | 389 |
375 ++output_buffers_at_component_; | 390 ++output_buffers_at_component_; |
376 OMX_ERRORTYPE result = | 391 OMX_ERRORTYPE result = |
377 OMX_FillThisBuffer(component_handle_, output_picture.omx_buffer_header); | 392 OMX_FillThisBuffer(component_handle_, output_picture.omx_buffer_header); |
378 RETURN_ON_OMX_FAILURE(result, "OMX_FillThisBuffer() failed", | 393 RETURN_ON_OMX_FAILURE(result, "OMX_FillThisBuffer() failed", |
379 PLATFORM_FAILURE,); | 394 PLATFORM_FAILURE,); |
380 } | 395 } |
381 | 396 |
382 void OmxVideoDecodeAccelerator::Flush() { | 397 void OmxVideoDecodeAccelerator::Flush() { |
383 DCHECK_EQ(message_loop_, MessageLoop::current()); | 398 DCHECK_EQ(message_loop_, MessageLoop::current()); |
384 DCHECK_EQ(current_state_change_, NO_TRANSITION); | 399 DCHECK_EQ(current_state_change_, NO_TRANSITION); |
385 DCHECK_EQ(client_state_, OMX_StateExecuting); | 400 DCHECK_EQ(client_state_, OMX_StateExecuting); |
386 current_state_change_ = FLUSHING; | 401 current_state_change_ = FLUSHING; |
387 | 402 |
388 // Cook up an empty buffer w/ EOS set and feed it to OMX. | 403 Decode(media::BitstreamBuffer(-1, base::SharedMemoryHandle(), 0)); |
389 OMX_BUFFERHEADERTYPE* omx_buffer = free_input_buffers_.front(); | |
390 free_input_buffers_.pop(); | |
391 omx_buffer->nFilledLen = 0; | |
392 omx_buffer->nAllocLen = omx_buffer->nFilledLen; | |
393 omx_buffer->nFlags |= OMX_BUFFERFLAG_EOS; | |
394 omx_buffer->nTimeStamp = -2; | |
395 OMX_ERRORTYPE result = OMX_EmptyThisBuffer(component_handle_, omx_buffer); | |
396 RETURN_ON_OMX_FAILURE(result, "OMX_EmptyThisBuffer() failed", | |
397 PLATFORM_FAILURE,); | |
398 input_buffers_at_component_++; | |
399 } | 404 } |
400 | 405 |
401 void OmxVideoDecodeAccelerator::OnReachedEOSInFlushing() { | 406 void OmxVideoDecodeAccelerator::OnReachedEOSInFlushing() { |
402 DCHECK_EQ(message_loop_, MessageLoop::current()); | 407 DCHECK_EQ(message_loop_, MessageLoop::current()); |
403 DCHECK_EQ(client_state_, OMX_StateExecuting); | 408 DCHECK_EQ(client_state_, OMX_StateExecuting); |
404 current_state_change_ = NO_TRANSITION; | 409 current_state_change_ = NO_TRANSITION; |
405 if (client_) | 410 if (client_) |
406 client_->NotifyFlushDone(); | 411 client_->NotifyFlushDone(); |
407 } | 412 } |
408 | 413 |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
528 | 533 |
529 void OmxVideoDecodeAccelerator::OnReachedPauseInResetting() { | 534 void OmxVideoDecodeAccelerator::OnReachedPauseInResetting() { |
530 DCHECK_EQ(client_state_, OMX_StateExecuting); | 535 DCHECK_EQ(client_state_, OMX_StateExecuting); |
531 client_state_ = OMX_StatePause; | 536 client_state_ = OMX_StatePause; |
532 FlushIOPorts(); | 537 FlushIOPorts(); |
533 } | 538 } |
534 | 539 |
535 void OmxVideoDecodeAccelerator::DecodeQueuedBitstreamBuffers() { | 540 void OmxVideoDecodeAccelerator::DecodeQueuedBitstreamBuffers() { |
536 BitstreamBufferList buffers; | 541 BitstreamBufferList buffers; |
537 buffers.swap(queued_bitstream_buffers_); | 542 buffers.swap(queued_bitstream_buffers_); |
| 543 if (current_state_change_ == DESTROYING || |
| 544 current_state_change_ == ERRORING) { |
| 545 return; |
| 546 } |
538 for (size_t i = 0; i < buffers.size(); ++i) | 547 for (size_t i = 0; i < buffers.size(); ++i) |
539 Decode(buffers[i]); | 548 Decode(buffers[i]); |
540 } | 549 } |
541 | 550 |
542 void OmxVideoDecodeAccelerator::OnReachedExecutingInResetting() { | 551 void OmxVideoDecodeAccelerator::OnReachedExecutingInResetting() { |
543 DCHECK_EQ(client_state_, OMX_StatePause); | 552 DCHECK_EQ(client_state_, OMX_StatePause); |
544 client_state_ = OMX_StateExecuting; | 553 client_state_ = OMX_StateExecuting; |
545 current_state_change_ = NO_TRANSITION; | 554 current_state_change_ = NO_TRANSITION; |
546 if (!client_) | 555 if (!client_) |
547 return; | 556 return; |
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1086 | 1095 |
1087 bool OmxVideoDecodeAccelerator::SendCommandToPort( | 1096 bool OmxVideoDecodeAccelerator::SendCommandToPort( |
1088 OMX_COMMANDTYPE cmd, int port_index) { | 1097 OMX_COMMANDTYPE cmd, int port_index) { |
1089 DCHECK_EQ(message_loop_, MessageLoop::current()); | 1098 DCHECK_EQ(message_loop_, MessageLoop::current()); |
1090 OMX_ERRORTYPE result = OMX_SendCommand(component_handle_, | 1099 OMX_ERRORTYPE result = OMX_SendCommand(component_handle_, |
1091 cmd, port_index, 0); | 1100 cmd, port_index, 0); |
1092 RETURN_ON_OMX_FAILURE(result, "SendCommand() failed" << cmd, | 1101 RETURN_ON_OMX_FAILURE(result, "SendCommand() failed" << cmd, |
1093 PLATFORM_FAILURE, false); | 1102 PLATFORM_FAILURE, false); |
1094 return true; | 1103 return true; |
1095 } | 1104 } |
OLD | NEW |