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

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

Issue 2076423004: Remove calls to MessageLoop::current() in media. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: CR Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/gpu/v4l2_video_decode_accelerator.cc ('k') | media/gpu/vaapi_video_decode_accelerator.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/gpu/v4l2_video_encode_accelerator.h" 5 #include "media/gpu/v4l2_video_encode_accelerator.h"
6 6
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 <utility> 15 #include <utility>
16 16
17 #include "base/callback.h" 17 #include "base/callback.h"
18 #include "base/command_line.h" 18 #include "base/command_line.h"
19 #include "base/macros.h" 19 #include "base/macros.h"
20 #include "base/numerics/safe_conversions.h" 20 #include "base/numerics/safe_conversions.h"
21 #include "base/single_thread_task_runner.h"
21 #include "base/threading/thread_task_runner_handle.h" 22 #include "base/threading/thread_task_runner_handle.h"
22 #include "base/trace_event/trace_event.h" 23 #include "base/trace_event/trace_event.h"
23 #include "media/base/bind_to_current_loop.h" 24 #include "media/base/bind_to_current_loop.h"
24 #include "media/base/bitstream_buffer.h" 25 #include "media/base/bitstream_buffer.h"
25 #include "media/gpu/shared_memory_region.h" 26 #include "media/gpu/shared_memory_region.h"
26 27
27 #define NOTIFY_ERROR(x) \ 28 #define NOTIFY_ERROR(x) \
28 do { \ 29 do { \
29 LOG(ERROR) << "Setting error state:" << x; \ 30 LOG(ERROR) << "Setting error state:" << x; \
30 SetErrorState(x); \ 31 SetErrorState(x); \
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 base::Bind(&V4L2VideoEncodeAccelerator::FrameProcessed, 236 base::Bind(&V4L2VideoEncodeAccelerator::FrameProcessed,
236 base::Unretained(this), force_keyframe, 237 base::Unretained(this), force_keyframe,
237 frame->timestamp())); 238 frame->timestamp()));
238 } else { 239 } else {
239 ImageProcessorInputRecord record; 240 ImageProcessorInputRecord record;
240 record.frame = frame; 241 record.frame = frame;
241 record.force_keyframe = force_keyframe; 242 record.force_keyframe = force_keyframe;
242 image_processor_input_queue_.push(record); 243 image_processor_input_queue_.push(record);
243 } 244 }
244 } else { 245 } else {
245 encoder_thread_.message_loop()->PostTask( 246 encoder_thread_.task_runner()->PostTask(
246 FROM_HERE, base::Bind(&V4L2VideoEncodeAccelerator::EncodeTask, 247 FROM_HERE, base::Bind(&V4L2VideoEncodeAccelerator::EncodeTask,
247 base::Unretained(this), frame, force_keyframe)); 248 base::Unretained(this), frame, force_keyframe));
248 } 249 }
249 } 250 }
250 251
251 void V4L2VideoEncodeAccelerator::UseOutputBitstreamBuffer( 252 void V4L2VideoEncodeAccelerator::UseOutputBitstreamBuffer(
252 const BitstreamBuffer& buffer) { 253 const BitstreamBuffer& buffer) {
253 DVLOG(3) << "UseOutputBitstreamBuffer(): id=" << buffer.id(); 254 DVLOG(3) << "UseOutputBitstreamBuffer(): id=" << buffer.id();
254 DCHECK(child_task_runner_->BelongsToCurrentThread()); 255 DCHECK(child_task_runner_->BelongsToCurrentThread());
255 256
256 if (buffer.size() < output_buffer_byte_size_) { 257 if (buffer.size() < output_buffer_byte_size_) {
257 NOTIFY_ERROR(kInvalidArgumentError); 258 NOTIFY_ERROR(kInvalidArgumentError);
258 return; 259 return;
259 } 260 }
260 261
261 std::unique_ptr<SharedMemoryRegion> shm( 262 std::unique_ptr<SharedMemoryRegion> shm(
262 new SharedMemoryRegion(buffer, false)); 263 new SharedMemoryRegion(buffer, false));
263 if (!shm->Map()) { 264 if (!shm->Map()) {
264 NOTIFY_ERROR(kPlatformFailureError); 265 NOTIFY_ERROR(kPlatformFailureError);
265 return; 266 return;
266 } 267 }
267 268
268 std::unique_ptr<BitstreamBufferRef> buffer_ref( 269 std::unique_ptr<BitstreamBufferRef> buffer_ref(
269 new BitstreamBufferRef(buffer.id(), std::move(shm))); 270 new BitstreamBufferRef(buffer.id(), std::move(shm)));
270 encoder_thread_.message_loop()->PostTask( 271 encoder_thread_.task_runner()->PostTask(
271 FROM_HERE, 272 FROM_HERE,
272 base::Bind(&V4L2VideoEncodeAccelerator::UseOutputBitstreamBufferTask, 273 base::Bind(&V4L2VideoEncodeAccelerator::UseOutputBitstreamBufferTask,
273 base::Unretained(this), base::Passed(&buffer_ref))); 274 base::Unretained(this), base::Passed(&buffer_ref)));
274 } 275 }
275 276
276 void V4L2VideoEncodeAccelerator::RequestEncodingParametersChange( 277 void V4L2VideoEncodeAccelerator::RequestEncodingParametersChange(
277 uint32_t bitrate, 278 uint32_t bitrate,
278 uint32_t framerate) { 279 uint32_t framerate) {
279 DVLOG(3) << "RequestEncodingParametersChange(): bitrate=" << bitrate 280 DVLOG(3) << "RequestEncodingParametersChange(): bitrate=" << bitrate
280 << ", framerate=" << framerate; 281 << ", framerate=" << framerate;
281 DCHECK(child_task_runner_->BelongsToCurrentThread()); 282 DCHECK(child_task_runner_->BelongsToCurrentThread());
282 283
283 encoder_thread_.message_loop()->PostTask( 284 encoder_thread_.task_runner()->PostTask(
284 FROM_HERE, 285 FROM_HERE,
285 base::Bind( 286 base::Bind(
286 &V4L2VideoEncodeAccelerator::RequestEncodingParametersChangeTask, 287 &V4L2VideoEncodeAccelerator::RequestEncodingParametersChangeTask,
287 base::Unretained(this), bitrate, framerate)); 288 base::Unretained(this), bitrate, framerate));
288 } 289 }
289 290
290 void V4L2VideoEncodeAccelerator::Destroy() { 291 void V4L2VideoEncodeAccelerator::Destroy() {
291 DVLOG(3) << "Destroy()"; 292 DVLOG(3) << "Destroy()";
292 DCHECK(child_task_runner_->BelongsToCurrentThread()); 293 DCHECK(child_task_runner_->BelongsToCurrentThread());
293 294
294 // We're destroying; cancel all callbacks. 295 // We're destroying; cancel all callbacks.
295 client_ptr_factory_.reset(); 296 client_ptr_factory_.reset();
296 weak_this_ptr_factory_.InvalidateWeakPtrs(); 297 weak_this_ptr_factory_.InvalidateWeakPtrs();
297 298
298 if (image_processor_.get()) 299 if (image_processor_.get())
299 image_processor_.release()->Destroy(); 300 image_processor_.release()->Destroy();
300 301
301 // If the encoder thread is running, destroy using posted task. 302 // If the encoder thread is running, destroy using posted task.
302 if (encoder_thread_.IsRunning()) { 303 if (encoder_thread_.IsRunning()) {
303 encoder_thread_.message_loop()->PostTask( 304 encoder_thread_.task_runner()->PostTask(
304 FROM_HERE, base::Bind(&V4L2VideoEncodeAccelerator::DestroyTask, 305 FROM_HERE, base::Bind(&V4L2VideoEncodeAccelerator::DestroyTask,
305 base::Unretained(this))); 306 base::Unretained(this)));
306 // DestroyTask() will put the encoder into kError state and cause all tasks 307 // DestroyTask() will put the encoder into kError state and cause all tasks
307 // to no-op. 308 // to no-op.
308 encoder_thread_.Stop(); 309 encoder_thread_.Stop();
309 } else { 310 } else {
310 // Otherwise, call the destroy task directly. 311 // Otherwise, call the destroy task directly.
311 DestroyTask(); 312 DestroyTask();
312 } 313 }
313 314
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 device_input_format_, image_processor_->output_allocated_size(), 377 device_input_format_, image_processor_->output_allocated_size(),
377 gfx::Rect(visible_size_), visible_size_, fds, timestamp); 378 gfx::Rect(visible_size_), visible_size_, fds, timestamp);
378 if (!output_frame) { 379 if (!output_frame) {
379 NOTIFY_ERROR(kPlatformFailureError); 380 NOTIFY_ERROR(kPlatformFailureError);
380 return; 381 return;
381 } 382 }
382 output_frame->AddDestructionObserver(BindToCurrentLoop( 383 output_frame->AddDestructionObserver(BindToCurrentLoop(
383 base::Bind(&V4L2VideoEncodeAccelerator::ReuseImageProcessorOutputBuffer, 384 base::Bind(&V4L2VideoEncodeAccelerator::ReuseImageProcessorOutputBuffer,
384 weak_this_, output_buffer_index))); 385 weak_this_, output_buffer_index)));
385 386
386 encoder_thread_.message_loop()->PostTask( 387 encoder_thread_.task_runner()->PostTask(
387 FROM_HERE, 388 FROM_HERE,
388 base::Bind(&V4L2VideoEncodeAccelerator::EncodeTask, 389 base::Bind(&V4L2VideoEncodeAccelerator::EncodeTask,
389 base::Unretained(this), output_frame, force_keyframe)); 390 base::Unretained(this), output_frame, force_keyframe));
390 } 391 }
391 392
392 void V4L2VideoEncodeAccelerator::ReuseImageProcessorOutputBuffer( 393 void V4L2VideoEncodeAccelerator::ReuseImageProcessorOutputBuffer(
393 int output_buffer_index) { 394 int output_buffer_index) {
394 DCHECK(child_task_runner_->BelongsToCurrentThread()); 395 DCHECK(child_task_runner_->BelongsToCurrentThread());
395 DVLOG(3) << __func__ << ": output_buffer_index=" << output_buffer_index; 396 DVLOG(3) << __func__ << ": output_buffer_index=" << output_buffer_index;
396 free_image_processor_output_buffers_.push_back(output_buffer_index); 397 free_image_processor_output_buffers_.push_back(output_buffer_index);
397 if (!image_processor_input_queue_.empty()) { 398 if (!image_processor_input_queue_.empty()) {
398 ImageProcessorInputRecord record = image_processor_input_queue_.front(); 399 ImageProcessorInputRecord record = image_processor_input_queue_.front();
399 image_processor_input_queue_.pop(); 400 image_processor_input_queue_.pop();
400 Encode(record.frame, record.force_keyframe); 401 Encode(record.frame, record.force_keyframe);
401 } 402 }
402 } 403 }
403 404
404 void V4L2VideoEncodeAccelerator::EncodeTask( 405 void V4L2VideoEncodeAccelerator::EncodeTask(
405 const scoped_refptr<VideoFrame>& frame, 406 const scoped_refptr<VideoFrame>& frame,
406 bool force_keyframe) { 407 bool force_keyframe) {
407 DVLOG(3) << "EncodeTask(): force_keyframe=" << force_keyframe; 408 DVLOG(3) << "EncodeTask(): force_keyframe=" << force_keyframe;
408 DCHECK_EQ(encoder_thread_.message_loop(), base::MessageLoop::current()); 409 DCHECK(encoder_thread_.task_runner()->BelongsToCurrentThread());
409 DCHECK_NE(encoder_state_, kUninitialized); 410 DCHECK_NE(encoder_state_, kUninitialized);
410 411
411 if (encoder_state_ == kError) { 412 if (encoder_state_ == kError) {
412 DVLOG(2) << "EncodeTask(): early out: kError state"; 413 DVLOG(2) << "EncodeTask(): early out: kError state";
413 return; 414 return;
414 } 415 }
415 416
416 encoder_input_queue_.push(frame); 417 encoder_input_queue_.push(frame);
417 Enqueue(); 418 Enqueue();
418 419
(...skipping 22 matching lines...) Expand all
441 NOTIFY_ERROR(kPlatformFailureError); 442 NOTIFY_ERROR(kPlatformFailureError);
442 return; 443 return;
443 } 444 }
444 } 445 }
445 } 446 }
446 } 447 }
447 448
448 void V4L2VideoEncodeAccelerator::UseOutputBitstreamBufferTask( 449 void V4L2VideoEncodeAccelerator::UseOutputBitstreamBufferTask(
449 std::unique_ptr<BitstreamBufferRef> buffer_ref) { 450 std::unique_ptr<BitstreamBufferRef> buffer_ref) {
450 DVLOG(3) << "UseOutputBitstreamBufferTask(): id=" << buffer_ref->id; 451 DVLOG(3) << "UseOutputBitstreamBufferTask(): id=" << buffer_ref->id;
451 DCHECK_EQ(encoder_thread_.message_loop(), base::MessageLoop::current()); 452 DCHECK(encoder_thread_.task_runner()->BelongsToCurrentThread());
452 453
453 encoder_output_queue_.push_back( 454 encoder_output_queue_.push_back(
454 linked_ptr<BitstreamBufferRef>(buffer_ref.release())); 455 linked_ptr<BitstreamBufferRef>(buffer_ref.release()));
455 Enqueue(); 456 Enqueue();
456 457
457 if (encoder_state_ == kInitialized) { 458 if (encoder_state_ == kInitialized) {
458 // Finish setting up our OUTPUT queue. See: Initialize(). 459 // Finish setting up our OUTPUT queue. See: Initialize().
459 // VIDIOC_REQBUFS on OUTPUT queue. 460 // VIDIOC_REQBUFS on OUTPUT queue.
460 if (!CreateInputBuffers()) 461 if (!CreateInputBuffers())
461 return; 462 return;
(...skipping 10 matching lines...) Expand all
472 473
473 // Stop streaming and the device_poll_thread_. 474 // Stop streaming and the device_poll_thread_.
474 StopDevicePoll(); 475 StopDevicePoll();
475 476
476 // Set our state to kError, and early-out all tasks. 477 // Set our state to kError, and early-out all tasks.
477 encoder_state_ = kError; 478 encoder_state_ = kError;
478 } 479 }
479 480
480 void V4L2VideoEncodeAccelerator::ServiceDeviceTask() { 481 void V4L2VideoEncodeAccelerator::ServiceDeviceTask() {
481 DVLOG(3) << "ServiceDeviceTask()"; 482 DVLOG(3) << "ServiceDeviceTask()";
482 DCHECK_EQ(encoder_thread_.message_loop(), base::MessageLoop::current()); 483 DCHECK(encoder_thread_.task_runner()->BelongsToCurrentThread());
483 DCHECK_NE(encoder_state_, kUninitialized); 484 DCHECK_NE(encoder_state_, kUninitialized);
484 DCHECK_NE(encoder_state_, kInitialized); 485 DCHECK_NE(encoder_state_, kInitialized);
485 486
486 if (encoder_state_ == kError) { 487 if (encoder_state_ == kError) {
487 DVLOG(2) << "ServiceDeviceTask(): early out: kError state"; 488 DVLOG(2) << "ServiceDeviceTask(): early out: kError state";
488 return; 489 return;
489 } 490 }
490 491
491 Dequeue(); 492 Dequeue();
492 Enqueue(); 493 Enqueue();
493 494
494 // Clear the interrupt fd. 495 // Clear the interrupt fd.
495 if (!device_->ClearDevicePollInterrupt()) 496 if (!device_->ClearDevicePollInterrupt())
496 return; 497 return;
497 498
498 // Device can be polled as soon as either input or output buffers are queued. 499 // Device can be polled as soon as either input or output buffers are queued.
499 bool poll_device = 500 bool poll_device =
500 (input_buffer_queued_count_ + output_buffer_queued_count_ > 0); 501 (input_buffer_queued_count_ + output_buffer_queued_count_ > 0);
501 502
502 // ServiceDeviceTask() should only ever be scheduled from DevicePollTask(), 503 // ServiceDeviceTask() should only ever be scheduled from DevicePollTask(),
503 // so either: 504 // so either:
504 // * device_poll_thread_ is running normally 505 // * device_poll_thread_ is running normally
505 // * device_poll_thread_ scheduled us, but then a DestroyTask() shut it down, 506 // * device_poll_thread_ scheduled us, but then a DestroyTask() shut it down,
506 // in which case we're in kError state, and we should have early-outed 507 // in which case we're in kError state, and we should have early-outed
507 // already. 508 // already.
508 DCHECK(device_poll_thread_.message_loop()); 509 DCHECK(device_poll_thread_.message_loop());
509 // Queue the DevicePollTask() now. 510 // Queue the DevicePollTask() now.
510 device_poll_thread_.message_loop()->PostTask( 511 device_poll_thread_.task_runner()->PostTask(
511 FROM_HERE, base::Bind(&V4L2VideoEncodeAccelerator::DevicePollTask, 512 FROM_HERE, base::Bind(&V4L2VideoEncodeAccelerator::DevicePollTask,
512 base::Unretained(this), poll_device)); 513 base::Unretained(this), poll_device));
513 514
514 DVLOG(2) << __func__ << ": buffer counts: ENC[" 515 DVLOG(2) << __func__ << ": buffer counts: ENC["
515 << encoder_input_queue_.size() << "] => DEVICE[" 516 << encoder_input_queue_.size() << "] => DEVICE["
516 << free_input_buffers_.size() << "+" 517 << free_input_buffers_.size() << "+"
517 << input_buffer_queued_count_ << "/" 518 << input_buffer_queued_count_ << "/"
518 << input_buffer_map_.size() << "->" 519 << input_buffer_map_.size() << "->"
519 << free_output_buffers_.size() << "+" 520 << free_output_buffers_.size() << "+"
520 << output_buffer_queued_count_ << "/" 521 << output_buffer_queued_count_ << "/"
521 << output_buffer_map_.size() << "] => OUT[" 522 << output_buffer_map_.size() << "] => OUT["
522 << encoder_output_queue_.size() << "]"; 523 << encoder_output_queue_.size() << "]";
523 } 524 }
524 525
525 void V4L2VideoEncodeAccelerator::Enqueue() { 526 void V4L2VideoEncodeAccelerator::Enqueue() {
526 DCHECK_EQ(encoder_thread_.message_loop(), base::MessageLoop::current()); 527 DCHECK(encoder_thread_.task_runner()->BelongsToCurrentThread());
527 528
528 DVLOG(3) << "Enqueue() " 529 DVLOG(3) << "Enqueue() "
529 << "free_input_buffers: " << free_input_buffers_.size() 530 << "free_input_buffers: " << free_input_buffers_.size()
530 << "input_queue: " << encoder_input_queue_.size(); 531 << "input_queue: " << encoder_input_queue_.size();
531 532
532 // Enqueue all the inputs we can. 533 // Enqueue all the inputs we can.
533 const int old_inputs_queued = input_buffer_queued_count_; 534 const int old_inputs_queued = input_buffer_queued_count_;
534 // while (!ready_input_buffers_.empty()) { 535 // while (!ready_input_buffers_.empty()) {
535 while (!encoder_input_queue_.empty() && !free_input_buffers_.empty()) { 536 while (!encoder_input_queue_.empty() && !free_input_buffers_.empty()) {
536 if (!EnqueueInputRecord()) 537 if (!EnqueueInputRecord())
(...skipping 27 matching lines...) Expand all
564 if (!output_streamon_) { 565 if (!output_streamon_) {
565 __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 566 __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
566 IOCTL_OR_ERROR_RETURN(VIDIOC_STREAMON, &type); 567 IOCTL_OR_ERROR_RETURN(VIDIOC_STREAMON, &type);
567 output_streamon_ = true; 568 output_streamon_ = true;
568 } 569 }
569 } 570 }
570 } 571 }
571 572
572 void V4L2VideoEncodeAccelerator::Dequeue() { 573 void V4L2VideoEncodeAccelerator::Dequeue() {
573 DVLOG(3) << "Dequeue()"; 574 DVLOG(3) << "Dequeue()";
574 DCHECK_EQ(encoder_thread_.message_loop(), base::MessageLoop::current()); 575 DCHECK(encoder_thread_.task_runner()->BelongsToCurrentThread());
575 576
576 // Dequeue completed input (VIDEO_OUTPUT) buffers, and recycle to the free 577 // Dequeue completed input (VIDEO_OUTPUT) buffers, and recycle to the free
577 // list. 578 // list.
578 struct v4l2_buffer dqbuf; 579 struct v4l2_buffer dqbuf;
579 struct v4l2_plane planes[VIDEO_MAX_PLANES]; 580 struct v4l2_plane planes[VIDEO_MAX_PLANES];
580 while (input_buffer_queued_count_ > 0) { 581 while (input_buffer_queued_count_ > 0) {
581 DVLOG(4) << "inputs queued: " << input_buffer_queued_count_; 582 DVLOG(4) << "inputs queued: " << input_buffer_queued_count_;
582 DCHECK(input_streamon_); 583 DCHECK(input_streamon_);
583 memset(&dqbuf, 0, sizeof(dqbuf)); 584 memset(&dqbuf, 0, sizeof(dqbuf));
584 memset(&planes, 0, sizeof(planes)); 585 memset(&planes, 0, sizeof(planes));
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
759 output_record.at_device = true; 760 output_record.at_device = true;
760 output_record.buffer_ref = output_buffer; 761 output_record.buffer_ref = output_buffer;
761 encoder_output_queue_.pop_back(); 762 encoder_output_queue_.pop_back();
762 free_output_buffers_.pop_back(); 763 free_output_buffers_.pop_back();
763 output_buffer_queued_count_++; 764 output_buffer_queued_count_++;
764 return true; 765 return true;
765 } 766 }
766 767
767 bool V4L2VideoEncodeAccelerator::StartDevicePoll() { 768 bool V4L2VideoEncodeAccelerator::StartDevicePoll() {
768 DVLOG(3) << "StartDevicePoll()"; 769 DVLOG(3) << "StartDevicePoll()";
769 DCHECK_EQ(encoder_thread_.message_loop(), base::MessageLoop::current()); 770 DCHECK(encoder_thread_.task_runner()->BelongsToCurrentThread());
770 DCHECK(!device_poll_thread_.IsRunning()); 771 DCHECK(!device_poll_thread_.IsRunning());
771 772
772 // Start up the device poll thread and schedule its first DevicePollTask(). 773 // Start up the device poll thread and schedule its first DevicePollTask().
773 if (!device_poll_thread_.Start()) { 774 if (!device_poll_thread_.Start()) {
774 LOG(ERROR) << "StartDevicePoll(): Device thread failed to start"; 775 LOG(ERROR) << "StartDevicePoll(): Device thread failed to start";
775 NOTIFY_ERROR(kPlatformFailureError); 776 NOTIFY_ERROR(kPlatformFailureError);
776 return false; 777 return false;
777 } 778 }
778 // Enqueue a poll task with no devices to poll on -- it will wait only on the 779 // Enqueue a poll task with no devices to poll on -- it will wait only on the
779 // interrupt fd. 780 // interrupt fd.
780 device_poll_thread_.message_loop()->PostTask( 781 device_poll_thread_.task_runner()->PostTask(
781 FROM_HERE, base::Bind(&V4L2VideoEncodeAccelerator::DevicePollTask, 782 FROM_HERE, base::Bind(&V4L2VideoEncodeAccelerator::DevicePollTask,
782 base::Unretained(this), false)); 783 base::Unretained(this), false));
783 784
784 return true; 785 return true;
785 } 786 }
786 787
787 bool V4L2VideoEncodeAccelerator::StopDevicePoll() { 788 bool V4L2VideoEncodeAccelerator::StopDevicePoll() {
788 DVLOG(3) << "StopDevicePoll()"; 789 DVLOG(3) << "StopDevicePoll()";
789 790
790 // Signal the DevicePollTask() to stop, and stop the device poll thread. 791 // Signal the DevicePollTask() to stop, and stop the device poll thread.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
829 output_buffer_queued_count_ = 0; 830 output_buffer_queued_count_ = 0;
830 831
831 encoder_output_queue_.clear(); 832 encoder_output_queue_.clear();
832 833
833 DVLOG(3) << "StopDevicePoll(): device poll stopped"; 834 DVLOG(3) << "StopDevicePoll(): device poll stopped";
834 return true; 835 return true;
835 } 836 }
836 837
837 void V4L2VideoEncodeAccelerator::DevicePollTask(bool poll_device) { 838 void V4L2VideoEncodeAccelerator::DevicePollTask(bool poll_device) {
838 DVLOG(3) << "DevicePollTask()"; 839 DVLOG(3) << "DevicePollTask()";
839 DCHECK_EQ(device_poll_thread_.message_loop(), base::MessageLoop::current()); 840 DCHECK(device_poll_thread_.task_runner()->BelongsToCurrentThread());
840 841
841 bool event_pending; 842 bool event_pending;
842 if (!device_->Poll(poll_device, &event_pending)) { 843 if (!device_->Poll(poll_device, &event_pending)) {
843 NOTIFY_ERROR(kPlatformFailureError); 844 NOTIFY_ERROR(kPlatformFailureError);
844 return; 845 return;
845 } 846 }
846 847
847 // All processing should happen on ServiceDeviceTask(), since we shouldn't 848 // All processing should happen on ServiceDeviceTask(), since we shouldn't
848 // touch encoder state from this thread. 849 // touch encoder state from this thread.
849 encoder_thread_.message_loop()->PostTask( 850 encoder_thread_.task_runner()->PostTask(
850 FROM_HERE, base::Bind(&V4L2VideoEncodeAccelerator::ServiceDeviceTask, 851 FROM_HERE, base::Bind(&V4L2VideoEncodeAccelerator::ServiceDeviceTask,
851 base::Unretained(this))); 852 base::Unretained(this)));
852 } 853 }
853 854
854 void V4L2VideoEncodeAccelerator::NotifyError(Error error) { 855 void V4L2VideoEncodeAccelerator::NotifyError(Error error) {
855 DVLOG(1) << "NotifyError(): error=" << error; 856 DVLOG(1) << "NotifyError(): error=" << error;
856 857
857 if (!child_task_runner_->BelongsToCurrentThread()) { 858 if (!child_task_runner_->BelongsToCurrentThread()) {
858 child_task_runner_->PostTask( 859 child_task_runner_->PostTask(
859 FROM_HERE, base::Bind(&V4L2VideoEncodeAccelerator::NotifyError, 860 FROM_HERE, base::Bind(&V4L2VideoEncodeAccelerator::NotifyError,
860 weak_this_, error)); 861 weak_this_, error));
861 return; 862 return;
862 } 863 }
863 864
864 if (client_) { 865 if (client_) {
865 client_->NotifyError(error); 866 client_->NotifyError(error);
866 client_ptr_factory_.reset(); 867 client_ptr_factory_.reset();
867 } 868 }
868 } 869 }
869 870
870 void V4L2VideoEncodeAccelerator::SetErrorState(Error error) { 871 void V4L2VideoEncodeAccelerator::SetErrorState(Error error) {
871 // We can touch encoder_state_ only if this is the encoder thread or the 872 // We can touch encoder_state_ only if this is the encoder thread or the
872 // encoder thread isn't running. 873 // encoder thread isn't running.
873 if (encoder_thread_.message_loop() != NULL && 874 scoped_refptr<base::SingleThreadTaskRunner> task_runner =
874 encoder_thread_.message_loop() != base::MessageLoop::current()) { 875 encoder_thread_.task_runner();
875 encoder_thread_.message_loop()->PostTask( 876 if (task_runner && !task_runner->BelongsToCurrentThread()) {
876 FROM_HERE, base::Bind(&V4L2VideoEncodeAccelerator::SetErrorState, 877 task_runner->PostTask(FROM_HERE,
877 base::Unretained(this), error)); 878 base::Bind(&V4L2VideoEncodeAccelerator::SetErrorState,
879 base::Unretained(this), error));
878 return; 880 return;
879 } 881 }
880 882
881 // Post NotifyError only if we are already initialized, as the API does 883 // Post NotifyError only if we are already initialized, as the API does
882 // not allow doing so before that. 884 // not allow doing so before that.
883 if (encoder_state_ != kError && encoder_state_ != kUninitialized) 885 if (encoder_state_ != kError && encoder_state_ != kUninitialized)
884 NotifyError(error); 886 NotifyError(error);
885 887
886 encoder_state_ = kError; 888 encoder_state_ = kError;
887 } 889 }
888 890
889 void V4L2VideoEncodeAccelerator::RequestEncodingParametersChangeTask( 891 void V4L2VideoEncodeAccelerator::RequestEncodingParametersChangeTask(
890 uint32_t bitrate, 892 uint32_t bitrate,
891 uint32_t framerate) { 893 uint32_t framerate) {
892 DVLOG(3) << "RequestEncodingParametersChangeTask(): bitrate=" << bitrate 894 DVLOG(3) << "RequestEncodingParametersChangeTask(): bitrate=" << bitrate
893 << ", framerate=" << framerate; 895 << ", framerate=" << framerate;
894 DCHECK_EQ(encoder_thread_.message_loop(), base::MessageLoop::current()); 896 DCHECK(encoder_thread_.task_runner()->BelongsToCurrentThread());
895 897
896 if (bitrate < 1) 898 if (bitrate < 1)
897 bitrate = 1; 899 bitrate = 1;
898 if (framerate < 1) 900 if (framerate < 1)
899 framerate = 1; 901 framerate = 1;
900 902
901 std::vector<struct v4l2_ext_control> ctrls; 903 std::vector<struct v4l2_ext_control> ctrls;
902 struct v4l2_ext_control ctrl; 904 struct v4l2_ext_control ctrl;
903 memset(&ctrl, 0, sizeof(ctrl)); 905 memset(&ctrl, 0, sizeof(ctrl));
904 ctrl.id = V4L2_CID_MPEG_VIDEO_BITRATE; 906 ctrl.id = V4L2_CID_MPEG_VIDEO_BITRATE;
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
1139 // Ignore return value as these controls are optional. 1141 // Ignore return value as these controls are optional.
1140 SetExtCtrls(ctrls); 1142 SetExtCtrls(ctrls);
1141 1143
1142 return true; 1144 return true;
1143 } 1145 }
1144 1146
1145 bool V4L2VideoEncodeAccelerator::CreateInputBuffers() { 1147 bool V4L2VideoEncodeAccelerator::CreateInputBuffers() {
1146 DVLOG(3) << "CreateInputBuffers()"; 1148 DVLOG(3) << "CreateInputBuffers()";
1147 // This function runs on encoder_thread_ after output buffers have been 1149 // This function runs on encoder_thread_ after output buffers have been
1148 // provided by the client. 1150 // provided by the client.
1149 DCHECK_EQ(encoder_thread_.message_loop(), base::MessageLoop::current()); 1151 DCHECK(encoder_thread_.task_runner()->BelongsToCurrentThread());
1150 DCHECK(!input_streamon_); 1152 DCHECK(!input_streamon_);
1151 1153
1152 struct v4l2_requestbuffers reqbufs; 1154 struct v4l2_requestbuffers reqbufs;
1153 memset(&reqbufs, 0, sizeof(reqbufs)); 1155 memset(&reqbufs, 0, sizeof(reqbufs));
1154 // Driver will modify to the appropriate number of buffers. 1156 // Driver will modify to the appropriate number of buffers.
1155 reqbufs.count = 1; 1157 reqbufs.count = 1;
1156 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1158 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1157 // TODO(posciak): Once we start doing zero-copy, we should decide based on 1159 // TODO(posciak): Once we start doing zero-copy, we should decide based on
1158 // the current pipeline setup which memory type to use. This should probably 1160 // the current pipeline setup which memory type to use. This should probably
1159 // be decided based on an argument to Initialize(). 1161 // be decided based on an argument to Initialize().
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1247 reqbufs.count = 0; 1249 reqbufs.count = 0;
1248 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1250 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1249 reqbufs.memory = V4L2_MEMORY_MMAP; 1251 reqbufs.memory = V4L2_MEMORY_MMAP;
1250 IOCTL_OR_LOG_ERROR(VIDIOC_REQBUFS, &reqbufs); 1252 IOCTL_OR_LOG_ERROR(VIDIOC_REQBUFS, &reqbufs);
1251 1253
1252 output_buffer_map_.clear(); 1254 output_buffer_map_.clear();
1253 free_output_buffers_.clear(); 1255 free_output_buffers_.clear();
1254 } 1256 }
1255 1257
1256 } // namespace media 1258 } // namespace media
OLDNEW
« no previous file with comments | « media/gpu/v4l2_video_decode_accelerator.cc ('k') | media/gpu/vaapi_video_decode_accelerator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698