OLD | NEW |
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 <fcntl.h> | 5 #include <fcntl.h> |
6 #include <linux/videodev2.h> | 6 #include <linux/videodev2.h> |
7 #include <poll.h> | 7 #include <poll.h> |
8 #include <sys/eventfd.h> | 8 #include <sys/eventfd.h> |
9 #include <sys/ioctl.h> | 9 #include <sys/ioctl.h> |
10 #include <sys/mman.h> | 10 #include <sys/mman.h> |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 : id(id), shm(shm.Pass()), size(size) {} | 53 : id(id), shm(shm.Pass()), size(size) {} |
54 const int32 id; | 54 const int32 id; |
55 const scoped_ptr<base::SharedMemory> shm; | 55 const scoped_ptr<base::SharedMemory> shm; |
56 const size_t size; | 56 const size_t size; |
57 }; | 57 }; |
58 | 58 |
59 V4L2VideoEncodeAccelerator::InputRecord::InputRecord() : at_device(false) { | 59 V4L2VideoEncodeAccelerator::InputRecord::InputRecord() : at_device(false) { |
60 } | 60 } |
61 | 61 |
62 V4L2VideoEncodeAccelerator::OutputRecord::OutputRecord() | 62 V4L2VideoEncodeAccelerator::OutputRecord::OutputRecord() |
63 : at_device(false), address(NULL), length(0) { | 63 : at_device(false), address(nullptr), length(0) { |
64 } | 64 } |
65 | 65 |
66 V4L2VideoEncodeAccelerator::V4L2VideoEncodeAccelerator( | 66 V4L2VideoEncodeAccelerator::V4L2VideoEncodeAccelerator( |
67 scoped_ptr<V4L2Device> device) | 67 scoped_ptr<V4L2Device> device) |
68 : child_message_loop_proxy_(base::MessageLoopProxy::current()), | 68 : child_message_loop_proxy_(base::MessageLoopProxy::current()), |
69 output_buffer_byte_size_(0), | 69 output_buffer_byte_size_(0), |
70 device_input_format_(media::VideoFrame::UNKNOWN), | 70 device_input_format_(media::VideoFrame::UNKNOWN), |
71 input_planes_count_(0), | 71 input_planes_count_(0), |
72 output_format_fourcc_(0), | 72 output_format_fourcc_(0), |
73 encoder_state_(kUninitialized), | 73 encoder_state_(kUninitialized), |
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
500 break; | 500 break; |
501 } | 501 } |
502 PLOG(ERROR) << "Dequeue(): ioctl() failed: VIDIOC_DQBUF"; | 502 PLOG(ERROR) << "Dequeue(): ioctl() failed: VIDIOC_DQBUF"; |
503 NOTIFY_ERROR(kPlatformFailureError); | 503 NOTIFY_ERROR(kPlatformFailureError); |
504 return; | 504 return; |
505 } | 505 } |
506 InputRecord& input_record = input_buffer_map_[dqbuf.index]; | 506 InputRecord& input_record = input_buffer_map_[dqbuf.index]; |
507 DCHECK(input_record.at_device); | 507 DCHECK(input_record.at_device); |
508 input_record.at_device = false; | 508 input_record.at_device = false; |
509 | 509 |
510 input_record.frame = NULL; | 510 input_record.frame = nullptr; |
511 free_input_buffers_.push_back(dqbuf.index); | 511 free_input_buffers_.push_back(dqbuf.index); |
512 input_buffer_queued_count_--; | 512 input_buffer_queued_count_--; |
513 } | 513 } |
514 | 514 |
515 // Dequeue completed output (VIDEO_CAPTURE) buffers, and recycle to the | 515 // Dequeue completed output (VIDEO_CAPTURE) buffers, and recycle to the |
516 // free list. Notify the client that an output buffer is complete. | 516 // free list. Notify the client that an output buffer is complete. |
517 while (output_buffer_queued_count_ > 0) { | 517 while (output_buffer_queued_count_ > 0) { |
518 DCHECK(output_streamon_); | 518 DCHECK(output_streamon_); |
519 memset(&dqbuf, 0, sizeof(dqbuf)); | 519 memset(&dqbuf, 0, sizeof(dqbuf)); |
520 memset(planes, 0, sizeof(planes)); | 520 memset(planes, 0, sizeof(planes)); |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
710 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_STREAMOFF, &type); | 710 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_STREAMOFF, &type); |
711 } | 711 } |
712 output_streamon_ = false; | 712 output_streamon_ = false; |
713 | 713 |
714 // Reset all our accounting info. | 714 // Reset all our accounting info. |
715 encoder_input_queue_.clear(); | 715 encoder_input_queue_.clear(); |
716 free_input_buffers_.clear(); | 716 free_input_buffers_.clear(); |
717 for (size_t i = 0; i < input_buffer_map_.size(); ++i) { | 717 for (size_t i = 0; i < input_buffer_map_.size(); ++i) { |
718 InputRecord& input_record = input_buffer_map_[i]; | 718 InputRecord& input_record = input_buffer_map_[i]; |
719 input_record.at_device = false; | 719 input_record.at_device = false; |
720 input_record.frame = NULL; | 720 input_record.frame = nullptr; |
721 free_input_buffers_.push_back(i); | 721 free_input_buffers_.push_back(i); |
722 } | 722 } |
723 input_buffer_queued_count_ = 0; | 723 input_buffer_queued_count_ = 0; |
724 | 724 |
725 free_output_buffers_.clear(); | 725 free_output_buffers_.clear(); |
726 for (size_t i = 0; i < output_buffer_map_.size(); ++i) { | 726 for (size_t i = 0; i < output_buffer_map_.size(); ++i) { |
727 OutputRecord& output_record = output_buffer_map_[i]; | 727 OutputRecord& output_record = output_buffer_map_[i]; |
728 output_record.at_device = false; | 728 output_record.at_device = false; |
729 output_record.buffer_ref.reset(); | 729 output_record.buffer_ref.reset(); |
730 free_output_buffers_.push_back(i); | 730 free_output_buffers_.push_back(i); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
770 client_->NotifyError(error); | 770 client_->NotifyError(error); |
771 client_ptr_factory_.reset(); | 771 client_ptr_factory_.reset(); |
772 } | 772 } |
773 } | 773 } |
774 | 774 |
775 void V4L2VideoEncodeAccelerator::SetEncoderState(State state) { | 775 void V4L2VideoEncodeAccelerator::SetEncoderState(State state) { |
776 DVLOG(3) << "SetEncoderState(): state=" << state; | 776 DVLOG(3) << "SetEncoderState(): state=" << state; |
777 | 777 |
778 // We can touch encoder_state_ only if this is the encoder thread or the | 778 // We can touch encoder_state_ only if this is the encoder thread or the |
779 // encoder thread isn't running. | 779 // encoder thread isn't running. |
780 if (encoder_thread_.message_loop() != NULL && | 780 if (encoder_thread_.message_loop() != nullptr && |
781 encoder_thread_.message_loop() != base::MessageLoop::current()) { | 781 encoder_thread_.message_loop() != base::MessageLoop::current()) { |
782 encoder_thread_.message_loop()->PostTask( | 782 encoder_thread_.message_loop()->PostTask( |
783 FROM_HERE, | 783 FROM_HERE, |
784 base::Bind(&V4L2VideoEncodeAccelerator::SetEncoderState, | 784 base::Bind(&V4L2VideoEncodeAccelerator::SetEncoderState, |
785 base::Unretained(this), | 785 base::Unretained(this), |
786 state)); | 786 state)); |
787 } else { | 787 } else { |
788 encoder_state_ = state; | 788 encoder_state_ = state; |
789 } | 789 } |
790 } | 790 } |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1033 struct v4l2_plane planes[1]; | 1033 struct v4l2_plane planes[1]; |
1034 struct v4l2_buffer buffer; | 1034 struct v4l2_buffer buffer; |
1035 memset(&buffer, 0, sizeof(buffer)); | 1035 memset(&buffer, 0, sizeof(buffer)); |
1036 memset(planes, 0, sizeof(planes)); | 1036 memset(planes, 0, sizeof(planes)); |
1037 buffer.index = i; | 1037 buffer.index = i; |
1038 buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | 1038 buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
1039 buffer.memory = V4L2_MEMORY_MMAP; | 1039 buffer.memory = V4L2_MEMORY_MMAP; |
1040 buffer.m.planes = planes; | 1040 buffer.m.planes = planes; |
1041 buffer.length = arraysize(planes); | 1041 buffer.length = arraysize(planes); |
1042 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYBUF, &buffer); | 1042 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYBUF, &buffer); |
1043 void* address = device_->Mmap(NULL, | 1043 void* address = device_->Mmap(nullptr, |
1044 buffer.m.planes[0].length, | 1044 buffer.m.planes[0].length, |
1045 PROT_READ | PROT_WRITE, | 1045 PROT_READ | PROT_WRITE, |
1046 MAP_SHARED, | 1046 MAP_SHARED, |
1047 buffer.m.planes[0].m.mem_offset); | 1047 buffer.m.planes[0].m.mem_offset); |
1048 if (address == MAP_FAILED) { | 1048 if (address == MAP_FAILED) { |
1049 PLOG(ERROR) << "CreateOutputBuffers(): mmap() failed"; | 1049 PLOG(ERROR) << "CreateOutputBuffers(): mmap() failed"; |
1050 return false; | 1050 return false; |
1051 } | 1051 } |
1052 output_buffer_map_[i].address = address; | 1052 output_buffer_map_[i].address = address; |
1053 output_buffer_map_[i].length = buffer.m.planes[0].length; | 1053 output_buffer_map_[i].length = buffer.m.planes[0].length; |
(...skipping 18 matching lines...) Expand all Loading... |
1072 input_buffer_map_.clear(); | 1072 input_buffer_map_.clear(); |
1073 free_input_buffers_.clear(); | 1073 free_input_buffers_.clear(); |
1074 } | 1074 } |
1075 | 1075 |
1076 void V4L2VideoEncodeAccelerator::DestroyOutputBuffers() { | 1076 void V4L2VideoEncodeAccelerator::DestroyOutputBuffers() { |
1077 DVLOG(3) << "DestroyOutputBuffers()"; | 1077 DVLOG(3) << "DestroyOutputBuffers()"; |
1078 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); | 1078 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); |
1079 DCHECK(!output_streamon_); | 1079 DCHECK(!output_streamon_); |
1080 | 1080 |
1081 for (size_t i = 0; i < output_buffer_map_.size(); ++i) { | 1081 for (size_t i = 0; i < output_buffer_map_.size(); ++i) { |
1082 if (output_buffer_map_[i].address != NULL) | 1082 if (output_buffer_map_[i].address != nullptr) |
1083 device_->Munmap(output_buffer_map_[i].address, | 1083 device_->Munmap(output_buffer_map_[i].address, |
1084 output_buffer_map_[i].length); | 1084 output_buffer_map_[i].length); |
1085 } | 1085 } |
1086 | 1086 |
1087 struct v4l2_requestbuffers reqbufs; | 1087 struct v4l2_requestbuffers reqbufs; |
1088 memset(&reqbufs, 0, sizeof(reqbufs)); | 1088 memset(&reqbufs, 0, sizeof(reqbufs)); |
1089 reqbufs.count = 0; | 1089 reqbufs.count = 0; |
1090 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | 1090 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
1091 reqbufs.memory = V4L2_MEMORY_MMAP; | 1091 reqbufs.memory = V4L2_MEMORY_MMAP; |
1092 IOCTL_OR_LOG_ERROR(VIDIOC_REQBUFS, &reqbufs); | 1092 IOCTL_OR_LOG_ERROR(VIDIOC_REQBUFS, &reqbufs); |
1093 | 1093 |
1094 output_buffer_map_.clear(); | 1094 output_buffer_map_.clear(); |
1095 free_output_buffers_.clear(); | 1095 free_output_buffers_.clear(); |
1096 } | 1096 } |
1097 | 1097 |
1098 } // namespace content | 1098 } // namespace content |
OLD | NEW |