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