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/message_loop/message_loop_proxy.h" | |
15 #include "base/numerics/safe_conversions.h" | 14 #include "base/numerics/safe_conversions.h" |
| 15 #include "base/thread_task_runner_handle.h" |
16 #include "base/trace_event/trace_event.h" | 16 #include "base/trace_event/trace_event.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 LOG(ERROR) << "Setting error state:" << x; \ | 23 LOG(ERROR) << "Setting error state:" << x; \ |
24 SetErrorState(x); \ | 24 SetErrorState(x); \ |
25 } while (0) | 25 } while (0) |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
63 | 63 |
64 V4L2VideoEncodeAccelerator::OutputRecord::OutputRecord() | 64 V4L2VideoEncodeAccelerator::OutputRecord::OutputRecord() |
65 : at_device(false), address(NULL), length(0) { | 65 : at_device(false), address(NULL), length(0) { |
66 } | 66 } |
67 | 67 |
68 V4L2VideoEncodeAccelerator::OutputRecord::~OutputRecord() { | 68 V4L2VideoEncodeAccelerator::OutputRecord::~OutputRecord() { |
69 } | 69 } |
70 | 70 |
71 V4L2VideoEncodeAccelerator::V4L2VideoEncodeAccelerator( | 71 V4L2VideoEncodeAccelerator::V4L2VideoEncodeAccelerator( |
72 const scoped_refptr<V4L2Device>& device) | 72 const scoped_refptr<V4L2Device>& device) |
73 : child_message_loop_proxy_(base::MessageLoopProxy::current()), | 73 : child_task_runner_(base::ThreadTaskRunnerHandle::Get()), |
74 output_buffer_byte_size_(0), | 74 output_buffer_byte_size_(0), |
75 device_input_format_(media::VideoFrame::UNKNOWN), | 75 device_input_format_(media::VideoFrame::UNKNOWN), |
76 input_planes_count_(0), | 76 input_planes_count_(0), |
77 output_format_fourcc_(0), | 77 output_format_fourcc_(0), |
78 encoder_state_(kUninitialized), | 78 encoder_state_(kUninitialized), |
79 stream_header_size_(0), | 79 stream_header_size_(0), |
80 device_(device), | 80 device_(device), |
81 input_streamon_(false), | 81 input_streamon_(false), |
82 input_buffer_queued_count_(0), | 82 input_buffer_queued_count_(0), |
83 input_memory_type_(V4L2_MEMORY_USERPTR), | 83 input_memory_type_(V4L2_MEMORY_USERPTR), |
(...skipping 24 matching lines...) Expand all Loading... |
108 << media::VideoFrame::FormatToString(input_format) | 108 << media::VideoFrame::FormatToString(input_format) |
109 << ", input_visible_size=" << input_visible_size.ToString() | 109 << ", input_visible_size=" << input_visible_size.ToString() |
110 << ", output_profile=" << output_profile | 110 << ", output_profile=" << output_profile |
111 << ", initial_bitrate=" << initial_bitrate; | 111 << ", initial_bitrate=" << initial_bitrate; |
112 | 112 |
113 visible_size_ = input_visible_size; | 113 visible_size_ = input_visible_size; |
114 | 114 |
115 client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client)); | 115 client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client)); |
116 client_ = client_ptr_factory_->GetWeakPtr(); | 116 client_ = client_ptr_factory_->GetWeakPtr(); |
117 | 117 |
118 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); | 118 DCHECK(child_task_runner_->BelongsToCurrentThread()); |
119 DCHECK_EQ(encoder_state_, kUninitialized); | 119 DCHECK_EQ(encoder_state_, kUninitialized); |
120 | 120 |
121 struct v4l2_capability caps; | 121 struct v4l2_capability caps; |
122 memset(&caps, 0, sizeof(caps)); | 122 memset(&caps, 0, sizeof(caps)); |
123 const __u32 kCapsRequired = V4L2_CAP_VIDEO_CAPTURE_MPLANE | | 123 const __u32 kCapsRequired = V4L2_CAP_VIDEO_CAPTURE_MPLANE | |
124 V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_STREAMING; | 124 V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_STREAMING; |
125 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps); | 125 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps); |
126 if ((caps.capabilities & kCapsRequired) != kCapsRequired) { | 126 if ((caps.capabilities & kCapsRequired) != kCapsRequired) { |
127 LOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP: " | 127 LOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP: " |
128 "caps check failed: 0x" << std::hex << caps.capabilities; | 128 "caps check failed: 0x" << std::hex << caps.capabilities; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 | 166 |
167 if (!encoder_thread_.Start()) { | 167 if (!encoder_thread_.Start()) { |
168 LOG(ERROR) << "Initialize(): encoder thread failed to start"; | 168 LOG(ERROR) << "Initialize(): encoder thread failed to start"; |
169 return false; | 169 return false; |
170 } | 170 } |
171 | 171 |
172 RequestEncodingParametersChange(initial_bitrate, kInitialFramerate); | 172 RequestEncodingParametersChange(initial_bitrate, kInitialFramerate); |
173 | 173 |
174 encoder_state_ = kInitialized; | 174 encoder_state_ = kInitialized; |
175 | 175 |
176 child_message_loop_proxy_->PostTask( | 176 child_task_runner_->PostTask( |
177 FROM_HERE, | 177 FROM_HERE, |
178 base::Bind(&Client::RequireBitstreamBuffers, | 178 base::Bind(&Client::RequireBitstreamBuffers, client_, kInputBufferCount, |
179 client_, | 179 image_processor_.get() |
180 kInputBufferCount, | 180 ? image_processor_->input_allocated_size() |
181 image_processor_.get() ? | 181 : input_allocated_size_, |
182 image_processor_->input_allocated_size() : | |
183 input_allocated_size_, | |
184 output_buffer_byte_size_)); | 182 output_buffer_byte_size_)); |
185 return true; | 183 return true; |
186 } | 184 } |
187 | 185 |
188 void V4L2VideoEncodeAccelerator::ImageProcessorError() { | 186 void V4L2VideoEncodeAccelerator::ImageProcessorError() { |
189 LOG(ERROR) << "Image processor error"; | 187 LOG(ERROR) << "Image processor error"; |
190 NOTIFY_ERROR(kPlatformFailureError); | 188 NOTIFY_ERROR(kPlatformFailureError); |
191 } | 189 } |
192 | 190 |
193 void V4L2VideoEncodeAccelerator::Encode( | 191 void V4L2VideoEncodeAccelerator::Encode( |
194 const scoped_refptr<media::VideoFrame>& frame, | 192 const scoped_refptr<media::VideoFrame>& frame, |
195 bool force_keyframe) { | 193 bool force_keyframe) { |
196 DVLOG(3) << "Encode(): force_keyframe=" << force_keyframe; | 194 DVLOG(3) << "Encode(): force_keyframe=" << force_keyframe; |
197 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); | 195 DCHECK(child_task_runner_->BelongsToCurrentThread()); |
198 | 196 |
199 if (image_processor_) { | 197 if (image_processor_) { |
200 image_processor_->Process( | 198 image_processor_->Process( |
201 frame, | 199 frame, |
202 base::Bind(&V4L2VideoEncodeAccelerator::FrameProcessed, | 200 base::Bind(&V4L2VideoEncodeAccelerator::FrameProcessed, |
203 weak_this_, | 201 weak_this_, |
204 force_keyframe)); | 202 force_keyframe)); |
205 } else { | 203 } else { |
206 encoder_thread_.message_loop()->PostTask( | 204 encoder_thread_.message_loop()->PostTask( |
207 FROM_HERE, | 205 FROM_HERE, |
208 base::Bind(&V4L2VideoEncodeAccelerator::EncodeTask, | 206 base::Bind(&V4L2VideoEncodeAccelerator::EncodeTask, |
209 base::Unretained(this), | 207 base::Unretained(this), |
210 frame, | 208 frame, |
211 force_keyframe)); | 209 force_keyframe)); |
212 } | 210 } |
213 } | 211 } |
214 | 212 |
215 void V4L2VideoEncodeAccelerator::UseOutputBitstreamBuffer( | 213 void V4L2VideoEncodeAccelerator::UseOutputBitstreamBuffer( |
216 const media::BitstreamBuffer& buffer) { | 214 const media::BitstreamBuffer& buffer) { |
217 DVLOG(3) << "UseOutputBitstreamBuffer(): id=" << buffer.id(); | 215 DVLOG(3) << "UseOutputBitstreamBuffer(): id=" << buffer.id(); |
218 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); | 216 DCHECK(child_task_runner_->BelongsToCurrentThread()); |
219 | 217 |
220 if (buffer.size() < output_buffer_byte_size_) { | 218 if (buffer.size() < output_buffer_byte_size_) { |
221 NOTIFY_ERROR(kInvalidArgumentError); | 219 NOTIFY_ERROR(kInvalidArgumentError); |
222 return; | 220 return; |
223 } | 221 } |
224 | 222 |
225 scoped_ptr<base::SharedMemory> shm( | 223 scoped_ptr<base::SharedMemory> shm( |
226 new base::SharedMemory(buffer.handle(), false)); | 224 new base::SharedMemory(buffer.handle(), false)); |
227 if (!shm->Map(buffer.size())) { | 225 if (!shm->Map(buffer.size())) { |
228 NOTIFY_ERROR(kPlatformFailureError); | 226 NOTIFY_ERROR(kPlatformFailureError); |
229 return; | 227 return; |
230 } | 228 } |
231 | 229 |
232 scoped_ptr<BitstreamBufferRef> buffer_ref( | 230 scoped_ptr<BitstreamBufferRef> buffer_ref( |
233 new BitstreamBufferRef(buffer.id(), shm.Pass(), buffer.size())); | 231 new BitstreamBufferRef(buffer.id(), shm.Pass(), buffer.size())); |
234 encoder_thread_.message_loop()->PostTask( | 232 encoder_thread_.message_loop()->PostTask( |
235 FROM_HERE, | 233 FROM_HERE, |
236 base::Bind(&V4L2VideoEncodeAccelerator::UseOutputBitstreamBufferTask, | 234 base::Bind(&V4L2VideoEncodeAccelerator::UseOutputBitstreamBufferTask, |
237 base::Unretained(this), | 235 base::Unretained(this), |
238 base::Passed(&buffer_ref))); | 236 base::Passed(&buffer_ref))); |
239 } | 237 } |
240 | 238 |
241 void V4L2VideoEncodeAccelerator::RequestEncodingParametersChange( | 239 void V4L2VideoEncodeAccelerator::RequestEncodingParametersChange( |
242 uint32 bitrate, | 240 uint32 bitrate, |
243 uint32 framerate) { | 241 uint32 framerate) { |
244 DVLOG(3) << "RequestEncodingParametersChange(): bitrate=" << bitrate | 242 DVLOG(3) << "RequestEncodingParametersChange(): bitrate=" << bitrate |
245 << ", framerate=" << framerate; | 243 << ", framerate=" << framerate; |
246 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); | 244 DCHECK(child_task_runner_->BelongsToCurrentThread()); |
247 | 245 |
248 encoder_thread_.message_loop()->PostTask( | 246 encoder_thread_.message_loop()->PostTask( |
249 FROM_HERE, | 247 FROM_HERE, |
250 base::Bind( | 248 base::Bind( |
251 &V4L2VideoEncodeAccelerator::RequestEncodingParametersChangeTask, | 249 &V4L2VideoEncodeAccelerator::RequestEncodingParametersChangeTask, |
252 base::Unretained(this), | 250 base::Unretained(this), |
253 bitrate, | 251 bitrate, |
254 framerate)); | 252 framerate)); |
255 } | 253 } |
256 | 254 |
257 void V4L2VideoEncodeAccelerator::Destroy() { | 255 void V4L2VideoEncodeAccelerator::Destroy() { |
258 DVLOG(3) << "Destroy()"; | 256 DVLOG(3) << "Destroy()"; |
259 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); | 257 DCHECK(child_task_runner_->BelongsToCurrentThread()); |
260 | 258 |
261 // We're destroying; cancel all callbacks. | 259 // We're destroying; cancel all callbacks. |
262 client_ptr_factory_.reset(); | 260 client_ptr_factory_.reset(); |
263 weak_this_ptr_factory_.InvalidateWeakPtrs(); | 261 weak_this_ptr_factory_.InvalidateWeakPtrs(); |
264 | 262 |
265 if (image_processor_.get()) | 263 if (image_processor_.get()) |
266 image_processor_.release()->Destroy(); | 264 image_processor_.release()->Destroy(); |
267 | 265 |
268 // If the encoder thread is running, destroy using posted task. | 266 // If the encoder thread is running, destroy using posted task. |
269 if (encoder_thread_.IsRunning()) { | 267 if (encoder_thread_.IsRunning()) { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 break; | 312 break; |
315 } | 313 } |
316 } | 314 } |
317 | 315 |
318 return profiles; | 316 return profiles; |
319 } | 317 } |
320 | 318 |
321 void V4L2VideoEncodeAccelerator::FrameProcessed( | 319 void V4L2VideoEncodeAccelerator::FrameProcessed( |
322 bool force_keyframe, | 320 bool force_keyframe, |
323 const scoped_refptr<media::VideoFrame>& frame) { | 321 const scoped_refptr<media::VideoFrame>& frame) { |
324 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); | 322 DCHECK(child_task_runner_->BelongsToCurrentThread()); |
325 DVLOG(3) << "FrameProcessed(): force_keyframe=" << force_keyframe; | 323 DVLOG(3) << "FrameProcessed(): force_keyframe=" << force_keyframe; |
326 | 324 |
327 encoder_thread_.message_loop()->PostTask( | 325 encoder_thread_.message_loop()->PostTask( |
328 FROM_HERE, | 326 FROM_HERE, |
329 base::Bind(&V4L2VideoEncodeAccelerator::EncodeTask, | 327 base::Bind(&V4L2VideoEncodeAccelerator::EncodeTask, |
330 base::Unretained(this), | 328 base::Unretained(this), |
331 frame, | 329 frame, |
332 force_keyframe)); | 330 force_keyframe)); |
333 } | 331 } |
334 | 332 |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
577 } else { | 575 } else { |
578 memcpy(target_data, output_data, output_size); | 576 memcpy(target_data, output_data, output_size); |
579 } | 577 } |
580 } else { | 578 } else { |
581 memcpy(target_data, output_data, output_size); | 579 memcpy(target_data, output_data, output_size); |
582 } | 580 } |
583 | 581 |
584 DVLOG(3) << "Dequeue(): returning " | 582 DVLOG(3) << "Dequeue(): returning " |
585 "bitstream_buffer_id=" << output_record.buffer_ref->id | 583 "bitstream_buffer_id=" << output_record.buffer_ref->id |
586 << ", size=" << output_size << ", key_frame=" << key_frame; | 584 << ", size=" << output_size << ", key_frame=" << key_frame; |
587 child_message_loop_proxy_->PostTask( | 585 child_task_runner_->PostTask( |
588 FROM_HERE, | 586 FROM_HERE, |
589 base::Bind(&Client::BitstreamBufferReady, | 587 base::Bind(&Client::BitstreamBufferReady, client_, |
590 client_, | 588 output_record.buffer_ref->id, output_size, key_frame)); |
591 output_record.buffer_ref->id, | |
592 output_size, | |
593 key_frame)); | |
594 output_record.at_device = false; | 589 output_record.at_device = false; |
595 output_record.buffer_ref.reset(); | 590 output_record.buffer_ref.reset(); |
596 free_output_buffers_.push_back(dqbuf.index); | 591 free_output_buffers_.push_back(dqbuf.index); |
597 output_buffer_queued_count_--; | 592 output_buffer_queued_count_--; |
598 } | 593 } |
599 } | 594 } |
600 | 595 |
601 bool V4L2VideoEncodeAccelerator::EnqueueInputRecord() { | 596 bool V4L2VideoEncodeAccelerator::EnqueueInputRecord() { |
602 DVLOG(3) << "EnqueueInputRecord()"; | 597 DVLOG(3) << "EnqueueInputRecord()"; |
603 DCHECK(!free_input_buffers_.empty()); | 598 DCHECK(!free_input_buffers_.empty()); |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
767 // touch encoder state from this thread. | 762 // touch encoder state from this thread. |
768 encoder_thread_.message_loop()->PostTask( | 763 encoder_thread_.message_loop()->PostTask( |
769 FROM_HERE, | 764 FROM_HERE, |
770 base::Bind(&V4L2VideoEncodeAccelerator::ServiceDeviceTask, | 765 base::Bind(&V4L2VideoEncodeAccelerator::ServiceDeviceTask, |
771 base::Unretained(this))); | 766 base::Unretained(this))); |
772 } | 767 } |
773 | 768 |
774 void V4L2VideoEncodeAccelerator::NotifyError(Error error) { | 769 void V4L2VideoEncodeAccelerator::NotifyError(Error error) { |
775 DVLOG(1) << "NotifyError(): error=" << error; | 770 DVLOG(1) << "NotifyError(): error=" << error; |
776 | 771 |
777 if (!child_message_loop_proxy_->BelongsToCurrentThread()) { | 772 if (!child_task_runner_->BelongsToCurrentThread()) { |
778 child_message_loop_proxy_->PostTask( | 773 child_task_runner_->PostTask( |
779 FROM_HERE, | 774 FROM_HERE, base::Bind(&V4L2VideoEncodeAccelerator::NotifyError, |
780 base::Bind( | 775 weak_this_, error)); |
781 &V4L2VideoEncodeAccelerator::NotifyError, weak_this_, error)); | |
782 return; | 776 return; |
783 } | 777 } |
784 | 778 |
785 if (client_) { | 779 if (client_) { |
786 client_->NotifyError(error); | 780 client_->NotifyError(error); |
787 client_ptr_factory_.reset(); | 781 client_ptr_factory_.reset(); |
788 } | 782 } |
789 } | 783 } |
790 | 784 |
791 void V4L2VideoEncodeAccelerator::SetErrorState(Error error) { | 785 void V4L2VideoEncodeAccelerator::SetErrorState(Error error) { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
836 parms.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; | 830 parms.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; |
837 // Note that we are provided "frames per second" but V4L2 expects "time per | 831 // Note that we are provided "frames per second" but V4L2 expects "time per |
838 // frame"; hence we provide the reciprocal of the framerate here. | 832 // frame"; hence we provide the reciprocal of the framerate here. |
839 parms.parm.output.timeperframe.numerator = 1; | 833 parms.parm.output.timeperframe.numerator = 1; |
840 parms.parm.output.timeperframe.denominator = framerate; | 834 parms.parm.output.timeperframe.denominator = framerate; |
841 IOCTL_OR_ERROR_RETURN(VIDIOC_S_PARM, &parms); | 835 IOCTL_OR_ERROR_RETURN(VIDIOC_S_PARM, &parms); |
842 } | 836 } |
843 | 837 |
844 bool V4L2VideoEncodeAccelerator::SetOutputFormat( | 838 bool V4L2VideoEncodeAccelerator::SetOutputFormat( |
845 media::VideoCodecProfile output_profile) { | 839 media::VideoCodecProfile output_profile) { |
846 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); | 840 DCHECK(child_task_runner_->BelongsToCurrentThread()); |
847 DCHECK(!input_streamon_); | 841 DCHECK(!input_streamon_); |
848 DCHECK(!output_streamon_); | 842 DCHECK(!output_streamon_); |
849 | 843 |
850 output_format_fourcc_ = | 844 output_format_fourcc_ = |
851 V4L2Device::VideoCodecProfileToV4L2PixFmt(output_profile, false); | 845 V4L2Device::VideoCodecProfileToV4L2PixFmt(output_profile, false); |
852 if (!output_format_fourcc_) { | 846 if (!output_format_fourcc_) { |
853 LOG(ERROR) << "Initialize(): invalid output_profile=" << output_profile; | 847 LOG(ERROR) << "Initialize(): invalid output_profile=" << output_profile; |
854 return false; | 848 return false; |
855 } | 849 } |
856 | 850 |
(...skipping 14 matching lines...) Expand all Loading... |
871 size_t adjusted_output_buffer_size = | 865 size_t adjusted_output_buffer_size = |
872 base::checked_cast<size_t>(format.fmt.pix_mp.plane_fmt[0].sizeimage); | 866 base::checked_cast<size_t>(format.fmt.pix_mp.plane_fmt[0].sizeimage); |
873 output_buffer_byte_size_ = adjusted_output_buffer_size; | 867 output_buffer_byte_size_ = adjusted_output_buffer_size; |
874 | 868 |
875 return true; | 869 return true; |
876 } | 870 } |
877 | 871 |
878 bool V4L2VideoEncodeAccelerator::NegotiateInputFormat( | 872 bool V4L2VideoEncodeAccelerator::NegotiateInputFormat( |
879 media::VideoFrame::Format input_format) { | 873 media::VideoFrame::Format input_format) { |
880 DVLOG(3) << "NegotiateInputFormat()"; | 874 DVLOG(3) << "NegotiateInputFormat()"; |
881 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); | 875 DCHECK(child_task_runner_->BelongsToCurrentThread()); |
882 DCHECK(!input_streamon_); | 876 DCHECK(!input_streamon_); |
883 DCHECK(!output_streamon_); | 877 DCHECK(!output_streamon_); |
884 | 878 |
885 device_input_format_ = media::VideoFrame::UNKNOWN; | 879 device_input_format_ = media::VideoFrame::UNKNOWN; |
886 input_planes_count_ = 0; | 880 input_planes_count_ = 0; |
887 | 881 |
888 uint32 input_format_fourcc = | 882 uint32 input_format_fourcc = |
889 V4L2Device::VideoFrameFormatToV4L2PixFmt(input_format); | 883 V4L2Device::VideoFrameFormatToV4L2PixFmt(input_format); |
890 if (!input_format_fourcc) { | 884 if (!input_format_fourcc) { |
891 LOG(ERROR) << "Unsupported input format"; | 885 LOG(ERROR) << "Unsupported input format"; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
931 | 925 |
932 device_input_format_ = input_format; | 926 device_input_format_ = input_format; |
933 input_planes_count_ = input_planes_count; | 927 input_planes_count_ = input_planes_count; |
934 return true; | 928 return true; |
935 } | 929 } |
936 | 930 |
937 bool V4L2VideoEncodeAccelerator::SetFormats( | 931 bool V4L2VideoEncodeAccelerator::SetFormats( |
938 media::VideoFrame::Format input_format, | 932 media::VideoFrame::Format input_format, |
939 media::VideoCodecProfile output_profile) { | 933 media::VideoCodecProfile output_profile) { |
940 DVLOG(3) << "SetFormats()"; | 934 DVLOG(3) << "SetFormats()"; |
941 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); | 935 DCHECK(child_task_runner_->BelongsToCurrentThread()); |
942 DCHECK(!input_streamon_); | 936 DCHECK(!input_streamon_); |
943 DCHECK(!output_streamon_); | 937 DCHECK(!output_streamon_); |
944 | 938 |
945 if (!SetOutputFormat(output_profile)) | 939 if (!SetOutputFormat(output_profile)) |
946 return false; | 940 return false; |
947 | 941 |
948 if (!NegotiateInputFormat(input_format)) | 942 if (!NegotiateInputFormat(input_format)) |
949 return false; | 943 return false; |
950 | 944 |
951 struct v4l2_crop crop; | 945 struct v4l2_crop crop; |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1071 DCHECK(input_buffer_map_.empty()); | 1065 DCHECK(input_buffer_map_.empty()); |
1072 input_buffer_map_.resize(reqbufs.count); | 1066 input_buffer_map_.resize(reqbufs.count); |
1073 for (size_t i = 0; i < input_buffer_map_.size(); ++i) | 1067 for (size_t i = 0; i < input_buffer_map_.size(); ++i) |
1074 free_input_buffers_.push_back(i); | 1068 free_input_buffers_.push_back(i); |
1075 | 1069 |
1076 return true; | 1070 return true; |
1077 } | 1071 } |
1078 | 1072 |
1079 bool V4L2VideoEncodeAccelerator::CreateOutputBuffers() { | 1073 bool V4L2VideoEncodeAccelerator::CreateOutputBuffers() { |
1080 DVLOG(3) << "CreateOutputBuffers()"; | 1074 DVLOG(3) << "CreateOutputBuffers()"; |
1081 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); | 1075 DCHECK(child_task_runner_->BelongsToCurrentThread()); |
1082 DCHECK(!output_streamon_); | 1076 DCHECK(!output_streamon_); |
1083 | 1077 |
1084 struct v4l2_requestbuffers reqbufs; | 1078 struct v4l2_requestbuffers reqbufs; |
1085 memset(&reqbufs, 0, sizeof(reqbufs)); | 1079 memset(&reqbufs, 0, sizeof(reqbufs)); |
1086 reqbufs.count = kOutputBufferCount; | 1080 reqbufs.count = kOutputBufferCount; |
1087 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | 1081 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
1088 reqbufs.memory = V4L2_MEMORY_MMAP; | 1082 reqbufs.memory = V4L2_MEMORY_MMAP; |
1089 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_REQBUFS, &reqbufs); | 1083 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_REQBUFS, &reqbufs); |
1090 | 1084 |
1091 DCHECK(output_buffer_map_.empty()); | 1085 DCHECK(output_buffer_map_.empty()); |
(...skipping 21 matching lines...) Expand all Loading... |
1113 output_buffer_map_[i].address = address; | 1107 output_buffer_map_[i].address = address; |
1114 output_buffer_map_[i].length = buffer.m.planes[0].length; | 1108 output_buffer_map_[i].length = buffer.m.planes[0].length; |
1115 free_output_buffers_.push_back(i); | 1109 free_output_buffers_.push_back(i); |
1116 } | 1110 } |
1117 | 1111 |
1118 return true; | 1112 return true; |
1119 } | 1113 } |
1120 | 1114 |
1121 void V4L2VideoEncodeAccelerator::DestroyInputBuffers() { | 1115 void V4L2VideoEncodeAccelerator::DestroyInputBuffers() { |
1122 DVLOG(3) << "DestroyInputBuffers()"; | 1116 DVLOG(3) << "DestroyInputBuffers()"; |
1123 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); | 1117 DCHECK(child_task_runner_->BelongsToCurrentThread()); |
1124 DCHECK(!input_streamon_); | 1118 DCHECK(!input_streamon_); |
1125 | 1119 |
1126 struct v4l2_requestbuffers reqbufs; | 1120 struct v4l2_requestbuffers reqbufs; |
1127 memset(&reqbufs, 0, sizeof(reqbufs)); | 1121 memset(&reqbufs, 0, sizeof(reqbufs)); |
1128 reqbufs.count = 0; | 1122 reqbufs.count = 0; |
1129 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; | 1123 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; |
1130 reqbufs.memory = input_memory_type_; | 1124 reqbufs.memory = input_memory_type_; |
1131 IOCTL_OR_LOG_ERROR(VIDIOC_REQBUFS, &reqbufs); | 1125 IOCTL_OR_LOG_ERROR(VIDIOC_REQBUFS, &reqbufs); |
1132 | 1126 |
1133 input_buffer_map_.clear(); | 1127 input_buffer_map_.clear(); |
1134 free_input_buffers_.clear(); | 1128 free_input_buffers_.clear(); |
1135 } | 1129 } |
1136 | 1130 |
1137 void V4L2VideoEncodeAccelerator::DestroyOutputBuffers() { | 1131 void V4L2VideoEncodeAccelerator::DestroyOutputBuffers() { |
1138 DVLOG(3) << "DestroyOutputBuffers()"; | 1132 DVLOG(3) << "DestroyOutputBuffers()"; |
1139 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); | 1133 DCHECK(child_task_runner_->BelongsToCurrentThread()); |
1140 DCHECK(!output_streamon_); | 1134 DCHECK(!output_streamon_); |
1141 | 1135 |
1142 for (size_t i = 0; i < output_buffer_map_.size(); ++i) { | 1136 for (size_t i = 0; i < output_buffer_map_.size(); ++i) { |
1143 if (output_buffer_map_[i].address != NULL) | 1137 if (output_buffer_map_[i].address != NULL) |
1144 device_->Munmap(output_buffer_map_[i].address, | 1138 device_->Munmap(output_buffer_map_[i].address, |
1145 output_buffer_map_[i].length); | 1139 output_buffer_map_[i].length); |
1146 } | 1140 } |
1147 | 1141 |
1148 struct v4l2_requestbuffers reqbufs; | 1142 struct v4l2_requestbuffers reqbufs; |
1149 memset(&reqbufs, 0, sizeof(reqbufs)); | 1143 memset(&reqbufs, 0, sizeof(reqbufs)); |
1150 reqbufs.count = 0; | 1144 reqbufs.count = 0; |
1151 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | 1145 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
1152 reqbufs.memory = V4L2_MEMORY_MMAP; | 1146 reqbufs.memory = V4L2_MEMORY_MMAP; |
1153 IOCTL_OR_LOG_ERROR(VIDIOC_REQBUFS, &reqbufs); | 1147 IOCTL_OR_LOG_ERROR(VIDIOC_REQBUFS, &reqbufs); |
1154 | 1148 |
1155 output_buffer_map_.clear(); | 1149 output_buffer_map_.clear(); |
1156 free_output_buffers_.clear(); | 1150 free_output_buffers_.clear(); |
1157 } | 1151 } |
1158 | 1152 |
1159 } // namespace content | 1153 } // namespace content |
OLD | NEW |