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

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

Issue 7057027: Updated OMX decoder for recent PPAPI changes, and added to the build. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: TODOd the removal of Picture::bitstream_buffer_id_. 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « content/common/gpu/omx_video_decode_accelerator.h ('k') | content/content_common.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/gpu/omx_video_decode_accelerator.h" 5 #include "content/common/gpu/omx_video_decode_accelerator.h"
6 6
7 #include "base/string_util.h"
8 #include "content/common/gpu/gles2_texture_to_egl_image_translator.h"
7 #include "content/common/gpu/gpu_channel.h" 9 #include "content/common/gpu/gpu_channel.h"
8 #include "content/common/gpu_messages.h"
9 #include "content/gpu/gles2_texture_to_egl_image_translator.h"
10 #include "media/base/bitstream_buffer.h" 10 #include "media/base/bitstream_buffer.h"
11 #include "media/base/data_buffer.h"
12 #include "media/video/picture.h" 11 #include "media/video/picture.h"
13 12
14 static Gles2TextureToEglImageTranslator* texture2eglImage_translator( 13 static Gles2TextureToEglImageTranslator* texture2eglImage_translator(
15 new Gles2TextureToEglImageTranslator(NULL, 0)); 14 new Gles2TextureToEglImageTranslator(NULL, 0));
16 enum { kNumPictureBuffers = 4 }; 15 enum { kNumPictureBuffers = 4 };
17 16
18 // Open the libnvomx here for now. 17 // Open the libnvomx here for now.
19 void* omx_handle = dlopen("libnvomx.so", RTLD_NOW); 18 void* omx_handle = dlopen("libnvomx.so", RTLD_NOW);
20 19
21 typedef OMX_ERRORTYPE (*OMXInit)(); 20 typedef OMX_ERRORTYPE (*OMXInit)();
(...skipping 29 matching lines...) Expand all
51 height_(-1), 50 height_(-1),
52 input_buffer_count_(0), 51 input_buffer_count_(0),
53 input_buffer_size_(0), 52 input_buffer_size_(0),
54 input_port_(0), 53 input_port_(0),
55 input_buffers_at_component_(0), 54 input_buffers_at_component_(0),
56 output_buffer_count_(0), 55 output_buffer_count_(0),
57 output_buffer_size_(0), 56 output_buffer_size_(0),
58 output_port_(0), 57 output_port_(0),
59 output_buffers_at_component_(0), 58 output_buffers_at_component_(0),
60 uses_egl_image_(false), 59 uses_egl_image_(false),
61 client_(client), 60 client_(client) {
62 egl_image_(NULL) {
63 if (!AreOMXFunctionPointersInitialized()) { 61 if (!AreOMXFunctionPointersInitialized()) {
64 LOG(ERROR) << "Failed to load openmax library"; 62 LOG(ERROR) << "Failed to load openmax library";
65 return; 63 return;
66 } 64 }
67 OMX_ERRORTYPE result = omx_init(); 65 OMX_ERRORTYPE result = omx_init();
68 if (result != OMX_ErrorNone) 66 if (result != OMX_ErrorNone)
69 LOG(ERROR) << "Failed to init OpenMAX core"; 67 LOG(ERROR) << "Failed to init OpenMAX core";
70 } 68 }
71 69
72 OmxVideoDecodeAccelerator::~OmxVideoDecodeAccelerator() { 70 OmxVideoDecodeAccelerator::~OmxVideoDecodeAccelerator() {
73 DCHECK(free_input_buffers_.empty()); 71 DCHECK(free_input_buffers_.empty());
74 DCHECK_EQ(0, input_buffers_at_component_); 72 DCHECK_EQ(0, input_buffers_at_component_);
75 DCHECK_EQ(0, output_buffers_at_component_); 73 DCHECK_EQ(0, output_buffers_at_component_);
76 DCHECK(output_pictures_.empty()); 74 DCHECK(output_pictures_.empty());
77 } 75 }
78 76
79 const std::vector<uint32>& OmxVideoDecodeAccelerator::GetConfig( 77 void OmxVideoDecodeAccelerator::GetConfigs(
80 const std::vector<uint32>& prototype_config) { 78 const std::vector<uint32>& requested_configs,
79 std::vector<uint32>* matched_configs) {
81 // TODO(vhiremath@nvidia.com) use this properly 80 // TODO(vhiremath@nvidia.com) use this properly
82 NOTIMPLEMENTED(); 81 NOTIMPLEMENTED();
83 return component_config_;
84 } 82 }
85 83
86 // This is to initialize the OMX data structures to default values. 84 // This is to initialize the OMX data structures to default values.
87 template <typename T> 85 template <typename T>
88 static void InitParam(const OmxVideoDecodeAccelerator& dec, T* param) { 86 static void InitParam(const OmxVideoDecodeAccelerator& dec, T* param) {
89 memset(param, 0, sizeof(T)); 87 memset(param, 0, sizeof(T));
90 param->nVersion.nVersion = 0x00000101; 88 param->nVersion.nVersion = 0x00000101;
91 param->nSize = sizeof(T); 89 param->nSize = sizeof(T);
92 } 90 }
93 91
94 bool OmxVideoDecodeAccelerator::Initialize(const std::vector<uint32>& config) { 92 bool OmxVideoDecodeAccelerator::Initialize(const std::vector<uint32>& config) {
95 // TODO(vhiremath@nvidia.com) get these acutal values from config 93 // TODO(vhiremath@nvidia.com) get these actual values from config
96 // Assume qvga for now 94 // Assume qvga for now
97 width_ = 320; 95 width_ = 320;
98 height_ = 240; 96 height_ = 240;
99 97
100 client_state_ = OMX_StateLoaded; 98 client_state_ = OMX_StateLoaded;
101 if (!CreateComponent()) { 99 if (!CreateComponent()) {
102 StopOnError(); 100 StopOnError();
103 return false; 101 return false;
104 } 102 }
105 // Transition component to Idle state 103 // Transition component to Idle state
106 on_state_event_func_ = 104 on_state_event_func_ =
107 &OmxVideoDecodeAccelerator::OnStateChangeLoadedToIdle; 105 &OmxVideoDecodeAccelerator::OnStateChangeLoadedToIdle;
108 if (!TransitionToState(OMX_StateIdle)) 106 if (!TransitionToState(OMX_StateIdle))
109 return false; 107 return false;
110 108
111 if (!AllocateInputBuffers()) { 109 if (!AllocateInputBuffers()) {
112 LOG(ERROR) << "OMX_AllocateBuffer() Input buffer error"; 110 LOG(ERROR) << "OMX_AllocateBuffer() Input buffer error";
113 StopOnError(); 111 StopOnError();
114 return false; 112 return false;
115 } 113 }
116 114
117 // After AllocateInputBuffers ideally this should be AllocateOutputBuffers. 115 // After AllocateInputBuffers ideally this should be AllocateOutputBuffers.
118 // Since in this case app provides the output buffers, 116 // Since in this case app provides the output buffers,
119 // we query this through ProvidePictureBuffers. 117 // we query this through ProvidePictureBuffers.
120 // This is call to ppapi to provide the output buffers initially. 118 // This is call to ppapi to provide the output buffers initially.
121 // ProvidePictureBuffers will provide 119 // ProvidePictureBuffers will provide
122 // - SharedMemHandle in case of decoding to system memory. 120 // - SharedMemHandle in case of decoding to system memory.
123 // - Textures in case of decoding to egl-images. 121 // - Textures in case of decoding to egl-images.
124 122
125 // Output buffers will be eventually allocated in AssignPictureBuffer(). 123 // Output buffers will be eventually handed to us via
126 124 // Assign{GLES,Sysmem}Buffers().
127 // TODO(vhiremath@nvidia.com) fill buffer_properties
128 std::vector<uint32> buffer_properties;
129 output_buffer_count_ = kNumPictureBuffers; 125 output_buffer_count_ = kNumPictureBuffers;
130 client_->ProvidePictureBuffers(output_buffer_count_, buffer_properties); 126 client_->ProvidePictureBuffers(
127 output_buffer_count_, gfx::Size(width_, height_),
128 PICTUREBUFFER_MEMORYTYPE_GL_TEXTURE);
129 // TODO(fischman): we always ask for GLES buffers above. So why maintain the
130 // !uses_egl_image_ path in this class at all? Theoretically it could be
131 // useful for testing, but today there's no such testing. Consider ripping it
132 // out of this class and replacing AssignSysmemBuffers() with
133 // NOTIMPLEMENTED().
131 return true; 134 return true;
132 } 135 }
133 136
134 bool OmxVideoDecodeAccelerator::CreateComponent() { 137 bool OmxVideoDecodeAccelerator::CreateComponent() {
135 OMX_CALLBACKTYPE omx_accelerator_callbacks = { 138 OMX_CALLBACKTYPE omx_accelerator_callbacks = {
136 &OmxVideoDecodeAccelerator::EventHandler, 139 &OmxVideoDecodeAccelerator::EventHandler,
137 &OmxVideoDecodeAccelerator::EmptyBufferCallback, 140 &OmxVideoDecodeAccelerator::EmptyBufferCallback,
138 &OmxVideoDecodeAccelerator::FillBufferCallback 141 &OmxVideoDecodeAccelerator::FillBufferCallback
139 }; 142 };
140 OMX_ERRORTYPE result = OMX_ErrorNone; 143 OMX_ERRORTYPE result = OMX_ErrorNone;
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 // OMX_IndexParamPortDefinition on output port to be done in 244 // OMX_IndexParamPortDefinition on output port to be done in
242 // AllocateOutputBuffers. 245 // AllocateOutputBuffers.
243 // Since at this point we dont know if we will be using system memory 246 // Since at this point we dont know if we will be using system memory
244 // or egl-image for decoding. 247 // or egl-image for decoding.
245 // We get this info in AssignPictureBuffers() from plugin. 248 // We get this info in AssignPictureBuffers() from plugin.
246 249
247 return true; 250 return true;
248 } 251 }
249 252
250 bool OmxVideoDecodeAccelerator::Decode( 253 bool OmxVideoDecodeAccelerator::Decode(
251 const media::BitstreamBuffer& bitstream_buffer, 254 const media::BitstreamBuffer& bitstream_buffer) {
252 const media::VideoDecodeAcceleratorCallback& callback) {
253 DCHECK(!free_input_buffers_.empty()); 255 DCHECK(!free_input_buffers_.empty());
254 DCHECK(bitstream_buffer);
255 256
256 if (!CanAcceptInput()) { 257 if (!CanAcceptInput()) {
257 return false; 258 return false;
258 } 259 }
259 260
260 OMX_BUFFERHEADERTYPE* omx_buffer = free_input_buffers_.front(); 261 OMX_BUFFERHEADERTYPE* omx_buffer = free_input_buffers_.front();
261 free_input_buffers_.pop(); 262 free_input_buffers_.pop();
262 263
263 // Setup |omx_buffer|. 264 // Setup |omx_buffer|.
264 scoped_ptr<base::SharedMemory> shm( 265 scoped_ptr<base::SharedMemory> shm(
265 new base::SharedMemory(bitstream_buffer.handle(), true)); 266 new base::SharedMemory(bitstream_buffer.handle(), true));
266 if (!shm->Map(bitstream_buffer.size())) { 267 if (!shm->Map(bitstream_buffer.size())) {
267 LOG(ERROR) << "Failed to SharedMemory::Map()."; 268 LOG(ERROR) << "Failed to SharedMemory::Map().";
268 return false; 269 return false;
269 } 270 }
270 omx_buffer->pBuffer = static_cast<OMX_U8*>(shm->memory()); 271 omx_buffer->pBuffer = static_cast<OMX_U8*>(shm->memory());
271 omx_buffer->nFilledLen = bitstream_buffer->size(); 272 omx_buffer->nFilledLen = bitstream_buffer.size();
272 omx_buffer->nAllocLen = omx_buffer->nFilledLen; 273 omx_buffer->nAllocLen = omx_buffer->nFilledLen;
273 274
274 omx_buffer->nFlags &= ~OMX_BUFFERFLAG_EOS; 275 omx_buffer->nFlags &= ~OMX_BUFFERFLAG_EOS;
275 omx_buffer->nTimeStamp = 0; 276 omx_buffer->nTimeStamp = 0;
276 277
277 // Give this buffer to OMX. 278 // Give this buffer to OMX.
278 OMX_ERRORTYPE result = OMX_ErrorNone; 279 OMX_ERRORTYPE result = OMX_ErrorNone;
279 result = OMX_EmptyThisBuffer(component_handle_, omx_buffer); 280 result = OMX_EmptyThisBuffer(component_handle_, omx_buffer);
280 if (result != OMX_ErrorNone) { 281 if (result != OMX_ErrorNone) {
281 LOG(ERROR) << "OMX_EmptyThisBuffer() failed with result " << result; 282 LOG(ERROR) << "OMX_EmptyThisBuffer() failed with result " << result;
282 StopOnError(); 283 StopOnError();
283 return false; 284 return false;
284 } 285 }
285 input_buffers_at_component_++; 286 input_buffers_at_component_++;
286 // OMX_EmptyThisBuffer is a non blocking call and should 287 // OMX_EmptyThisBuffer is a non blocking call and should
287 // not make any assumptions about its completion. 288 // not make any assumptions about its completion.
288 omx_buff_cb_.insert(std::make_pair( 289 omx_buff_ids_.insert(std::make_pair(
289 omx_buffer, make_pair(shm.release(), callback))); 290 omx_buffer, std::make_pair(shm.release(), bitstream_buffer.id())));
290 return true; 291 return true;
291 } 292 }
292 293
293 void OmxVideoDecodeAccelerator::AssignPictureBuffer( 294 // NOTE: this is only partially-implemented as it only inspects the first
294 std::vector<PictureBuffer*> picture_buffers) { 295 // picture buffer passed in each AssignPictureBuffer call, and never unsets
295 // NOTE: this is only partially-implemented as it only inspects the first 296 // uses_egl_image_ once set.
296 // picture buffer passed in each AssignPictureBuffer call, and never unsets 297 void OmxVideoDecodeAccelerator::AssignGLESBuffers(
297 // uses_egl_image_ once set. 298 const std::vector<media::GLESBuffer>& buffers) {
298 if (PictureBuffer::PICTUREBUFFER_MEMORYTYPE_GL_TEXTURE == 299 uses_egl_image_ = true;
299 picture_buffers[0]->GetMemoryType()) { 300 std::vector<media::BaseBuffer*> base_buffers(buffers.size());
300 uses_egl_image_ = true; 301 for (size_t i = 0; i < buffers.size(); ++i)
301 } 302 base_buffers[i] = new media::GLESBuffer(buffers[i]);
303 AssignBuffersHelper(base_buffers);
304 }
302 305
306 void OmxVideoDecodeAccelerator::AssignSysmemBuffers(
307 const std::vector<media::SysmemBuffer>& buffers) {
308 DCHECK(!uses_egl_image_);
309 std::vector<media::BaseBuffer*> base_buffers(buffers.size());
310 for (size_t i = 0; i < buffers.size(); ++i)
311 base_buffers[i] = new media::SysmemBuffer(buffers[i]);
312 AssignBuffersHelper(base_buffers);
313 }
314
315 void OmxVideoDecodeAccelerator::AssignBuffersHelper(
316 const std::vector<media::BaseBuffer*>& buffers) {
303 assigned_picture_buffers_.insert( 317 assigned_picture_buffers_.insert(
304 assigned_picture_buffers_.begin(), 318 assigned_picture_buffers_.end(), buffers.begin(), buffers.end());
305 picture_buffers.begin(),
306 picture_buffers.end());
307 319
308 if (assigned_picture_buffers_.size() < kNumPictureBuffers) 320 if (assigned_picture_buffers_.size() < kNumPictureBuffers)
309 return; // get all the buffers first. 321 return; // get all the buffers first.
310 322
311 // Obtain the information about the output port. 323 // Obtain the information about the output port.
312 OMX_PARAM_PORTDEFINITIONTYPE port_format; 324 OMX_PARAM_PORTDEFINITIONTYPE port_format;
313 InitParam(*this, &port_format); 325 InitParam(*this, &port_format);
314 port_format.nPortIndex = output_port_; 326 port_format.nPortIndex = output_port_;
315 OMX_ERRORTYPE result = OMX_GetParameter(component_handle_, 327 OMX_ERRORTYPE result = OMX_GetParameter(component_handle_,
316 OMX_IndexParamPortDefinition, 328 OMX_IndexParamPortDefinition,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 StopOnError(); 361 StopOnError();
350 } 362 }
351 } 363 }
352 364
353 void OmxVideoDecodeAccelerator::ReusePictureBuffer(int32 picture_buffer_id) { 365 void OmxVideoDecodeAccelerator::ReusePictureBuffer(int32 picture_buffer_id) {
354 // TODO(vhiremath@nvidia.com) Avoid leaking of the picture buffer. 366 // TODO(vhiremath@nvidia.com) Avoid leaking of the picture buffer.
355 if (!CanFillBuffer()) 367 if (!CanFillBuffer())
356 return; 368 return;
357 369
358 for (int i = 0; i < output_buffer_count_; ++i) { 370 for (int i = 0; i < output_buffer_count_; ++i) {
359 if (picture_buffer_id != assigned_picture_buffers_[i]->GetId()) 371 if (picture_buffer_id != assigned_picture_buffers_[i]->id())
360 continue; 372 continue;
361 output_buffers_at_component_++; 373 output_buffers_at_component_++;
362 OMX_ERRORTYPE result = 374 OMX_ERRORTYPE result =
363 OMX_FillThisBuffer(component_handle_, output_pictures_[i].second); 375 OMX_FillThisBuffer(component_handle_, output_pictures_[i].second);
364 if (result != OMX_ErrorNone) { 376 if (result != OMX_ErrorNone) {
365 LOG(ERROR) << "OMX_FillThisBuffer() failed with result " << result; 377 LOG(ERROR) << "OMX_FillThisBuffer() failed with result " << result;
366 StopOnError(); 378 StopOnError();
367 } 379 }
368 // Sent one buffer to omx. 380 // Sent one buffer to omx.
369 return; 381 return;
(...skipping 13 matching lines...) Expand all
383 output_buffers_at_component_++; 395 output_buffers_at_component_++;
384 OMX_ERRORTYPE result = OMX_FillThisBuffer(component_handle_, omx_buffer); 396 OMX_ERRORTYPE result = OMX_FillThisBuffer(component_handle_, omx_buffer);
385 if (result != OMX_ErrorNone) { 397 if (result != OMX_ErrorNone) {
386 LOG(ERROR) << "OMX_FillThisBuffer() failed with result " << result; 398 LOG(ERROR) << "OMX_FillThisBuffer() failed with result " << result;
387 StopOnError(); 399 StopOnError();
388 return; 400 return;
389 } 401 }
390 } 402 }
391 } 403 }
392 404
393 bool OmxVideoDecodeAccelerator::Flush( 405 bool OmxVideoDecodeAccelerator::Flush() {
394 const media::VideoDecodeAcceleratorCallback& callback) {
395 OMX_STATETYPE il_state; 406 OMX_STATETYPE il_state;
396 OMX_GetState(component_handle_, &il_state); 407 OMX_GetState(component_handle_, &il_state);
397 DCHECK_EQ(il_state, OMX_StateExecuting); 408 DCHECK_EQ(il_state, OMX_StateExecuting);
398 if (il_state != OMX_StateExecuting) { 409 if (il_state != OMX_StateExecuting) {
399 callback.Run(); 410 client_->NotifyFlushDone();
400 return false; 411 return false;
401 } 412 }
402 on_buffer_flag_event_func_ = &OmxVideoDecodeAccelerator::FlushBegin; 413 on_buffer_flag_event_func_ = &OmxVideoDecodeAccelerator::FlushBegin;
403 flush_done_callback_ = callback;
404 414
405 OMX_BUFFERHEADERTYPE* omx_buffer = free_input_buffers_.front(); 415 OMX_BUFFERHEADERTYPE* omx_buffer = free_input_buffers_.front();
406 omx_buffer->nFilledLen = 0; 416 omx_buffer->nFilledLen = 0;
407 omx_buffer->nAllocLen = omx_buffer->nFilledLen; 417 omx_buffer->nAllocLen = omx_buffer->nFilledLen;
408 omx_buffer->nFlags |= OMX_BUFFERFLAG_EOS; 418 omx_buffer->nFlags |= OMX_BUFFERFLAG_EOS;
409 omx_buffer->nTimeStamp = 0; 419 omx_buffer->nTimeStamp = 0;
410 // Give this buffer to OMX. 420 // Give this buffer to OMX.
411 OMX_ERRORTYPE result = OMX_ErrorNone; 421 OMX_ERRORTYPE result = OMX_ErrorNone;
412 result = OMX_EmptyThisBuffer(component_handle_, omx_buffer); 422 result = OMX_EmptyThisBuffer(component_handle_, omx_buffer);
413 if (result != OMX_ErrorNone) { 423 if (result != OMX_ErrorNone) {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 VLOG(1) << "Output Port had been flushed"; 480 VLOG(1) << "Output Port had been flushed";
471 DCHECK_EQ(output_buffers_at_component_, 0); 481 DCHECK_EQ(output_buffers_at_component_, 0);
472 } 482 }
473 483
474 client_state_ = OMX_StatePause; 484 client_state_ = OMX_StatePause;
475 // So Finally call OnPortCommandFlush which should 485 // So Finally call OnPortCommandFlush which should
476 // internally call DismissPictureBuffer(); 486 // internally call DismissPictureBuffer();
477 OnPortCommandFlush(OMX_StateExecuting); 487 OnPortCommandFlush(OMX_StateExecuting);
478 } 488 }
479 489
480 bool OmxVideoDecodeAccelerator::Abort( 490 bool OmxVideoDecodeAccelerator::Abort() {
481 const media::VideoDecodeAcceleratorCallback& callback) {
482 // TODO(vhiremath@nvidia.com) 491 // TODO(vhiremath@nvidia.com)
483 // Need more thinking on this to handle w.r.t OMX. 492 // Need more thinking on this to handle w.r.t OMX.
484 // There is no explicit UnInitialize call for this. 493 // There is no explicit UnInitialize call for this.
485 // Also review again for trick modes. 494 // Also review again for trick modes.
486 callback.Run(); 495 client_->NotifyAbortDone();
487 return true; 496 return true;
488 } 497 }
489 498
490 // Event callback during initialization to handle DoneStateSet to idle 499 // Event callback during initialization to handle DoneStateSet to idle
491 void OmxVideoDecodeAccelerator::OnStateChangeLoadedToIdle(OMX_STATETYPE state) { 500 void OmxVideoDecodeAccelerator::OnStateChangeLoadedToIdle(OMX_STATETYPE state) {
492 DCHECK_EQ(client_state_, OMX_StateLoaded); 501 DCHECK_EQ(client_state_, OMX_StateLoaded);
493 DCHECK_EQ(OMX_StateIdle, state); 502 DCHECK_EQ(OMX_StateIdle, state);
494 VLOG(1) << "OMX video decode engine is in Idle"; 503 VLOG(1) << "OMX video decode engine is in Idle";
495 504
496 on_state_event_func_ = 505 on_state_event_func_ =
497 &OmxVideoDecodeAccelerator::OnStateChangeIdleToExecuting; 506 &OmxVideoDecodeAccelerator::OnStateChangeIdleToExecuting;
498 if (!TransitionToState(OMX_StateExecuting)) 507 if (!TransitionToState(OMX_StateExecuting))
499 return; 508 return;
500 } 509 }
501 510
502 // Event callback during initialization to handle DoneStateSet to executing 511 // Event callback during initialization to handle DoneStateSet to executing
503 void OmxVideoDecodeAccelerator::OnStateChangeIdleToExecuting( 512 void OmxVideoDecodeAccelerator::OnStateChangeIdleToExecuting(
504 OMX_STATETYPE state) { 513 OMX_STATETYPE state) {
505 DCHECK_EQ(OMX_StateExecuting, state); 514 DCHECK_EQ(OMX_StateExecuting, state);
506 VLOG(1) << "OMX video decode engine is in Executing"; 515 VLOG(1) << "OMX video decode engine is in Executing";
507 516
508 client_state_ = OMX_StateExecuting; 517 client_state_ = OMX_StateExecuting;
509 on_state_event_func_ = NULL; 518 on_state_event_func_ = NULL;
510 // This will kickoff the actual decoding 519 // This will kickoff the actual decoding
511 client_->NotifyResourcesAcquired();
512 InitialFillBuffer(); 520 InitialFillBuffer();
513 } 521 }
514 522
515 // Send state transition command to component. 523 // Send state transition command to component.
516 bool OmxVideoDecodeAccelerator::TransitionToState(OMX_STATETYPE new_state) { 524 bool OmxVideoDecodeAccelerator::TransitionToState(OMX_STATETYPE new_state) {
517 OMX_ERRORTYPE result = OMX_SendCommand(component_handle_, 525 OMX_ERRORTYPE result = OMX_SendCommand(component_handle_,
518 OMX_CommandStateSet, 526 OMX_CommandStateSet,
519 new_state, 0); 527 new_state, 0);
520 if (result != OMX_ErrorNone) { 528 if (result != OMX_ErrorNone) {
521 LOG(ERROR) << "SendCommand(OMX_CommandStateSet) failed"; 529 LOG(ERROR) << "SendCommand(OMX_CommandStateSet) failed";
522 StopOnError(); 530 StopOnError();
523 return false; 531 return false;
524 } 532 }
525 return true; 533 return true;
526 } 534 }
527 535
528 void OmxVideoDecodeAccelerator::OnPortCommandFlush(OMX_STATETYPE state) { 536 void OmxVideoDecodeAccelerator::OnPortCommandFlush(OMX_STATETYPE state) {
529 DCHECK_EQ(state, OMX_StateExecuting); 537 DCHECK_EQ(state, OMX_StateExecuting);
530 538
531 VLOG(1) << "Deinit from Executing"; 539 VLOG(1) << "Deinit from Executing";
532 on_state_event_func_ = 540 on_state_event_func_ =
533 &OmxVideoDecodeAccelerator::OnStateChangeExecutingToIdle; 541 &OmxVideoDecodeAccelerator::OnStateChangeExecutingToIdle;
534 TransitionToState(OMX_StateIdle); 542 TransitionToState(OMX_StateIdle);
535 for (int i = 0; i < output_buffer_count_; ++i) { 543 for (int i = 0; i < output_buffer_count_; ++i) {
536 OutputPicture output_picture = output_pictures_[i]; 544 OutputPicture output_picture = output_pictures_[i];
537 client_->DismissPictureBuffer(output_picture.first); 545 client_->DismissPictureBuffer(output_picture.first);
vrk (LEFT CHROMIUM) 2011/05/23 23:35:00 (Sorry if this was asked/answered before in a prev
538 } 546 }
539 output_pictures_.clear(); 547 output_pictures_.clear();
540 } 548 }
541 549
542 void OmxVideoDecodeAccelerator::OnStateChangeExecutingToIdle( 550 void OmxVideoDecodeAccelerator::OnStateChangeExecutingToIdle(
543 OMX_STATETYPE state) { 551 OMX_STATETYPE state) {
544 DCHECK_EQ(state, OMX_StateIdle); 552 DCHECK_EQ(state, OMX_StateIdle);
545 553
546 VLOG(1) << "Deinit from Idle"; 554 VLOG(1) << "Deinit from Idle";
547 on_state_event_func_ = 555 on_state_event_func_ =
(...skipping 14 matching lines...) Expand all
562 570
563 if (component_handle_) { 571 if (component_handle_) {
564 OMX_ERRORTYPE result = (*omx_free_handle)(component_handle_); 572 OMX_ERRORTYPE result = (*omx_free_handle)(component_handle_);
565 if (result != OMX_ErrorNone) 573 if (result != OMX_ErrorNone)
566 LOG(ERROR) << "OMX_FreeHandle() error. Error code: " << result; 574 LOG(ERROR) << "OMX_FreeHandle() error. Error code: " << result;
567 component_handle_ = NULL; 575 component_handle_ = NULL;
568 } 576 }
569 client_state_ = OMX_StateLoaded; 577 client_state_ = OMX_StateLoaded;
570 (*omx_deinit)(); 578 (*omx_deinit)();
571 VLOG(1) << "OMX Deinit Clean exit done"; 579 VLOG(1) << "OMX Deinit Clean exit done";
572 flush_done_callback_.Run(); 580 client_->NotifyFlushDone();
573 } 581 }
574 582
575 void OmxVideoDecodeAccelerator::StopOnError() { 583 void OmxVideoDecodeAccelerator::StopOnError() {
576 OMX_STATETYPE il_state; 584 OMX_STATETYPE il_state;
577 OMX_GetState(component_handle_, &il_state); 585 OMX_GetState(component_handle_, &il_state);
578 client_state_ = OMX_StateInvalid; 586 client_state_ = OMX_StateInvalid;
579 switch (il_state) { 587 switch (il_state) {
580 case OMX_StateExecuting: 588 case OMX_StateExecuting:
581 OnPortCommandFlush(OMX_StateExecuting); 589 OnPortCommandFlush(OMX_StateExecuting);
582 return; 590 return;
(...skipping 21 matching lines...) Expand all
604 return false; 612 return false;
605 buffer->nInputPortIndex = input_port_; 613 buffer->nInputPortIndex = input_port_;
606 buffer->nOffset = 0; 614 buffer->nOffset = 0;
607 buffer->nFlags = 0; 615 buffer->nFlags = 0;
608 free_input_buffers_.push(buffer); 616 free_input_buffers_.push(buffer);
609 } 617 }
610 return true; 618 return true;
611 } 619 }
612 620
613 bool OmxVideoDecodeAccelerator::AllocateOutputBuffers() { 621 bool OmxVideoDecodeAccelerator::AllocateOutputBuffers() {
614 OMX_BUFFERHEADERTYPE* buffer;
615 Picture* picture;
616 OMX_ERRORTYPE result;
617 gfx::Size decoded_pixel_size(width_, height_); 622 gfx::Size decoded_pixel_size(width_, height_);
618 gfx::Size visible_pixel_size(width_, height_); 623 gfx::Size visible_pixel_size(width_, height_);
619 624 // TODO(fischman): remove garbage bitstream buffer id's below (42 and 24) when
625 // the bitstream_buffer_id field is removed from Picture.
620 if (uses_egl_image_) { 626 if (uses_egl_image_) {
621 media::VideoDecodeAccelerator::PictureBuffer::DataPlaneHandle egl_ids;
622 std::vector<PictureBuffer::DataPlaneHandle> planes;
623 uint32 texture;
624
625 for (uint32 i = 0; i < assigned_picture_buffers_.size(); i++) { 627 for (uint32 i = 0; i < assigned_picture_buffers_.size(); i++) {
626 picture = new media::Picture( 628 media::GLESBuffer* gles_buffer =
627 reinterpret_cast<media::PictureBuffer*>(assigned_picture_buffers_[i]), 629 reinterpret_cast<media::GLESBuffer*>(assigned_picture_buffers_[i]);
628 decoded_pixel_size, visible_pixel_size, 630 OMX_BUFFERHEADERTYPE* omx_buffer;
629 static_cast<void*>(component_handle_)); 631 void* egl = texture2eglImage_translator->TranslateToEglImage(
630 632 gles_buffer->texture_id());
631 planes = assigned_picture_buffers_[i]->GetPlaneHandles(); 633 OMX_ERRORTYPE result = OMX_UseEGLImage(
632 egl_ids = planes[i]; 634 component_handle_, &omx_buffer, output_port_, gles_buffer, egl);
633 texture = egl_ids.texture_id;
634 egl_image_ = texture2eglImage_translator->TranslateToEglImage(texture);
635 result = OMX_UseEGLImage(
636 component_handle_,
637 &buffer,
638 output_port_,
639 reinterpret_cast<media::PictureBuffer*>(assigned_picture_buffers_[i]),
640 egl_image_);
641
642 if (result != OMX_ErrorNone) { 635 if (result != OMX_ErrorNone) {
643 LOG(ERROR) << "OMX_UseEGLImage failed"; 636 LOG(ERROR) << "OMX_UseEGLImage failed";
644 return false; 637 return false;
645 } 638 }
639 omx_buffer->pAppPrivate =
640 new media::Picture(gles_buffer->id(),
641 42 /* garbage bitstreambuffer id */,
642 decoded_pixel_size, visible_pixel_size);
646 output_pictures_.push_back( 643 output_pictures_.push_back(
647 std::make_pair( 644 std::make_pair(assigned_picture_buffers_[i]->id(), omx_buffer));
648 reinterpret_cast<media::PictureBuffer*>(
649 assigned_picture_buffers_[i]),
650 buffer));
651 buffer->pAppPrivate = picture;
652 } 645 }
653 } else { 646 } else {
654 for (uint32 i = 0; i < assigned_picture_buffers_.size(); i++) { 647 for (uint32 i = 0; i < assigned_picture_buffers_.size(); i++) {
655 picture = new media::Picture( 648 media::SysmemBuffer* sysmem_buffer =
656 reinterpret_cast<media::PictureBuffer*>(assigned_picture_buffers_[i]), 649 reinterpret_cast<media::SysmemBuffer*>(assigned_picture_buffers_[i]);
657 decoded_pixel_size, visible_pixel_size, 650 OMX_BUFFERHEADERTYPE* omx_buffer;
658 static_cast<void*>(component_handle_)); 651 OMX_ERRORTYPE result = OMX_AllocateBuffer(
659 652 component_handle_, &omx_buffer, output_port_, NULL,
660 result = OMX_AllocateBuffer(component_handle_, &buffer, output_port_, 653 output_buffer_size_);
661 NULL, output_buffer_size_);
662 if (result != OMX_ErrorNone) 654 if (result != OMX_ErrorNone)
663 return false; 655 return false;
656 omx_buffer->pAppPrivate = new media::Picture(
657 sysmem_buffer->id(),
658 24 /* garbage bitstreambuffer id */,
659 decoded_pixel_size, visible_pixel_size);
664 output_pictures_.push_back( 660 output_pictures_.push_back(
665 std::make_pair( 661 std::make_pair(sysmem_buffer->id(), omx_buffer));
666 reinterpret_cast<media::PictureBuffer*>(
667 assigned_picture_buffers_[i]),
668 buffer));
669 buffer->pAppPrivate = picture;
670 } 662 }
671 } 663 }
672 return true; 664 return true;
673 } 665 }
674 666
675 void OmxVideoDecodeAccelerator::FreeInputBuffers() { 667 void OmxVideoDecodeAccelerator::FreeInputBuffers() {
676 // Calls to OMX to free buffers. 668 // Calls to OMX to free buffers.
677 OMX_ERRORTYPE result; 669 OMX_ERRORTYPE result;
678 OMX_BUFFERHEADERTYPE* omx_buffer; 670 OMX_BUFFERHEADERTYPE* omx_buffer;
679 for (int i = 0; i < input_buffer_count_; ++i) { 671 for (int i = 0; i < input_buffer_count_; ++i) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
712 // In this case, the component detects PortSettingsChanged 704 // In this case, the component detects PortSettingsChanged
713 // and sends the particular event to the IL-client. 705 // and sends the particular event to the IL-client.
714 // This needs to be handled in this method. 706 // This needs to be handled in this method.
715 return; 707 return;
716 } 708 }
717 709
718 void OmxVideoDecodeAccelerator::FillBufferDoneTask( 710 void OmxVideoDecodeAccelerator::FillBufferDoneTask(
719 OMX_BUFFERHEADERTYPE* buffer) { 711 OMX_BUFFERHEADERTYPE* buffer) {
720 DCHECK_GT(output_buffers_at_component_, 0); 712 DCHECK_GT(output_buffers_at_component_, 0);
721 output_buffers_at_component_--; 713 output_buffers_at_component_--;
722 client_->PictureReady(reinterpret_cast<Picture*>(buffer->pAppPrivate)); 714 client_->PictureReady(*reinterpret_cast<media::Picture*>(
715 buffer->pAppPrivate));
723 } 716 }
724 717
725 void OmxVideoDecodeAccelerator::EmptyBufferDoneTask( 718 void OmxVideoDecodeAccelerator::EmptyBufferDoneTask(
726 OMX_BUFFERHEADERTYPE* buffer) { 719 OMX_BUFFERHEADERTYPE* buffer) {
727 DCHECK_GT(input_buffers_at_component_, 0); 720 DCHECK_GT(input_buffers_at_component_, 0);
728 free_input_buffers_.push(buffer); 721 free_input_buffers_.push(buffer);
729 input_buffers_at_component_--; 722 input_buffers_at_component_--;
730 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) 723 if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
731 return; 724 return;
732 // Retrieve the corresponding callback and run it. 725 // Retrieve the corresponding BitstreamBuffer's id and notify the client of
733 OMXBufferCallbackMap::iterator it = omx_buff_cb_.find(buffer); 726 // its completion.
734 if (it == omx_buff_cb_.end()) { 727 OMXBufferIdMap::iterator it = omx_buff_ids_.find(buffer);
735 LOG(ERROR) << "Unexpectedly failed to find a buffer callback."; 728 if (it == omx_buff_ids_.end()) {
729 LOG(ERROR) << "Unexpectedly failed to find a buffer id.";
736 StopOnError(); 730 StopOnError();
737 return; 731 return;
738 } 732 }
739 delete it->second.first; 733 delete it->second.first;
740 it->second.second.Run(); 734 client_->NotifyEndOfBitstreamBuffer(it->second.second);
741 omx_buff_cb_.erase(it); 735 omx_buff_ids_.erase(it);
742 } 736 }
743 737
744 void OmxVideoDecodeAccelerator::EventHandlerCompleteTask(OMX_EVENTTYPE event, 738 void OmxVideoDecodeAccelerator::EventHandlerCompleteTask(OMX_EVENTTYPE event,
745 OMX_U32 data1, 739 OMX_U32 data1,
746 OMX_U32 data2) { 740 OMX_U32 data2) {
747 switch (event) { 741 switch (event) {
748 case OMX_EventCmdComplete: { 742 case OMX_EventCmdComplete: {
749 // If the last command was successful, we have completed 743 // If the last command was successful, we have completed
750 // a state transition. So notify that we have done it 744 // a state transition. So notify that we have done it
751 // accordingly. 745 // accordingly.
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
803 OMX_ERRORTYPE OmxVideoDecodeAccelerator::EventHandler(OMX_HANDLETYPE component, 797 OMX_ERRORTYPE OmxVideoDecodeAccelerator::EventHandler(OMX_HANDLETYPE component,
804 OMX_PTR priv_data, 798 OMX_PTR priv_data,
805 OMX_EVENTTYPE event, 799 OMX_EVENTTYPE event,
806 OMX_U32 data1, 800 OMX_U32 data1,
807 OMX_U32 data2, 801 OMX_U32 data2,
808 OMX_PTR event_data) { 802 OMX_PTR event_data) {
809 OmxVideoDecodeAccelerator* decoder = 803 OmxVideoDecodeAccelerator* decoder =
810 static_cast<OmxVideoDecodeAccelerator*>(priv_data); 804 static_cast<OmxVideoDecodeAccelerator*>(priv_data);
811 DCHECK_EQ(component, decoder->component_handle_); 805 DCHECK_EQ(component, decoder->component_handle_);
812 806
813 decoder->message_loop_->PostTask(FROM_HERE, 807 decoder->message_loop_->PostTask(
814 NewRunnableMethod(decoder, 808 FROM_HERE,
815 &OmxVideoDecodeAccelerator::EventHandlerCompleteTask, 809 NewRunnableMethod(decoder,
816 event, data1, data2)); 810 &OmxVideoDecodeAccelerator::EventHandlerCompleteTask,
811 event, data1, data2));
817 812
818 return OMX_ErrorNone; 813 return OMX_ErrorNone;
819 } 814 }
820 815
821 // static 816 // static
822 OMX_ERRORTYPE OmxVideoDecodeAccelerator::EmptyBufferCallback( 817 OMX_ERRORTYPE OmxVideoDecodeAccelerator::EmptyBufferCallback(
823 OMX_HANDLETYPE component, 818 OMX_HANDLETYPE component,
824 OMX_PTR priv_data, 819 OMX_PTR priv_data,
825 OMX_BUFFERHEADERTYPE* buffer) { 820 OMX_BUFFERHEADERTYPE* buffer) {
826 OmxVideoDecodeAccelerator* decoder = 821 OmxVideoDecodeAccelerator* decoder =
(...skipping 10 matching lines...) Expand all
837 832
838 // static 833 // static
839 OMX_ERRORTYPE OmxVideoDecodeAccelerator::FillBufferCallback( 834 OMX_ERRORTYPE OmxVideoDecodeAccelerator::FillBufferCallback(
840 OMX_HANDLETYPE component, 835 OMX_HANDLETYPE component,
841 OMX_PTR priv_data, 836 OMX_PTR priv_data,
842 OMX_BUFFERHEADERTYPE* buffer) { 837 OMX_BUFFERHEADERTYPE* buffer) {
843 OmxVideoDecodeAccelerator* decoder = 838 OmxVideoDecodeAccelerator* decoder =
844 static_cast<OmxVideoDecodeAccelerator*>(priv_data); 839 static_cast<OmxVideoDecodeAccelerator*>(priv_data);
845 DCHECK_EQ(component, decoder->component_handle_); 840 DCHECK_EQ(component, decoder->component_handle_);
846 841
847 decoder->message_loop_->PostTask(FROM_HERE, 842 decoder->message_loop_->PostTask(
843 FROM_HERE,
848 NewRunnableMethod( 844 NewRunnableMethod(
849 decoder, 845 decoder,
850 &OmxVideoDecodeAccelerator::FillBufferDoneTask, buffer)); 846 &OmxVideoDecodeAccelerator::FillBufferDoneTask, buffer));
851 return OMX_ErrorNone; 847 return OMX_ErrorNone;
852 } 848 }
853 849
854 bool OmxVideoDecodeAccelerator::CanAcceptInput() { 850 bool OmxVideoDecodeAccelerator::CanAcceptInput() {
855 // We can't take input buffer when in error state. 851 // We can't take input buffer when in error state.
856 return (client_state_ != OMX_StateInvalid && 852 return (client_state_ != OMX_StateInvalid &&
857 client_state_ != OMX_StatePause && 853 client_state_ != OMX_StatePause &&
(...skipping 20 matching lines...) Expand all
878 OMX_ERRORTYPE result = OMX_SendCommand(component_handle_, 874 OMX_ERRORTYPE result = OMX_SendCommand(component_handle_,
879 cmd, port_index, 0); 875 cmd, port_index, 0);
880 if (result != OMX_ErrorNone) { 876 if (result != OMX_ErrorNone) {
881 LOG(ERROR) << "SendCommand(OMX_CommandPortDisable) failed"; 877 LOG(ERROR) << "SendCommand(OMX_CommandPortDisable) failed";
882 StopOnError(); 878 StopOnError();
883 return; 879 return;
884 } 880 }
885 } 881 }
886 882
887 DISABLE_RUNNABLE_METHOD_REFCOUNT(OmxVideoDecodeAccelerator); 883 DISABLE_RUNNABLE_METHOD_REFCOUNT(OmxVideoDecodeAccelerator);
OLDNEW
« 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