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

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

Issue 1882373004: Migrate content/common/gpu/media code to media/gpu (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix several more bot-identified build issues Created 4 years, 8 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
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 <dlfcn.h> 5 #include <dlfcn.h>
6 #include <errno.h> 6 #include <errno.h>
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <linux/videodev2.h> 8 #include <linux/videodev2.h>
9 #include <poll.h> 9 #include <poll.h>
10 #include <string.h> 10 #include <string.h>
11 #include <sys/eventfd.h> 11 #include <sys/eventfd.h>
12 #include <sys/ioctl.h> 12 #include <sys/ioctl.h>
13 #include <sys/mman.h> 13 #include <sys/mman.h>
14 14
15 #include "base/bind.h" 15 #include "base/bind.h"
16 #include "base/command_line.h" 16 #include "base/command_line.h"
17 #include "base/macros.h" 17 #include "base/macros.h"
18 #include "base/message_loop/message_loop.h" 18 #include "base/message_loop/message_loop.h"
19 #include "base/numerics/safe_conversions.h" 19 #include "base/numerics/safe_conversions.h"
20 #include "base/thread_task_runner_handle.h" 20 #include "base/thread_task_runner_handle.h"
21 #include "base/trace_event/trace_event.h" 21 #include "base/trace_event/trace_event.h"
22 #include "build/build_config.h" 22 #include "build/build_config.h"
23 #include "content/common/gpu/media/shared_memory_region.h"
24 #include "content/common/gpu/media/v4l2_video_decode_accelerator.h"
25 #include "media/base/media_switches.h" 23 #include "media/base/media_switches.h"
26 #include "media/filters/h264_parser.h" 24 #include "media/filters/h264_parser.h"
25 #include "media/gpu/shared_memory_region.h"
26 #include "media/gpu/v4l2_video_decode_accelerator.h"
27 #include "ui/gfx/geometry/rect.h" 27 #include "ui/gfx/geometry/rect.h"
28 #include "ui/gl/gl_context.h" 28 #include "ui/gl/gl_context.h"
29 #include "ui/gl/scoped_binders.h" 29 #include "ui/gl/scoped_binders.h"
30 30
31 #define NOTIFY_ERROR(x) \ 31 #define NOTIFY_ERROR(x) \
32 do { \ 32 do { \
33 LOG(ERROR) << "Setting error state:" << x; \ 33 LOG(ERROR) << "Setting error state:" << x; \
34 SetErrorState(x); \ 34 SetErrorState(x); \
35 } while (0) 35 } while (0)
36 36
37 #define IOCTL_OR_ERROR_RETURN_VALUE(type, arg, value, type_str) \ 37 #define IOCTL_OR_ERROR_RETURN_VALUE(type, arg, value, type_str) \
38 do { \ 38 do { \
39 if (device_->Ioctl(type, arg) != 0) { \ 39 if (device_->Ioctl(type, arg) != 0) { \
40 PLOG(ERROR) << __func__ << "(): ioctl() failed: " << type_str; \ 40 PLOG(ERROR) << __func__ << "(): ioctl() failed: " << type_str; \
41 NOTIFY_ERROR(PLATFORM_FAILURE); \ 41 NOTIFY_ERROR(PLATFORM_FAILURE); \
42 return value; \ 42 return value; \
43 } \ 43 } \
44 } while (0) 44 } while (0)
45 45
46 #define IOCTL_OR_ERROR_RETURN(type, arg) \ 46 #define IOCTL_OR_ERROR_RETURN(type, arg) \
47 IOCTL_OR_ERROR_RETURN_VALUE(type, arg, ((void)0), #type) 47 IOCTL_OR_ERROR_RETURN_VALUE(type, arg, ((void)0), #type)
48 48
49 #define IOCTL_OR_ERROR_RETURN_FALSE(type, arg) \ 49 #define IOCTL_OR_ERROR_RETURN_FALSE(type, arg) \
50 IOCTL_OR_ERROR_RETURN_VALUE(type, arg, false, #type) 50 IOCTL_OR_ERROR_RETURN_VALUE(type, arg, false, #type)
51 51
52 #define IOCTL_OR_LOG_ERROR(type, arg) \ 52 #define IOCTL_OR_LOG_ERROR(type, arg) \
53 do { \ 53 do { \
54 if (device_->Ioctl(type, arg) != 0) \ 54 if (device_->Ioctl(type, arg) != 0) \
55 PLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \ 55 PLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \
56 } while (0) 56 } while (0)
57 57
58 namespace content { 58 namespace media {
59 59
60 // static 60 // static
61 const uint32_t V4L2VideoDecodeAccelerator::supported_input_fourccs_[] = { 61 const uint32_t V4L2VideoDecodeAccelerator::supported_input_fourccs_[] = {
62 V4L2_PIX_FMT_H264, V4L2_PIX_FMT_VP8, V4L2_PIX_FMT_VP9, 62 V4L2_PIX_FMT_H264, V4L2_PIX_FMT_VP8, V4L2_PIX_FMT_VP9,
63 }; 63 };
64 64
65 struct V4L2VideoDecodeAccelerator::BitstreamBufferRef { 65 struct V4L2VideoDecodeAccelerator::BitstreamBufferRef {
66 BitstreamBufferRef( 66 BitstreamBufferRef(
67 base::WeakPtr<Client>& client, 67 base::WeakPtr<Client>& client,
68 scoped_refptr<base::SingleThreadTaskRunner>& client_task_runner, 68 scoped_refptr<base::SingleThreadTaskRunner>& client_task_runner,
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 input_id(input_id) {} 102 input_id(input_id) {}
103 103
104 V4L2VideoDecodeAccelerator::BitstreamBufferRef::~BitstreamBufferRef() { 104 V4L2VideoDecodeAccelerator::BitstreamBufferRef::~BitstreamBufferRef() {
105 if (input_id >= 0) { 105 if (input_id >= 0) {
106 client_task_runner->PostTask( 106 client_task_runner->PostTask(
107 FROM_HERE, 107 FROM_HERE,
108 base::Bind(&Client::NotifyEndOfBitstreamBuffer, client, input_id)); 108 base::Bind(&Client::NotifyEndOfBitstreamBuffer, client, input_id));
109 } 109 }
110 } 110 }
111 111
112 V4L2VideoDecodeAccelerator::EGLSyncKHRRef::EGLSyncKHRRef( 112 V4L2VideoDecodeAccelerator::EGLSyncKHRRef::EGLSyncKHRRef(EGLDisplay egl_display,
113 EGLDisplay egl_display, EGLSyncKHR egl_sync) 113 EGLSyncKHR egl_sync)
114 : egl_display(egl_display), 114 : egl_display(egl_display), egl_sync(egl_sync) {}
115 egl_sync(egl_sync) {
116 }
117 115
118 V4L2VideoDecodeAccelerator::EGLSyncKHRRef::~EGLSyncKHRRef() { 116 V4L2VideoDecodeAccelerator::EGLSyncKHRRef::~EGLSyncKHRRef() {
119 // We don't check for eglDestroySyncKHR failures, because if we get here 117 // We don't check for eglDestroySyncKHR failures, because if we get here
120 // with a valid sync object, something went wrong and we are getting 118 // with a valid sync object, something went wrong and we are getting
121 // destroyed anyway. 119 // destroyed anyway.
122 if (egl_sync != EGL_NO_SYNC_KHR) 120 if (egl_sync != EGL_NO_SYNC_KHR)
123 eglDestroySyncKHR(egl_display, egl_sync); 121 eglDestroySyncKHR(egl_display, egl_sync);
124 } 122 }
125 123
126 V4L2VideoDecodeAccelerator::InputRecord::InputRecord() 124 V4L2VideoDecodeAccelerator::InputRecord::InputRecord()
127 : at_device(false), 125 : at_device(false), address(NULL), length(0), bytes_used(0), input_id(-1) {}
128 address(NULL),
129 length(0),
130 bytes_used(0),
131 input_id(-1) {
132 }
133 126
134 V4L2VideoDecodeAccelerator::InputRecord::~InputRecord() { 127 V4L2VideoDecodeAccelerator::InputRecord::~InputRecord() {}
135 }
136 128
137 V4L2VideoDecodeAccelerator::OutputRecord::OutputRecord() 129 V4L2VideoDecodeAccelerator::OutputRecord::OutputRecord()
138 : at_device(false), 130 : at_device(false),
139 at_client(false), 131 at_client(false),
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 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 return false; 244 return false;
254 } 245 }
255 #endif 246 #endif
256 247
257 // Capabilities check. 248 // Capabilities check.
258 struct v4l2_capability caps; 249 struct v4l2_capability caps;
259 const __u32 kCapsRequired = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; 250 const __u32 kCapsRequired = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
260 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps); 251 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps);
261 if ((caps.capabilities & kCapsRequired) != kCapsRequired) { 252 if ((caps.capabilities & kCapsRequired) != kCapsRequired) {
262 LOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP" 253 LOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP"
263 ", caps check failed: 0x" << std::hex << caps.capabilities; 254 ", caps check failed: 0x"
255 << std::hex << caps.capabilities;
264 return false; 256 return false;
265 } 257 }
266 258
267 if (!SetupFormats()) 259 if (!SetupFormats())
268 return false; 260 return false;
269 261
270 // Subscribe to the resolution change event. 262 // Subscribe to the resolution change event.
271 struct v4l2_event_subscription sub; 263 struct v4l2_event_subscription sub;
272 memset(&sub, 0, sizeof(sub)); 264 memset(&sub, 0, sizeof(sub));
273 sub.type = V4L2_EVENT_SOURCE_CHANGE; 265 sub.type = V4L2_EVENT_SOURCE_CHANGE;
274 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_SUBSCRIBE_EVENT, &sub); 266 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_SUBSCRIBE_EVENT, &sub);
275 267
276 if (video_profile_ >= media::H264PROFILE_MIN && 268 if (video_profile_ >= media::H264PROFILE_MIN &&
277 video_profile_ <= media::H264PROFILE_MAX) { 269 video_profile_ <= media::H264PROFILE_MAX) {
278 decoder_h264_parser_.reset(new media::H264Parser()); 270 decoder_h264_parser_.reset(new media::H264Parser());
279 } 271 }
280 272
281 if (!CreateInputBuffers()) 273 if (!CreateInputBuffers())
282 return false; 274 return false;
283 275
284 if (!decoder_thread_.Start()) { 276 if (!decoder_thread_.Start()) {
285 LOG(ERROR) << "Initialize(): decoder thread failed to start"; 277 LOG(ERROR) << "Initialize(): decoder thread failed to start";
286 return false; 278 return false;
287 } 279 }
288 280
289 decoder_state_ = kInitialized; 281 decoder_state_ = kInitialized;
290 282
291 // StartDevicePoll will NOTIFY_ERROR on failure, so IgnoreResult is fine here. 283 // StartDevicePoll will NOTIFY_ERROR on failure, so IgnoreResult is fine here.
292 decoder_thread_.message_loop()->PostTask( 284 decoder_thread_.message_loop()->PostTask(
293 FROM_HERE, 285 FROM_HERE, base::Bind(base::IgnoreResult(
294 base::Bind( 286 &V4L2VideoDecodeAccelerator::StartDevicePoll),
295 base::IgnoreResult(&V4L2VideoDecodeAccelerator::StartDevicePoll), 287 base::Unretained(this)));
296 base::Unretained(this)));
297 288
298 return true; 289 return true;
299 } 290 }
300 291
301 void V4L2VideoDecodeAccelerator::Decode( 292 void V4L2VideoDecodeAccelerator::Decode(
302 const media::BitstreamBuffer& bitstream_buffer) { 293 const media::BitstreamBuffer& bitstream_buffer) {
303 DVLOG(1) << "Decode(): input_id=" << bitstream_buffer.id() 294 DVLOG(1) << "Decode(): input_id=" << bitstream_buffer.id()
304 << ", size=" << bitstream_buffer.size(); 295 << ", size=" << bitstream_buffer.size();
305 DCHECK(decode_task_runner_->BelongsToCurrentThread()); 296 DCHECK(decode_task_runner_->BelongsToCurrentThread());
306 297
307 if (bitstream_buffer.id() < 0) { 298 if (bitstream_buffer.id() < 0) {
308 LOG(ERROR) << "Invalid bitstream_buffer, id: " << bitstream_buffer.id(); 299 LOG(ERROR) << "Invalid bitstream_buffer, id: " << bitstream_buffer.id();
309 if (base::SharedMemory::IsHandleValid(bitstream_buffer.handle())) 300 if (base::SharedMemory::IsHandleValid(bitstream_buffer.handle()))
310 base::SharedMemory::CloseHandle(bitstream_buffer.handle()); 301 base::SharedMemory::CloseHandle(bitstream_buffer.handle());
311 NOTIFY_ERROR(INVALID_ARGUMENT); 302 NOTIFY_ERROR(INVALID_ARGUMENT);
312 return; 303 return;
313 } 304 }
314 305
315 // DecodeTask() will take care of running a DecodeBufferTask(). 306 // DecodeTask() will take care of running a DecodeBufferTask().
316 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 307 decoder_thread_.message_loop()->PostTask(
317 &V4L2VideoDecodeAccelerator::DecodeTask, base::Unretained(this), 308 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::DecodeTask,
318 bitstream_buffer)); 309 base::Unretained(this), bitstream_buffer));
319 } 310 }
320 311
321 void V4L2VideoDecodeAccelerator::AssignPictureBuffers( 312 void V4L2VideoDecodeAccelerator::AssignPictureBuffers(
322 const std::vector<media::PictureBuffer>& buffers) { 313 const std::vector<media::PictureBuffer>& buffers) {
323 DVLOG(3) << "AssignPictureBuffers(): buffer_count=" << buffers.size(); 314 DVLOG(3) << "AssignPictureBuffers(): buffer_count=" << buffers.size();
324 DCHECK(child_task_runner_->BelongsToCurrentThread()); 315 DCHECK(child_task_runner_->BelongsToCurrentThread());
325 316
326 const uint32_t req_buffer_count = 317 const uint32_t req_buffer_count =
327 output_dpb_size_ + kDpbOutputBufferExtraCount; 318 output_dpb_size_ + kDpbOutputBufferExtraCount;
328 319
329 if (buffers.size() < req_buffer_count) { 320 if (buffers.size() < req_buffer_count) {
330 LOG(ERROR) << "AssignPictureBuffers(): Failed to provide requested picture" 321 LOG(ERROR) << "AssignPictureBuffers(): Failed to provide requested picture"
331 " buffers. (Got " << buffers.size() 322 " buffers. (Got "
332 << ", requested " << req_buffer_count << ")"; 323 << buffers.size() << ", requested " << req_buffer_count << ")";
333 NOTIFY_ERROR(INVALID_ARGUMENT); 324 NOTIFY_ERROR(INVALID_ARGUMENT);
334 return; 325 return;
335 } 326 }
336 327
337 gfx::GLContext* gl_context = get_gl_context_cb_.Run(); 328 gfx::GLContext* gl_context = get_gl_context_cb_.Run();
338 if (!gl_context || !make_context_current_cb_.Run()) { 329 if (!gl_context || !make_context_current_cb_.Run()) {
339 LOG(ERROR) << "AssignPictureBuffers(): could not make context current"; 330 LOG(ERROR) << "AssignPictureBuffers(): could not make context current";
340 NOTIFY_ERROR(PLATFORM_FAILURE); 331 NOTIFY_ERROR(PLATFORM_FAILURE);
341 return; 332 return;
342 } 333 }
343 334
344 gfx::ScopedTextureBinder bind_restore(GL_TEXTURE_EXTERNAL_OES, 0); 335 gfx::ScopedTextureBinder bind_restore(GL_TEXTURE_EXTERNAL_OES, 0);
345 336
346 // It's safe to manipulate all the buffer state here, because the decoder 337 // It's safe to manipulate all the buffer state here, because the decoder
347 // thread is waiting on pictures_assigned_. 338 // thread is waiting on pictures_assigned_.
348 339
349 // Allocate the output buffers. 340 // Allocate the output buffers.
350 struct v4l2_requestbuffers reqbufs; 341 struct v4l2_requestbuffers reqbufs;
351 memset(&reqbufs, 0, sizeof(reqbufs)); 342 memset(&reqbufs, 0, sizeof(reqbufs));
352 reqbufs.count = buffers.size(); 343 reqbufs.count = buffers.size();
353 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 344 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
354 reqbufs.memory = V4L2_MEMORY_MMAP; 345 reqbufs.memory = V4L2_MEMORY_MMAP;
355 IOCTL_OR_ERROR_RETURN(VIDIOC_REQBUFS, &reqbufs); 346 IOCTL_OR_ERROR_RETURN(VIDIOC_REQBUFS, &reqbufs);
356 347
357 if (reqbufs.count != buffers.size()) { 348 if (reqbufs.count != buffers.size()) {
358 DLOG(ERROR) << "Could not allocate enough output buffers"; 349 DLOG(ERROR) << "Could not allocate enough output buffers";
359 NOTIFY_ERROR(PLATFORM_FAILURE); 350 NOTIFY_ERROR(PLATFORM_FAILURE);
360 return; 351 return;
361 } 352 }
362 353
363 output_buffer_map_.resize(buffers.size()); 354 output_buffer_map_.resize(buffers.size());
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 egl_sync = eglCreateSyncKHR(egl_display_, EGL_SYNC_FENCE_KHR, NULL); 405 egl_sync = eglCreateSyncKHR(egl_display_, EGL_SYNC_FENCE_KHR, NULL);
415 if (egl_sync == EGL_NO_SYNC_KHR) { 406 if (egl_sync == EGL_NO_SYNC_KHR) {
416 LOG(ERROR) << "ReusePictureBuffer(): eglCreateSyncKHR() failed"; 407 LOG(ERROR) << "ReusePictureBuffer(): eglCreateSyncKHR() failed";
417 NOTIFY_ERROR(PLATFORM_FAILURE); 408 NOTIFY_ERROR(PLATFORM_FAILURE);
418 return; 409 return;
419 } 410 }
420 #endif 411 #endif
421 412
422 std::unique_ptr<EGLSyncKHRRef> egl_sync_ref( 413 std::unique_ptr<EGLSyncKHRRef> egl_sync_ref(
423 new EGLSyncKHRRef(egl_display_, egl_sync)); 414 new EGLSyncKHRRef(egl_display_, egl_sync));
424 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 415 decoder_thread_.message_loop()->PostTask(
425 &V4L2VideoDecodeAccelerator::ReusePictureBufferTask, 416 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::ReusePictureBufferTask,
426 base::Unretained(this), picture_buffer_id, base::Passed(&egl_sync_ref))); 417 base::Unretained(this), picture_buffer_id,
418 base::Passed(&egl_sync_ref)));
427 } 419 }
428 420
429 void V4L2VideoDecodeAccelerator::Flush() { 421 void V4L2VideoDecodeAccelerator::Flush() {
430 DVLOG(3) << "Flush()"; 422 DVLOG(3) << "Flush()";
431 DCHECK(child_task_runner_->BelongsToCurrentThread()); 423 DCHECK(child_task_runner_->BelongsToCurrentThread());
432 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 424 decoder_thread_.message_loop()->PostTask(
433 &V4L2VideoDecodeAccelerator::FlushTask, base::Unretained(this))); 425 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::FlushTask,
426 base::Unretained(this)));
434 } 427 }
435 428
436 void V4L2VideoDecodeAccelerator::Reset() { 429 void V4L2VideoDecodeAccelerator::Reset() {
437 DVLOG(3) << "Reset()"; 430 DVLOG(3) << "Reset()";
438 DCHECK(child_task_runner_->BelongsToCurrentThread()); 431 DCHECK(child_task_runner_->BelongsToCurrentThread());
439 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 432 decoder_thread_.message_loop()->PostTask(
440 &V4L2VideoDecodeAccelerator::ResetTask, base::Unretained(this))); 433 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::ResetTask,
434 base::Unretained(this)));
441 } 435 }
442 436
443 void V4L2VideoDecodeAccelerator::Destroy() { 437 void V4L2VideoDecodeAccelerator::Destroy() {
444 DVLOG(3) << "Destroy()"; 438 DVLOG(3) << "Destroy()";
445 DCHECK(child_task_runner_->BelongsToCurrentThread()); 439 DCHECK(child_task_runner_->BelongsToCurrentThread());
446 440
447 // We're destroying; cancel all callbacks. 441 // We're destroying; cancel all callbacks.
448 client_ptr_factory_.reset(); 442 client_ptr_factory_.reset();
449 weak_this_factory_.InvalidateWeakPtrs(); 443 weak_this_factory_.InvalidateWeakPtrs();
450 444
451 // If the decoder thread is running, destroy using posted task. 445 // If the decoder thread is running, destroy using posted task.
452 if (decoder_thread_.IsRunning()) { 446 if (decoder_thread_.IsRunning()) {
453 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 447 decoder_thread_.message_loop()->PostTask(
454 &V4L2VideoDecodeAccelerator::DestroyTask, base::Unretained(this))); 448 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::DestroyTask,
449 base::Unretained(this)));
455 pictures_assigned_.Signal(); 450 pictures_assigned_.Signal();
456 // DestroyTask() will cause the decoder_thread_ to flush all tasks. 451 // DestroyTask() will cause the decoder_thread_ to flush all tasks.
457 decoder_thread_.Stop(); 452 decoder_thread_.Stop();
458 } else { 453 } else {
459 // Otherwise, call the destroy task directly. 454 // Otherwise, call the destroy task directly.
460 DestroyTask(); 455 DestroyTask();
461 } 456 }
462 457
463 delete this; 458 delete this;
464 } 459 }
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 722
728 void V4L2VideoDecodeAccelerator::ScheduleDecodeBufferTaskIfNeeded() { 723 void V4L2VideoDecodeAccelerator::ScheduleDecodeBufferTaskIfNeeded() {
729 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 724 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
730 725
731 // If we're behind on tasks, schedule another one. 726 // If we're behind on tasks, schedule another one.
732 int buffers_to_decode = decoder_input_queue_.size(); 727 int buffers_to_decode = decoder_input_queue_.size();
733 if (decoder_current_bitstream_buffer_ != NULL) 728 if (decoder_current_bitstream_buffer_ != NULL)
734 buffers_to_decode++; 729 buffers_to_decode++;
735 if (decoder_decode_buffer_tasks_scheduled_ < buffers_to_decode) { 730 if (decoder_decode_buffer_tasks_scheduled_ < buffers_to_decode) {
736 decoder_decode_buffer_tasks_scheduled_++; 731 decoder_decode_buffer_tasks_scheduled_++;
737 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 732 decoder_thread_.message_loop()->PostTask(
738 &V4L2VideoDecodeAccelerator::DecodeBufferTask, 733 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::DecodeBufferTask,
739 base::Unretained(this))); 734 base::Unretained(this)));
740 } 735 }
741 } 736 }
742 737
743 bool V4L2VideoDecodeAccelerator::DecodeBufferInitial( 738 bool V4L2VideoDecodeAccelerator::DecodeBufferInitial(const void* data,
744 const void* data, size_t size, size_t* endpos) { 739 size_t size,
740 size_t* endpos) {
745 DVLOG(3) << "DecodeBufferInitial(): data=" << data << ", size=" << size; 741 DVLOG(3) << "DecodeBufferInitial(): data=" << data << ", size=" << size;
746 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 742 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
747 DCHECK_NE(decoder_state_, kUninitialized); 743 DCHECK_NE(decoder_state_, kUninitialized);
748 DCHECK_NE(decoder_state_, kDecoding); 744 DCHECK_NE(decoder_state_, kDecoding);
749 // Initial decode. We haven't been able to get output stream format info yet. 745 // Initial decode. We haven't been able to get output stream format info yet.
750 // Get it, and start decoding. 746 // Get it, and start decoding.
751 747
752 // Copy in and send to HW. 748 // Copy in and send to HW.
753 if (!AppendToInputFrame(data, size)) 749 if (!AppendToInputFrame(data, size))
754 return false; 750 return false;
(...skipping 28 matching lines...) Expand all
783 // Success! Setup our parameters. 779 // Success! Setup our parameters.
784 if (!CreateBuffersForFormat(format, visible_size)) 780 if (!CreateBuffersForFormat(format, visible_size))
785 return false; 781 return false;
786 } 782 }
787 783
788 decoder_state_ = kDecoding; 784 decoder_state_ = kDecoding;
789 ScheduleDecodeBufferTaskIfNeeded(); 785 ScheduleDecodeBufferTaskIfNeeded();
790 return true; 786 return true;
791 } 787 }
792 788
793 bool V4L2VideoDecodeAccelerator::DecodeBufferContinue( 789 bool V4L2VideoDecodeAccelerator::DecodeBufferContinue(const void* data,
794 const void* data, size_t size) { 790 size_t size) {
795 DVLOG(3) << "DecodeBufferContinue(): data=" << data << ", size=" << size; 791 DVLOG(3) << "DecodeBufferContinue(): data=" << data << ", size=" << size;
796 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 792 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
797 DCHECK_EQ(decoder_state_, kDecoding); 793 DCHECK_EQ(decoder_state_, kDecoding);
798 794
799 // Both of these calls will set kError state if they fail. 795 // Both of these calls will set kError state if they fail.
800 // Only flush the frame if it's complete. 796 // Only flush the frame if it's complete.
801 return (AppendToInputFrame(data, size) && 797 return (AppendToInputFrame(data, size) &&
802 (decoder_partial_frame_pending_ || FlushInputFrame())); 798 (decoder_partial_frame_pending_ || FlushInputFrame()));
803 } 799 }
804 800
805 bool V4L2VideoDecodeAccelerator::AppendToInputFrame( 801 bool V4L2VideoDecodeAccelerator::AppendToInputFrame(const void* data,
806 const void* data, size_t size) { 802 size_t size) {
807 DVLOG(3) << "AppendToInputFrame()"; 803 DVLOG(3) << "AppendToInputFrame()";
808 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 804 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
809 DCHECK_NE(decoder_state_, kUninitialized); 805 DCHECK_NE(decoder_state_, kUninitialized);
810 DCHECK_NE(decoder_state_, kResetting); 806 DCHECK_NE(decoder_state_, kResetting);
811 DCHECK_NE(decoder_state_, kError); 807 DCHECK_NE(decoder_state_, kError);
812 // This routine can handle data == NULL and size == 0, which occurs when 808 // This routine can handle data == NULL and size == 0, which occurs when
813 // we queue an empty buffer for the purposes of flushing the pipe. 809 // we queue an empty buffer for the purposes of flushing the pipe.
814 810
815 // Flush if we're too big 811 // Flush if we're too big
816 if (decoder_current_input_buffer_ != -1) { 812 if (decoder_current_input_buffer_ != -1) {
(...skipping 29 matching lines...) Expand all
846 842
847 DCHECK(data != NULL || size == 0); 843 DCHECK(data != NULL || size == 0);
848 if (size == 0) { 844 if (size == 0) {
849 // If we asked for an empty buffer, return now. We return only after 845 // If we asked for an empty buffer, return now. We return only after
850 // getting the next input buffer, since we might actually want an empty 846 // getting the next input buffer, since we might actually want an empty
851 // input buffer for flushing purposes. 847 // input buffer for flushing purposes.
852 return true; 848 return true;
853 } 849 }
854 850
855 // Copy in to the buffer. 851 // Copy in to the buffer.
856 InputRecord& input_record = 852 InputRecord& input_record = input_buffer_map_[decoder_current_input_buffer_];
857 input_buffer_map_[decoder_current_input_buffer_];
858 if (size > input_record.length - input_record.bytes_used) { 853 if (size > input_record.length - input_record.bytes_used) {
859 LOG(ERROR) << "AppendToInputFrame(): over-size frame, erroring"; 854 LOG(ERROR) << "AppendToInputFrame(): over-size frame, erroring";
860 NOTIFY_ERROR(UNREADABLE_INPUT); 855 NOTIFY_ERROR(UNREADABLE_INPUT);
861 return false; 856 return false;
862 } 857 }
863 memcpy(reinterpret_cast<uint8_t*>(input_record.address) + 858 memcpy(reinterpret_cast<uint8_t*>(input_record.address) +
864 input_record.bytes_used, 859 input_record.bytes_used,
865 data, size); 860 data, size);
866 input_record.bytes_used += size; 861 input_record.bytes_used += size;
867 862
868 return true; 863 return true;
869 } 864 }
870 865
871 bool V4L2VideoDecodeAccelerator::FlushInputFrame() { 866 bool V4L2VideoDecodeAccelerator::FlushInputFrame() {
872 DVLOG(3) << "FlushInputFrame()"; 867 DVLOG(3) << "FlushInputFrame()";
873 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 868 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
874 DCHECK_NE(decoder_state_, kUninitialized); 869 DCHECK_NE(decoder_state_, kUninitialized);
875 DCHECK_NE(decoder_state_, kResetting); 870 DCHECK_NE(decoder_state_, kResetting);
876 DCHECK_NE(decoder_state_, kError); 871 DCHECK_NE(decoder_state_, kError);
877 872
878 if (decoder_current_input_buffer_ == -1) 873 if (decoder_current_input_buffer_ == -1)
879 return true; 874 return true;
880 875
881 InputRecord& input_record = 876 InputRecord& input_record = input_buffer_map_[decoder_current_input_buffer_];
882 input_buffer_map_[decoder_current_input_buffer_];
883 DCHECK_NE(input_record.input_id, -1); 877 DCHECK_NE(input_record.input_id, -1);
884 DCHECK(input_record.input_id != kFlushBufferId || 878 DCHECK(input_record.input_id != kFlushBufferId ||
885 input_record.bytes_used == 0); 879 input_record.bytes_used == 0);
886 // * if input_id >= 0, this input buffer was prompted by a bitstream buffer we 880 // * if input_id >= 0, this input buffer was prompted by a bitstream buffer we
887 // got from the client. We can skip it if it is empty. 881 // got from the client. We can skip it if it is empty.
888 // * if input_id < 0 (should be kFlushBufferId in this case), this input 882 // * if input_id < 0 (should be kFlushBufferId in this case), this input
889 // buffer was prompted by a flush buffer, and should be queued even when 883 // buffer was prompted by a flush buffer, and should be queued even when
890 // empty. 884 // empty.
891 if (input_record.input_id >= 0 && input_record.bytes_used == 0) { 885 if (input_record.input_id >= 0 && input_record.bytes_used == 0) {
892 input_record.input_id = -1; 886 input_record.input_id = -1;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
943 937
944 // ServiceDeviceTask() should only ever be scheduled from DevicePollTask(), 938 // ServiceDeviceTask() should only ever be scheduled from DevicePollTask(),
945 // so either: 939 // so either:
946 // * device_poll_thread_ is running normally 940 // * device_poll_thread_ is running normally
947 // * device_poll_thread_ scheduled us, but then a ResetTask() or DestroyTask() 941 // * device_poll_thread_ scheduled us, but then a ResetTask() or DestroyTask()
948 // shut it down, in which case we're either in kResetting or kError states 942 // shut it down, in which case we're either in kResetting or kError states
949 // respectively, and we should have early-outed already. 943 // respectively, and we should have early-outed already.
950 DCHECK(device_poll_thread_.message_loop()); 944 DCHECK(device_poll_thread_.message_loop());
951 // Queue the DevicePollTask() now. 945 // Queue the DevicePollTask() now.
952 device_poll_thread_.message_loop()->PostTask( 946 device_poll_thread_.message_loop()->PostTask(
953 FROM_HERE, 947 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::DevicePollTask,
954 base::Bind(&V4L2VideoDecodeAccelerator::DevicePollTask, 948 base::Unretained(this), poll_device));
955 base::Unretained(this),
956 poll_device));
957 949
958 DVLOG(1) << "ServiceDeviceTask(): buffer counts: DEC[" 950 DVLOG(1) << "ServiceDeviceTask(): buffer counts: DEC["
959 << decoder_input_queue_.size() << "->" 951 << decoder_input_queue_.size() << "->" << input_ready_queue_.size()
960 << input_ready_queue_.size() << "] => DEVICE[" 952 << "] => DEVICE[" << free_input_buffers_.size() << "+"
961 << free_input_buffers_.size() << "+" 953 << input_buffer_queued_count_ << "/" << input_buffer_map_.size()
962 << input_buffer_queued_count_ << "/" 954 << "->" << free_output_buffers_.size() << "+"
963 << input_buffer_map_.size() << "->" 955 << output_buffer_queued_count_ << "/" << output_buffer_map_.size()
964 << free_output_buffers_.size() << "+" 956 << "] => VDA[" << decoder_frames_at_client_ << "]";
965 << output_buffer_queued_count_ << "/"
966 << output_buffer_map_.size() << "] => VDA["
967 << decoder_frames_at_client_ << "]";
968 957
969 ScheduleDecodeBufferTaskIfNeeded(); 958 ScheduleDecodeBufferTaskIfNeeded();
970 if (resolution_change_pending) 959 if (resolution_change_pending)
971 StartResolutionChange(); 960 StartResolutionChange();
972 } 961 }
973 962
974 void V4L2VideoDecodeAccelerator::Enqueue() { 963 void V4L2VideoDecodeAccelerator::Enqueue() {
975 DVLOG(3) << "Enqueue()"; 964 DVLOG(3) << "Enqueue()";
976 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 965 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
977 DCHECK_NE(decoder_state_, kUninitialized); 966 DCHECK_NE(decoder_state_, kUninitialized);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1052 TRACE_EVENT0("Video Decoder", "V4L2VDA::Dequeue"); 1041 TRACE_EVENT0("Video Decoder", "V4L2VDA::Dequeue");
1053 1042
1054 // Dequeue completed input (VIDEO_OUTPUT) buffers, and recycle to the free 1043 // Dequeue completed input (VIDEO_OUTPUT) buffers, and recycle to the free
1055 // list. 1044 // list.
1056 while (input_buffer_queued_count_ > 0) { 1045 while (input_buffer_queued_count_ > 0) {
1057 DCHECK(input_streamon_); 1046 DCHECK(input_streamon_);
1058 struct v4l2_buffer dqbuf; 1047 struct v4l2_buffer dqbuf;
1059 struct v4l2_plane planes[1]; 1048 struct v4l2_plane planes[1];
1060 memset(&dqbuf, 0, sizeof(dqbuf)); 1049 memset(&dqbuf, 0, sizeof(dqbuf));
1061 memset(planes, 0, sizeof(planes)); 1050 memset(planes, 0, sizeof(planes));
1062 dqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1051 dqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1063 dqbuf.memory = V4L2_MEMORY_MMAP; 1052 dqbuf.memory = V4L2_MEMORY_MMAP;
1064 dqbuf.m.planes = planes; 1053 dqbuf.m.planes = planes;
1065 dqbuf.length = 1; 1054 dqbuf.length = 1;
1066 if (device_->Ioctl(VIDIOC_DQBUF, &dqbuf) != 0) { 1055 if (device_->Ioctl(VIDIOC_DQBUF, &dqbuf) != 0) {
1067 if (errno == EAGAIN) { 1056 if (errno == EAGAIN) {
1068 // EAGAIN if we're just out of buffers to dequeue. 1057 // EAGAIN if we're just out of buffers to dequeue.
1069 break; 1058 break;
1070 } 1059 }
1071 PLOG(ERROR) << "Dequeue(): ioctl() failed: VIDIOC_DQBUF"; 1060 PLOG(ERROR) << "Dequeue(): ioctl() failed: VIDIOC_DQBUF";
1072 NOTIFY_ERROR(PLATFORM_FAILURE); 1061 NOTIFY_ERROR(PLATFORM_FAILURE);
(...skipping 10 matching lines...) Expand all
1083 1072
1084 // Dequeue completed output (VIDEO_CAPTURE) buffers, and queue to the 1073 // Dequeue completed output (VIDEO_CAPTURE) buffers, and queue to the
1085 // completed queue. 1074 // completed queue.
1086 while (output_buffer_queued_count_ > 0) { 1075 while (output_buffer_queued_count_ > 0) {
1087 DCHECK(output_streamon_); 1076 DCHECK(output_streamon_);
1088 struct v4l2_buffer dqbuf; 1077 struct v4l2_buffer dqbuf;
1089 std::unique_ptr<struct v4l2_plane[]> planes( 1078 std::unique_ptr<struct v4l2_plane[]> planes(
1090 new v4l2_plane[output_planes_count_]); 1079 new v4l2_plane[output_planes_count_]);
1091 memset(&dqbuf, 0, sizeof(dqbuf)); 1080 memset(&dqbuf, 0, sizeof(dqbuf));
1092 memset(planes.get(), 0, sizeof(struct v4l2_plane) * output_planes_count_); 1081 memset(planes.get(), 0, sizeof(struct v4l2_plane) * output_planes_count_);
1093 dqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1082 dqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1094 dqbuf.memory = V4L2_MEMORY_MMAP; 1083 dqbuf.memory = V4L2_MEMORY_MMAP;
1095 dqbuf.m.planes = planes.get(); 1084 dqbuf.m.planes = planes.get();
1096 dqbuf.length = output_planes_count_; 1085 dqbuf.length = output_planes_count_;
1097 if (device_->Ioctl(VIDIOC_DQBUF, &dqbuf) != 0) { 1086 if (device_->Ioctl(VIDIOC_DQBUF, &dqbuf) != 0) {
1098 if (errno == EAGAIN) { 1087 if (errno == EAGAIN) {
1099 // EAGAIN if we're just out of buffers to dequeue. 1088 // EAGAIN if we're just out of buffers to dequeue.
1100 break; 1089 break;
1101 } 1090 }
1102 PLOG(ERROR) << "Dequeue(): ioctl() failed: VIDIOC_DQBUF"; 1091 PLOG(ERROR) << "Dequeue(): ioctl() failed: VIDIOC_DQBUF";
1103 NOTIFY_ERROR(PLATFORM_FAILURE); 1092 NOTIFY_ERROR(PLATFORM_FAILURE);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1137 DCHECK(!input_ready_queue_.empty()); 1126 DCHECK(!input_ready_queue_.empty());
1138 1127
1139 // Enqueue an input (VIDEO_OUTPUT) buffer. 1128 // Enqueue an input (VIDEO_OUTPUT) buffer.
1140 const int buffer = input_ready_queue_.front(); 1129 const int buffer = input_ready_queue_.front();
1141 InputRecord& input_record = input_buffer_map_[buffer]; 1130 InputRecord& input_record = input_buffer_map_[buffer];
1142 DCHECK(!input_record.at_device); 1131 DCHECK(!input_record.at_device);
1143 struct v4l2_buffer qbuf; 1132 struct v4l2_buffer qbuf;
1144 struct v4l2_plane qbuf_plane; 1133 struct v4l2_plane qbuf_plane;
1145 memset(&qbuf, 0, sizeof(qbuf)); 1134 memset(&qbuf, 0, sizeof(qbuf));
1146 memset(&qbuf_plane, 0, sizeof(qbuf_plane)); 1135 memset(&qbuf_plane, 0, sizeof(qbuf_plane));
1147 qbuf.index = buffer; 1136 qbuf.index = buffer;
1148 qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1137 qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1149 qbuf.timestamp.tv_sec = input_record.input_id; 1138 qbuf.timestamp.tv_sec = input_record.input_id;
1150 qbuf.memory = V4L2_MEMORY_MMAP; 1139 qbuf.memory = V4L2_MEMORY_MMAP;
1151 qbuf.m.planes = &qbuf_plane; 1140 qbuf.m.planes = &qbuf_plane;
1152 qbuf.m.planes[0].bytesused = input_record.bytes_used; 1141 qbuf.m.planes[0].bytesused = input_record.bytes_used;
1153 qbuf.length = 1; 1142 qbuf.length = 1;
1154 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QBUF, &qbuf); 1143 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QBUF, &qbuf);
1155 input_ready_queue_.pop(); 1144 input_ready_queue_.pop();
1156 input_record.at_device = true; 1145 input_record.at_device = true;
1157 input_buffer_queued_count_++; 1146 input_buffer_queued_count_++;
1158 DVLOG(3) << "EnqueueInputRecord(): enqueued input_id=" 1147 DVLOG(3) << "EnqueueInputRecord(): enqueued input_id="
1159 << input_record.input_id << " size=" << input_record.bytes_used; 1148 << input_record.input_id << " size=" << input_record.bytes_used;
1160 return true; 1149 return true;
1161 } 1150 }
1162 1151
1163 bool V4L2VideoDecodeAccelerator::EnqueueOutputRecord() { 1152 bool V4L2VideoDecodeAccelerator::EnqueueOutputRecord() {
1164 DVLOG(3) << "EnqueueOutputRecord()"; 1153 DVLOG(3) << "EnqueueOutputRecord()";
1165 DCHECK(!free_output_buffers_.empty()); 1154 DCHECK(!free_output_buffers_.empty());
1166 1155
1167 // Enqueue an output (VIDEO_CAPTURE) buffer. 1156 // Enqueue an output (VIDEO_CAPTURE) buffer.
1168 const int buffer = free_output_buffers_.front(); 1157 const int buffer = free_output_buffers_.front();
1169 OutputRecord& output_record = output_buffer_map_[buffer]; 1158 OutputRecord& output_record = output_buffer_map_[buffer];
(...skipping 16 matching lines...) Expand all
1186 LOG(ERROR) << __func__ << " eglDestroySyncKHR failed!"; 1175 LOG(ERROR) << __func__ << " eglDestroySyncKHR failed!";
1187 NOTIFY_ERROR(PLATFORM_FAILURE); 1176 NOTIFY_ERROR(PLATFORM_FAILURE);
1188 return false; 1177 return false;
1189 } 1178 }
1190 output_record.egl_sync = EGL_NO_SYNC_KHR; 1179 output_record.egl_sync = EGL_NO_SYNC_KHR;
1191 } 1180 }
1192 struct v4l2_buffer qbuf; 1181 struct v4l2_buffer qbuf;
1193 std::unique_ptr<struct v4l2_plane[]> qbuf_planes( 1182 std::unique_ptr<struct v4l2_plane[]> qbuf_planes(
1194 new v4l2_plane[output_planes_count_]); 1183 new v4l2_plane[output_planes_count_]);
1195 memset(&qbuf, 0, sizeof(qbuf)); 1184 memset(&qbuf, 0, sizeof(qbuf));
1196 memset( 1185 memset(qbuf_planes.get(), 0,
1197 qbuf_planes.get(), 0, sizeof(struct v4l2_plane) * output_planes_count_); 1186 sizeof(struct v4l2_plane) * output_planes_count_);
1198 qbuf.index = buffer; 1187 qbuf.index = buffer;
1199 qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1188 qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1200 qbuf.memory = V4L2_MEMORY_MMAP; 1189 qbuf.memory = V4L2_MEMORY_MMAP;
1201 qbuf.m.planes = qbuf_planes.get(); 1190 qbuf.m.planes = qbuf_planes.get();
1202 qbuf.length = output_planes_count_; 1191 qbuf.length = output_planes_count_;
1203 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QBUF, &qbuf); 1192 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QBUF, &qbuf);
1204 free_output_buffers_.pop(); 1193 free_output_buffers_.pop();
1205 output_record.at_device = true; 1194 output_record.at_device = true;
1206 output_buffer_queued_count_++; 1195 output_buffer_queued_count_++;
1207 return true; 1196 return true;
1208 } 1197 }
1209 1198
1210 void V4L2VideoDecodeAccelerator::ReusePictureBufferTask( 1199 void V4L2VideoDecodeAccelerator::ReusePictureBufferTask(
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
1379 decoder_current_input_buffer_ = -1; 1368 decoder_current_input_buffer_ = -1;
1380 1369
1381 // If we were flushing, we'll never return any more BitstreamBuffers or 1370 // If we were flushing, we'll never return any more BitstreamBuffers or
1382 // PictureBuffers; they have all been dropped and returned by now. 1371 // PictureBuffers; they have all been dropped and returned by now.
1383 NotifyFlushDoneIfNeeded(); 1372 NotifyFlushDoneIfNeeded();
1384 1373
1385 // Mark that we're resetting, then enqueue a ResetDoneTask(). All intervening 1374 // Mark that we're resetting, then enqueue a ResetDoneTask(). All intervening
1386 // jobs will early-out in the kResetting state. 1375 // jobs will early-out in the kResetting state.
1387 decoder_state_ = kResetting; 1376 decoder_state_ = kResetting;
1388 SendPictureReady(); // Send all pending PictureReady. 1377 SendPictureReady(); // Send all pending PictureReady.
1389 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 1378 decoder_thread_.message_loop()->PostTask(
1390 &V4L2VideoDecodeAccelerator::ResetDoneTask, base::Unretained(this))); 1379 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::ResetDoneTask,
1380 base::Unretained(this)));
1391 } 1381 }
1392 1382
1393 void V4L2VideoDecodeAccelerator::ResetDoneTask() { 1383 void V4L2VideoDecodeAccelerator::ResetDoneTask() {
1394 DVLOG(3) << "ResetDoneTask()"; 1384 DVLOG(3) << "ResetDoneTask()";
1395 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1385 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1396 TRACE_EVENT0("Video Decoder", "V4L2VDA::ResetDoneTask"); 1386 TRACE_EVENT0("Video Decoder", "V4L2VDA::ResetDoneTask");
1397 1387
1398 if (decoder_state_ == kError) { 1388 if (decoder_state_ == kError) {
1399 DVLOG(2) << "ResetDoneTask(): early out: kError state"; 1389 DVLOG(2) << "ResetDoneTask(): early out: kError state";
1400 return; 1390 return;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1454 DVLOG(3) << "StartDevicePoll()"; 1444 DVLOG(3) << "StartDevicePoll()";
1455 DCHECK(!device_poll_thread_.IsRunning()); 1445 DCHECK(!device_poll_thread_.IsRunning());
1456 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1446 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1457 1447
1458 // Start up the device poll thread and schedule its first DevicePollTask(). 1448 // Start up the device poll thread and schedule its first DevicePollTask().
1459 if (!device_poll_thread_.Start()) { 1449 if (!device_poll_thread_.Start()) {
1460 LOG(ERROR) << "StartDevicePoll(): Device thread failed to start"; 1450 LOG(ERROR) << "StartDevicePoll(): Device thread failed to start";
1461 NOTIFY_ERROR(PLATFORM_FAILURE); 1451 NOTIFY_ERROR(PLATFORM_FAILURE);
1462 return false; 1452 return false;
1463 } 1453 }
1464 device_poll_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 1454 device_poll_thread_.message_loop()->PostTask(
1465 &V4L2VideoDecodeAccelerator::DevicePollTask, 1455 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::DevicePollTask,
1466 base::Unretained(this), 1456 base::Unretained(this), 0));
1467 0));
1468 1457
1469 return true; 1458 return true;
1470 } 1459 }
1471 1460
1472 bool V4L2VideoDecodeAccelerator::StopDevicePoll() { 1461 bool V4L2VideoDecodeAccelerator::StopDevicePoll() {
1473 DVLOG(3) << "StopDevicePoll()"; 1462 DVLOG(3) << "StopDevicePoll()";
1474 1463
1475 if (!device_poll_thread_.IsRunning()) 1464 if (!device_poll_thread_.IsRunning())
1476 return true; 1465 return true;
1477 1466
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
1617 1606
1618 bool event_pending = false; 1607 bool event_pending = false;
1619 1608
1620 if (!device_->Poll(poll_device, &event_pending)) { 1609 if (!device_->Poll(poll_device, &event_pending)) {
1621 NOTIFY_ERROR(PLATFORM_FAILURE); 1610 NOTIFY_ERROR(PLATFORM_FAILURE);
1622 return; 1611 return;
1623 } 1612 }
1624 1613
1625 // All processing should happen on ServiceDeviceTask(), since we shouldn't 1614 // All processing should happen on ServiceDeviceTask(), since we shouldn't
1626 // touch decoder state from this thread. 1615 // touch decoder state from this thread.
1627 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 1616 decoder_thread_.message_loop()->PostTask(
1628 &V4L2VideoDecodeAccelerator::ServiceDeviceTask, 1617 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::ServiceDeviceTask,
1629 base::Unretained(this), event_pending)); 1618 base::Unretained(this), event_pending));
1630 } 1619 }
1631 1620
1632 void V4L2VideoDecodeAccelerator::NotifyError(Error error) { 1621 void V4L2VideoDecodeAccelerator::NotifyError(Error error) {
1633 DVLOG(2) << "NotifyError()"; 1622 DVLOG(2) << "NotifyError()";
1634 1623
1635 if (!child_task_runner_->BelongsToCurrentThread()) { 1624 if (!child_task_runner_->BelongsToCurrentThread()) {
1636 child_task_runner_->PostTask( 1625 child_task_runner_->PostTask(
1637 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::NotifyError, 1626 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::NotifyError,
1638 weak_this_, error)); 1627 weak_this_, error));
1639 return; 1628 return;
1640 } 1629 }
1641 1630
1642 if (client_) { 1631 if (client_) {
1643 client_->NotifyError(error); 1632 client_->NotifyError(error);
1644 client_ptr_factory_.reset(); 1633 client_ptr_factory_.reset();
1645 } 1634 }
1646 } 1635 }
1647 1636
1648 void V4L2VideoDecodeAccelerator::SetErrorState(Error error) { 1637 void V4L2VideoDecodeAccelerator::SetErrorState(Error error) {
1649 // We can touch decoder_state_ only if this is the decoder thread or the 1638 // We can touch decoder_state_ only if this is the decoder thread or the
1650 // decoder thread isn't running. 1639 // decoder thread isn't running.
1651 if (decoder_thread_.message_loop() != NULL && 1640 if (decoder_thread_.message_loop() != NULL &&
1652 decoder_thread_.message_loop() != base::MessageLoop::current()) { 1641 decoder_thread_.message_loop() != base::MessageLoop::current()) {
1653 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 1642 decoder_thread_.message_loop()->PostTask(
1654 &V4L2VideoDecodeAccelerator::SetErrorState, 1643 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::SetErrorState,
1655 base::Unretained(this), error)); 1644 base::Unretained(this), error));
1656 return; 1645 return;
1657 } 1646 }
1658 1647
1659 // Post NotifyError only if we are already initialized, as the API does 1648 // Post NotifyError only if we are already initialized, as the API does
1660 // not allow doing so before that. 1649 // not allow doing so before that.
1661 if (decoder_state_ != kError && decoder_state_ != kUninitialized) 1650 if (decoder_state_ != kError && decoder_state_ != kUninitialized)
1662 NotifyError(error); 1651 NotifyError(error);
1663 1652
1664 decoder_state_ = kError; 1653 decoder_state_ = kError;
1665 } 1654 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1698 } 1687 }
1699 1688
1700 bool V4L2VideoDecodeAccelerator::CreateBuffersForFormat( 1689 bool V4L2VideoDecodeAccelerator::CreateBuffersForFormat(
1701 const struct v4l2_format& format, 1690 const struct v4l2_format& format,
1702 const gfx::Size& visible_size) { 1691 const gfx::Size& visible_size) {
1703 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1692 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1704 output_planes_count_ = format.fmt.pix_mp.num_planes; 1693 output_planes_count_ = format.fmt.pix_mp.num_planes;
1705 coded_size_.SetSize(format.fmt.pix_mp.width, format.fmt.pix_mp.height); 1694 coded_size_.SetSize(format.fmt.pix_mp.width, format.fmt.pix_mp.height);
1706 visible_size_ = visible_size; 1695 visible_size_ = visible_size;
1707 DVLOG(3) << "CreateBuffersForFormat(): new resolution: " 1696 DVLOG(3) << "CreateBuffersForFormat(): new resolution: "
1708 << coded_size_.ToString() << ", visible size: " 1697 << coded_size_.ToString()
1709 << visible_size_.ToString(); 1698 << ", visible size: " << visible_size_.ToString();
1710 1699
1711 return CreateOutputBuffers(); 1700 return CreateOutputBuffers();
1712 } 1701 }
1713 1702
1714 gfx::Size V4L2VideoDecodeAccelerator::GetVisibleSize( 1703 gfx::Size V4L2VideoDecodeAccelerator::GetVisibleSize(
1715 const gfx::Size& coded_size) { 1704 const gfx::Size& coded_size) {
1716 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1705 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1717 1706
1718 struct v4l2_crop crop_arg; 1707 struct v4l2_crop crop_arg;
1719 memset(&crop_arg, 0, sizeof(crop_arg)); 1708 memset(&crop_arg, 0, sizeof(crop_arg));
(...skipping 29 matching lines...) Expand all
1749 1738
1750 bool V4L2VideoDecodeAccelerator::CreateInputBuffers() { 1739 bool V4L2VideoDecodeAccelerator::CreateInputBuffers() {
1751 DVLOG(3) << "CreateInputBuffers()"; 1740 DVLOG(3) << "CreateInputBuffers()";
1752 // We always run this as we prepare to initialize. 1741 // We always run this as we prepare to initialize.
1753 DCHECK_EQ(decoder_state_, kUninitialized); 1742 DCHECK_EQ(decoder_state_, kUninitialized);
1754 DCHECK(!input_streamon_); 1743 DCHECK(!input_streamon_);
1755 DCHECK(input_buffer_map_.empty()); 1744 DCHECK(input_buffer_map_.empty());
1756 1745
1757 struct v4l2_requestbuffers reqbufs; 1746 struct v4l2_requestbuffers reqbufs;
1758 memset(&reqbufs, 0, sizeof(reqbufs)); 1747 memset(&reqbufs, 0, sizeof(reqbufs));
1759 reqbufs.count = kInputBufferCount; 1748 reqbufs.count = kInputBufferCount;
1760 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1749 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1761 reqbufs.memory = V4L2_MEMORY_MMAP; 1750 reqbufs.memory = V4L2_MEMORY_MMAP;
1762 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_REQBUFS, &reqbufs); 1751 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_REQBUFS, &reqbufs);
1763 input_buffer_map_.resize(reqbufs.count); 1752 input_buffer_map_.resize(reqbufs.count);
1764 for (size_t i = 0; i < input_buffer_map_.size(); ++i) { 1753 for (size_t i = 0; i < input_buffer_map_.size(); ++i) {
1765 free_input_buffers_.push_back(i); 1754 free_input_buffers_.push_back(i);
1766 1755
1767 // Query for the MEMORY_MMAP pointer. 1756 // Query for the MEMORY_MMAP pointer.
1768 struct v4l2_plane planes[1]; 1757 struct v4l2_plane planes[1];
1769 struct v4l2_buffer buffer; 1758 struct v4l2_buffer buffer;
1770 memset(&buffer, 0, sizeof(buffer)); 1759 memset(&buffer, 0, sizeof(buffer));
1771 memset(planes, 0, sizeof(planes)); 1760 memset(planes, 0, sizeof(planes));
1772 buffer.index = i; 1761 buffer.index = i;
1773 buffer.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1762 buffer.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1774 buffer.memory = V4L2_MEMORY_MMAP; 1763 buffer.memory = V4L2_MEMORY_MMAP;
1775 buffer.m.planes = planes; 1764 buffer.m.planes = planes;
1776 buffer.length = 1; 1765 buffer.length = 1;
1777 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYBUF, &buffer); 1766 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYBUF, &buffer);
1778 void* address = device_->Mmap(NULL, 1767 void* address =
1779 buffer.m.planes[0].length, 1768 device_->Mmap(NULL, buffer.m.planes[0].length, PROT_READ | PROT_WRITE,
1780 PROT_READ | PROT_WRITE, 1769 MAP_SHARED, buffer.m.planes[0].m.mem_offset);
1781 MAP_SHARED,
1782 buffer.m.planes[0].m.mem_offset);
1783 if (address == MAP_FAILED) { 1770 if (address == MAP_FAILED) {
1784 PLOG(ERROR) << "CreateInputBuffers(): mmap() failed"; 1771 PLOG(ERROR) << "CreateInputBuffers(): mmap() failed";
1785 return false; 1772 return false;
1786 } 1773 }
1787 input_buffer_map_[i].address = address; 1774 input_buffer_map_[i].address = address;
1788 input_buffer_map_[i].length = buffer.m.planes[0].length; 1775 input_buffer_map_[i].length = buffer.m.planes[0].length;
1789 } 1776 }
1790 1777
1791 return true; 1778 return true;
1792 } 1779 }
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
1986 DCHECK(child_task_runner_->BelongsToCurrentThread()); 1973 DCHECK(child_task_runner_->BelongsToCurrentThread());
1987 DVLOG(3) << "ResolutionChangeDestroyBuffers()"; 1974 DVLOG(3) << "ResolutionChangeDestroyBuffers()";
1988 1975
1989 if (!DestroyOutputBuffers()) { 1976 if (!DestroyOutputBuffers()) {
1990 LOG(ERROR) << __func__ << " Failed destroying output buffers."; 1977 LOG(ERROR) << __func__ << " Failed destroying output buffers.";
1991 NOTIFY_ERROR(PLATFORM_FAILURE); 1978 NOTIFY_ERROR(PLATFORM_FAILURE);
1992 return; 1979 return;
1993 } 1980 }
1994 1981
1995 // Finish resolution change on decoder thread. 1982 // Finish resolution change on decoder thread.
1996 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 1983 decoder_thread_.message_loop()->PostTask(
1997 &V4L2VideoDecodeAccelerator::FinishResolutionChange, 1984 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::FinishResolutionChange,
1998 base::Unretained(this))); 1985 base::Unretained(this)));
1999 } 1986 }
2000 1987
2001 void V4L2VideoDecodeAccelerator::SendPictureReady() { 1988 void V4L2VideoDecodeAccelerator::SendPictureReady() {
2002 DVLOG(3) << "SendPictureReady()"; 1989 DVLOG(3) << "SendPictureReady()";
2003 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1990 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
2004 bool resetting_or_flushing = 1991 bool resetting_or_flushing =
2005 (decoder_state_ == kResetting || decoder_flushing_); 1992 (decoder_state_ == kResetting || decoder_flushing_);
2006 while (pending_picture_ready_.size() > 0) { 1993 while (pending_picture_ready_.size() > 0) {
2007 bool cleared = pending_picture_ready_.front().cleared; 1994 bool cleared = pending_picture_ready_.front().cleared;
2008 const media::Picture& picture = pending_picture_ready_.front().picture; 1995 const media::Picture& picture = pending_picture_ready_.front().picture;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2042 } 2029 }
2043 2030
2044 void V4L2VideoDecodeAccelerator::PictureCleared() { 2031 void V4L2VideoDecodeAccelerator::PictureCleared() {
2045 DVLOG(3) << "PictureCleared(). clearing count=" << picture_clearing_count_; 2032 DVLOG(3) << "PictureCleared(). clearing count=" << picture_clearing_count_;
2046 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 2033 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
2047 DCHECK_GT(picture_clearing_count_, 0); 2034 DCHECK_GT(picture_clearing_count_, 0);
2048 picture_clearing_count_--; 2035 picture_clearing_count_--;
2049 SendPictureReady(); 2036 SendPictureReady();
2050 } 2037 }
2051 2038
2052 } // namespace content 2039 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698