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

Side by Side Diff: media/gpu/v4l2_video_decode_accelerator.cc

Issue 1939683002: Test X11 header pollution (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 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
« no previous file with comments | « media/gpu/v4l2_video_decode_accelerator.h ('k') | media/gpu/v4l2_video_encode_accelerator.h » ('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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/v4l2_video_decode_accelerator.h" 5 #include "media/gpu/v4l2_video_decode_accelerator.h"
6 6
7 #include <dlfcn.h> 7 #include <dlfcn.h>
8 #include <errno.h> 8 #include <errno.h>
9 #include <fcntl.h> 9 #include <fcntl.h>
10 #include <linux/videodev2.h> 10 #include <linux/videodev2.h>
11 #include <poll.h> 11 #include <poll.h>
12 #include <string.h> 12 #include <string.h>
13 #include <sys/eventfd.h> 13 #include <sys/eventfd.h>
14 #include <sys/ioctl.h> 14 #include <sys/ioctl.h>
15 #include <sys/mman.h> 15 #include <sys/mman.h>
16 16
17 #include "base/bind.h" 17 #include "base/bind.h"
18 #include "base/command_line.h" 18 #include "base/command_line.h"
19 #include "base/message_loop/message_loop.h" 19 #include "base/message_loop/message_loop.h"
20 #include "base/numerics/safe_conversions.h" 20 #include "base/numerics/safe_conversions.h"
21 #include "base/thread_task_runner_handle.h" 21 #include "base/thread_task_runner_handle.h"
22 #include "base/trace_event/trace_event.h" 22 #include "base/trace_event/trace_event.h"
23 #include "build/build_config.h" 23 #include "build/build_config.h"
24 #include "content/common/gpu/media/shared_memory_region.h"
25 #include "media/base/bind_to_current_loop.h" 24 #include "media/base/bind_to_current_loop.h"
26 #include "media/base/media_switches.h" 25 #include "media/base/media_switches.h"
27 #include "media/filters/h264_parser.h" 26 #include "media/filters/h264_parser.h"
27 #include "media/gpu/shared_memory_region.h"
28 #include "ui/gfx/geometry/rect.h" 28 #include "ui/gfx/geometry/rect.h"
29 #include "ui/gl/gl_context.h" 29 #include "ui/gl/gl_context.h"
30 #include "ui/gl/scoped_binders.h" 30 #include "ui/gl/scoped_binders.h"
31 31
32 #define NOTIFY_ERROR(x) \ 32 #define NOTIFY_ERROR(x) \
33 do { \ 33 do { \
34 LOG(ERROR) << "Setting error state:" << x; \ 34 LOG(ERROR) << "Setting error state:" << x; \
35 SetErrorState(x); \ 35 SetErrorState(x); \
36 } while (0) 36 } while (0)
37 37
38 #define IOCTL_OR_ERROR_RETURN_VALUE(type, arg, value, type_str) \ 38 #define IOCTL_OR_ERROR_RETURN_VALUE(type, arg, value, type_str) \
39 do { \ 39 do { \
40 if (device_->Ioctl(type, arg) != 0) { \ 40 if (device_->Ioctl(type, arg) != 0) { \
41 PLOG(ERROR) << __func__ << "(): ioctl() failed: " << type_str; \ 41 PLOG(ERROR) << __func__ << "(): ioctl() failed: " << type_str; \
42 NOTIFY_ERROR(PLATFORM_FAILURE); \ 42 NOTIFY_ERROR(PLATFORM_FAILURE); \
43 return value; \ 43 return value; \
44 } \ 44 } \
45 } while (0) 45 } while (0)
46 46
47 #define IOCTL_OR_ERROR_RETURN(type, arg) \ 47 #define IOCTL_OR_ERROR_RETURN(type, arg) \
48 IOCTL_OR_ERROR_RETURN_VALUE(type, arg, ((void)0), #type) 48 IOCTL_OR_ERROR_RETURN_VALUE(type, arg, ((void)0), #type)
49 49
50 #define IOCTL_OR_ERROR_RETURN_FALSE(type, arg) \ 50 #define IOCTL_OR_ERROR_RETURN_FALSE(type, arg) \
51 IOCTL_OR_ERROR_RETURN_VALUE(type, arg, false, #type) 51 IOCTL_OR_ERROR_RETURN_VALUE(type, arg, false, #type)
52 52
53 #define IOCTL_OR_LOG_ERROR(type, arg) \ 53 #define IOCTL_OR_LOG_ERROR(type, arg) \
54 do { \ 54 do { \
55 if (device_->Ioctl(type, arg) != 0) \ 55 if (device_->Ioctl(type, arg) != 0) \
56 PLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \ 56 PLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \
57 } while (0) 57 } while (0)
58 58
59 namespace content { 59 namespace media {
60 60
61 // static 61 // static
62 const uint32_t V4L2VideoDecodeAccelerator::supported_input_fourccs_[] = { 62 const uint32_t V4L2VideoDecodeAccelerator::supported_input_fourccs_[] = {
63 V4L2_PIX_FMT_H264, V4L2_PIX_FMT_VP8, V4L2_PIX_FMT_VP9, 63 V4L2_PIX_FMT_H264, V4L2_PIX_FMT_VP8, V4L2_PIX_FMT_VP9,
64 }; 64 };
65 65
66 struct V4L2VideoDecodeAccelerator::BitstreamBufferRef { 66 struct V4L2VideoDecodeAccelerator::BitstreamBufferRef {
67 BitstreamBufferRef( 67 BitstreamBufferRef(
68 base::WeakPtr<Client>& client, 68 base::WeakPtr<Client>& client,
69 scoped_refptr<base::SingleThreadTaskRunner>& client_task_runner, 69 scoped_refptr<base::SingleThreadTaskRunner>& client_task_runner,
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 input_id(input_id) {} 103 input_id(input_id) {}
104 104
105 V4L2VideoDecodeAccelerator::BitstreamBufferRef::~BitstreamBufferRef() { 105 V4L2VideoDecodeAccelerator::BitstreamBufferRef::~BitstreamBufferRef() {
106 if (input_id >= 0) { 106 if (input_id >= 0) {
107 client_task_runner->PostTask( 107 client_task_runner->PostTask(
108 FROM_HERE, 108 FROM_HERE,
109 base::Bind(&Client::NotifyEndOfBitstreamBuffer, client, input_id)); 109 base::Bind(&Client::NotifyEndOfBitstreamBuffer, client, input_id));
110 } 110 }
111 } 111 }
112 112
113 V4L2VideoDecodeAccelerator::EGLSyncKHRRef::EGLSyncKHRRef( 113 V4L2VideoDecodeAccelerator::EGLSyncKHRRef::EGLSyncKHRRef(EGLDisplay egl_display,
114 EGLDisplay egl_display, EGLSyncKHR egl_sync) 114 EGLSyncKHR egl_sync)
115 : egl_display(egl_display), 115 : egl_display(egl_display), egl_sync(egl_sync) {}
116 egl_sync(egl_sync) {
117 }
118 116
119 V4L2VideoDecodeAccelerator::EGLSyncKHRRef::~EGLSyncKHRRef() { 117 V4L2VideoDecodeAccelerator::EGLSyncKHRRef::~EGLSyncKHRRef() {
120 // We don't check for eglDestroySyncKHR failures, because if we get here 118 // We don't check for eglDestroySyncKHR failures, because if we get here
121 // with a valid sync object, something went wrong and we are getting 119 // with a valid sync object, something went wrong and we are getting
122 // destroyed anyway. 120 // destroyed anyway.
123 if (egl_sync != EGL_NO_SYNC_KHR) 121 if (egl_sync != EGL_NO_SYNC_KHR)
124 eglDestroySyncKHR(egl_display, egl_sync); 122 eglDestroySyncKHR(egl_display, egl_sync);
125 } 123 }
126 124
127 V4L2VideoDecodeAccelerator::InputRecord::InputRecord() 125 V4L2VideoDecodeAccelerator::InputRecord::InputRecord()
128 : at_device(false), 126 : at_device(false), address(NULL), length(0), bytes_used(0), input_id(-1) {}
129 address(NULL),
130 length(0),
131 bytes_used(0),
132 input_id(-1) {
133 }
134 127
135 V4L2VideoDecodeAccelerator::InputRecord::~InputRecord() { 128 V4L2VideoDecodeAccelerator::InputRecord::~InputRecord() {}
136 }
137 129
138 V4L2VideoDecodeAccelerator::OutputRecord::OutputRecord() 130 V4L2VideoDecodeAccelerator::OutputRecord::OutputRecord()
139 : state(kFree), 131 : state(kFree),
140 egl_image(EGL_NO_IMAGE_KHR), 132 egl_image(EGL_NO_IMAGE_KHR),
141 egl_sync(EGL_NO_SYNC_KHR), 133 egl_sync(EGL_NO_SYNC_KHR),
142 picture_id(-1), 134 picture_id(-1),
143 cleared(false) { 135 cleared(false) {}
144 }
145 136
146 V4L2VideoDecodeAccelerator::OutputRecord::~OutputRecord() {} 137 V4L2VideoDecodeAccelerator::OutputRecord::~OutputRecord() {}
147 138
148 V4L2VideoDecodeAccelerator::PictureRecord::PictureRecord( 139 V4L2VideoDecodeAccelerator::PictureRecord::PictureRecord(
149 bool cleared, 140 bool cleared,
150 const media::Picture& picture) 141 const media::Picture& picture)
151 : cleared(cleared), picture(picture) {} 142 : cleared(cleared), picture(picture) {}
152 143
153 V4L2VideoDecodeAccelerator::PictureRecord::~PictureRecord() {} 144 V4L2VideoDecodeAccelerator::PictureRecord::~PictureRecord() {}
154 145
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 return false; 251 return false;
261 } 252 }
262 #endif 253 #endif
263 254
264 // Capabilities check. 255 // Capabilities check.
265 struct v4l2_capability caps; 256 struct v4l2_capability caps;
266 const __u32 kCapsRequired = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; 257 const __u32 kCapsRequired = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
267 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps); 258 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps);
268 if ((caps.capabilities & kCapsRequired) != kCapsRequired) { 259 if ((caps.capabilities & kCapsRequired) != kCapsRequired) {
269 LOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP" 260 LOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP"
270 ", caps check failed: 0x" << std::hex << caps.capabilities; 261 ", caps check failed: 0x"
262 << std::hex << caps.capabilities;
271 return false; 263 return false;
272 } 264 }
273 265
274 if (!SetupFormats()) 266 if (!SetupFormats())
275 return false; 267 return false;
276 268
277 // Subscribe to the resolution change event. 269 // Subscribe to the resolution change event.
278 struct v4l2_event_subscription sub; 270 struct v4l2_event_subscription sub;
279 memset(&sub, 0, sizeof(sub)); 271 memset(&sub, 0, sizeof(sub));
280 sub.type = V4L2_EVENT_SOURCE_CHANGE; 272 sub.type = V4L2_EVENT_SOURCE_CHANGE;
281 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_SUBSCRIBE_EVENT, &sub); 273 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_SUBSCRIBE_EVENT, &sub);
282 274
283 if (video_profile_ >= media::H264PROFILE_MIN && 275 if (video_profile_ >= media::H264PROFILE_MIN &&
284 video_profile_ <= media::H264PROFILE_MAX) { 276 video_profile_ <= media::H264PROFILE_MAX) {
285 decoder_h264_parser_.reset(new media::H264Parser()); 277 decoder_h264_parser_.reset(new media::H264Parser());
286 } 278 }
287 279
288 if (!CreateInputBuffers()) 280 if (!CreateInputBuffers())
289 return false; 281 return false;
290 282
291 if (!decoder_thread_.Start()) { 283 if (!decoder_thread_.Start()) {
292 LOG(ERROR) << "Initialize(): decoder thread failed to start"; 284 LOG(ERROR) << "Initialize(): decoder thread failed to start";
293 return false; 285 return false;
294 } 286 }
295 287
296 decoder_state_ = kInitialized; 288 decoder_state_ = kInitialized;
297 289
298 // StartDevicePoll will NOTIFY_ERROR on failure, so IgnoreResult is fine here. 290 // StartDevicePoll will NOTIFY_ERROR on failure, so IgnoreResult is fine here.
299 decoder_thread_.message_loop()->PostTask( 291 decoder_thread_.message_loop()->PostTask(
300 FROM_HERE, 292 FROM_HERE, base::Bind(base::IgnoreResult(
301 base::Bind( 293 &V4L2VideoDecodeAccelerator::StartDevicePoll),
302 base::IgnoreResult(&V4L2VideoDecodeAccelerator::StartDevicePoll), 294 base::Unretained(this)));
303 base::Unretained(this)));
304 295
305 return true; 296 return true;
306 } 297 }
307 298
308 void V4L2VideoDecodeAccelerator::Decode( 299 void V4L2VideoDecodeAccelerator::Decode(
309 const media::BitstreamBuffer& bitstream_buffer) { 300 const media::BitstreamBuffer& bitstream_buffer) {
310 DVLOG(1) << "Decode(): input_id=" << bitstream_buffer.id() 301 DVLOG(1) << "Decode(): input_id=" << bitstream_buffer.id()
311 << ", size=" << bitstream_buffer.size(); 302 << ", size=" << bitstream_buffer.size();
312 DCHECK(decode_task_runner_->BelongsToCurrentThread()); 303 DCHECK(decode_task_runner_->BelongsToCurrentThread());
313 304
314 if (bitstream_buffer.id() < 0) { 305 if (bitstream_buffer.id() < 0) {
315 LOG(ERROR) << "Invalid bitstream_buffer, id: " << bitstream_buffer.id(); 306 LOG(ERROR) << "Invalid bitstream_buffer, id: " << bitstream_buffer.id();
316 if (base::SharedMemory::IsHandleValid(bitstream_buffer.handle())) 307 if (base::SharedMemory::IsHandleValid(bitstream_buffer.handle()))
317 base::SharedMemory::CloseHandle(bitstream_buffer.handle()); 308 base::SharedMemory::CloseHandle(bitstream_buffer.handle());
318 NOTIFY_ERROR(INVALID_ARGUMENT); 309 NOTIFY_ERROR(INVALID_ARGUMENT);
319 return; 310 return;
320 } 311 }
321 312
322 // DecodeTask() will take care of running a DecodeBufferTask(). 313 // DecodeTask() will take care of running a DecodeBufferTask().
323 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 314 decoder_thread_.message_loop()->PostTask(
324 &V4L2VideoDecodeAccelerator::DecodeTask, base::Unretained(this), 315 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::DecodeTask,
325 bitstream_buffer)); 316 base::Unretained(this), bitstream_buffer));
326 } 317 }
327 318
328 void V4L2VideoDecodeAccelerator::AssignPictureBuffers( 319 void V4L2VideoDecodeAccelerator::AssignPictureBuffers(
329 const std::vector<media::PictureBuffer>& buffers) { 320 const std::vector<media::PictureBuffer>& buffers) {
330 DVLOG(3) << "AssignPictureBuffers(): buffer_count=" << buffers.size(); 321 DVLOG(3) << "AssignPictureBuffers(): buffer_count=" << buffers.size();
331 DCHECK(child_task_runner_->BelongsToCurrentThread()); 322 DCHECK(child_task_runner_->BelongsToCurrentThread());
332 323
333 const uint32_t req_buffer_count = 324 const uint32_t req_buffer_count =
334 output_dpb_size_ + kDpbOutputBufferExtraCount; 325 output_dpb_size_ + kDpbOutputBufferExtraCount;
335 326
336 if (buffers.size() < req_buffer_count) { 327 if (buffers.size() < req_buffer_count) {
337 LOG(ERROR) << "AssignPictureBuffers(): Failed to provide requested picture" 328 LOG(ERROR) << "AssignPictureBuffers(): Failed to provide requested picture"
338 " buffers. (Got " << buffers.size() 329 " buffers. (Got "
339 << ", requested " << req_buffer_count << ")"; 330 << buffers.size() << ", requested " << req_buffer_count << ")";
340 NOTIFY_ERROR(INVALID_ARGUMENT); 331 NOTIFY_ERROR(INVALID_ARGUMENT);
341 return; 332 return;
342 } 333 }
343 334
344 gfx::GLContext* gl_context = get_gl_context_cb_.Run(); 335 gfx::GLContext* gl_context = get_gl_context_cb_.Run();
345 if (!gl_context || !make_context_current_cb_.Run()) { 336 if (!gl_context || !make_context_current_cb_.Run()) {
346 LOG(ERROR) << "AssignPictureBuffers(): could not make context current"; 337 LOG(ERROR) << "AssignPictureBuffers(): could not make context current";
347 NOTIFY_ERROR(PLATFORM_FAILURE); 338 NOTIFY_ERROR(PLATFORM_FAILURE);
348 return; 339 return;
349 } 340 }
350 341
351 gfx::ScopedTextureBinder bind_restore(GL_TEXTURE_EXTERNAL_OES, 0); 342 gfx::ScopedTextureBinder bind_restore(GL_TEXTURE_EXTERNAL_OES, 0);
352 343
353 // It's safe to manipulate all the buffer state here, because the decoder 344 // It's safe to manipulate all the buffer state here, because the decoder
354 // thread is waiting on pictures_assigned_. 345 // thread is waiting on pictures_assigned_.
355 346
356 // Allocate the output buffers. 347 // Allocate the output buffers.
357 struct v4l2_requestbuffers reqbufs; 348 struct v4l2_requestbuffers reqbufs;
358 memset(&reqbufs, 0, sizeof(reqbufs)); 349 memset(&reqbufs, 0, sizeof(reqbufs));
359 reqbufs.count = buffers.size(); 350 reqbufs.count = buffers.size();
360 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 351 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
361 reqbufs.memory = V4L2_MEMORY_MMAP; 352 reqbufs.memory = V4L2_MEMORY_MMAP;
362 IOCTL_OR_ERROR_RETURN(VIDIOC_REQBUFS, &reqbufs); 353 IOCTL_OR_ERROR_RETURN(VIDIOC_REQBUFS, &reqbufs);
363 354
364 if (reqbufs.count != buffers.size()) { 355 if (reqbufs.count != buffers.size()) {
365 DLOG(ERROR) << "Could not allocate enough output buffers"; 356 DLOG(ERROR) << "Could not allocate enough output buffers";
366 NOTIFY_ERROR(PLATFORM_FAILURE); 357 NOTIFY_ERROR(PLATFORM_FAILURE);
367 return; 358 return;
368 } 359 }
369 360
370 if (image_processor_device_) { 361 if (image_processor_device_) {
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 egl_sync = eglCreateSyncKHR(egl_display_, EGL_SYNC_FENCE_KHR, NULL); 459 egl_sync = eglCreateSyncKHR(egl_display_, EGL_SYNC_FENCE_KHR, NULL);
469 if (egl_sync == EGL_NO_SYNC_KHR) { 460 if (egl_sync == EGL_NO_SYNC_KHR) {
470 LOG(ERROR) << "ReusePictureBuffer(): eglCreateSyncKHR() failed"; 461 LOG(ERROR) << "ReusePictureBuffer(): eglCreateSyncKHR() failed";
471 NOTIFY_ERROR(PLATFORM_FAILURE); 462 NOTIFY_ERROR(PLATFORM_FAILURE);
472 return; 463 return;
473 } 464 }
474 #endif 465 #endif
475 466
476 std::unique_ptr<EGLSyncKHRRef> egl_sync_ref( 467 std::unique_ptr<EGLSyncKHRRef> egl_sync_ref(
477 new EGLSyncKHRRef(egl_display_, egl_sync)); 468 new EGLSyncKHRRef(egl_display_, egl_sync));
478 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 469 decoder_thread_.message_loop()->PostTask(
479 &V4L2VideoDecodeAccelerator::ReusePictureBufferTask, 470 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::ReusePictureBufferTask,
480 base::Unretained(this), picture_buffer_id, base::Passed(&egl_sync_ref))); 471 base::Unretained(this), picture_buffer_id,
472 base::Passed(&egl_sync_ref)));
481 } 473 }
482 474
483 void V4L2VideoDecodeAccelerator::Flush() { 475 void V4L2VideoDecodeAccelerator::Flush() {
484 DVLOG(3) << "Flush()"; 476 DVLOG(3) << "Flush()";
485 DCHECK(child_task_runner_->BelongsToCurrentThread()); 477 DCHECK(child_task_runner_->BelongsToCurrentThread());
486 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 478 decoder_thread_.message_loop()->PostTask(
487 &V4L2VideoDecodeAccelerator::FlushTask, base::Unretained(this))); 479 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::FlushTask,
480 base::Unretained(this)));
488 } 481 }
489 482
490 void V4L2VideoDecodeAccelerator::Reset() { 483 void V4L2VideoDecodeAccelerator::Reset() {
491 DVLOG(3) << "Reset()"; 484 DVLOG(3) << "Reset()";
492 DCHECK(child_task_runner_->BelongsToCurrentThread()); 485 DCHECK(child_task_runner_->BelongsToCurrentThread());
493 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 486 decoder_thread_.message_loop()->PostTask(
494 &V4L2VideoDecodeAccelerator::ResetTask, base::Unretained(this))); 487 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::ResetTask,
488 base::Unretained(this)));
495 } 489 }
496 490
497 void V4L2VideoDecodeAccelerator::Destroy() { 491 void V4L2VideoDecodeAccelerator::Destroy() {
498 DVLOG(3) << "Destroy()"; 492 DVLOG(3) << "Destroy()";
499 DCHECK(child_task_runner_->BelongsToCurrentThread()); 493 DCHECK(child_task_runner_->BelongsToCurrentThread());
500 494
501 // We're destroying; cancel all callbacks. 495 // We're destroying; cancel all callbacks.
502 client_ptr_factory_.reset(); 496 client_ptr_factory_.reset();
503 weak_this_factory_.InvalidateWeakPtrs(); 497 weak_this_factory_.InvalidateWeakPtrs();
504 498
505 // If the decoder thread is running, destroy using posted task. 499 // If the decoder thread is running, destroy using posted task.
506 if (decoder_thread_.IsRunning()) { 500 if (decoder_thread_.IsRunning()) {
507 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 501 decoder_thread_.message_loop()->PostTask(
508 &V4L2VideoDecodeAccelerator::DestroyTask, base::Unretained(this))); 502 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::DestroyTask,
503 base::Unretained(this)));
509 pictures_assigned_.Signal(); 504 pictures_assigned_.Signal();
510 // DestroyTask() will cause the decoder_thread_ to flush all tasks. 505 // DestroyTask() will cause the decoder_thread_ to flush all tasks.
511 decoder_thread_.Stop(); 506 decoder_thread_.Stop();
512 } else { 507 } else {
513 // Otherwise, call the destroy task directly. 508 // Otherwise, call the destroy task directly.
514 DestroyTask(); 509 DestroyTask();
515 } 510 }
516 511
517 delete this; 512 delete this;
518 } 513 }
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
790 785
791 void V4L2VideoDecodeAccelerator::ScheduleDecodeBufferTaskIfNeeded() { 786 void V4L2VideoDecodeAccelerator::ScheduleDecodeBufferTaskIfNeeded() {
792 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 787 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
793 788
794 // If we're behind on tasks, schedule another one. 789 // If we're behind on tasks, schedule another one.
795 int buffers_to_decode = decoder_input_queue_.size(); 790 int buffers_to_decode = decoder_input_queue_.size();
796 if (decoder_current_bitstream_buffer_ != NULL) 791 if (decoder_current_bitstream_buffer_ != NULL)
797 buffers_to_decode++; 792 buffers_to_decode++;
798 if (decoder_decode_buffer_tasks_scheduled_ < buffers_to_decode) { 793 if (decoder_decode_buffer_tasks_scheduled_ < buffers_to_decode) {
799 decoder_decode_buffer_tasks_scheduled_++; 794 decoder_decode_buffer_tasks_scheduled_++;
800 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 795 decoder_thread_.message_loop()->PostTask(
801 &V4L2VideoDecodeAccelerator::DecodeBufferTask, 796 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::DecodeBufferTask,
802 base::Unretained(this))); 797 base::Unretained(this)));
803 } 798 }
804 } 799 }
805 800
806 bool V4L2VideoDecodeAccelerator::DecodeBufferInitial( 801 bool V4L2VideoDecodeAccelerator::DecodeBufferInitial(const void* data,
807 const void* data, size_t size, size_t* endpos) { 802 size_t size,
803 size_t* endpos) {
808 DVLOG(3) << "DecodeBufferInitial(): data=" << data << ", size=" << size; 804 DVLOG(3) << "DecodeBufferInitial(): data=" << data << ", size=" << size;
809 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 805 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
810 DCHECK_NE(decoder_state_, kUninitialized); 806 DCHECK_NE(decoder_state_, kUninitialized);
811 DCHECK_NE(decoder_state_, kDecoding); 807 DCHECK_NE(decoder_state_, kDecoding);
812 // Initial decode. We haven't been able to get output stream format info yet. 808 // Initial decode. We haven't been able to get output stream format info yet.
813 // Get it, and start decoding. 809 // Get it, and start decoding.
814 810
815 // Copy in and send to HW. 811 // Copy in and send to HW.
816 if (!AppendToInputFrame(data, size)) 812 if (!AppendToInputFrame(data, size))
817 return false; 813 return false;
(...skipping 28 matching lines...) Expand all
846 // Success! Setup our parameters. 842 // Success! Setup our parameters.
847 if (!CreateBuffersForFormat(format, visible_size)) 843 if (!CreateBuffersForFormat(format, visible_size))
848 return false; 844 return false;
849 } 845 }
850 846
851 decoder_state_ = kDecoding; 847 decoder_state_ = kDecoding;
852 ScheduleDecodeBufferTaskIfNeeded(); 848 ScheduleDecodeBufferTaskIfNeeded();
853 return true; 849 return true;
854 } 850 }
855 851
856 bool V4L2VideoDecodeAccelerator::DecodeBufferContinue( 852 bool V4L2VideoDecodeAccelerator::DecodeBufferContinue(const void* data,
857 const void* data, size_t size) { 853 size_t size) {
858 DVLOG(3) << "DecodeBufferContinue(): data=" << data << ", size=" << size; 854 DVLOG(3) << "DecodeBufferContinue(): data=" << data << ", size=" << size;
859 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 855 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
860 DCHECK_EQ(decoder_state_, kDecoding); 856 DCHECK_EQ(decoder_state_, kDecoding);
861 857
862 // Both of these calls will set kError state if they fail. 858 // Both of these calls will set kError state if they fail.
863 // Only flush the frame if it's complete. 859 // Only flush the frame if it's complete.
864 return (AppendToInputFrame(data, size) && 860 return (AppendToInputFrame(data, size) &&
865 (decoder_partial_frame_pending_ || FlushInputFrame())); 861 (decoder_partial_frame_pending_ || FlushInputFrame()));
866 } 862 }
867 863
868 bool V4L2VideoDecodeAccelerator::AppendToInputFrame( 864 bool V4L2VideoDecodeAccelerator::AppendToInputFrame(const void* data,
869 const void* data, size_t size) { 865 size_t size) {
870 DVLOG(3) << "AppendToInputFrame()"; 866 DVLOG(3) << "AppendToInputFrame()";
871 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 867 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
872 DCHECK_NE(decoder_state_, kUninitialized); 868 DCHECK_NE(decoder_state_, kUninitialized);
873 DCHECK_NE(decoder_state_, kResetting); 869 DCHECK_NE(decoder_state_, kResetting);
874 DCHECK_NE(decoder_state_, kError); 870 DCHECK_NE(decoder_state_, kError);
875 // This routine can handle data == NULL and size == 0, which occurs when 871 // This routine can handle data == NULL and size == 0, which occurs when
876 // we queue an empty buffer for the purposes of flushing the pipe. 872 // we queue an empty buffer for the purposes of flushing the pipe.
877 873
878 // Flush if we're too big 874 // Flush if we're too big
879 if (decoder_current_input_buffer_ != -1) { 875 if (decoder_current_input_buffer_ != -1) {
(...skipping 29 matching lines...) Expand all
909 905
910 DCHECK(data != NULL || size == 0); 906 DCHECK(data != NULL || size == 0);
911 if (size == 0) { 907 if (size == 0) {
912 // If we asked for an empty buffer, return now. We return only after 908 // If we asked for an empty buffer, return now. We return only after
913 // getting the next input buffer, since we might actually want an empty 909 // getting the next input buffer, since we might actually want an empty
914 // input buffer for flushing purposes. 910 // input buffer for flushing purposes.
915 return true; 911 return true;
916 } 912 }
917 913
918 // Copy in to the buffer. 914 // Copy in to the buffer.
919 InputRecord& input_record = 915 InputRecord& input_record = input_buffer_map_[decoder_current_input_buffer_];
920 input_buffer_map_[decoder_current_input_buffer_];
921 if (size > input_record.length - input_record.bytes_used) { 916 if (size > input_record.length - input_record.bytes_used) {
922 LOG(ERROR) << "AppendToInputFrame(): over-size frame, erroring"; 917 LOG(ERROR) << "AppendToInputFrame(): over-size frame, erroring";
923 NOTIFY_ERROR(UNREADABLE_INPUT); 918 NOTIFY_ERROR(UNREADABLE_INPUT);
924 return false; 919 return false;
925 } 920 }
926 memcpy(reinterpret_cast<uint8_t*>(input_record.address) + 921 memcpy(reinterpret_cast<uint8_t*>(input_record.address) +
927 input_record.bytes_used, 922 input_record.bytes_used,
928 data, size); 923 data, size);
929 input_record.bytes_used += size; 924 input_record.bytes_used += size;
930 925
931 return true; 926 return true;
932 } 927 }
933 928
934 bool V4L2VideoDecodeAccelerator::FlushInputFrame() { 929 bool V4L2VideoDecodeAccelerator::FlushInputFrame() {
935 DVLOG(3) << "FlushInputFrame()"; 930 DVLOG(3) << "FlushInputFrame()";
936 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 931 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
937 DCHECK_NE(decoder_state_, kUninitialized); 932 DCHECK_NE(decoder_state_, kUninitialized);
938 DCHECK_NE(decoder_state_, kResetting); 933 DCHECK_NE(decoder_state_, kResetting);
939 DCHECK_NE(decoder_state_, kError); 934 DCHECK_NE(decoder_state_, kError);
940 935
941 if (decoder_current_input_buffer_ == -1) 936 if (decoder_current_input_buffer_ == -1)
942 return true; 937 return true;
943 938
944 InputRecord& input_record = 939 InputRecord& input_record = input_buffer_map_[decoder_current_input_buffer_];
945 input_buffer_map_[decoder_current_input_buffer_];
946 DCHECK_NE(input_record.input_id, -1); 940 DCHECK_NE(input_record.input_id, -1);
947 DCHECK(input_record.input_id != kFlushBufferId || 941 DCHECK(input_record.input_id != kFlushBufferId ||
948 input_record.bytes_used == 0); 942 input_record.bytes_used == 0);
949 // * if input_id >= 0, this input buffer was prompted by a bitstream buffer we 943 // * if input_id >= 0, this input buffer was prompted by a bitstream buffer we
950 // got from the client. We can skip it if it is empty. 944 // got from the client. We can skip it if it is empty.
951 // * if input_id < 0 (should be kFlushBufferId in this case), this input 945 // * if input_id < 0 (should be kFlushBufferId in this case), this input
952 // buffer was prompted by a flush buffer, and should be queued even when 946 // buffer was prompted by a flush buffer, and should be queued even when
953 // empty. 947 // empty.
954 if (input_record.input_id >= 0 && input_record.bytes_used == 0) { 948 if (input_record.input_id >= 0 && input_record.bytes_used == 0) {
955 input_record.input_id = -1; 949 input_record.input_id = -1;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1006 1000
1007 // ServiceDeviceTask() should only ever be scheduled from DevicePollTask(), 1001 // ServiceDeviceTask() should only ever be scheduled from DevicePollTask(),
1008 // so either: 1002 // so either:
1009 // * device_poll_thread_ is running normally 1003 // * device_poll_thread_ is running normally
1010 // * device_poll_thread_ scheduled us, but then a ResetTask() or DestroyTask() 1004 // * device_poll_thread_ scheduled us, but then a ResetTask() or DestroyTask()
1011 // shut it down, in which case we're either in kResetting or kError states 1005 // shut it down, in which case we're either in kResetting or kError states
1012 // respectively, and we should have early-outed already. 1006 // respectively, and we should have early-outed already.
1013 DCHECK(device_poll_thread_.message_loop()); 1007 DCHECK(device_poll_thread_.message_loop());
1014 // Queue the DevicePollTask() now. 1008 // Queue the DevicePollTask() now.
1015 device_poll_thread_.message_loop()->PostTask( 1009 device_poll_thread_.message_loop()->PostTask(
1016 FROM_HERE, 1010 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::DevicePollTask,
1017 base::Bind(&V4L2VideoDecodeAccelerator::DevicePollTask, 1011 base::Unretained(this), poll_device));
1018 base::Unretained(this),
1019 poll_device));
1020 1012
1021 DVLOG(1) << "ServiceDeviceTask(): buffer counts: DEC[" 1013 DVLOG(1) << "ServiceDeviceTask(): buffer counts: DEC["
1022 << decoder_input_queue_.size() << "->" 1014 << decoder_input_queue_.size() << "->"
1023 << input_ready_queue_.size() << "] => DEVICE[" 1015 << input_ready_queue_.size() << "] => DEVICE["
1024 << free_input_buffers_.size() << "+" 1016 << free_input_buffers_.size() << "+"
1025 << input_buffer_queued_count_ << "/" 1017 << input_buffer_queued_count_ << "/"
1026 << input_buffer_map_.size() << "->" 1018 << input_buffer_map_.size() << "->"
1027 << free_output_buffers_.size() << "+" 1019 << free_output_buffers_.size() << "+"
1028 << output_buffer_queued_count_ << "/" 1020 << output_buffer_queued_count_ << "/"
1029 << output_buffer_map_.size() << "] => PROCESSOR[" 1021 << output_buffer_map_.size() << "] => PROCESSOR["
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1116 TRACE_EVENT0("Video Decoder", "V4L2VDA::Dequeue"); 1108 TRACE_EVENT0("Video Decoder", "V4L2VDA::Dequeue");
1117 1109
1118 // Dequeue completed input (VIDEO_OUTPUT) buffers, and recycle to the free 1110 // Dequeue completed input (VIDEO_OUTPUT) buffers, and recycle to the free
1119 // list. 1111 // list.
1120 while (input_buffer_queued_count_ > 0) { 1112 while (input_buffer_queued_count_ > 0) {
1121 DCHECK(input_streamon_); 1113 DCHECK(input_streamon_);
1122 struct v4l2_buffer dqbuf; 1114 struct v4l2_buffer dqbuf;
1123 struct v4l2_plane planes[1]; 1115 struct v4l2_plane planes[1];
1124 memset(&dqbuf, 0, sizeof(dqbuf)); 1116 memset(&dqbuf, 0, sizeof(dqbuf));
1125 memset(planes, 0, sizeof(planes)); 1117 memset(planes, 0, sizeof(planes));
1126 dqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1118 dqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1127 dqbuf.memory = V4L2_MEMORY_MMAP; 1119 dqbuf.memory = V4L2_MEMORY_MMAP;
1128 dqbuf.m.planes = planes; 1120 dqbuf.m.planes = planes;
1129 dqbuf.length = 1; 1121 dqbuf.length = 1;
1130 if (device_->Ioctl(VIDIOC_DQBUF, &dqbuf) != 0) { 1122 if (device_->Ioctl(VIDIOC_DQBUF, &dqbuf) != 0) {
1131 if (errno == EAGAIN) { 1123 if (errno == EAGAIN) {
1132 // EAGAIN if we're just out of buffers to dequeue. 1124 // EAGAIN if we're just out of buffers to dequeue.
1133 break; 1125 break;
1134 } 1126 }
1135 PLOG(ERROR) << "Dequeue(): ioctl() failed: VIDIOC_DQBUF"; 1127 PLOG(ERROR) << "Dequeue(): ioctl() failed: VIDIOC_DQBUF";
1136 NOTIFY_ERROR(PLATFORM_FAILURE); 1128 NOTIFY_ERROR(PLATFORM_FAILURE);
(...skipping 10 matching lines...) Expand all
1147 1139
1148 // Dequeue completed output (VIDEO_CAPTURE) buffers, and queue to the 1140 // Dequeue completed output (VIDEO_CAPTURE) buffers, and queue to the
1149 // completed queue. 1141 // completed queue.
1150 while (output_buffer_queued_count_ > 0) { 1142 while (output_buffer_queued_count_ > 0) {
1151 DCHECK(output_streamon_); 1143 DCHECK(output_streamon_);
1152 struct v4l2_buffer dqbuf; 1144 struct v4l2_buffer dqbuf;
1153 std::unique_ptr<struct v4l2_plane[]> planes( 1145 std::unique_ptr<struct v4l2_plane[]> planes(
1154 new v4l2_plane[output_planes_count_]); 1146 new v4l2_plane[output_planes_count_]);
1155 memset(&dqbuf, 0, sizeof(dqbuf)); 1147 memset(&dqbuf, 0, sizeof(dqbuf));
1156 memset(planes.get(), 0, sizeof(struct v4l2_plane) * output_planes_count_); 1148 memset(planes.get(), 0, sizeof(struct v4l2_plane) * output_planes_count_);
1157 dqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1149 dqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1158 dqbuf.memory = V4L2_MEMORY_MMAP; 1150 dqbuf.memory = V4L2_MEMORY_MMAP;
1159 dqbuf.m.planes = planes.get(); 1151 dqbuf.m.planes = planes.get();
1160 dqbuf.length = output_planes_count_; 1152 dqbuf.length = output_planes_count_;
1161 if (device_->Ioctl(VIDIOC_DQBUF, &dqbuf) != 0) { 1153 if (device_->Ioctl(VIDIOC_DQBUF, &dqbuf) != 0) {
1162 if (errno == EAGAIN) { 1154 if (errno == EAGAIN) {
1163 // EAGAIN if we're just out of buffers to dequeue. 1155 // EAGAIN if we're just out of buffers to dequeue.
1164 break; 1156 break;
1165 } 1157 }
1166 PLOG(ERROR) << "Dequeue(): ioctl() failed: VIDIOC_DQBUF"; 1158 PLOG(ERROR) << "Dequeue(): ioctl() failed: VIDIOC_DQBUF";
1167 NOTIFY_ERROR(PLATFORM_FAILURE); 1159 NOTIFY_ERROR(PLATFORM_FAILURE);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1224 DCHECK(!input_ready_queue_.empty()); 1216 DCHECK(!input_ready_queue_.empty());
1225 1217
1226 // Enqueue an input (VIDEO_OUTPUT) buffer. 1218 // Enqueue an input (VIDEO_OUTPUT) buffer.
1227 const int buffer = input_ready_queue_.front(); 1219 const int buffer = input_ready_queue_.front();
1228 InputRecord& input_record = input_buffer_map_[buffer]; 1220 InputRecord& input_record = input_buffer_map_[buffer];
1229 DCHECK(!input_record.at_device); 1221 DCHECK(!input_record.at_device);
1230 struct v4l2_buffer qbuf; 1222 struct v4l2_buffer qbuf;
1231 struct v4l2_plane qbuf_plane; 1223 struct v4l2_plane qbuf_plane;
1232 memset(&qbuf, 0, sizeof(qbuf)); 1224 memset(&qbuf, 0, sizeof(qbuf));
1233 memset(&qbuf_plane, 0, sizeof(qbuf_plane)); 1225 memset(&qbuf_plane, 0, sizeof(qbuf_plane));
1234 qbuf.index = buffer; 1226 qbuf.index = buffer;
1235 qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1227 qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1236 qbuf.timestamp.tv_sec = input_record.input_id; 1228 qbuf.timestamp.tv_sec = input_record.input_id;
1237 qbuf.memory = V4L2_MEMORY_MMAP; 1229 qbuf.memory = V4L2_MEMORY_MMAP;
1238 qbuf.m.planes = &qbuf_plane; 1230 qbuf.m.planes = &qbuf_plane;
1239 qbuf.m.planes[0].bytesused = input_record.bytes_used; 1231 qbuf.m.planes[0].bytesused = input_record.bytes_used;
1240 qbuf.length = 1; 1232 qbuf.length = 1;
1241 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QBUF, &qbuf); 1233 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QBUF, &qbuf);
1242 input_ready_queue_.pop(); 1234 input_ready_queue_.pop();
1243 input_record.at_device = true; 1235 input_record.at_device = true;
1244 input_buffer_queued_count_++; 1236 input_buffer_queued_count_++;
1245 DVLOG(3) << "EnqueueInputRecord(): enqueued input_id=" 1237 DVLOG(3) << "EnqueueInputRecord(): enqueued input_id="
1246 << input_record.input_id << " size=" << input_record.bytes_used; 1238 << input_record.input_id << " size=" << input_record.bytes_used;
1247 return true; 1239 return true;
1248 } 1240 }
1249 1241
1250 bool V4L2VideoDecodeAccelerator::EnqueueOutputRecord() { 1242 bool V4L2VideoDecodeAccelerator::EnqueueOutputRecord() {
1251 DVLOG(3) << "EnqueueOutputRecord()"; 1243 DVLOG(3) << "EnqueueOutputRecord()";
1252 DCHECK(!free_output_buffers_.empty()); 1244 DCHECK(!free_output_buffers_.empty());
1253 1245
1254 // Enqueue an output (VIDEO_CAPTURE) buffer. 1246 // Enqueue an output (VIDEO_CAPTURE) buffer.
1255 const int buffer = free_output_buffers_.front(); 1247 const int buffer = free_output_buffers_.front();
1256 OutputRecord& output_record = output_buffer_map_[buffer]; 1248 OutputRecord& output_record = output_buffer_map_[buffer];
(...skipping 15 matching lines...) Expand all
1272 LOG(ERROR) << __func__ << " eglDestroySyncKHR failed!"; 1264 LOG(ERROR) << __func__ << " eglDestroySyncKHR failed!";
1273 NOTIFY_ERROR(PLATFORM_FAILURE); 1265 NOTIFY_ERROR(PLATFORM_FAILURE);
1274 return false; 1266 return false;
1275 } 1267 }
1276 output_record.egl_sync = EGL_NO_SYNC_KHR; 1268 output_record.egl_sync = EGL_NO_SYNC_KHR;
1277 } 1269 }
1278 struct v4l2_buffer qbuf; 1270 struct v4l2_buffer qbuf;
1279 std::unique_ptr<struct v4l2_plane[]> qbuf_planes( 1271 std::unique_ptr<struct v4l2_plane[]> qbuf_planes(
1280 new v4l2_plane[output_planes_count_]); 1272 new v4l2_plane[output_planes_count_]);
1281 memset(&qbuf, 0, sizeof(qbuf)); 1273 memset(&qbuf, 0, sizeof(qbuf));
1282 memset( 1274 memset(qbuf_planes.get(), 0,
1283 qbuf_planes.get(), 0, sizeof(struct v4l2_plane) * output_planes_count_); 1275 sizeof(struct v4l2_plane) * output_planes_count_);
1284 qbuf.index = buffer; 1276 qbuf.index = buffer;
1285 qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1277 qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1286 qbuf.memory = V4L2_MEMORY_MMAP; 1278 qbuf.memory = V4L2_MEMORY_MMAP;
1287 qbuf.m.planes = qbuf_planes.get(); 1279 qbuf.m.planes = qbuf_planes.get();
1288 qbuf.length = output_planes_count_; 1280 qbuf.length = output_planes_count_;
1289 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QBUF, &qbuf); 1281 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QBUF, &qbuf);
1290 free_output_buffers_.pop(); 1282 free_output_buffers_.pop();
1291 output_record.state = kAtDevice; 1283 output_record.state = kAtDevice;
1292 output_buffer_queued_count_++; 1284 output_buffer_queued_count_++;
1293 return true; 1285 return true;
1294 } 1286 }
1295 1287
1296 void V4L2VideoDecodeAccelerator::ReusePictureBufferTask( 1288 void V4L2VideoDecodeAccelerator::ReusePictureBufferTask(
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
1472 image_processor_bitstream_buffer_ids_.pop(); 1464 image_processor_bitstream_buffer_ids_.pop();
1473 1465
1474 // If we were flushing, we'll never return any more BitstreamBuffers or 1466 // If we were flushing, we'll never return any more BitstreamBuffers or
1475 // PictureBuffers; they have all been dropped and returned by now. 1467 // PictureBuffers; they have all been dropped and returned by now.
1476 NotifyFlushDoneIfNeeded(); 1468 NotifyFlushDoneIfNeeded();
1477 1469
1478 // Mark that we're resetting, then enqueue a ResetDoneTask(). All intervening 1470 // Mark that we're resetting, then enqueue a ResetDoneTask(). All intervening
1479 // jobs will early-out in the kResetting state. 1471 // jobs will early-out in the kResetting state.
1480 decoder_state_ = kResetting; 1472 decoder_state_ = kResetting;
1481 SendPictureReady(); // Send all pending PictureReady. 1473 SendPictureReady(); // Send all pending PictureReady.
1482 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 1474 decoder_thread_.message_loop()->PostTask(
1483 &V4L2VideoDecodeAccelerator::ResetDoneTask, base::Unretained(this))); 1475 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::ResetDoneTask,
1476 base::Unretained(this)));
1484 } 1477 }
1485 1478
1486 void V4L2VideoDecodeAccelerator::ResetDoneTask() { 1479 void V4L2VideoDecodeAccelerator::ResetDoneTask() {
1487 DVLOG(3) << "ResetDoneTask()"; 1480 DVLOG(3) << "ResetDoneTask()";
1488 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1481 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1489 TRACE_EVENT0("Video Decoder", "V4L2VDA::ResetDoneTask"); 1482 TRACE_EVENT0("Video Decoder", "V4L2VDA::ResetDoneTask");
1490 1483
1491 if (decoder_state_ == kError) { 1484 if (decoder_state_ == kError) {
1492 DVLOG(2) << "ResetDoneTask(): early out: kError state"; 1485 DVLOG(2) << "ResetDoneTask(): early out: kError state";
1493 return; 1486 return;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1547 DVLOG(3) << "StartDevicePoll()"; 1540 DVLOG(3) << "StartDevicePoll()";
1548 DCHECK(!device_poll_thread_.IsRunning()); 1541 DCHECK(!device_poll_thread_.IsRunning());
1549 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1542 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1550 1543
1551 // Start up the device poll thread and schedule its first DevicePollTask(). 1544 // Start up the device poll thread and schedule its first DevicePollTask().
1552 if (!device_poll_thread_.Start()) { 1545 if (!device_poll_thread_.Start()) {
1553 LOG(ERROR) << "StartDevicePoll(): Device thread failed to start"; 1546 LOG(ERROR) << "StartDevicePoll(): Device thread failed to start";
1554 NOTIFY_ERROR(PLATFORM_FAILURE); 1547 NOTIFY_ERROR(PLATFORM_FAILURE);
1555 return false; 1548 return false;
1556 } 1549 }
1557 device_poll_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 1550 device_poll_thread_.message_loop()->PostTask(
1558 &V4L2VideoDecodeAccelerator::DevicePollTask, 1551 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::DevicePollTask,
1559 base::Unretained(this), 1552 base::Unretained(this), 0));
1560 0));
1561 1553
1562 return true; 1554 return true;
1563 } 1555 }
1564 1556
1565 bool V4L2VideoDecodeAccelerator::StopDevicePoll() { 1557 bool V4L2VideoDecodeAccelerator::StopDevicePoll() {
1566 DVLOG(3) << "StopDevicePoll()"; 1558 DVLOG(3) << "StopDevicePoll()";
1567 1559
1568 if (!device_poll_thread_.IsRunning()) 1560 if (!device_poll_thread_.IsRunning())
1569 return true; 1561 return true;
1570 1562
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
1708 1700
1709 bool event_pending = false; 1701 bool event_pending = false;
1710 1702
1711 if (!device_->Poll(poll_device, &event_pending)) { 1703 if (!device_->Poll(poll_device, &event_pending)) {
1712 NOTIFY_ERROR(PLATFORM_FAILURE); 1704 NOTIFY_ERROR(PLATFORM_FAILURE);
1713 return; 1705 return;
1714 } 1706 }
1715 1707
1716 // All processing should happen on ServiceDeviceTask(), since we shouldn't 1708 // All processing should happen on ServiceDeviceTask(), since we shouldn't
1717 // touch decoder state from this thread. 1709 // touch decoder state from this thread.
1718 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 1710 decoder_thread_.message_loop()->PostTask(
1719 &V4L2VideoDecodeAccelerator::ServiceDeviceTask, 1711 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::ServiceDeviceTask,
1720 base::Unretained(this), event_pending)); 1712 base::Unretained(this), event_pending));
1721 } 1713 }
1722 1714
1723 void V4L2VideoDecodeAccelerator::NotifyError(Error error) { 1715 void V4L2VideoDecodeAccelerator::NotifyError(Error error) {
1724 DVLOG(2) << "NotifyError()"; 1716 DVLOG(2) << "NotifyError()";
1725 1717
1726 if (!child_task_runner_->BelongsToCurrentThread()) { 1718 if (!child_task_runner_->BelongsToCurrentThread()) {
1727 child_task_runner_->PostTask( 1719 child_task_runner_->PostTask(
1728 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::NotifyError, 1720 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::NotifyError,
1729 weak_this_, error)); 1721 weak_this_, error));
1730 return; 1722 return;
1731 } 1723 }
1732 1724
1733 if (client_) { 1725 if (client_) {
1734 client_->NotifyError(error); 1726 client_->NotifyError(error);
1735 client_ptr_factory_.reset(); 1727 client_ptr_factory_.reset();
1736 } 1728 }
1737 } 1729 }
1738 1730
1739 void V4L2VideoDecodeAccelerator::SetErrorState(Error error) { 1731 void V4L2VideoDecodeAccelerator::SetErrorState(Error error) {
1740 // We can touch decoder_state_ only if this is the decoder thread or the 1732 // We can touch decoder_state_ only if this is the decoder thread or the
1741 // decoder thread isn't running. 1733 // decoder thread isn't running.
1742 if (decoder_thread_.message_loop() != NULL && 1734 if (decoder_thread_.message_loop() != NULL &&
1743 decoder_thread_.message_loop() != base::MessageLoop::current()) { 1735 decoder_thread_.message_loop() != base::MessageLoop::current()) {
1744 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 1736 decoder_thread_.message_loop()->PostTask(
1745 &V4L2VideoDecodeAccelerator::SetErrorState, 1737 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::SetErrorState,
1746 base::Unretained(this), error)); 1738 base::Unretained(this), error));
1747 return; 1739 return;
1748 } 1740 }
1749 1741
1750 // Post NotifyError only if we are already initialized, as the API does 1742 // Post NotifyError only if we are already initialized, as the API does
1751 // not allow doing so before that. 1743 // not allow doing so before that.
1752 if (decoder_state_ != kError && decoder_state_ != kUninitialized) 1744 if (decoder_state_ != kError && decoder_state_ != kUninitialized)
1753 NotifyError(error); 1745 NotifyError(error);
1754 1746
1755 decoder_state_ = kError; 1747 decoder_state_ = kError;
1756 } 1748 }
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1854 1846
1855 bool V4L2VideoDecodeAccelerator::CreateInputBuffers() { 1847 bool V4L2VideoDecodeAccelerator::CreateInputBuffers() {
1856 DVLOG(3) << "CreateInputBuffers()"; 1848 DVLOG(3) << "CreateInputBuffers()";
1857 // We always run this as we prepare to initialize. 1849 // We always run this as we prepare to initialize.
1858 DCHECK_EQ(decoder_state_, kUninitialized); 1850 DCHECK_EQ(decoder_state_, kUninitialized);
1859 DCHECK(!input_streamon_); 1851 DCHECK(!input_streamon_);
1860 DCHECK(input_buffer_map_.empty()); 1852 DCHECK(input_buffer_map_.empty());
1861 1853
1862 struct v4l2_requestbuffers reqbufs; 1854 struct v4l2_requestbuffers reqbufs;
1863 memset(&reqbufs, 0, sizeof(reqbufs)); 1855 memset(&reqbufs, 0, sizeof(reqbufs));
1864 reqbufs.count = kInputBufferCount; 1856 reqbufs.count = kInputBufferCount;
1865 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1857 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1866 reqbufs.memory = V4L2_MEMORY_MMAP; 1858 reqbufs.memory = V4L2_MEMORY_MMAP;
1867 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_REQBUFS, &reqbufs); 1859 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_REQBUFS, &reqbufs);
1868 input_buffer_map_.resize(reqbufs.count); 1860 input_buffer_map_.resize(reqbufs.count);
1869 for (size_t i = 0; i < input_buffer_map_.size(); ++i) { 1861 for (size_t i = 0; i < input_buffer_map_.size(); ++i) {
1870 free_input_buffers_.push_back(i); 1862 free_input_buffers_.push_back(i);
1871 1863
1872 // Query for the MEMORY_MMAP pointer. 1864 // Query for the MEMORY_MMAP pointer.
1873 struct v4l2_plane planes[1]; 1865 struct v4l2_plane planes[1];
1874 struct v4l2_buffer buffer; 1866 struct v4l2_buffer buffer;
1875 memset(&buffer, 0, sizeof(buffer)); 1867 memset(&buffer, 0, sizeof(buffer));
1876 memset(planes, 0, sizeof(planes)); 1868 memset(planes, 0, sizeof(planes));
1877 buffer.index = i; 1869 buffer.index = i;
1878 buffer.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1870 buffer.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1879 buffer.memory = V4L2_MEMORY_MMAP; 1871 buffer.memory = V4L2_MEMORY_MMAP;
1880 buffer.m.planes = planes; 1872 buffer.m.planes = planes;
1881 buffer.length = 1; 1873 buffer.length = 1;
1882 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYBUF, &buffer); 1874 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYBUF, &buffer);
1883 void* address = device_->Mmap(NULL, 1875 void* address =
1884 buffer.m.planes[0].length, 1876 device_->Mmap(NULL, buffer.m.planes[0].length, PROT_READ | PROT_WRITE,
1885 PROT_READ | PROT_WRITE, 1877 MAP_SHARED, buffer.m.planes[0].m.mem_offset);
1886 MAP_SHARED,
1887 buffer.m.planes[0].m.mem_offset);
1888 if (address == MAP_FAILED) { 1878 if (address == MAP_FAILED) {
1889 PLOG(ERROR) << "CreateInputBuffers(): mmap() failed"; 1879 PLOG(ERROR) << "CreateInputBuffers(): mmap() failed";
1890 return false; 1880 return false;
1891 } 1881 }
1892 input_buffer_map_[i].address = address; 1882 input_buffer_map_[i].address = address;
1893 input_buffer_map_[i].length = buffer.m.planes[0].length; 1883 input_buffer_map_[i].length = buffer.m.planes[0].length;
1894 } 1884 }
1895 1885
1896 return true; 1886 return true;
1897 } 1887 }
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
2151 DCHECK(child_task_runner_->BelongsToCurrentThread()); 2141 DCHECK(child_task_runner_->BelongsToCurrentThread());
2152 DVLOG(3) << "ResolutionChangeDestroyBuffers()"; 2142 DVLOG(3) << "ResolutionChangeDestroyBuffers()";
2153 2143
2154 if (!DestroyOutputBuffers()) { 2144 if (!DestroyOutputBuffers()) {
2155 LOG(ERROR) << __func__ << " Failed destroying output buffers."; 2145 LOG(ERROR) << __func__ << " Failed destroying output buffers.";
2156 NOTIFY_ERROR(PLATFORM_FAILURE); 2146 NOTIFY_ERROR(PLATFORM_FAILURE);
2157 return; 2147 return;
2158 } 2148 }
2159 2149
2160 // Finish resolution change on decoder thread. 2150 // Finish resolution change on decoder thread.
2161 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 2151 decoder_thread_.message_loop()->PostTask(
2162 &V4L2VideoDecodeAccelerator::FinishResolutionChange, 2152 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::FinishResolutionChange,
2163 base::Unretained(this))); 2153 base::Unretained(this)));
2164 } 2154 }
2165 2155
2166 void V4L2VideoDecodeAccelerator::SendPictureReady() { 2156 void V4L2VideoDecodeAccelerator::SendPictureReady() {
2167 DVLOG(3) << "SendPictureReady()"; 2157 DVLOG(3) << "SendPictureReady()";
2168 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 2158 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
2169 bool resetting_or_flushing = 2159 bool resetting_or_flushing =
2170 (decoder_state_ == kResetting || decoder_flushing_); 2160 (decoder_state_ == kResetting || decoder_flushing_);
2171 while (pending_picture_ready_.size() > 0) { 2161 while (pending_picture_ready_.size() > 0) {
2172 bool cleared = pending_picture_ready_.front().cleared; 2162 bool cleared = pending_picture_ready_.front().cleared;
2173 const media::Picture& picture = pending_picture_ready_.front().picture; 2163 const media::Picture& picture = pending_picture_ready_.front().picture;
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
2251 free_output_buffers_.push(output_buffer_index); 2241 free_output_buffers_.push(output_buffer_index);
2252 Enqueue(); 2242 Enqueue();
2253 } 2243 }
2254 } 2244 }
2255 2245
2256 void V4L2VideoDecodeAccelerator::ImageProcessorError() { 2246 void V4L2VideoDecodeAccelerator::ImageProcessorError() {
2257 LOG(ERROR) << "Image processor error"; 2247 LOG(ERROR) << "Image processor error";
2258 NOTIFY_ERROR(PLATFORM_FAILURE); 2248 NOTIFY_ERROR(PLATFORM_FAILURE);
2259 } 2249 }
2260 2250
2261 } // namespace content 2251 } // namespace media
OLDNEW
« no previous file with comments | « media/gpu/v4l2_video_decode_accelerator.h ('k') | media/gpu/v4l2_video_encode_accelerator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698