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

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

Issue 597473002: Change log level to show real errors in release mode (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: address review comments Created 6 years, 2 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 <sys/eventfd.h> 10 #include <sys/eventfd.h>
11 #include <sys/ioctl.h> 11 #include <sys/ioctl.h>
12 #include <sys/mman.h> 12 #include <sys/mman.h>
13 13
14 #include "base/bind.h" 14 #include "base/bind.h"
15 #include "base/command_line.h" 15 #include "base/command_line.h"
16 #include "base/debug/trace_event.h" 16 #include "base/debug/trace_event.h"
17 #include "base/memory/shared_memory.h" 17 #include "base/memory/shared_memory.h"
18 #include "base/message_loop/message_loop.h" 18 #include "base/message_loop/message_loop.h"
19 #include "base/message_loop/message_loop_proxy.h" 19 #include "base/message_loop/message_loop_proxy.h"
20 #include "base/numerics/safe_conversions.h" 20 #include "base/numerics/safe_conversions.h"
21 #include "content/common/gpu/media/v4l2_video_decode_accelerator.h" 21 #include "content/common/gpu/media/v4l2_video_decode_accelerator.h"
22 #include "media/base/media_switches.h" 22 #include "media/base/media_switches.h"
23 #include "media/filters/h264_parser.h" 23 #include "media/filters/h264_parser.h"
24 #include "ui/gl/scoped_binders.h" 24 #include "ui/gl/scoped_binders.h"
25 25
26 #define NOTIFY_ERROR(x) \ 26 #define NOTIFY_ERROR(x) \
27 do { \ 27 do { \
28 SetDecoderState(kError); \ 28 SetDecoderState(kError); \
29 DLOG(ERROR) << "calling NotifyError(): " << x; \ 29 LOG(ERROR) << "calling NotifyError(): " << x; \
30 NotifyError(x); \ 30 NotifyError(x); \
31 } while (0) 31 } while (0)
32 32
33 #define IOCTL_OR_ERROR_RETURN_VALUE(type, arg, value) \ 33 #define IOCTL_OR_ERROR_RETURN_VALUE(type, arg, value) \
34 do { \ 34 do { \
35 if (device_->Ioctl(type, arg) != 0) { \ 35 if (device_->Ioctl(type, arg) != 0) { \
36 DPLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \ 36 PLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \
37 NOTIFY_ERROR(PLATFORM_FAILURE); \ 37 NOTIFY_ERROR(PLATFORM_FAILURE); \
38 return value; \ 38 return value; \
39 } \ 39 } \
40 } while (0) 40 } while (0)
41 41
42 #define IOCTL_OR_ERROR_RETURN(type, arg) \ 42 #define IOCTL_OR_ERROR_RETURN(type, arg) \
43 IOCTL_OR_ERROR_RETURN_VALUE(type, arg, ((void)0)) 43 IOCTL_OR_ERROR_RETURN_VALUE(type, arg, ((void)0))
44 44
45 #define IOCTL_OR_ERROR_RETURN_FALSE(type, arg) \ 45 #define IOCTL_OR_ERROR_RETURN_FALSE(type, arg) \
46 IOCTL_OR_ERROR_RETURN_VALUE(type, arg, false) 46 IOCTL_OR_ERROR_RETURN_VALUE(type, arg, false)
47 47
48 #define IOCTL_OR_LOG_ERROR(type, arg) \ 48 #define IOCTL_OR_LOG_ERROR(type, arg) \
49 do { \ 49 do { \
50 if (device_->Ioctl(type, arg) != 0) \ 50 if (device_->Ioctl(type, arg) != 0) \
51 DPLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \ 51 PLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \
52 } while (0) 52 } while (0)
53 53
54 namespace content { 54 namespace content {
55 55
56 namespace { 56 namespace {
57 57
58 // TODO(posciak): remove once we update linux-headers. 58 // TODO(posciak): remove once we update linux-headers.
59 #ifndef V4L2_EVENT_RESOLUTION_CHANGE 59 #ifndef V4L2_EVENT_RESOLUTION_CHANGE
60 #define V4L2_EVENT_RESOLUTION_CHANGE 5 60 #define V4L2_EVENT_RESOLUTION_CHANGE 5
61 #endif 61 #endif
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 case media::VP8PROFILE_ANY: 227 case media::VP8PROFILE_ANY:
228 DVLOG(2) << "Initialize(): profile VP8PROFILE_ANY"; 228 DVLOG(2) << "Initialize(): profile VP8PROFILE_ANY";
229 break; 229 break;
230 default: 230 default:
231 DLOG(ERROR) << "Initialize(): unsupported profile=" << profile; 231 DLOG(ERROR) << "Initialize(): unsupported profile=" << profile;
232 return false; 232 return false;
233 }; 233 };
234 video_profile_ = profile; 234 video_profile_ = profile;
235 235
236 if (egl_display_ == EGL_NO_DISPLAY) { 236 if (egl_display_ == EGL_NO_DISPLAY) {
237 DLOG(ERROR) << "Initialize(): could not get EGLDisplay"; 237 LOG(ERROR) << "Initialize(): could not get EGLDisplay";
238 NOTIFY_ERROR(PLATFORM_FAILURE); 238 NOTIFY_ERROR(PLATFORM_FAILURE);
239 return false; 239 return false;
240 } 240 }
241 241
242 // We need the context to be initialized to query extensions. 242 // We need the context to be initialized to query extensions.
243 if (!make_context_current_.Run()) { 243 if (!make_context_current_.Run()) {
244 DLOG(ERROR) << "Initialize(): could not make context current"; 244 LOG(ERROR) << "Initialize(): could not make context current";
245 NOTIFY_ERROR(PLATFORM_FAILURE); 245 NOTIFY_ERROR(PLATFORM_FAILURE);
246 return false; 246 return false;
247 } 247 }
248 248
249 if (!gfx::g_driver_egl.ext.b_EGL_KHR_fence_sync) { 249 if (!gfx::g_driver_egl.ext.b_EGL_KHR_fence_sync) {
250 DLOG(ERROR) << "Initialize(): context does not have EGL_KHR_fence_sync"; 250 LOG(ERROR) << "Initialize(): context does not have EGL_KHR_fence_sync";
251 NOTIFY_ERROR(PLATFORM_FAILURE); 251 NOTIFY_ERROR(PLATFORM_FAILURE);
252 return false; 252 return false;
253 } 253 }
254 254
255 // Capabilities check. 255 // Capabilities check.
256 struct v4l2_capability caps; 256 struct v4l2_capability caps;
257 const __u32 kCapsRequired = 257 const __u32 kCapsRequired =
258 V4L2_CAP_VIDEO_CAPTURE_MPLANE | 258 V4L2_CAP_VIDEO_CAPTURE_MPLANE |
259 V4L2_CAP_VIDEO_OUTPUT_MPLANE | 259 V4L2_CAP_VIDEO_OUTPUT_MPLANE |
260 V4L2_CAP_STREAMING; 260 V4L2_CAP_STREAMING;
261 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps); 261 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps);
262 if ((caps.capabilities & kCapsRequired) != kCapsRequired) { 262 if ((caps.capabilities & kCapsRequired) != kCapsRequired) {
263 DLOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP" 263 LOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP"
264 ", caps check failed: 0x" << std::hex << caps.capabilities; 264 ", caps check failed: 0x" << std::hex << caps.capabilities;
265 NOTIFY_ERROR(PLATFORM_FAILURE); 265 NOTIFY_ERROR(PLATFORM_FAILURE);
266 return false; 266 return false;
267 } 267 }
268 268
269 if (!CreateInputBuffers()) 269 if (!CreateInputBuffers())
270 return false; 270 return false;
271 271
272 // Output format has to be setup before streaming starts. 272 // Output format has to be setup before streaming starts.
273 struct v4l2_format format; 273 struct v4l2_format format;
(...skipping 14 matching lines...) Expand all
288 sub.type = V4L2_EVENT_RESOLUTION_CHANGE; 288 sub.type = V4L2_EVENT_RESOLUTION_CHANGE;
289 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_SUBSCRIBE_EVENT, &sub); 289 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_SUBSCRIBE_EVENT, &sub);
290 290
291 // Initialize format-specific bits. 291 // Initialize format-specific bits.
292 if (video_profile_ >= media::H264PROFILE_MIN && 292 if (video_profile_ >= media::H264PROFILE_MIN &&
293 video_profile_ <= media::H264PROFILE_MAX) { 293 video_profile_ <= media::H264PROFILE_MAX) {
294 decoder_h264_parser_.reset(new media::H264Parser()); 294 decoder_h264_parser_.reset(new media::H264Parser());
295 } 295 }
296 296
297 if (!decoder_thread_.Start()) { 297 if (!decoder_thread_.Start()) {
298 DLOG(ERROR) << "Initialize(): decoder thread failed to start"; 298 LOG(ERROR) << "Initialize(): decoder thread failed to start";
299 NOTIFY_ERROR(PLATFORM_FAILURE); 299 NOTIFY_ERROR(PLATFORM_FAILURE);
300 return false; 300 return false;
301 } 301 }
302 302
303 // StartDevicePoll will NOTIFY_ERROR on failure, so IgnoreResult is fine here. 303 // StartDevicePoll will NOTIFY_ERROR on failure, so IgnoreResult is fine here.
304 decoder_thread_.message_loop()->PostTask( 304 decoder_thread_.message_loop()->PostTask(
305 FROM_HERE, 305 FROM_HERE,
306 base::Bind( 306 base::Bind(
307 base::IgnoreResult(&V4L2VideoDecodeAccelerator::StartDevicePoll), 307 base::IgnoreResult(&V4L2VideoDecodeAccelerator::StartDevicePoll),
308 base::Unretained(this))); 308 base::Unretained(this)));
(...skipping 13 matching lines...) Expand all
322 &V4L2VideoDecodeAccelerator::DecodeTask, base::Unretained(this), 322 &V4L2VideoDecodeAccelerator::DecodeTask, base::Unretained(this),
323 bitstream_buffer)); 323 bitstream_buffer));
324 } 324 }
325 325
326 void V4L2VideoDecodeAccelerator::AssignPictureBuffers( 326 void V4L2VideoDecodeAccelerator::AssignPictureBuffers(
327 const std::vector<media::PictureBuffer>& buffers) { 327 const std::vector<media::PictureBuffer>& buffers) {
328 DVLOG(3) << "AssignPictureBuffers(): buffer_count=" << buffers.size(); 328 DVLOG(3) << "AssignPictureBuffers(): buffer_count=" << buffers.size();
329 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 329 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
330 330
331 if (buffers.size() != output_buffer_map_.size()) { 331 if (buffers.size() != output_buffer_map_.size()) {
332 DLOG(ERROR) << "AssignPictureBuffers(): Failed to provide requested picture" 332 LOG(ERROR) << "AssignPictureBuffers(): Failed to provide requested picture"
333 " buffers. (Got " << buffers.size() 333 " buffers. (Got " << buffers.size()
334 << ", requested " << output_buffer_map_.size() << ")"; 334 << ", requested " << output_buffer_map_.size() << ")";
335 NOTIFY_ERROR(INVALID_ARGUMENT); 335 NOTIFY_ERROR(INVALID_ARGUMENT);
336 return; 336 return;
337 } 337 }
338 338
339 if (!make_context_current_.Run()) { 339 if (!make_context_current_.Run()) {
340 DLOG(ERROR) << "AssignPictureBuffers(): could not make context current"; 340 LOG(ERROR) << "AssignPictureBuffers(): could not make context current";
341 NOTIFY_ERROR(PLATFORM_FAILURE); 341 NOTIFY_ERROR(PLATFORM_FAILURE);
342 return; 342 return;
343 } 343 }
344 344
345 gfx::ScopedTextureBinder bind_restore(GL_TEXTURE_EXTERNAL_OES, 0); 345 gfx::ScopedTextureBinder bind_restore(GL_TEXTURE_EXTERNAL_OES, 0);
346 346
347 // It's safe to manipulate all the buffer state here, because the decoder 347 // It's safe to manipulate all the buffer state here, because the decoder
348 // thread is waiting on pictures_assigned_. 348 // thread is waiting on pictures_assigned_.
349 DCHECK(free_output_buffers_.empty()); 349 DCHECK(free_output_buffers_.empty());
350 for (size_t i = 0; i < output_buffer_map_.size(); ++i) { 350 for (size_t i = 0; i < output_buffer_map_.size(); ++i) {
351 DCHECK(buffers[i].size() == frame_buffer_size_); 351 DCHECK(buffers[i].size() == frame_buffer_size_);
352 352
353 OutputRecord& output_record = output_buffer_map_[i]; 353 OutputRecord& output_record = output_buffer_map_[i];
354 DCHECK(!output_record.at_device); 354 DCHECK(!output_record.at_device);
355 DCHECK(!output_record.at_client); 355 DCHECK(!output_record.at_client);
356 DCHECK_EQ(output_record.egl_image, EGL_NO_IMAGE_KHR); 356 DCHECK_EQ(output_record.egl_image, EGL_NO_IMAGE_KHR);
357 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR); 357 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR);
358 DCHECK_EQ(output_record.picture_id, -1); 358 DCHECK_EQ(output_record.picture_id, -1);
359 DCHECK_EQ(output_record.cleared, false); 359 DCHECK_EQ(output_record.cleared, false);
360 360
361 EGLImageKHR egl_image = device_->CreateEGLImage(egl_display_, 361 EGLImageKHR egl_image = device_->CreateEGLImage(egl_display_,
362 egl_context_, 362 egl_context_,
363 buffers[i].texture_id(), 363 buffers[i].texture_id(),
364 frame_buffer_size_, 364 frame_buffer_size_,
365 i, 365 i,
366 output_planes_count_); 366 output_planes_count_);
367 if (egl_image == EGL_NO_IMAGE_KHR) { 367 if (egl_image == EGL_NO_IMAGE_KHR) {
368 DLOG(ERROR) << "AssignPictureBuffers(): could not create EGLImageKHR"; 368 LOG(ERROR) << "AssignPictureBuffers(): could not create EGLImageKHR";
369 // Ownership of EGLImages allocated in previous iterations of this loop 369 // Ownership of EGLImages allocated in previous iterations of this loop
370 // has been transferred to output_buffer_map_. After we error-out here 370 // has been transferred to output_buffer_map_. After we error-out here
371 // the destructor will handle their cleanup. 371 // the destructor will handle their cleanup.
372 NOTIFY_ERROR(PLATFORM_FAILURE); 372 NOTIFY_ERROR(PLATFORM_FAILURE);
373 return; 373 return;
374 } 374 }
375 375
376 output_record.egl_image = egl_image; 376 output_record.egl_image = egl_image;
377 output_record.picture_id = buffers[i].id(); 377 output_record.picture_id = buffers[i].id();
378 free_output_buffers_.push(i); 378 free_output_buffers_.push(i);
379 DVLOG(3) << "AssignPictureBuffers(): buffer[" << i 379 DVLOG(3) << "AssignPictureBuffers(): buffer[" << i
380 << "]: picture_id=" << output_record.picture_id; 380 << "]: picture_id=" << output_record.picture_id;
381 } 381 }
382 382
383 pictures_assigned_.Signal(); 383 pictures_assigned_.Signal();
384 } 384 }
385 385
386 void V4L2VideoDecodeAccelerator::ReusePictureBuffer(int32 picture_buffer_id) { 386 void V4L2VideoDecodeAccelerator::ReusePictureBuffer(int32 picture_buffer_id) {
387 DVLOG(3) << "ReusePictureBuffer(): picture_buffer_id=" << picture_buffer_id; 387 DVLOG(3) << "ReusePictureBuffer(): picture_buffer_id=" << picture_buffer_id;
388 // Must be run on child thread, as we'll insert a sync in the EGL context. 388 // Must be run on child thread, as we'll insert a sync in the EGL context.
389 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 389 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
390 390
391 if (!make_context_current_.Run()) { 391 if (!make_context_current_.Run()) {
392 DLOG(ERROR) << "ReusePictureBuffer(): could not make context current"; 392 LOG(ERROR) << "ReusePictureBuffer(): could not make context current";
393 NOTIFY_ERROR(PLATFORM_FAILURE); 393 NOTIFY_ERROR(PLATFORM_FAILURE);
394 return; 394 return;
395 } 395 }
396 396
397 EGLSyncKHR egl_sync = 397 EGLSyncKHR egl_sync =
398 eglCreateSyncKHR(egl_display_, EGL_SYNC_FENCE_KHR, NULL); 398 eglCreateSyncKHR(egl_display_, EGL_SYNC_FENCE_KHR, NULL);
399 if (egl_sync == EGL_NO_SYNC_KHR) { 399 if (egl_sync == EGL_NO_SYNC_KHR) {
400 DLOG(ERROR) << "ReusePictureBuffer(): eglCreateSyncKHR() failed"; 400 LOG(ERROR) << "ReusePictureBuffer(): eglCreateSyncKHR() failed";
401 NOTIFY_ERROR(PLATFORM_FAILURE); 401 NOTIFY_ERROR(PLATFORM_FAILURE);
402 return; 402 return;
403 } 403 }
404 404
405 scoped_ptr<EGLSyncKHRRef> egl_sync_ref(new EGLSyncKHRRef( 405 scoped_ptr<EGLSyncKHRRef> egl_sync_ref(new EGLSyncKHRRef(
406 egl_display_, egl_sync)); 406 egl_display_, egl_sync));
407 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 407 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
408 &V4L2VideoDecodeAccelerator::ReusePictureBufferTask, 408 &V4L2VideoDecodeAccelerator::ReusePictureBufferTask,
409 base::Unretained(this), picture_buffer_id, base::Passed(&egl_sync_ref))); 409 base::Unretained(this), picture_buffer_id, base::Passed(&egl_sync_ref)));
410 } 410 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 457 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
458 DCHECK_NE(decoder_state_, kUninitialized); 458 DCHECK_NE(decoder_state_, kUninitialized);
459 TRACE_EVENT1("Video Decoder", "V4L2VDA::DecodeTask", "input_id", 459 TRACE_EVENT1("Video Decoder", "V4L2VDA::DecodeTask", "input_id",
460 bitstream_buffer.id()); 460 bitstream_buffer.id());
461 461
462 scoped_ptr<BitstreamBufferRef> bitstream_record(new BitstreamBufferRef( 462 scoped_ptr<BitstreamBufferRef> bitstream_record(new BitstreamBufferRef(
463 io_client_, io_message_loop_proxy_, 463 io_client_, io_message_loop_proxy_,
464 new base::SharedMemory(bitstream_buffer.handle(), true), 464 new base::SharedMemory(bitstream_buffer.handle(), true),
465 bitstream_buffer.size(), bitstream_buffer.id())); 465 bitstream_buffer.size(), bitstream_buffer.id()));
466 if (!bitstream_record->shm->Map(bitstream_buffer.size())) { 466 if (!bitstream_record->shm->Map(bitstream_buffer.size())) {
467 DLOG(ERROR) << "Decode(): could not map bitstream_buffer"; 467 LOG(ERROR) << "Decode(): could not map bitstream_buffer";
468 NOTIFY_ERROR(UNREADABLE_INPUT); 468 NOTIFY_ERROR(UNREADABLE_INPUT);
469 return; 469 return;
470 } 470 }
471 DVLOG(3) << "DecodeTask(): mapped at=" << bitstream_record->shm->memory(); 471 DVLOG(3) << "DecodeTask(): mapped at=" << bitstream_record->shm->memory();
472 472
473 if (decoder_state_ == kResetting || decoder_flushing_) { 473 if (decoder_state_ == kResetting || decoder_flushing_) {
474 // In the case that we're resetting or flushing, we need to delay decoding 474 // In the case that we're resetting or flushing, we need to delay decoding
475 // the BitstreamBuffers that come after the Reset() or Flush() call. When 475 // the BitstreamBuffers that come after the Reset() or Flush() call. When
476 // we're here, we know that this DecodeTask() was scheduled by a Decode() 476 // we're here, we know that this DecodeTask() was scheduled by a Decode()
477 // call that came after (in the client thread) the Reset() or Flush() call; 477 // call that came after (in the client thread) the Reset() or Flush() call;
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after
957 // Drain the pipe of completed decode buffers. 957 // Drain the pipe of completed decode buffers.
958 const int old_inputs_queued = input_buffer_queued_count_; 958 const int old_inputs_queued = input_buffer_queued_count_;
959 while (!input_ready_queue_.empty()) { 959 while (!input_ready_queue_.empty()) {
960 if (!EnqueueInputRecord()) 960 if (!EnqueueInputRecord())
961 return; 961 return;
962 } 962 }
963 if (old_inputs_queued == 0 && input_buffer_queued_count_ != 0) { 963 if (old_inputs_queued == 0 && input_buffer_queued_count_ != 0) {
964 // We just started up a previously empty queue. 964 // We just started up a previously empty queue.
965 // Queue state changed; signal interrupt. 965 // Queue state changed; signal interrupt.
966 if (!device_->SetDevicePollInterrupt()) { 966 if (!device_->SetDevicePollInterrupt()) {
967 DPLOG(ERROR) << "SetDevicePollInterrupt(): failed"; 967 PLOG(ERROR) << "SetDevicePollInterrupt(): failed";
968 NOTIFY_ERROR(PLATFORM_FAILURE); 968 NOTIFY_ERROR(PLATFORM_FAILURE);
969 return; 969 return;
970 } 970 }
971 // Start VIDIOC_STREAMON if we haven't yet. 971 // Start VIDIOC_STREAMON if we haven't yet.
972 if (!input_streamon_) { 972 if (!input_streamon_) {
973 __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 973 __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
974 IOCTL_OR_ERROR_RETURN(VIDIOC_STREAMON, &type); 974 IOCTL_OR_ERROR_RETURN(VIDIOC_STREAMON, &type);
975 input_streamon_ = true; 975 input_streamon_ = true;
976 } 976 }
977 } 977 }
978 978
979 // Enqueue all the outputs we can. 979 // Enqueue all the outputs we can.
980 const int old_outputs_queued = output_buffer_queued_count_; 980 const int old_outputs_queued = output_buffer_queued_count_;
981 while (!free_output_buffers_.empty()) { 981 while (!free_output_buffers_.empty()) {
982 if (!EnqueueOutputRecord()) 982 if (!EnqueueOutputRecord())
983 return; 983 return;
984 } 984 }
985 if (old_outputs_queued == 0 && output_buffer_queued_count_ != 0) { 985 if (old_outputs_queued == 0 && output_buffer_queued_count_ != 0) {
986 // We just started up a previously empty queue. 986 // We just started up a previously empty queue.
987 // Queue state changed; signal interrupt. 987 // Queue state changed; signal interrupt.
988 if (!device_->SetDevicePollInterrupt()) { 988 if (!device_->SetDevicePollInterrupt()) {
989 DPLOG(ERROR) << "SetDevicePollInterrupt(): failed"; 989 PLOG(ERROR) << "SetDevicePollInterrupt(): failed";
990 NOTIFY_ERROR(PLATFORM_FAILURE); 990 NOTIFY_ERROR(PLATFORM_FAILURE);
991 return; 991 return;
992 } 992 }
993 // Start VIDIOC_STREAMON if we haven't yet. 993 // Start VIDIOC_STREAMON if we haven't yet.
994 if (!output_streamon_) { 994 if (!output_streamon_) {
995 __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 995 __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
996 IOCTL_OR_ERROR_RETURN(VIDIOC_STREAMON, &type); 996 IOCTL_OR_ERROR_RETURN(VIDIOC_STREAMON, &type);
997 output_streamon_ = true; 997 output_streamon_ = true;
998 } 998 }
999 } 999 }
1000 } 1000 }
1001 1001
1002 void V4L2VideoDecodeAccelerator::DequeueEvents() { 1002 void V4L2VideoDecodeAccelerator::DequeueEvents() {
1003 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1003 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1004 DCHECK_NE(decoder_state_, kUninitialized); 1004 DCHECK_NE(decoder_state_, kUninitialized);
1005 DVLOG(3) << "DequeueEvents()"; 1005 DVLOG(3) << "DequeueEvents()";
1006 1006
1007 struct v4l2_event ev; 1007 struct v4l2_event ev;
1008 memset(&ev, 0, sizeof(ev)); 1008 memset(&ev, 0, sizeof(ev));
1009 1009
1010 while (device_->Ioctl(VIDIOC_DQEVENT, &ev) == 0) { 1010 while (device_->Ioctl(VIDIOC_DQEVENT, &ev) == 0) {
1011 if (ev.type == V4L2_EVENT_RESOLUTION_CHANGE) { 1011 if (ev.type == V4L2_EVENT_RESOLUTION_CHANGE) {
1012 DVLOG(3) << "DequeueEvents(): got resolution change event."; 1012 DVLOG(3) << "DequeueEvents(): got resolution change event.";
1013 DCHECK(!resolution_change_pending_); 1013 DCHECK(!resolution_change_pending_);
1014 resolution_change_pending_ = IsResolutionChangeNecessary(); 1014 resolution_change_pending_ = IsResolutionChangeNecessary();
1015 } else { 1015 } else {
1016 DLOG(FATAL) << "DequeueEvents(): got an event (" << ev.type 1016 LOG(ERROR) << "DequeueEvents(): got an event (" << ev.type
1017 << ") we haven't subscribed to."; 1017 << ") we haven't subscribed to.";
1018 } 1018 }
1019 } 1019 }
1020 } 1020 }
1021 1021
1022 void V4L2VideoDecodeAccelerator::Dequeue() { 1022 void V4L2VideoDecodeAccelerator::Dequeue() {
1023 DVLOG(3) << "Dequeue()"; 1023 DVLOG(3) << "Dequeue()";
1024 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1024 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1025 DCHECK_NE(decoder_state_, kUninitialized); 1025 DCHECK_NE(decoder_state_, kUninitialized);
1026 TRACE_EVENT0("Video Decoder", "V4L2VDA::Dequeue"); 1026 TRACE_EVENT0("Video Decoder", "V4L2VDA::Dequeue");
1027 1027
1028 // Dequeue completed input (VIDEO_OUTPUT) buffers, and recycle to the free 1028 // Dequeue completed input (VIDEO_OUTPUT) buffers, and recycle to the free
1029 // list. 1029 // list.
1030 while (input_buffer_queued_count_ > 0) { 1030 while (input_buffer_queued_count_ > 0) {
1031 DCHECK(input_streamon_); 1031 DCHECK(input_streamon_);
1032 struct v4l2_buffer dqbuf; 1032 struct v4l2_buffer dqbuf;
1033 struct v4l2_plane planes[1]; 1033 struct v4l2_plane planes[1];
1034 memset(&dqbuf, 0, sizeof(dqbuf)); 1034 memset(&dqbuf, 0, sizeof(dqbuf));
1035 memset(planes, 0, sizeof(planes)); 1035 memset(planes, 0, sizeof(planes));
1036 dqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1036 dqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1037 dqbuf.memory = V4L2_MEMORY_MMAP; 1037 dqbuf.memory = V4L2_MEMORY_MMAP;
1038 dqbuf.m.planes = planes; 1038 dqbuf.m.planes = planes;
1039 dqbuf.length = 1; 1039 dqbuf.length = 1;
1040 if (device_->Ioctl(VIDIOC_DQBUF, &dqbuf) != 0) { 1040 if (device_->Ioctl(VIDIOC_DQBUF, &dqbuf) != 0) {
1041 if (errno == EAGAIN) { 1041 if (errno == EAGAIN) {
1042 // EAGAIN if we're just out of buffers to dequeue. 1042 // EAGAIN if we're just out of buffers to dequeue.
1043 break; 1043 break;
1044 } 1044 }
1045 DPLOG(ERROR) << "Dequeue(): ioctl() failed: VIDIOC_DQBUF"; 1045 PLOG(ERROR) << "Dequeue(): ioctl() failed: VIDIOC_DQBUF";
1046 NOTIFY_ERROR(PLATFORM_FAILURE); 1046 NOTIFY_ERROR(PLATFORM_FAILURE);
1047 return; 1047 return;
1048 } 1048 }
1049 InputRecord& input_record = input_buffer_map_[dqbuf.index]; 1049 InputRecord& input_record = input_buffer_map_[dqbuf.index];
1050 DCHECK(input_record.at_device); 1050 DCHECK(input_record.at_device);
1051 free_input_buffers_.push_back(dqbuf.index); 1051 free_input_buffers_.push_back(dqbuf.index);
1052 input_record.at_device = false; 1052 input_record.at_device = false;
1053 input_record.bytes_used = 0; 1053 input_record.bytes_used = 0;
1054 input_record.input_id = -1; 1054 input_record.input_id = -1;
1055 input_buffer_queued_count_--; 1055 input_buffer_queued_count_--;
(...skipping 10 matching lines...) Expand all
1066 memset(planes.get(), 0, sizeof(struct v4l2_plane) * output_planes_count_); 1066 memset(planes.get(), 0, sizeof(struct v4l2_plane) * output_planes_count_);
1067 dqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1067 dqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1068 dqbuf.memory = V4L2_MEMORY_MMAP; 1068 dqbuf.memory = V4L2_MEMORY_MMAP;
1069 dqbuf.m.planes = planes.get(); 1069 dqbuf.m.planes = planes.get();
1070 dqbuf.length = output_planes_count_; 1070 dqbuf.length = output_planes_count_;
1071 if (device_->Ioctl(VIDIOC_DQBUF, &dqbuf) != 0) { 1071 if (device_->Ioctl(VIDIOC_DQBUF, &dqbuf) != 0) {
1072 if (errno == EAGAIN) { 1072 if (errno == EAGAIN) {
1073 // EAGAIN if we're just out of buffers to dequeue. 1073 // EAGAIN if we're just out of buffers to dequeue.
1074 break; 1074 break;
1075 } 1075 }
1076 DPLOG(ERROR) << "Dequeue(): ioctl() failed: VIDIOC_DQBUF"; 1076 PLOG(ERROR) << "Dequeue(): ioctl() failed: VIDIOC_DQBUF";
1077 NOTIFY_ERROR(PLATFORM_FAILURE); 1077 NOTIFY_ERROR(PLATFORM_FAILURE);
1078 return; 1078 return;
1079 } 1079 }
1080 OutputRecord& output_record = output_buffer_map_[dqbuf.index]; 1080 OutputRecord& output_record = output_buffer_map_[dqbuf.index];
1081 DCHECK(output_record.at_device); 1081 DCHECK(output_record.at_device);
1082 DCHECK(!output_record.at_client); 1082 DCHECK(!output_record.at_client);
1083 DCHECK_NE(output_record.egl_image, EGL_NO_IMAGE_KHR); 1083 DCHECK_NE(output_record.egl_image, EGL_NO_IMAGE_KHR);
1084 DCHECK_NE(output_record.picture_id, -1); 1084 DCHECK_NE(output_record.picture_id, -1);
1085 output_record.at_device = false; 1085 output_record.at_device = false;
1086 if (dqbuf.m.planes[0].bytesused + dqbuf.m.planes[1].bytesused == 0) { 1086 if (dqbuf.m.planes[0].bytesused + dqbuf.m.planes[1].bytesused == 0) {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1151 "V4L2VDA::EnqueueOutputRecord: eglClientWaitSyncKHR"); 1151 "V4L2VDA::EnqueueOutputRecord: eglClientWaitSyncKHR");
1152 // If we have to wait for completion, wait. Note that 1152 // If we have to wait for completion, wait. Note that
1153 // free_output_buffers_ is a FIFO queue, so we always wait on the 1153 // free_output_buffers_ is a FIFO queue, so we always wait on the
1154 // buffer that has been in the queue the longest. 1154 // buffer that has been in the queue the longest.
1155 if (eglClientWaitSyncKHR(egl_display_, output_record.egl_sync, 0, 1155 if (eglClientWaitSyncKHR(egl_display_, output_record.egl_sync, 0,
1156 EGL_FOREVER_KHR) == EGL_FALSE) { 1156 EGL_FOREVER_KHR) == EGL_FALSE) {
1157 // This will cause tearing, but is safe otherwise. 1157 // This will cause tearing, but is safe otherwise.
1158 DVLOG(1) << __func__ << " eglClientWaitSyncKHR failed!"; 1158 DVLOG(1) << __func__ << " eglClientWaitSyncKHR failed!";
1159 } 1159 }
1160 if (eglDestroySyncKHR(egl_display_, output_record.egl_sync) != EGL_TRUE) { 1160 if (eglDestroySyncKHR(egl_display_, output_record.egl_sync) != EGL_TRUE) {
1161 DLOG(FATAL) << __func__ << " eglDestroySyncKHR failed!"; 1161 LOG(ERROR) << __func__ << " eglDestroySyncKHR failed!";
1162 NOTIFY_ERROR(PLATFORM_FAILURE); 1162 NOTIFY_ERROR(PLATFORM_FAILURE);
1163 return false; 1163 return false;
1164 } 1164 }
1165 output_record.egl_sync = EGL_NO_SYNC_KHR; 1165 output_record.egl_sync = EGL_NO_SYNC_KHR;
1166 } 1166 }
1167 struct v4l2_buffer qbuf; 1167 struct v4l2_buffer qbuf;
1168 scoped_ptr<struct v4l2_plane[]> qbuf_planes( 1168 scoped_ptr<struct v4l2_plane[]> qbuf_planes(
1169 new v4l2_plane[output_planes_count_]); 1169 new v4l2_plane[output_planes_count_]);
1170 memset(&qbuf, 0, sizeof(qbuf)); 1170 memset(&qbuf, 0, sizeof(qbuf));
1171 memset( 1171 memset(
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1211 // posted to us by the client. In that case just ignore this (we've already 1211 // posted to us by the client. In that case just ignore this (we've already
1212 // dismissed it and accounted for that) and let the sync object get 1212 // dismissed it and accounted for that) and let the sync object get
1213 // destroyed. 1213 // destroyed.
1214 DVLOG(4) << "ReusePictureBufferTask(): got picture id= " 1214 DVLOG(4) << "ReusePictureBufferTask(): got picture id= "
1215 << picture_buffer_id << " not in use (anymore?)."; 1215 << picture_buffer_id << " not in use (anymore?).";
1216 return; 1216 return;
1217 } 1217 }
1218 1218
1219 OutputRecord& output_record = output_buffer_map_[index]; 1219 OutputRecord& output_record = output_buffer_map_[index];
1220 if (output_record.at_device || !output_record.at_client) { 1220 if (output_record.at_device || !output_record.at_client) {
1221 DLOG(ERROR) << "ReusePictureBufferTask(): picture_buffer_id not reusable"; 1221 LOG(ERROR) << "ReusePictureBufferTask(): picture_buffer_id not reusable";
1222 NOTIFY_ERROR(INVALID_ARGUMENT); 1222 NOTIFY_ERROR(INVALID_ARGUMENT);
1223 return; 1223 return;
1224 } 1224 }
1225 1225
1226 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR); 1226 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR);
1227 DCHECK(!output_record.at_device); 1227 DCHECK(!output_record.at_device);
1228 output_record.at_client = false; 1228 output_record.at_client = false;
1229 output_record.egl_sync = egl_sync_ref->egl_sync; 1229 output_record.egl_sync = egl_sync_ref->egl_sync;
1230 free_output_buffers_.push(index); 1230 free_output_buffers_.push(index);
1231 decoder_frames_at_client_--; 1231 decoder_frames_at_client_--;
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
1417 decoder_state_ = kError; 1417 decoder_state_ = kError;
1418 } 1418 }
1419 1419
1420 bool V4L2VideoDecodeAccelerator::StartDevicePoll() { 1420 bool V4L2VideoDecodeAccelerator::StartDevicePoll() {
1421 DVLOG(3) << "StartDevicePoll()"; 1421 DVLOG(3) << "StartDevicePoll()";
1422 DCHECK(!device_poll_thread_.IsRunning()); 1422 DCHECK(!device_poll_thread_.IsRunning());
1423 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1423 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1424 1424
1425 // Start up the device poll thread and schedule its first DevicePollTask(). 1425 // Start up the device poll thread and schedule its first DevicePollTask().
1426 if (!device_poll_thread_.Start()) { 1426 if (!device_poll_thread_.Start()) {
1427 DLOG(ERROR) << "StartDevicePoll(): Device thread failed to start"; 1427 LOG(ERROR) << "StartDevicePoll(): Device thread failed to start";
1428 NOTIFY_ERROR(PLATFORM_FAILURE); 1428 NOTIFY_ERROR(PLATFORM_FAILURE);
1429 return false; 1429 return false;
1430 } 1430 }
1431 device_poll_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 1431 device_poll_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
1432 &V4L2VideoDecodeAccelerator::DevicePollTask, 1432 &V4L2VideoDecodeAccelerator::DevicePollTask,
1433 base::Unretained(this), 1433 base::Unretained(this),
1434 0)); 1434 0));
1435 1435
1436 return true; 1436 return true;
1437 } 1437 }
1438 1438
1439 bool V4L2VideoDecodeAccelerator::StopDevicePoll(bool keep_input_state) { 1439 bool V4L2VideoDecodeAccelerator::StopDevicePoll(bool keep_input_state) {
1440 DVLOG(3) << "StopDevicePoll()"; 1440 DVLOG(3) << "StopDevicePoll()";
1441 if (decoder_thread_.IsRunning()) 1441 if (decoder_thread_.IsRunning())
1442 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1442 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1443 1443
1444 // Signal the DevicePollTask() to stop, and stop the device poll thread. 1444 // Signal the DevicePollTask() to stop, and stop the device poll thread.
1445 if (!device_->SetDevicePollInterrupt()) { 1445 if (!device_->SetDevicePollInterrupt()) {
1446 DPLOG(ERROR) << "SetDevicePollInterrupt(): failed"; 1446 PLOG(ERROR) << "SetDevicePollInterrupt(): failed";
1447 NOTIFY_ERROR(PLATFORM_FAILURE); 1447 NOTIFY_ERROR(PLATFORM_FAILURE);
1448 return false; 1448 return false;
1449 } 1449 }
1450 device_poll_thread_.Stop(); 1450 device_poll_thread_.Stop();
1451 // Clear the interrupt now, to be sure. 1451 // Clear the interrupt now, to be sure.
1452 if (!device_->ClearDevicePollInterrupt()) { 1452 if (!device_->ClearDevicePollInterrupt()) {
1453 NOTIFY_ERROR(PLATFORM_FAILURE); 1453 NOTIFY_ERROR(PLATFORM_FAILURE);
1454 return false; 1454 return false;
1455 } 1455 }
1456 1456
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1537 1537
1538 if (decoder_state_ == kError) { 1538 if (decoder_state_ == kError) {
1539 DVLOG(2) << "FinishResolutionChange(): early out: kError state"; 1539 DVLOG(2) << "FinishResolutionChange(): early out: kError state";
1540 return; 1540 return;
1541 } 1541 }
1542 1542
1543 struct v4l2_format format; 1543 struct v4l2_format format;
1544 bool again; 1544 bool again;
1545 bool ret = GetFormatInfo(&format, &again); 1545 bool ret = GetFormatInfo(&format, &again);
1546 if (!ret || again) { 1546 if (!ret || again) {
1547 DVLOG(3) << "Couldn't get format information after resolution change"; 1547 LOG(ERROR) << "Couldn't get format information after resolution change";
1548 NOTIFY_ERROR(PLATFORM_FAILURE); 1548 NOTIFY_ERROR(PLATFORM_FAILURE);
1549 return; 1549 return;
1550 } 1550 }
1551 1551
1552 if (!CreateBuffersForFormat(format)) { 1552 if (!CreateBuffersForFormat(format)) {
1553 DVLOG(3) << "Couldn't reallocate buffers after resolution change"; 1553 LOG(ERROR) << "Couldn't reallocate buffers after resolution change";
1554 NOTIFY_ERROR(PLATFORM_FAILURE); 1554 NOTIFY_ERROR(PLATFORM_FAILURE);
1555 return; 1555 return;
1556 } 1556 }
1557 1557
1558 decoder_state_ = kDecoding; 1558 decoder_state_ = kDecoding;
1559 1559
1560 if (resolution_change_reset_pending_) { 1560 if (resolution_change_reset_pending_) {
1561 resolution_change_reset_pending_ = false; 1561 resolution_change_reset_pending_ = false;
1562 ResetTask(); 1562 ResetTask();
1563 return; 1563 return;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1625 1625
1626 *again = false; 1626 *again = false;
1627 memset(format, 0, sizeof(*format)); 1627 memset(format, 0, sizeof(*format));
1628 format->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1628 format->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1629 if (device_->Ioctl(VIDIOC_G_FMT, format) != 0) { 1629 if (device_->Ioctl(VIDIOC_G_FMT, format) != 0) {
1630 if (errno == EINVAL) { 1630 if (errno == EINVAL) {
1631 // EINVAL means we haven't seen sufficient stream to decode the format. 1631 // EINVAL means we haven't seen sufficient stream to decode the format.
1632 *again = true; 1632 *again = true;
1633 return true; 1633 return true;
1634 } else { 1634 } else {
1635 DPLOG(ERROR) << __func__ << "(): ioctl() failed: VIDIOC_G_FMT"; 1635 PLOG(ERROR) << __func__ << "(): ioctl() failed: VIDIOC_G_FMT";
1636 NOTIFY_ERROR(PLATFORM_FAILURE); 1636 NOTIFY_ERROR(PLATFORM_FAILURE);
1637 return false; 1637 return false;
1638 } 1638 }
1639 } 1639 }
1640 1640
1641 return true; 1641 return true;
1642 } 1642 }
1643 1643
1644 bool V4L2VideoDecodeAccelerator::CreateBuffersForFormat( 1644 bool V4L2VideoDecodeAccelerator::CreateBuffersForFormat(
1645 const struct v4l2_format& format) { 1645 const struct v4l2_format& format) {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1701 buffer.memory = V4L2_MEMORY_MMAP; 1701 buffer.memory = V4L2_MEMORY_MMAP;
1702 buffer.m.planes = planes; 1702 buffer.m.planes = planes;
1703 buffer.length = 1; 1703 buffer.length = 1;
1704 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYBUF, &buffer); 1704 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYBUF, &buffer);
1705 void* address = device_->Mmap(NULL, 1705 void* address = device_->Mmap(NULL,
1706 buffer.m.planes[0].length, 1706 buffer.m.planes[0].length,
1707 PROT_READ | PROT_WRITE, 1707 PROT_READ | PROT_WRITE,
1708 MAP_SHARED, 1708 MAP_SHARED,
1709 buffer.m.planes[0].m.mem_offset); 1709 buffer.m.planes[0].m.mem_offset);
1710 if (address == MAP_FAILED) { 1710 if (address == MAP_FAILED) {
1711 DPLOG(ERROR) << "CreateInputBuffers(): mmap() failed"; 1711 PLOG(ERROR) << "CreateInputBuffers(): mmap() failed";
1712 return false; 1712 return false;
1713 } 1713 }
1714 input_buffer_map_[i].address = address; 1714 input_buffer_map_[i].address = address;
1715 input_buffer_map_[i].length = buffer.m.planes[0].length; 1715 input_buffer_map_[i].length = buffer.m.planes[0].length;
1716 } 1716 }
1717 1717
1718 return true; 1718 return true;
1719 } 1719 }
1720 1720
1721 bool V4L2VideoDecodeAccelerator::CreateOutputBuffers() { 1721 bool V4L2VideoDecodeAccelerator::CreateOutputBuffers() {
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
1828 base::Bind( 1828 base::Bind(
1829 &Client::DismissPictureBuffer, client_, output_record.picture_id)); 1829 &Client::DismissPictureBuffer, client_, output_record.picture_id));
1830 } 1830 }
1831 1831
1832 struct v4l2_requestbuffers reqbufs; 1832 struct v4l2_requestbuffers reqbufs;
1833 memset(&reqbufs, 0, sizeof(reqbufs)); 1833 memset(&reqbufs, 0, sizeof(reqbufs));
1834 reqbufs.count = 0; 1834 reqbufs.count = 0;
1835 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1835 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1836 reqbufs.memory = V4L2_MEMORY_MMAP; 1836 reqbufs.memory = V4L2_MEMORY_MMAP;
1837 if (device_->Ioctl(VIDIOC_REQBUFS, &reqbufs) != 0) { 1837 if (device_->Ioctl(VIDIOC_REQBUFS, &reqbufs) != 0) {
1838 DPLOG(ERROR) << "DestroyOutputBuffers() ioctl() failed: VIDIOC_REQBUFS"; 1838 PLOG(ERROR) << "DestroyOutputBuffers() ioctl() failed: VIDIOC_REQBUFS";
1839 success = false; 1839 success = false;
1840 } 1840 }
1841 1841
1842 output_buffer_map_.clear(); 1842 output_buffer_map_.clear();
1843 while (!free_output_buffers_.empty()) 1843 while (!free_output_buffers_.empty())
1844 free_output_buffers_.pop(); 1844 free_output_buffers_.pop();
1845 1845
1846 return success; 1846 return success;
1847 } 1847 }
1848 1848
1849 void V4L2VideoDecodeAccelerator::ResolutionChangeDestroyBuffers() { 1849 void V4L2VideoDecodeAccelerator::ResolutionChangeDestroyBuffers() {
1850 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 1850 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
1851 DVLOG(3) << "ResolutionChangeDestroyBuffers()"; 1851 DVLOG(3) << "ResolutionChangeDestroyBuffers()";
1852 1852
1853 if (!DestroyOutputBuffers()) { 1853 if (!DestroyOutputBuffers()) {
1854 DLOG(FATAL) << __func__ << " Failed destroying output buffers."; 1854 LOG(ERROR) << __func__ << " Failed destroying output buffers.";
1855 NOTIFY_ERROR(PLATFORM_FAILURE); 1855 NOTIFY_ERROR(PLATFORM_FAILURE);
1856 return; 1856 return;
1857 } 1857 }
1858 1858
1859 // Finish resolution change on decoder thread. 1859 // Finish resolution change on decoder thread.
1860 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 1860 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
1861 &V4L2VideoDecodeAccelerator::FinishResolutionChange, 1861 &V4L2VideoDecodeAccelerator::FinishResolutionChange,
1862 base::Unretained(this))); 1862 base::Unretained(this)));
1863 } 1863 }
1864 1864
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1934 gfx::Size new_size(base::checked_cast<int>(format.fmt.pix_mp.width), 1934 gfx::Size new_size(base::checked_cast<int>(format.fmt.pix_mp.width),
1935 base::checked_cast<int>(format.fmt.pix_mp.height)); 1935 base::checked_cast<int>(format.fmt.pix_mp.height));
1936 if (frame_buffer_size_ != new_size) { 1936 if (frame_buffer_size_ != new_size) {
1937 DVLOG(3) << "IsResolutionChangeNecessary(): Resolution change detected"; 1937 DVLOG(3) << "IsResolutionChangeNecessary(): Resolution change detected";
1938 return true; 1938 return true;
1939 } 1939 }
1940 return false; 1940 return false;
1941 } 1941 }
1942 1942
1943 } // namespace content 1943 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/media/v4l2_image_processor.cc ('k') | content/common/gpu/media/v4l2_video_device.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698