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

Unified Diff: content/common/gpu/omx_video_decode_accelerator.cc

Issue 6979017: Revert 86681 - Updated OMX decoder for recent PPAPI changes, and added to the build. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/common/gpu/omx_video_decode_accelerator.h ('k') | content/content_common.gypi » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/common/gpu/omx_video_decode_accelerator.cc
===================================================================
--- content/common/gpu/omx_video_decode_accelerator.cc (revision 86686)
+++ content/common/gpu/omx_video_decode_accelerator.cc (working copy)
@@ -1,887 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/common/gpu/omx_video_decode_accelerator.h"
-
-#include "base/stl_util-inl.h"
-#include "base/string_util.h"
-#include "content/common/gpu/gles2_texture_to_egl_image_translator.h"
-#include "content/common/gpu/gpu_channel.h"
-#include "media/base/bitstream_buffer.h"
-#include "media/video/picture.h"
-
-enum { kNumPictureBuffers = 4 };
-
-// Open the libnvomx here for now.
-void* omx_handle = dlopen("libnvomx.so", RTLD_NOW);
-
-typedef OMX_ERRORTYPE (*OMXInit)();
-typedef OMX_ERRORTYPE (*OMXGetHandle)(
- OMX_HANDLETYPE*, OMX_STRING, OMX_PTR, OMX_CALLBACKTYPE*);
-typedef OMX_ERRORTYPE (*OMXGetComponentsOfRole)(OMX_STRING, OMX_U32*, OMX_U8**);
-typedef OMX_ERRORTYPE (*OMXFreeHandle)(OMX_HANDLETYPE);
-typedef OMX_ERRORTYPE (*OMXDeinit)();
-
-OMXInit omx_init = reinterpret_cast<OMXInit>(dlsym(omx_handle, "OMX_Init"));
-OMXGetHandle omx_gethandle =
- reinterpret_cast<OMXGetHandle>(dlsym(omx_handle, "OMX_GetHandle"));
-OMXGetComponentsOfRole omx_get_components_of_role =
- reinterpret_cast<OMXGetComponentsOfRole>(
- dlsym(omx_handle, "OMX_GetComponentsOfRole"));
-OMXFreeHandle omx_free_handle =
- reinterpret_cast<OMXFreeHandle>(dlsym(omx_handle, "OMX_FreeHandle"));
-OMXDeinit omx_deinit =
- reinterpret_cast<OMXDeinit>(dlsym(omx_handle, "OMX_Deinit"));
-
-static bool AreOMXFunctionPointersInitialized() {
- return (omx_init && omx_gethandle && omx_get_components_of_role &&
- omx_free_handle && omx_deinit);
-}
-
-OmxVideoDecodeAccelerator::OmxVideoDecodeAccelerator(
- media::VideoDecodeAccelerator::Client* client,
- MessageLoop* message_loop)
- : message_loop_(message_loop),
- component_handle_(NULL),
- width_(-1),
- height_(-1),
- input_buffer_count_(0),
- input_buffer_size_(0),
- input_port_(0),
- input_buffers_at_component_(0),
- output_buffer_count_(0),
- output_buffer_size_(0),
- output_port_(0),
- output_buffers_at_component_(0),
- uses_egl_image_(false),
- client_(client) {
- if (!AreOMXFunctionPointersInitialized()) {
- LOG(ERROR) << "Failed to load openmax library";
- return;
- }
- OMX_ERRORTYPE result = omx_init();
- if (result != OMX_ErrorNone)
- LOG(ERROR) << "Failed to init OpenMAX core";
-}
-
-OmxVideoDecodeAccelerator::~OmxVideoDecodeAccelerator() {
- DCHECK(free_input_buffers_.empty());
- DCHECK_EQ(0, input_buffers_at_component_);
- DCHECK_EQ(0, output_buffers_at_component_);
- DCHECK(output_pictures_.empty());
-}
-
-void OmxVideoDecodeAccelerator::GetConfigs(
- const std::vector<uint32>& requested_configs,
- std::vector<uint32>* matched_configs) {
- // TODO(vhiremath@nvidia.com) use this properly
- NOTIMPLEMENTED();
-}
-
-// This is to initialize the OMX data structures to default values.
-template <typename T>
-static void InitParam(const OmxVideoDecodeAccelerator& dec, T* param) {
- memset(param, 0, sizeof(T));
- param->nVersion.nVersion = 0x00000101;
- param->nSize = sizeof(T);
-}
-
-bool OmxVideoDecodeAccelerator::Initialize(const std::vector<uint32>& config) {
- // TODO(vhiremath@nvidia.com) get these actual values from config
- // Assume qvga for now
- width_ = 320;
- height_ = 240;
-
- client_state_ = OMX_StateLoaded;
- if (!CreateComponent()) {
- StopOnError();
- return false;
- }
- // Transition component to Idle state
- on_state_event_func_ =
- &OmxVideoDecodeAccelerator::OnStateChangeLoadedToIdle;
- if (!TransitionToState(OMX_StateIdle))
- return false;
-
- if (!AllocateInputBuffers()) {
- LOG(ERROR) << "OMX_AllocateBuffer() Input buffer error";
- StopOnError();
- return false;
- }
-
- // After AllocateInputBuffers ideally this should be AllocateOutputBuffers.
- // Since in this case app provides the output buffers,
- // we query this through ProvidePictureBuffers.
- // This is call to ppapi to provide the output buffers initially.
- // ProvidePictureBuffers will provide
- // - SharedMemHandle in case of decoding to system memory.
- // - Textures in case of decoding to egl-images.
-
- // Output buffers will be eventually handed to us via
- // Assign{GLES,Sysmem}Buffers().
- output_buffer_count_ = kNumPictureBuffers;
- client_->ProvidePictureBuffers(
- output_buffer_count_, gfx::Size(width_, height_),
- PICTUREBUFFER_MEMORYTYPE_GL_TEXTURE);
- // TODO(fischman): we always ask for GLES buffers above. So why maintain the
- // !uses_egl_image_ path in this class at all? Theoretically it could be
- // useful for testing, but today there's no such testing. Consider ripping it
- // out of this class and replacing AssignSysmemBuffers() with
- // NOTIMPLEMENTED().
- return true;
-}
-
-bool OmxVideoDecodeAccelerator::CreateComponent() {
- OMX_CALLBACKTYPE omx_accelerator_callbacks = {
- &OmxVideoDecodeAccelerator::EventHandler,
- &OmxVideoDecodeAccelerator::EmptyBufferCallback,
- &OmxVideoDecodeAccelerator::FillBufferCallback
- };
- OMX_ERRORTYPE result = OMX_ErrorNone;
-
- // 1. Set the role and get all components of this role.
- // TODO(vhiremath@nvidia.com) Get this role_name from the configs
- // For now hard coding to avc.
- const char* role_name = "video_decoder.avc";
- OMX_U32 num_roles = 0;
- // Get all the components with this role.
- result = (*omx_get_components_of_role)(
- const_cast<OMX_STRING>(role_name), &num_roles, 0);
- if (result != OMX_ErrorNone || num_roles == 0) {
- LOG(ERROR) << "Unsupported Role: " << role_name;
- StopOnError();
- return false;
- }
-
- // We haven't seen HW that needs more yet,
- // but there is no reason not to raise.
- const OMX_U32 kMaxRolePerComponent = 3;
- CHECK_LT(num_roles, kMaxRolePerComponent);
-
- scoped_array<scoped_array<OMX_U8> > component_names(
- new scoped_array<OMX_U8>[num_roles]);
- for (size_t i = 0; i < num_roles; ++i)
- component_names[i].reset(new OMX_U8[OMX_MAX_STRINGNAME_SIZE]);
- result = (*omx_get_components_of_role)(
- const_cast<OMX_STRING>(role_name),
- &num_roles, reinterpret_cast<OMX_U8**>(component_names.get()));
-
- // Use first component only. Copy the name of the first component
- // so that we could free the memory.
- std::string component_name;
- if (result == OMX_ErrorNone)
- component_name = reinterpret_cast<char*>(component_names[0].get());
-
- if (result != OMX_ErrorNone || num_roles == 0) {
- LOG(ERROR) << "Unsupported Role: " << component_name.c_str();
- StopOnError();
- return false;
- }
-
- // 3. Get the handle to the component.
- // After OMX_GetHandle(), the component is in loaded state.
- OMX_STRING component = const_cast<OMX_STRING>(component_name.c_str());
- result = omx_gethandle(&component_handle_, component, this,
- &omx_accelerator_callbacks);
- if (result != OMX_ErrorNone) {
- LOG(ERROR) << "Failed to Load the component: " << component;
- StopOnError();
- return false;
- }
-
- // 4. Get the port information. This will obtain information about the
- // number of ports and index of the first port.
- OMX_PORT_PARAM_TYPE port_param;
- InitParam(*this, &port_param);
- result = OMX_GetParameter(component_handle_, OMX_IndexParamVideoInit,
- &port_param);
- if ((result != OMX_ErrorNone) || (port_param.nPorts != 2)) {
- LOG(ERROR) << "Failed to get Port Param";
- StopOnError();
- return false;
- }
- input_port_ = port_param.nStartPortNumber;
- output_port_ = input_port_ + 1;
- // 5. Set role for the component because components can have multiple roles.
- OMX_PARAM_COMPONENTROLETYPE role_type;
- InitParam(*this, &role_type);
- base::strlcpy(reinterpret_cast<char*>(role_type.cRole),
- role_name,
- OMX_MAX_STRINGNAME_SIZE);
-
- result = OMX_SetParameter(component_handle_,
- OMX_IndexParamStandardComponentRole,
- &role_type);
- if (result != OMX_ErrorNone) {
- LOG(ERROR) << "Failed to Set Role";
- StopOnError();
- return false;
- }
-
- // 7. Populate input-buffer-related members based on input port data.
- OMX_PARAM_PORTDEFINITIONTYPE port_format;
- InitParam(*this, &port_format);
- port_format.nPortIndex = input_port_;
- result = OMX_GetParameter(component_handle_,
- OMX_IndexParamPortDefinition,
- &port_format);
- if (result != OMX_ErrorNone) {
- LOG(ERROR) << "GetParameter(OMX_IndexParamPortDefinition) failed";
- StopOnError();
- return false;
- }
- if (OMX_DirInput != port_format.eDir) {
- LOG(ERROR) << "Expected input port";
- StopOnError();
- return false;
- }
- input_buffer_count_ = port_format.nBufferCountActual;
- input_buffer_size_ = port_format.nBufferSize;
-
- // OMX_IndexParamPortDefinition on output port to be done in
- // AllocateOutputBuffers.
- // Since at this point we dont know if we will be using system memory
- // or egl-image for decoding.
- // We get this info in AssignPictureBuffers() from plugin.
-
- return true;
-}
-
-bool OmxVideoDecodeAccelerator::Decode(
- const media::BitstreamBuffer& bitstream_buffer) {
- DCHECK(!free_input_buffers_.empty());
-
- if (!CanAcceptInput()) {
- return false;
- }
-
- OMX_BUFFERHEADERTYPE* omx_buffer = free_input_buffers_.front();
- free_input_buffers_.pop();
-
- // Setup |omx_buffer|.
- scoped_ptr<base::SharedMemory> shm(
- new base::SharedMemory(bitstream_buffer.handle(), true));
- if (!shm->Map(bitstream_buffer.size())) {
- LOG(ERROR) << "Failed to SharedMemory::Map().";
- return false;
- }
- omx_buffer->pBuffer = static_cast<OMX_U8*>(shm->memory());
- omx_buffer->nFilledLen = bitstream_buffer.size();
- omx_buffer->nAllocLen = omx_buffer->nFilledLen;
-
- omx_buffer->nFlags &= ~OMX_BUFFERFLAG_EOS;
- omx_buffer->nTimeStamp = 0;
-
- // Give this buffer to OMX.
- OMX_ERRORTYPE result = OMX_ErrorNone;
- result = OMX_EmptyThisBuffer(component_handle_, omx_buffer);
- if (result != OMX_ErrorNone) {
- LOG(ERROR) << "OMX_EmptyThisBuffer() failed with result " << result;
- StopOnError();
- return false;
- }
- input_buffers_at_component_++;
- // OMX_EmptyThisBuffer is a non blocking call and should
- // not make any assumptions about its completion.
- omx_buff_ids_.insert(std::make_pair(
- omx_buffer, std::make_pair(shm.release(), bitstream_buffer.id())));
- return true;
-}
-
-// NOTE: this is only partially-implemented as never unsets uses_egl_image_ once
-// set.
-void OmxVideoDecodeAccelerator::AssignGLESBuffers(
- const std::vector<media::GLESBuffer>& buffers) {
- uses_egl_image_ = true;
- std::vector<media::BaseBuffer*> base_buffers(buffers.size());
- for (size_t i = 0; i < buffers.size(); ++i)
- base_buffers[i] = new media::GLESBuffer(buffers[i]);
- AssignBuffersHelper(base_buffers);
-}
-
-void OmxVideoDecodeAccelerator::AssignSysmemBuffers(
- const std::vector<media::SysmemBuffer>& buffers) {
- DCHECK(!uses_egl_image_);
- std::vector<media::BaseBuffer*> base_buffers(buffers.size());
- for (size_t i = 0; i < buffers.size(); ++i)
- base_buffers[i] = new media::SysmemBuffer(buffers[i]);
- AssignBuffersHelper(base_buffers);
-}
-
-void OmxVideoDecodeAccelerator::AssignBuffersHelper(
- const std::vector<media::BaseBuffer*>& buffers) {
- assigned_picture_buffers_.insert(
- assigned_picture_buffers_.end(), buffers.begin(), buffers.end());
-
- if (assigned_picture_buffers_.size() < kNumPictureBuffers)
- return; // get all the buffers first.
-
- // Obtain the information about the output port.
- OMX_PARAM_PORTDEFINITIONTYPE port_format;
- InitParam(*this, &port_format);
- port_format.nPortIndex = output_port_;
- OMX_ERRORTYPE result = OMX_GetParameter(component_handle_,
- OMX_IndexParamPortDefinition,
- &port_format);
- if (result != OMX_ErrorNone) {
- LOG(ERROR) << "GetParameter(OMX_IndexParamPortDefinition) failed";
- StopOnError();
- return;
- }
- if (OMX_DirOutput != port_format.eDir) {
- LOG(ERROR) << "Expect Output Port";
- StopOnError();
- return;
- }
-
- if (uses_egl_image_) {
- port_format.nBufferCountActual = kNumPictureBuffers;
- port_format.nBufferCountMin = kNumPictureBuffers;
- output_buffer_count_ = kNumPictureBuffers;
-
- result = OMX_SetParameter(component_handle_,
- OMX_IndexParamPortDefinition,
- &port_format);
- if (result != OMX_ErrorNone) {
- LOG(ERROR) << "SetParameter(OMX_IndexParamPortDefinition) failed";
- StopOnError();
- return;
- }
- } else {
- output_buffer_count_ = port_format.nBufferCountActual;
- }
- output_buffer_size_ = port_format.nBufferSize;
-
- if (!AllocateOutputBuffers()) {
- LOG(ERROR) << "OMX_AllocateBuffer() Output buffer error";
- StopOnError();
- }
-}
-
-void OmxVideoDecodeAccelerator::ReusePictureBuffer(int32 picture_buffer_id) {
- // TODO(vhiremath@nvidia.com) Avoid leaking of the picture buffer.
- if (!CanFillBuffer())
- return;
-
- for (int i = 0; i < output_buffer_count_; ++i) {
- if (picture_buffer_id != assigned_picture_buffers_[i]->id())
- continue;
- output_buffers_at_component_++;
- OMX_ERRORTYPE result =
- OMX_FillThisBuffer(component_handle_, output_pictures_[i].second);
- if (result != OMX_ErrorNone) {
- LOG(ERROR) << "OMX_FillThisBuffer() failed with result " << result;
- StopOnError();
- }
- // Sent one buffer to omx.
- return;
- }
-}
-
-void OmxVideoDecodeAccelerator::InitialFillBuffer() {
- if (!CanFillBuffer())
- return;
-
- // Ask the decoder to fill the output buffers.
- for (uint32 i = 0; i < output_pictures_.size(); ++i) {
- OMX_BUFFERHEADERTYPE* omx_buffer = output_pictures_[i].second;
- // clear EOS flag.
- omx_buffer->nFlags &= ~OMX_BUFFERFLAG_EOS;
- omx_buffer->nOutputPortIndex = output_port_;
- output_buffers_at_component_++;
- OMX_ERRORTYPE result = OMX_FillThisBuffer(component_handle_, omx_buffer);
- if (result != OMX_ErrorNone) {
- LOG(ERROR) << "OMX_FillThisBuffer() failed with result " << result;
- StopOnError();
- return;
- }
- }
-}
-
-bool OmxVideoDecodeAccelerator::Flush() {
- OMX_STATETYPE il_state;
- OMX_GetState(component_handle_, &il_state);
- DCHECK_EQ(il_state, OMX_StateExecuting);
- if (il_state != OMX_StateExecuting) {
- client_->NotifyFlushDone();
- return false;
- }
- on_buffer_flag_event_func_ = &OmxVideoDecodeAccelerator::FlushBegin;
-
- OMX_BUFFERHEADERTYPE* omx_buffer = free_input_buffers_.front();
- free_input_buffers_.pop();
- omx_buffer->nFilledLen = 0;
- omx_buffer->nAllocLen = omx_buffer->nFilledLen;
- omx_buffer->nFlags |= OMX_BUFFERFLAG_EOS;
- omx_buffer->nTimeStamp = 0;
- // Give this buffer to OMX.
- OMX_ERRORTYPE result = OMX_ErrorNone;
- result = OMX_EmptyThisBuffer(component_handle_, omx_buffer);
- if (result != OMX_ErrorNone) {
- LOG(ERROR) << "OMX_EmptyThisBuffer() failed with result " << result;
- StopOnError();
- return false;
- }
- input_buffers_at_component_++;
- return true;
-}
-
-void OmxVideoDecodeAccelerator::FlushBegin() {
- VLOG(1) << "Starting actual flush for EOS";
- on_state_event_func_ = &OmxVideoDecodeAccelerator::PauseFromExecuting;
- TransitionToState(OMX_StatePause);
-}
-
-void OmxVideoDecodeAccelerator::PauseFromExecuting(OMX_STATETYPE ignored) {
- on_state_event_func_ = NULL;
- FlushIOPorts();
-}
-
-void OmxVideoDecodeAccelerator::FlushIOPorts() {
- // TODO(vhiremath@nvidia.com) review again for trick modes.
- VLOG(1) << "FlushIOPorts";
-
- // Flush input port first.
- on_flush_event_func_ = &OmxVideoDecodeAccelerator::PortFlushDone;
- OMX_ERRORTYPE result;
- result = OMX_SendCommand(component_handle_,
- OMX_CommandFlush,
- input_port_, 0);
- if (result != OMX_ErrorNone) {
- LOG(ERROR) << "OMX_SendCommand(OMX_CommandFlush) failed";
- StopOnError();
- return;
- }
-}
-
-void OmxVideoDecodeAccelerator::PortFlushDone(int port) {
- DCHECK_NE(port, static_cast<int>(OMX_ALL));
-
- if (port == input_port_) {
- VLOG(1) << "Input Port had been flushed";
- DCHECK_EQ(input_buffers_at_component_, 0);
- // Flush output port next.
- OMX_ERRORTYPE result;
- result = OMX_SendCommand(component_handle_,
- OMX_CommandFlush,
- output_port_, 0);
- if (result != OMX_ErrorNone) {
- LOG(ERROR) << "OMX_SendCommand(OMX_CommandFlush) failed";
- StopOnError();
- return;
- }
- return;
- }
-
- if (port == output_port_) {
- VLOG(1) << "Output Port had been flushed";
- DCHECK_EQ(output_buffers_at_component_, 0);
- }
-
- client_state_ = OMX_StatePause;
- // So Finally call OnPortCommandFlush which should
- // internally call DismissPictureBuffer();
- OnPortCommandFlush(OMX_StateExecuting);
-}
-
-bool OmxVideoDecodeAccelerator::Abort() {
- // TODO(vhiremath@nvidia.com)
- // Need more thinking on this to handle w.r.t OMX.
- // There is no explicit UnInitialize call for this.
- // Also review again for trick modes.
- client_->NotifyAbortDone();
- return true;
-}
-
-// Event callback during initialization to handle DoneStateSet to idle
-void OmxVideoDecodeAccelerator::OnStateChangeLoadedToIdle(OMX_STATETYPE state) {
- DCHECK_EQ(client_state_, OMX_StateLoaded);
- DCHECK_EQ(OMX_StateIdle, state);
- VLOG(1) << "OMX video decode engine is in Idle";
-
- on_state_event_func_ =
- &OmxVideoDecodeAccelerator::OnStateChangeIdleToExecuting;
- if (!TransitionToState(OMX_StateExecuting))
- return;
-}
-
-// Event callback during initialization to handle DoneStateSet to executing
-void OmxVideoDecodeAccelerator::OnStateChangeIdleToExecuting(
- OMX_STATETYPE state) {
- DCHECK_EQ(OMX_StateExecuting, state);
- VLOG(1) << "OMX video decode engine is in Executing";
-
- client_state_ = OMX_StateExecuting;
- on_state_event_func_ = NULL;
- // This will kickoff the actual decoding
- InitialFillBuffer();
-}
-
-// Send state transition command to component.
-bool OmxVideoDecodeAccelerator::TransitionToState(OMX_STATETYPE new_state) {
- OMX_ERRORTYPE result = OMX_SendCommand(component_handle_,
- OMX_CommandStateSet,
- new_state, 0);
- if (result != OMX_ErrorNone) {
- LOG(ERROR) << "SendCommand(OMX_CommandStateSet) failed";
- StopOnError();
- return false;
- }
- return true;
-}
-
-void OmxVideoDecodeAccelerator::OnPortCommandFlush(OMX_STATETYPE state) {
- DCHECK_EQ(state, OMX_StateExecuting);
-
- VLOG(1) << "Deinit from Executing";
- on_state_event_func_ =
- &OmxVideoDecodeAccelerator::OnStateChangeExecutingToIdle;
- TransitionToState(OMX_StateIdle);
- for (int i = 0; i < output_buffer_count_; ++i) {
- OutputPicture output_picture = output_pictures_[i];
- client_->DismissPictureBuffer(output_picture.first);
- }
- STLDeleteElements(&assigned_picture_buffers_);
-}
-
-void OmxVideoDecodeAccelerator::OnStateChangeExecutingToIdle(
- OMX_STATETYPE state) {
- DCHECK_EQ(state, OMX_StateIdle);
-
- VLOG(1) << "Deinit from Idle";
- on_state_event_func_ =
- &OmxVideoDecodeAccelerator::OnStateChangeIdleToLoaded;
- TransitionToState(OMX_StateLoaded);
-
- if (!input_buffers_at_component_)
- FreeInputBuffers();
-
- if (!output_buffers_at_component_)
- FreeOutputBuffers();
-}
-
-void OmxVideoDecodeAccelerator::OnStateChangeIdleToLoaded(OMX_STATETYPE state) {
- DCHECK_EQ(state, OMX_StateLoaded);
-
- VLOG(1) << "Idle to Loaded";
-
- if (component_handle_) {
- OMX_ERRORTYPE result = (*omx_free_handle)(component_handle_);
- if (result != OMX_ErrorNone)
- LOG(ERROR) << "OMX_FreeHandle() error. Error code: " << result;
- component_handle_ = NULL;
- }
- client_state_ = OMX_StateLoaded;
- (*omx_deinit)();
- VLOG(1) << "OMX Deinit Clean exit done";
- client_->NotifyFlushDone();
-}
-
-void OmxVideoDecodeAccelerator::StopOnError() {
- OMX_STATETYPE il_state;
- OMX_GetState(component_handle_, &il_state);
- client_state_ = OMX_StateInvalid;
- switch (il_state) {
- case OMX_StateExecuting:
- OnPortCommandFlush(OMX_StateExecuting);
- return;
- case OMX_StateIdle:
- OnStateChangeExecutingToIdle(OMX_StateIdle);
- return;
- case OMX_StateLoaded:
- OnStateChangeIdleToLoaded(OMX_StateLoaded);
- return;
- default:
- // LOG unexpected state or just ignore?
- return;
- }
-}
-
-bool OmxVideoDecodeAccelerator::AllocateInputBuffers() {
- scoped_array<uint8> data(new uint8[input_buffer_size_]);
-
- for (int i = 0; i < input_buffer_count_; ++i) {
- OMX_BUFFERHEADERTYPE* buffer;
- OMX_ERRORTYPE result =
- OMX_UseBuffer(component_handle_, &buffer, input_port_,
- this, input_buffer_size_, data.get());
- if (result != OMX_ErrorNone)
- return false;
- buffer->nInputPortIndex = input_port_;
- buffer->nOffset = 0;
- buffer->nFlags = 0;
- free_input_buffers_.push(buffer);
- }
- return true;
-}
-
-bool OmxVideoDecodeAccelerator::AllocateOutputBuffers() {
- static Gles2TextureToEglImageTranslator* texture2eglImage_translator(
- new Gles2TextureToEglImageTranslator(NULL, 0));
-
- gfx::Size decoded_pixel_size(width_, height_);
- gfx::Size visible_pixel_size(width_, height_);
- // TODO(fischman): remove garbage bitstream buffer id's below (42 and 24) when
- // the bitstream_buffer_id field is removed from Picture.
- if (uses_egl_image_) {
- for (uint32 i = 0; i < assigned_picture_buffers_.size(); i++) {
- media::GLESBuffer* gles_buffer =
- reinterpret_cast<media::GLESBuffer*>(assigned_picture_buffers_[i]);
- OMX_BUFFERHEADERTYPE* omx_buffer;
- void* egl = texture2eglImage_translator->TranslateToEglImage(
- gles_buffer->texture_id());
- OMX_ERRORTYPE result = OMX_UseEGLImage(
- component_handle_, &omx_buffer, output_port_, gles_buffer, egl);
- if (result != OMX_ErrorNone) {
- LOG(ERROR) << "OMX_UseEGLImage failed";
- return false;
- }
- omx_buffer->pAppPrivate =
- new media::Picture(gles_buffer->id(),
- 42 /* garbage bitstreambuffer id */,
- decoded_pixel_size, visible_pixel_size);
- output_pictures_.push_back(
- std::make_pair(assigned_picture_buffers_[i]->id(), omx_buffer));
- }
- } else {
- for (uint32 i = 0; i < assigned_picture_buffers_.size(); i++) {
- media::SysmemBuffer* sysmem_buffer =
- reinterpret_cast<media::SysmemBuffer*>(assigned_picture_buffers_[i]);
- OMX_BUFFERHEADERTYPE* omx_buffer;
- OMX_ERRORTYPE result = OMX_AllocateBuffer(
- component_handle_, &omx_buffer, output_port_, NULL,
- output_buffer_size_);
- if (result != OMX_ErrorNone)
- return false;
- omx_buffer->pAppPrivate = new media::Picture(
- sysmem_buffer->id(),
- 24 /* garbage bitstreambuffer id */,
- decoded_pixel_size, visible_pixel_size);
- output_pictures_.push_back(
- std::make_pair(sysmem_buffer->id(), omx_buffer));
- }
- }
- return true;
-}
-
-void OmxVideoDecodeAccelerator::FreeInputBuffers() {
- // Calls to OMX to free buffers.
- OMX_ERRORTYPE result;
- OMX_BUFFERHEADERTYPE* omx_buffer;
- while (!free_input_buffers_.empty()) {
- omx_buffer = free_input_buffers_.front();
- free_input_buffers_.pop();
- result = OMX_FreeBuffer(component_handle_, input_port_, omx_buffer);
- if (result != OMX_ErrorNone) {
- LOG(ERROR) << "SendCommand(OMX_CommandPortDisable) failed";
- StopOnError();
- return;
- }
- }
-}
-
-void OmxVideoDecodeAccelerator::FreeOutputBuffers() {
- // Calls to OMX to free buffers.
- OMX_ERRORTYPE result;
- for (size_t i = 0; i < output_pictures_.size(); ++i) {
- OMX_BUFFERHEADERTYPE* omx_buffer = output_pictures_[i].second;
- CHECK(omx_buffer);
- delete reinterpret_cast<media::Picture*>(omx_buffer->pAppPrivate);
- result = OMX_FreeBuffer(component_handle_, output_port_, omx_buffer);
- if (result != OMX_ErrorNone) {
- LOG(ERROR) << "SendCommand(OMX_CommandPortDisable) failed";
- StopOnError();
- return;
- }
- }
- output_pictures_.clear();
-}
-
-void OmxVideoDecodeAccelerator::OnPortSettingsChangedRun(
- int port, OMX_INDEXTYPE index) {
- // TODO(vhiremath@nvidia.com) visit again later
- // Port settings changes can be called during run time
- // changes in the resolution of video playback.
- // In this case, the component detects PortSettingsChanged
- // and sends the particular event to the IL-client.
- // This needs to be handled in this method.
- return;
-}
-
-void OmxVideoDecodeAccelerator::FillBufferDoneTask(
- OMX_BUFFERHEADERTYPE* buffer) {
- DCHECK_GT(output_buffers_at_component_, 0);
- output_buffers_at_component_--;
- client_->PictureReady(*reinterpret_cast<media::Picture*>(
- buffer->pAppPrivate));
-}
-
-void OmxVideoDecodeAccelerator::EmptyBufferDoneTask(
- OMX_BUFFERHEADERTYPE* buffer) {
- DCHECK_GT(input_buffers_at_component_, 0);
- free_input_buffers_.push(buffer);
- input_buffers_at_component_--;
- if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
- return;
- // Retrieve the corresponding BitstreamBuffer's id and notify the client of
- // its completion.
- OMXBufferIdMap::iterator it = omx_buff_ids_.find(buffer);
- if (it == omx_buff_ids_.end()) {
- LOG(ERROR) << "Unexpectedly failed to find a buffer id.";
- StopOnError();
- return;
- }
- delete it->second.first;
- client_->NotifyEndOfBitstreamBuffer(it->second.second);
- omx_buff_ids_.erase(it);
-}
-
-void OmxVideoDecodeAccelerator::EventHandlerCompleteTask(OMX_EVENTTYPE event,
- OMX_U32 data1,
- OMX_U32 data2) {
- switch (event) {
- case OMX_EventCmdComplete: {
- // If the last command was successful, we have completed
- // a state transition. So notify that we have done it
- // accordingly.
- OMX_COMMANDTYPE cmd = static_cast<OMX_COMMANDTYPE>(data1);
- switch (cmd) {
- case OMX_CommandPortDisable: {
- if (on_port_disable_event_func_)
- (this->*on_port_disable_event_func_)(static_cast<int>(data2));
- }
- break;
- case OMX_CommandPortEnable: {
- if (on_port_enable_event_func_)
- (this->*on_port_enable_event_func_)(static_cast<int>(data2));
- }
- break;
- case OMX_CommandStateSet:
- (this->*on_state_event_func_)(static_cast<OMX_STATETYPE>(data2));
- break;
- case OMX_CommandFlush:
- (this->*on_flush_event_func_)(data2);
- break;
- default:
- LOG(ERROR) << "Unknown command completed\n" << data1;
- break;
- }
- break;
- }
- case OMX_EventError:
- if (static_cast<OMX_ERRORTYPE>(data1) == OMX_ErrorInvalidState)
- StopOnError();
- break;
- case OMX_EventPortSettingsChanged:
- // TODO(vhiremath@nvidia.com) remove this hack
- // when all vendors observe same spec.
- if (data1 < OMX_IndexComponentStartUnused) {
- OnPortSettingsChangedRun(static_cast<int>(data1),
- static_cast<OMX_INDEXTYPE>(data2));
- } else {
- OnPortSettingsChangedRun(static_cast<int>(data2),
- static_cast<OMX_INDEXTYPE>(data1));
- }
- break;
- case OMX_EventBufferFlag:
- if (data1 == static_cast<OMX_U32>(output_port_)) {
- (this->*on_buffer_flag_event_func_)();
- }
- break;
- default:
- LOG(ERROR) << "Warning - Unknown event received\n";
- break;
- }
-}
-
-// static
-OMX_ERRORTYPE OmxVideoDecodeAccelerator::EventHandler(OMX_HANDLETYPE component,
- OMX_PTR priv_data,
- OMX_EVENTTYPE event,
- OMX_U32 data1,
- OMX_U32 data2,
- OMX_PTR event_data) {
- OmxVideoDecodeAccelerator* decoder =
- static_cast<OmxVideoDecodeAccelerator*>(priv_data);
- DCHECK_EQ(component, decoder->component_handle_);
-
- decoder->message_loop_->PostTask(
- FROM_HERE,
- NewRunnableMethod(decoder,
- &OmxVideoDecodeAccelerator::EventHandlerCompleteTask,
- event, data1, data2));
-
- return OMX_ErrorNone;
-}
-
-// static
-OMX_ERRORTYPE OmxVideoDecodeAccelerator::EmptyBufferCallback(
- OMX_HANDLETYPE component,
- OMX_PTR priv_data,
- OMX_BUFFERHEADERTYPE* buffer) {
- OmxVideoDecodeAccelerator* decoder =
- static_cast<OmxVideoDecodeAccelerator*>(priv_data);
- DCHECK_EQ(component, decoder->component_handle_);
-
- decoder->message_loop_->PostTask(
- FROM_HERE,
- NewRunnableMethod(
- decoder,
- &OmxVideoDecodeAccelerator::EmptyBufferDoneTask, buffer));
- return OMX_ErrorNone;
-}
-
-// static
-OMX_ERRORTYPE OmxVideoDecodeAccelerator::FillBufferCallback(
- OMX_HANDLETYPE component,
- OMX_PTR priv_data,
- OMX_BUFFERHEADERTYPE* buffer) {
- OmxVideoDecodeAccelerator* decoder =
- static_cast<OmxVideoDecodeAccelerator*>(priv_data);
- DCHECK_EQ(component, decoder->component_handle_);
-
- decoder->message_loop_->PostTask(
- FROM_HERE,
- NewRunnableMethod(
- decoder,
- &OmxVideoDecodeAccelerator::FillBufferDoneTask, buffer));
- return OMX_ErrorNone;
-}
-
-bool OmxVideoDecodeAccelerator::CanAcceptInput() {
- // We can't take input buffer when in error state.
- return (client_state_ != OMX_StateInvalid &&
- client_state_ != OMX_StatePause &&
- client_state_ != OMX_StateLoaded);
-}
-
-bool OmxVideoDecodeAccelerator::CanFillBuffer() {
- // Make sure component is in the executing state and end-of-stream
- // has not been reached.
- OMX_ERRORTYPE result;
- OMX_STATETYPE il_state;
- if (client_state_ == OMX_StateLoaded)
- return false;
- result = OMX_GetState(component_handle_, &il_state);
- if (result != OMX_ErrorNone) {
- LOG(ERROR) << "SendCommand(OMX_CommandPortDisable) failed";
- StopOnError();
- return false;
- }
- return (il_state == OMX_StateExecuting);
-}
-
-// Send command to disable/enable port.
-void OmxVideoDecodeAccelerator::ChangePort(
- OMX_COMMANDTYPE cmd, int port_index) {
- OMX_ERRORTYPE result = OMX_SendCommand(component_handle_,
- cmd, port_index, 0);
- if (result != OMX_ErrorNone) {
- LOG(ERROR) << "SendCommand(OMX_CommandPortDisable) failed";
- StopOnError();
- return;
- }
-}
-
-DISABLE_RUNNABLE_METHOD_REFCOUNT(OmxVideoDecodeAccelerator);
« no previous file with comments | « content/common/gpu/omx_video_decode_accelerator.h ('k') | content/content_common.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698