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

Side by Side Diff: content/common/gpu/media/omx_video_decode_accelerator.cc

Issue 7260008: Implement proper synchronization between HW video decode IPC and CommandBuffer. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 9 years, 5 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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/stl_util-inl.h" 7 #include "base/stl_util-inl.h"
8 #include "base/string_util.h" 8 #include "base/string_util.h"
9 #include "content/common/gpu/gpu_channel.h" 9 #include "content/common/gpu/gpu_channel.h"
10 #include "content/common/gpu/media/gles2_texture_to_egl_image_translator.h" 10 #include "content/common/gpu/media/gles2_texture_to_egl_image_translator.h"
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 } 328 }
329 buffer->pAppPrivate = NULL; 329 buffer->pAppPrivate = NULL;
330 buffer->nTimeStamp = 0; 330 buffer->nTimeStamp = 0;
331 buffer->nOutputPortIndex = output_port_; 331 buffer->nOutputPortIndex = output_port_;
332 CHECK(fake_output_buffers_.insert(buffer).second); 332 CHECK(fake_output_buffers_.insert(buffer).second);
333 } 333 }
334 334
335 return true; 335 return true;
336 } 336 }
337 337
338 bool OmxVideoDecodeAccelerator::Decode( 338 void OmxVideoDecodeAccelerator::Decode(
339 const media::BitstreamBuffer& bitstream_buffer) { 339 const media::BitstreamBuffer& bitstream_buffer) {
340 DCHECK(!free_input_buffers_.empty()); 340 DCHECK(!free_input_buffers_.empty());
341 341
342 if (!CanAcceptInput()) 342 if (!CanAcceptInput())
343 return false; 343 return;
344 344
345 OMX_BUFFERHEADERTYPE* omx_buffer = free_input_buffers_.front(); 345 OMX_BUFFERHEADERTYPE* omx_buffer = free_input_buffers_.front();
346 free_input_buffers_.pop(); 346 free_input_buffers_.pop();
347 347
348 // Setup |omx_buffer|. 348 // Setup |omx_buffer|.
349 scoped_ptr<base::SharedMemory> shm( 349 scoped_ptr<base::SharedMemory> shm(
350 new base::SharedMemory(bitstream_buffer.handle(), true)); 350 new base::SharedMemory(bitstream_buffer.handle(), true));
351 if (!shm->Map(bitstream_buffer.size())) { 351 if (!shm->Map(bitstream_buffer.size())) {
352 LOG(ERROR) << "Failed to SharedMemory::Map()."; 352 LOG(ERROR) << "Failed to SharedMemory::Map().";
353 return false; 353 return;
354 } 354 }
355 SharedMemoryAndId* input_buffer_details = new SharedMemoryAndId(); 355 SharedMemoryAndId* input_buffer_details = new SharedMemoryAndId();
356 input_buffer_details->first.reset(shm.release()); 356 input_buffer_details->first.reset(shm.release());
357 input_buffer_details->second = bitstream_buffer.id(); 357 input_buffer_details->second = bitstream_buffer.id();
358 DCHECK(!omx_buffer->pAppPrivate); 358 DCHECK(!omx_buffer->pAppPrivate);
359 omx_buffer->pAppPrivate = input_buffer_details; 359 omx_buffer->pAppPrivate = input_buffer_details;
360 omx_buffer->pBuffer = 360 omx_buffer->pBuffer =
361 static_cast<OMX_U8*>(input_buffer_details->first->memory()); 361 static_cast<OMX_U8*>(input_buffer_details->first->memory());
362 omx_buffer->nFilledLen = bitstream_buffer.size(); 362 omx_buffer->nFilledLen = bitstream_buffer.size();
363 omx_buffer->nAllocLen = omx_buffer->nFilledLen; 363 omx_buffer->nAllocLen = omx_buffer->nFilledLen;
364 omx_buffer->nFlags &= ~OMX_BUFFERFLAG_EOS; 364 omx_buffer->nFlags &= ~OMX_BUFFERFLAG_EOS;
365 // Abuse the header's nTimeStamp field to propagate the bitstream buffer ID to 365 // Abuse the header's nTimeStamp field to propagate the bitstream buffer ID to
366 // the output buffer's nTimeStamp field, so we can report it back to the 366 // the output buffer's nTimeStamp field, so we can report it back to the
367 // client in PictureReady(). 367 // client in PictureReady().
368 omx_buffer->nTimeStamp = bitstream_buffer.id(); 368 omx_buffer->nTimeStamp = bitstream_buffer.id();
369 369
370 // Give this buffer to OMX. 370 // Give this buffer to OMX.
371 OMX_ERRORTYPE result = OMX_ErrorNone; 371 OMX_ERRORTYPE result = OMX_ErrorNone;
372 result = OMX_EmptyThisBuffer(component_handle_, omx_buffer); 372 result = OMX_EmptyThisBuffer(component_handle_, omx_buffer);
373 if (result != OMX_ErrorNone) { 373 if (result != OMX_ErrorNone) {
374 LOG(ERROR) << "OMX_EmptyThisBuffer() failed with result " << result; 374 LOG(ERROR) << "OMX_EmptyThisBuffer() failed with result " << result;
375 StopOnError(); 375 StopOnError();
376 return false; 376 return;
377 } 377 }
378 input_buffers_at_component_++; 378 input_buffers_at_component_++;
379 return true;
380 } 379 }
381 380
382 void OmxVideoDecodeAccelerator::AssignGLESBuffers( 381 void OmxVideoDecodeAccelerator::AssignGLESBuffers(
383 const std::vector<media::GLESBuffer>& buffers) { 382 const std::vector<media::GLESBuffer>& buffers) {
384 if (!CanFillBuffer()) { 383 if (!CanFillBuffer()) {
385 StopOnError(); 384 StopOnError();
386 return; 385 return;
387 } 386 }
388 CHECK_EQ(output_buffers_at_component_, 0); 387 CHECK_EQ(output_buffers_at_component_, 0);
389 CHECK_EQ(fake_output_buffers_.size(), 0U); 388 CHECK_EQ(fake_output_buffers_.size(), 0U);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 ++output_buffers_at_component_; 432 ++output_buffers_at_component_;
434 OMX_ERRORTYPE result = 433 OMX_ERRORTYPE result =
435 OMX_FillThisBuffer(component_handle_, output_picture.omx_buffer_header); 434 OMX_FillThisBuffer(component_handle_, output_picture.omx_buffer_header);
436 if (result != OMX_ErrorNone) { 435 if (result != OMX_ErrorNone) {
437 LOG(ERROR) << "OMX_FillThisBuffer() failed with result " << result; 436 LOG(ERROR) << "OMX_FillThisBuffer() failed with result " << result;
438 StopOnError(); 437 StopOnError();
439 return; 438 return;
440 } 439 }
441 } 440 }
442 441
443 bool OmxVideoDecodeAccelerator::Flush() { 442 void OmxVideoDecodeAccelerator::Flush() {
444 OMX_STATETYPE il_state; 443 OMX_STATETYPE il_state;
445 OMX_GetState(component_handle_, &il_state); 444 OMX_GetState(component_handle_, &il_state);
446 DCHECK_EQ(il_state, OMX_StateExecuting); 445 DCHECK_EQ(il_state, OMX_StateExecuting);
447 // Decode the pending data first. Then flush I/O ports. 446 // Decode the pending data first. Then flush I/O ports.
448 if (il_state != OMX_StateExecuting) { 447 if (il_state != OMX_StateExecuting) {
449 client_->NotifyFlushDone(); 448 client_->NotifyFlushDone();
450 return false; 449 return;
451 } 450 }
452 on_buffer_flag_event_func_ = &OmxVideoDecodeAccelerator::FlushBegin; 451 on_buffer_flag_event_func_ = &OmxVideoDecodeAccelerator::FlushBegin;
453 452
454 OMX_BUFFERHEADERTYPE* omx_buffer = free_input_buffers_.front(); 453 OMX_BUFFERHEADERTYPE* omx_buffer = free_input_buffers_.front();
455 free_input_buffers_.pop(); 454 free_input_buffers_.pop();
456 455
457 omx_buffer->nFilledLen = 0; 456 omx_buffer->nFilledLen = 0;
458 omx_buffer->nAllocLen = omx_buffer->nFilledLen; 457 omx_buffer->nAllocLen = omx_buffer->nFilledLen;
459 omx_buffer->nFlags |= OMX_BUFFERFLAG_EOS; 458 omx_buffer->nFlags |= OMX_BUFFERFLAG_EOS;
460 omx_buffer->nTimeStamp = 0; 459 omx_buffer->nTimeStamp = 0;
461 // Give this buffer to OMX. 460 // Give this buffer to OMX.
462 OMX_ERRORTYPE result = OMX_ErrorNone; 461 OMX_ERRORTYPE result = OMX_ErrorNone;
463 result = OMX_EmptyThisBuffer(component_handle_, omx_buffer); 462 result = OMX_EmptyThisBuffer(component_handle_, omx_buffer);
464 if (result != OMX_ErrorNone) { 463 if (result != OMX_ErrorNone) {
465 LOG(ERROR) << "OMX_EmptyThisBuffer() failed with result " << result; 464 LOG(ERROR) << "OMX_EmptyThisBuffer() failed with result " << result;
466 StopOnError(); 465 StopOnError();
467 return false; 466 return;
468 } 467 }
469 input_buffers_at_component_++; 468 input_buffers_at_component_++;
470 return true;
471 } 469 }
472 470
473 void OmxVideoDecodeAccelerator::FlushBegin() { 471 void OmxVideoDecodeAccelerator::FlushBegin() {
474 VLOG(1) << "Starting actual flush for EOS"; 472 VLOG(1) << "Starting actual flush for EOS";
475 DCHECK(!on_state_event_func_); 473 DCHECK(!on_state_event_func_);
476 on_state_event_func_ = &OmxVideoDecodeAccelerator::PauseFromExecuting; 474 on_state_event_func_ = &OmxVideoDecodeAccelerator::PauseFromExecuting;
477 TransitionToState(OMX_StatePause); 475 TransitionToState(OMX_StatePause);
478 } 476 }
479 477
480 void OmxVideoDecodeAccelerator::PauseFromExecuting(OMX_STATETYPE ignored) { 478 void OmxVideoDecodeAccelerator::PauseFromExecuting(OMX_STATETYPE ignored) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 516
519 void OmxVideoDecodeAccelerator::OutputPortFlushDone(int port) { 517 void OmxVideoDecodeAccelerator::OutputPortFlushDone(int port) {
520 DCHECK_EQ(port, output_port_); 518 DCHECK_EQ(port, output_port_);
521 519
522 VLOG(1) << "Output Port has been flushed"; 520 VLOG(1) << "Output Port has been flushed";
523 DCHECK_EQ(output_buffers_at_component_, 0); 521 DCHECK_EQ(output_buffers_at_component_, 0);
524 client_state_ = OMX_StatePause; 522 client_state_ = OMX_StatePause;
525 client_->NotifyFlushDone(); 523 client_->NotifyFlushDone();
526 } 524 }
527 525
528 bool OmxVideoDecodeAccelerator::Abort() { 526 void OmxVideoDecodeAccelerator::Abort() {
529 CHECK_EQ(message_loop_, MessageLoop::current()); 527 CHECK_EQ(message_loop_, MessageLoop::current());
530 // Abort() implies immediacy but Flush() actually decodes pending data first. 528 // Abort() implies immediacy but Flush() actually decodes pending data first.
531 // TODO(vhiremath@nvidia.com) Fix the Abort to handle this immediacy. 529 // TODO(vhiremath@nvidia.com) Fix the Abort to handle this immediacy.
532 ShutDownOMXFromExecuting(); 530 ShutDownOMXFromExecuting();
533 return true; 531 return;
534 } 532 }
535 533
536 // Event callback during initialization to handle DoneStateSet to idle 534 // Event callback during initialization to handle DoneStateSet to idle
537 void OmxVideoDecodeAccelerator::OnStateChangeLoadedToIdle(OMX_STATETYPE state) { 535 void OmxVideoDecodeAccelerator::OnStateChangeLoadedToIdle(OMX_STATETYPE state) {
538 DCHECK(!on_state_event_func_); 536 DCHECK(!on_state_event_func_);
539 DCHECK_EQ(client_state_, OMX_StateLoaded); 537 DCHECK_EQ(client_state_, OMX_StateLoaded);
540 DCHECK_EQ(OMX_StateIdle, state); 538 DCHECK_EQ(OMX_StateIdle, state);
541 539
542 VLOG(1) << "OMX video decode engine is in Idle"; 540 VLOG(1) << "OMX video decode engine is in Idle";
543 541
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after
1022 OMX_ERRORTYPE result = OMX_SendCommand(component_handle_, 1020 OMX_ERRORTYPE result = OMX_SendCommand(component_handle_,
1023 cmd, port_index, 0); 1021 cmd, port_index, 0);
1024 if (result != OMX_ErrorNone) { 1022 if (result != OMX_ErrorNone) {
1025 LOG(ERROR) << "SendCommand() failed" << cmd << ":" << result; 1023 LOG(ERROR) << "SendCommand() failed" << cmd << ":" << result;
1026 StopOnError(); 1024 StopOnError();
1027 return; 1025 return;
1028 } 1026 }
1029 } 1027 }
1030 1028
1031 DISABLE_RUNNABLE_METHOD_REFCOUNT(OmxVideoDecodeAccelerator); 1029 DISABLE_RUNNABLE_METHOD_REFCOUNT(OmxVideoDecodeAccelerator);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698