| 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> |
| 11 | 11 |
| 12 #include "base/callback.h" | 12 #include "base/callback.h" |
| 13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
| 14 #include "base/debug/trace_event.h" | 14 #include "base/debug/trace_event.h" |
| 15 #include "base/message_loop/message_loop_proxy.h" | 15 #include "base/message_loop/message_loop_proxy.h" |
| 16 #include "base/numerics/safe_conversions.h" | 16 #include "base/numerics/safe_conversions.h" |
| 17 #include "content/common/gpu/media/v4l2_video_encode_accelerator.h" | 17 #include "content/common/gpu/media/v4l2_video_encode_accelerator.h" |
| 18 #include "content/public/common/content_switches.h" | 18 #include "content/public/common/content_switches.h" |
| 19 #include "media/base/bitstream_buffer.h" | 19 #include "media/base/bitstream_buffer.h" |
| 20 | 20 |
| 21 #define NOTIFY_ERROR(x) \ | 21 #define NOTIFY_ERROR(x) \ |
| 22 do { \ | 22 do { \ |
| 23 SetEncoderState(kError); \ | 23 SetEncoderState(kError); \ |
| 24 DLOG(ERROR) << "calling NotifyError(): " << x; \ | 24 LOG(ERROR) << "calling NotifyError(): " << x; \ |
| 25 NotifyError(x); \ | 25 NotifyError(x); \ |
| 26 } while (0) | 26 } while (0) |
| 27 | 27 |
| 28 #define IOCTL_OR_ERROR_RETURN_VALUE(type, arg, value) \ | 28 #define IOCTL_OR_ERROR_RETURN_VALUE(type, arg, value) \ |
| 29 do { \ | 29 do { \ |
| 30 if (device_->Ioctl(type, arg) != 0) { \ | 30 if (device_->Ioctl(type, arg) != 0) { \ |
| 31 DPLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \ | 31 PLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \ |
| 32 NOTIFY_ERROR(kPlatformFailureError); \ | 32 NOTIFY_ERROR(kPlatformFailureError); \ |
| 33 return value; \ | 33 return value; \ |
| 34 } \ | 34 } \ |
| 35 } while (0) | 35 } while (0) |
| 36 | 36 |
| 37 #define IOCTL_OR_ERROR_RETURN(type, arg) \ | 37 #define IOCTL_OR_ERROR_RETURN(type, arg) \ |
| 38 IOCTL_OR_ERROR_RETURN_VALUE(type, arg, ((void)0)) | 38 IOCTL_OR_ERROR_RETURN_VALUE(type, arg, ((void)0)) |
| 39 | 39 |
| 40 #define IOCTL_OR_ERROR_RETURN_FALSE(type, arg) \ | 40 #define IOCTL_OR_ERROR_RETURN_FALSE(type, arg) \ |
| 41 IOCTL_OR_ERROR_RETURN_VALUE(type, arg, false) | 41 IOCTL_OR_ERROR_RETURN_VALUE(type, arg, false) |
| 42 | 42 |
| 43 #define IOCTL_OR_LOG_ERROR(type, arg) \ | 43 #define IOCTL_OR_LOG_ERROR(type, arg) \ |
| 44 do { \ | 44 do { \ |
| 45 if (device_->Ioctl(type, arg) != 0) \ | 45 if (device_->Ioctl(type, arg) != 0) \ |
| 46 DPLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \ | 46 PLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \ |
| 47 } while (0) | 47 } while (0) |
| 48 | 48 |
| 49 namespace content { | 49 namespace content { |
| 50 | 50 |
| 51 struct V4L2VideoEncodeAccelerator::BitstreamBufferRef { | 51 struct V4L2VideoEncodeAccelerator::BitstreamBufferRef { |
| 52 BitstreamBufferRef(int32 id, scoped_ptr<base::SharedMemory> shm, size_t size) | 52 BitstreamBufferRef(int32 id, scoped_ptr<base::SharedMemory> shm, size_t size) |
| 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; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 | 112 |
| 113 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); | 113 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); |
| 114 DCHECK_EQ(encoder_state_, kUninitialized); | 114 DCHECK_EQ(encoder_state_, kUninitialized); |
| 115 | 115 |
| 116 struct v4l2_capability caps; | 116 struct v4l2_capability caps; |
| 117 memset(&caps, 0, sizeof(caps)); | 117 memset(&caps, 0, sizeof(caps)); |
| 118 const __u32 kCapsRequired = V4L2_CAP_VIDEO_CAPTURE_MPLANE | | 118 const __u32 kCapsRequired = V4L2_CAP_VIDEO_CAPTURE_MPLANE | |
| 119 V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_STREAMING; | 119 V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_STREAMING; |
| 120 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps); | 120 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps); |
| 121 if ((caps.capabilities & kCapsRequired) != kCapsRequired) { | 121 if ((caps.capabilities & kCapsRequired) != kCapsRequired) { |
| 122 DLOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP: " | 122 LOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP: " |
| 123 "caps check failed: 0x" << std::hex << caps.capabilities; | 123 "caps check failed: 0x" << std::hex << caps.capabilities; |
| 124 return false; | 124 return false; |
| 125 } | 125 } |
| 126 | 126 |
| 127 if (!SetFormats(input_format, output_profile)) { | 127 if (!SetFormats(input_format, output_profile)) { |
| 128 DLOG(ERROR) << "Failed setting up formats"; | 128 LOG(ERROR) << "Failed setting up formats"; |
| 129 return false; | 129 return false; |
| 130 } | 130 } |
| 131 | 131 |
| 132 if (input_format != device_input_format_) { | 132 if (input_format != device_input_format_) { |
| 133 DVLOG(1) << "Input format not supported by the HW, will convert to " | 133 DVLOG(1) << "Input format not supported by the HW, will convert to " |
| 134 << media::VideoFrame::FormatToString(device_input_format_); | 134 << media::VideoFrame::FormatToString(device_input_format_); |
| 135 | 135 |
| 136 scoped_ptr<V4L2Device> device = | 136 scoped_ptr<V4L2Device> device = |
| 137 V4L2Device::Create(V4L2Device::kImageProcessor); | 137 V4L2Device::Create(V4L2Device::kImageProcessor); |
| 138 image_processor_.reset(new V4L2ImageProcessor(device.Pass())); | 138 image_processor_.reset(new V4L2ImageProcessor(device.Pass())); |
| 139 | 139 |
| 140 // Convert from input_format to device_input_format_, keeping the size | 140 // Convert from input_format to device_input_format_, keeping the size |
| 141 // at visible_size_ and requiring the output buffers to be of at least | 141 // at visible_size_ and requiring the output buffers to be of at least |
| 142 // input_allocated_size_. | 142 // input_allocated_size_. |
| 143 if (!image_processor_->Initialize( | 143 if (!image_processor_->Initialize( |
| 144 input_format, | 144 input_format, |
| 145 device_input_format_, | 145 device_input_format_, |
| 146 visible_size_, | 146 visible_size_, |
| 147 visible_size_, | 147 visible_size_, |
| 148 input_allocated_size_, | 148 input_allocated_size_, |
| 149 base::Bind(&V4L2VideoEncodeAccelerator::ImageProcessorError, | 149 base::Bind(&V4L2VideoEncodeAccelerator::ImageProcessorError, |
| 150 weak_this_))) { | 150 weak_this_))) { |
| 151 DLOG(ERROR) << "Failed initializing image processor"; | 151 LOG(ERROR) << "Failed initializing image processor"; |
| 152 return false; | 152 return false; |
| 153 } | 153 } |
| 154 } | 154 } |
| 155 | 155 |
| 156 if (!InitControls()) | 156 if (!InitControls()) |
| 157 return false; | 157 return false; |
| 158 | 158 |
| 159 if (!CreateOutputBuffers()) | 159 if (!CreateOutputBuffers()) |
| 160 return false; | 160 return false; |
| 161 | 161 |
| 162 if (!encoder_thread_.Start()) { | 162 if (!encoder_thread_.Start()) { |
| 163 DLOG(ERROR) << "Initialize(): encoder thread failed to start"; | 163 LOG(ERROR) << "Initialize(): encoder thread failed to start"; |
| 164 return false; | 164 return false; |
| 165 } | 165 } |
| 166 | 166 |
| 167 RequestEncodingParametersChange(initial_bitrate, kInitialFramerate); | 167 RequestEncodingParametersChange(initial_bitrate, kInitialFramerate); |
| 168 | 168 |
| 169 SetEncoderState(kInitialized); | 169 SetEncoderState(kInitialized); |
| 170 | 170 |
| 171 child_message_loop_proxy_->PostTask( | 171 child_message_loop_proxy_->PostTask( |
| 172 FROM_HERE, | 172 FROM_HERE, |
| 173 base::Bind(&Client::RequireBitstreamBuffers, | 173 base::Bind(&Client::RequireBitstreamBuffers, |
| 174 client_, | 174 client_, |
| 175 kInputBufferCount, | 175 kInputBufferCount, |
| 176 image_processor_.get() ? | 176 image_processor_.get() ? |
| 177 image_processor_->input_allocated_size() : | 177 image_processor_->input_allocated_size() : |
| 178 input_allocated_size_, | 178 input_allocated_size_, |
| 179 output_buffer_byte_size_)); | 179 output_buffer_byte_size_)); |
| 180 return true; | 180 return true; |
| 181 } | 181 } |
| 182 | 182 |
| 183 void V4L2VideoEncodeAccelerator::ImageProcessorError() { | 183 void V4L2VideoEncodeAccelerator::ImageProcessorError() { |
| 184 DVLOG(1) << "Image processor error"; | 184 LOG(ERROR) << "Image processor error"; |
| 185 NOTIFY_ERROR(kPlatformFailureError); | 185 NOTIFY_ERROR(kPlatformFailureError); |
| 186 } | 186 } |
| 187 | 187 |
| 188 void V4L2VideoEncodeAccelerator::Encode( | 188 void V4L2VideoEncodeAccelerator::Encode( |
| 189 const scoped_refptr<media::VideoFrame>& frame, | 189 const scoped_refptr<media::VideoFrame>& frame, |
| 190 bool force_keyframe) { | 190 bool force_keyframe) { |
| 191 DVLOG(3) << "Encode(): force_keyframe=" << force_keyframe; | 191 DVLOG(3) << "Encode(): force_keyframe=" << force_keyframe; |
| 192 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); | 192 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); |
| 193 | 193 |
| 194 if (image_processor_) { | 194 if (image_processor_) { |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 492 memset(&planes, 0, sizeof(planes)); | 492 memset(&planes, 0, sizeof(planes)); |
| 493 dqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; | 493 dqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; |
| 494 dqbuf.memory = V4L2_MEMORY_MMAP; | 494 dqbuf.memory = V4L2_MEMORY_MMAP; |
| 495 dqbuf.m.planes = planes; | 495 dqbuf.m.planes = planes; |
| 496 dqbuf.length = input_planes_count_; | 496 dqbuf.length = input_planes_count_; |
| 497 if (device_->Ioctl(VIDIOC_DQBUF, &dqbuf) != 0) { | 497 if (device_->Ioctl(VIDIOC_DQBUF, &dqbuf) != 0) { |
| 498 if (errno == EAGAIN) { | 498 if (errno == EAGAIN) { |
| 499 // EAGAIN if we're just out of buffers to dequeue. | 499 // EAGAIN if we're just out of buffers to dequeue. |
| 500 break; | 500 break; |
| 501 } | 501 } |
| 502 DPLOG(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 = NULL; |
| 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)); |
| 521 dqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | 521 dqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
| 522 dqbuf.memory = V4L2_MEMORY_MMAP; | 522 dqbuf.memory = V4L2_MEMORY_MMAP; |
| 523 dqbuf.m.planes = planes; | 523 dqbuf.m.planes = planes; |
| 524 dqbuf.length = 1; | 524 dqbuf.length = 1; |
| 525 if (device_->Ioctl(VIDIOC_DQBUF, &dqbuf) != 0) { | 525 if (device_->Ioctl(VIDIOC_DQBUF, &dqbuf) != 0) { |
| 526 if (errno == EAGAIN) { | 526 if (errno == EAGAIN) { |
| 527 // EAGAIN if we're just out of buffers to dequeue. | 527 // EAGAIN if we're just out of buffers to dequeue. |
| 528 break; | 528 break; |
| 529 } | 529 } |
| 530 DPLOG(ERROR) << "Dequeue(): ioctl() failed: VIDIOC_DQBUF"; | 530 PLOG(ERROR) << "Dequeue(): ioctl() failed: VIDIOC_DQBUF"; |
| 531 NOTIFY_ERROR(kPlatformFailureError); | 531 NOTIFY_ERROR(kPlatformFailureError); |
| 532 return; | 532 return; |
| 533 } | 533 } |
| 534 const bool key_frame = ((dqbuf.flags & V4L2_BUF_FLAG_KEYFRAME) != 0); | 534 const bool key_frame = ((dqbuf.flags & V4L2_BUF_FLAG_KEYFRAME) != 0); |
| 535 OutputRecord& output_record = output_buffer_map_[dqbuf.index]; | 535 OutputRecord& output_record = output_buffer_map_[dqbuf.index]; |
| 536 DCHECK(output_record.at_device); | 536 DCHECK(output_record.at_device); |
| 537 DCHECK(output_record.buffer_ref.get()); | 537 DCHECK(output_record.buffer_ref.get()); |
| 538 | 538 |
| 539 void* output_data = output_record.address; | 539 void* output_data = output_record.address; |
| 540 size_t output_size = dqbuf.m.planes[0].bytesused; | 540 size_t output_size = dqbuf.m.planes[0].bytesused; |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 666 return true; | 666 return true; |
| 667 } | 667 } |
| 668 | 668 |
| 669 bool V4L2VideoEncodeAccelerator::StartDevicePoll() { | 669 bool V4L2VideoEncodeAccelerator::StartDevicePoll() { |
| 670 DVLOG(3) << "StartDevicePoll()"; | 670 DVLOG(3) << "StartDevicePoll()"; |
| 671 DCHECK_EQ(encoder_thread_.message_loop(), base::MessageLoop::current()); | 671 DCHECK_EQ(encoder_thread_.message_loop(), base::MessageLoop::current()); |
| 672 DCHECK(!device_poll_thread_.IsRunning()); | 672 DCHECK(!device_poll_thread_.IsRunning()); |
| 673 | 673 |
| 674 // Start up the device poll thread and schedule its first DevicePollTask(). | 674 // Start up the device poll thread and schedule its first DevicePollTask(). |
| 675 if (!device_poll_thread_.Start()) { | 675 if (!device_poll_thread_.Start()) { |
| 676 DLOG(ERROR) << "StartDevicePoll(): Device thread failed to start"; | 676 LOG(ERROR) << "StartDevicePoll(): Device thread failed to start"; |
| 677 NOTIFY_ERROR(kPlatformFailureError); | 677 NOTIFY_ERROR(kPlatformFailureError); |
| 678 return false; | 678 return false; |
| 679 } | 679 } |
| 680 // Enqueue a poll task with no devices to poll on -- it will wait only on the | 680 // Enqueue a poll task with no devices to poll on -- it will wait only on the |
| 681 // interrupt fd. | 681 // interrupt fd. |
| 682 device_poll_thread_.message_loop()->PostTask( | 682 device_poll_thread_.message_loop()->PostTask( |
| 683 FROM_HERE, | 683 FROM_HERE, |
| 684 base::Bind(&V4L2VideoEncodeAccelerator::DevicePollTask, | 684 base::Bind(&V4L2VideoEncodeAccelerator::DevicePollTask, |
| 685 base::Unretained(this), | 685 base::Unretained(this), |
| 686 false)); | 686 false)); |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 824 | 824 |
| 825 bool V4L2VideoEncodeAccelerator::SetOutputFormat( | 825 bool V4L2VideoEncodeAccelerator::SetOutputFormat( |
| 826 media::VideoCodecProfile output_profile) { | 826 media::VideoCodecProfile output_profile) { |
| 827 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); | 827 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); |
| 828 DCHECK(!input_streamon_); | 828 DCHECK(!input_streamon_); |
| 829 DCHECK(!output_streamon_); | 829 DCHECK(!output_streamon_); |
| 830 | 830 |
| 831 output_format_fourcc_ = | 831 output_format_fourcc_ = |
| 832 V4L2Device::VideoCodecProfileToV4L2PixFmt(output_profile); | 832 V4L2Device::VideoCodecProfileToV4L2PixFmt(output_profile); |
| 833 if (!output_format_fourcc_) { | 833 if (!output_format_fourcc_) { |
| 834 DLOG(ERROR) << "Initialize(): invalid output_profile=" << output_profile; | 834 LOG(ERROR) << "Initialize(): invalid output_profile=" << output_profile; |
| 835 return false; | 835 return false; |
| 836 } | 836 } |
| 837 | 837 |
| 838 output_buffer_byte_size_ = kOutputBufferSize; | 838 output_buffer_byte_size_ = kOutputBufferSize; |
| 839 | 839 |
| 840 struct v4l2_format format; | 840 struct v4l2_format format; |
| 841 memset(&format, 0, sizeof(format)); | 841 memset(&format, 0, sizeof(format)); |
| 842 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | 842 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
| 843 format.fmt.pix_mp.width = visible_size_.width(); | 843 format.fmt.pix_mp.width = visible_size_.width(); |
| 844 format.fmt.pix_mp.height = visible_size_.height(); | 844 format.fmt.pix_mp.height = visible_size_.height(); |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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(NULL, |
| 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 DPLOG(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; |
| 1054 free_output_buffers_.push_back(i); | 1054 free_output_buffers_.push_back(i); |
| 1055 } | 1055 } |
| 1056 | 1056 |
| 1057 return true; | 1057 return true; |
| 1058 } | 1058 } |
| 1059 | 1059 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 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 |