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

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

Issue 1939683002: Test X11 header pollution (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 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_encode_accelerator.h ('k') | media/gpu/va.sigs » ('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 "content/common/gpu/media/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/thread_task_runner_handle.h" 21 #include "base/thread_task_runner_handle.h"
22 #include "base/trace_event/trace_event.h" 22 #include "base/trace_event/trace_event.h"
23 #include "content/common/gpu/media/shared_memory_region.h"
24 #include "media/base/bind_to_current_loop.h" 23 #include "media/base/bind_to_current_loop.h"
25 #include "media/base/bitstream_buffer.h" 24 #include "media/base/bitstream_buffer.h"
25 #include "media/gpu/shared_memory_region.h"
26 26
27 #define NOTIFY_ERROR(x) \ 27 #define NOTIFY_ERROR(x) \
28 do { \ 28 do { \
29 LOG(ERROR) << "Setting error state:" << x; \ 29 LOG(ERROR) << "Setting error state:" << x; \
30 SetErrorState(x); \ 30 SetErrorState(x); \
31 } while (0) 31 } while (0)
32 32
33 #define IOCTL_OR_ERROR_RETURN_VALUE(type, arg, value, type_str) \ 33 #define IOCTL_OR_ERROR_RETURN_VALUE(type, arg, value, type_str) \
34 do { \ 34 do { \
35 if (device_->Ioctl(type, arg) != 0) { \ 35 if (device_->Ioctl(type, arg) != 0) { \
36 PLOG(ERROR) << __func__ << "(): ioctl() failed: " << type_str; \ 36 PLOG(ERROR) << __func__ << "(): ioctl() failed: " << type_str; \
37 NOTIFY_ERROR(kPlatformFailureError); \ 37 NOTIFY_ERROR(kPlatformFailureError); \
38 return value; \ 38 return value; \
39 } \ 39 } \
40 } while (0) 40 } while (0)
41 41
42 #define IOCTL_OR_ERROR_RETURN(type, arg) \ 42 #define IOCTL_OR_ERROR_RETURN(type, arg) \
43 IOCTL_OR_ERROR_RETURN_VALUE(type, arg, ((void)0), #type) 43 IOCTL_OR_ERROR_RETURN_VALUE(type, arg, ((void)0), #type)
44 44
45 #define IOCTL_OR_ERROR_RETURN_FALSE(type, arg) \ 45 #define IOCTL_OR_ERROR_RETURN_FALSE(type, arg) \
46 IOCTL_OR_ERROR_RETURN_VALUE(type, arg, false, #type) 46 IOCTL_OR_ERROR_RETURN_VALUE(type, arg, false, #type)
47 47
48 #define IOCTL_OR_LOG_ERROR(type, arg) \ 48 #define IOCTL_OR_LOG_ERROR(type, arg) \
49 do { \ 49 do { \
50 if (device_->Ioctl(type, arg) != 0) \ 50 if (device_->Ioctl(type, arg) != 0) \
51 PLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \ 51 PLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \
52 } while (0) 52 } while (0)
53 53
54 namespace content { 54 namespace media {
55 55
56 struct V4L2VideoEncodeAccelerator::BitstreamBufferRef { 56 struct V4L2VideoEncodeAccelerator::BitstreamBufferRef {
57 BitstreamBufferRef(int32_t id, std::unique_ptr<SharedMemoryRegion> shm) 57 BitstreamBufferRef(int32_t id, std::unique_ptr<SharedMemoryRegion> shm)
58 : id(id), shm(std::move(shm)) {} 58 : id(id), shm(std::move(shm)) {}
59 const int32_t id; 59 const int32_t id;
60 const std::unique_ptr<SharedMemoryRegion> shm; 60 const std::unique_ptr<SharedMemoryRegion> shm;
61 }; 61 };
62 62
63 V4L2VideoEncodeAccelerator::InputRecord::InputRecord() : at_device(false) { 63 V4L2VideoEncodeAccelerator::InputRecord::InputRecord() : at_device(false) {}
64 }
65 64
66 V4L2VideoEncodeAccelerator::InputRecord::~InputRecord() { 65 V4L2VideoEncodeAccelerator::InputRecord::~InputRecord() {}
67 }
68 66
69 V4L2VideoEncodeAccelerator::OutputRecord::OutputRecord() 67 V4L2VideoEncodeAccelerator::OutputRecord::OutputRecord()
70 : at_device(false), address(NULL), length(0) { 68 : at_device(false), address(NULL), length(0) {}
71 }
72 69
73 V4L2VideoEncodeAccelerator::OutputRecord::~OutputRecord() { 70 V4L2VideoEncodeAccelerator::OutputRecord::~OutputRecord() {}
74 }
75 71
76 V4L2VideoEncodeAccelerator::ImageProcessorInputRecord:: 72 V4L2VideoEncodeAccelerator::ImageProcessorInputRecord::
77 ImageProcessorInputRecord() 73 ImageProcessorInputRecord()
78 : force_keyframe(false) {} 74 : force_keyframe(false) {}
79 75
80 V4L2VideoEncodeAccelerator::ImageProcessorInputRecord:: 76 V4L2VideoEncodeAccelerator::ImageProcessorInputRecord::
81 ~ImageProcessorInputRecord() {} 77 ~ImageProcessorInputRecord() {}
82 78
83 V4L2VideoEncodeAccelerator::V4L2VideoEncodeAccelerator( 79 V4L2VideoEncodeAccelerator::V4L2VideoEncodeAccelerator(
84 const scoped_refptr<V4L2Device>& device) 80 const scoped_refptr<V4L2Device>& device)
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 125
130 DCHECK(child_task_runner_->BelongsToCurrentThread()); 126 DCHECK(child_task_runner_->BelongsToCurrentThread());
131 DCHECK_EQ(encoder_state_, kUninitialized); 127 DCHECK_EQ(encoder_state_, kUninitialized);
132 128
133 struct v4l2_capability caps; 129 struct v4l2_capability caps;
134 memset(&caps, 0, sizeof(caps)); 130 memset(&caps, 0, sizeof(caps));
135 const __u32 kCapsRequired = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; 131 const __u32 kCapsRequired = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
136 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps); 132 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps);
137 if ((caps.capabilities & kCapsRequired) != kCapsRequired) { 133 if ((caps.capabilities & kCapsRequired) != kCapsRequired) {
138 LOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP: " 134 LOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP: "
139 "caps check failed: 0x" << std::hex << caps.capabilities; 135 "caps check failed: 0x"
136 << std::hex << caps.capabilities;
140 return false; 137 return false;
141 } 138 }
142 139
143 if (!SetFormats(input_format, output_profile)) { 140 if (!SetFormats(input_format, output_profile)) {
144 DLOG(ERROR) << "Failed setting up formats"; 141 DLOG(ERROR) << "Failed setting up formats";
145 return false; 142 return false;
146 } 143 }
147 144
148 if (input_format != device_input_format_) { 145 if (input_format != device_input_format_) {
149 DVLOG(1) << "Input format not supported by the HW, will convert to " 146 DVLOG(1) << "Input format not supported by the HW, will convert to "
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 base::Unretained(this), force_keyframe, 239 base::Unretained(this), force_keyframe,
243 frame->timestamp())); 240 frame->timestamp()));
244 } else { 241 } else {
245 ImageProcessorInputRecord record; 242 ImageProcessorInputRecord record;
246 record.frame = frame; 243 record.frame = frame;
247 record.force_keyframe = force_keyframe; 244 record.force_keyframe = force_keyframe;
248 image_processor_input_queue_.push(record); 245 image_processor_input_queue_.push(record);
249 } 246 }
250 } else { 247 } else {
251 encoder_thread_.message_loop()->PostTask( 248 encoder_thread_.message_loop()->PostTask(
252 FROM_HERE, 249 FROM_HERE, base::Bind(&V4L2VideoEncodeAccelerator::EncodeTask,
253 base::Bind(&V4L2VideoEncodeAccelerator::EncodeTask, 250 base::Unretained(this), frame, force_keyframe));
254 base::Unretained(this),
255 frame,
256 force_keyframe));
257 } 251 }
258 } 252 }
259 253
260 void V4L2VideoEncodeAccelerator::UseOutputBitstreamBuffer( 254 void V4L2VideoEncodeAccelerator::UseOutputBitstreamBuffer(
261 const media::BitstreamBuffer& buffer) { 255 const media::BitstreamBuffer& buffer) {
262 DVLOG(3) << "UseOutputBitstreamBuffer(): id=" << buffer.id(); 256 DVLOG(3) << "UseOutputBitstreamBuffer(): id=" << buffer.id();
263 DCHECK(child_task_runner_->BelongsToCurrentThread()); 257 DCHECK(child_task_runner_->BelongsToCurrentThread());
264 258
265 if (buffer.size() < output_buffer_byte_size_) { 259 if (buffer.size() < output_buffer_byte_size_) {
266 NOTIFY_ERROR(kInvalidArgumentError); 260 NOTIFY_ERROR(kInvalidArgumentError);
267 return; 261 return;
268 } 262 }
269 263
270 std::unique_ptr<SharedMemoryRegion> shm( 264 std::unique_ptr<SharedMemoryRegion> shm(
271 new SharedMemoryRegion(buffer, false)); 265 new SharedMemoryRegion(buffer, false));
272 if (!shm->Map()) { 266 if (!shm->Map()) {
273 NOTIFY_ERROR(kPlatformFailureError); 267 NOTIFY_ERROR(kPlatformFailureError);
274 return; 268 return;
275 } 269 }
276 270
277 std::unique_ptr<BitstreamBufferRef> buffer_ref( 271 std::unique_ptr<BitstreamBufferRef> buffer_ref(
278 new BitstreamBufferRef(buffer.id(), std::move(shm))); 272 new BitstreamBufferRef(buffer.id(), std::move(shm)));
279 encoder_thread_.message_loop()->PostTask( 273 encoder_thread_.message_loop()->PostTask(
280 FROM_HERE, 274 FROM_HERE,
281 base::Bind(&V4L2VideoEncodeAccelerator::UseOutputBitstreamBufferTask, 275 base::Bind(&V4L2VideoEncodeAccelerator::UseOutputBitstreamBufferTask,
282 base::Unretained(this), 276 base::Unretained(this), base::Passed(&buffer_ref)));
283 base::Passed(&buffer_ref)));
284 } 277 }
285 278
286 void V4L2VideoEncodeAccelerator::RequestEncodingParametersChange( 279 void V4L2VideoEncodeAccelerator::RequestEncodingParametersChange(
287 uint32_t bitrate, 280 uint32_t bitrate,
288 uint32_t framerate) { 281 uint32_t framerate) {
289 DVLOG(3) << "RequestEncodingParametersChange(): bitrate=" << bitrate 282 DVLOG(3) << "RequestEncodingParametersChange(): bitrate=" << bitrate
290 << ", framerate=" << framerate; 283 << ", framerate=" << framerate;
291 DCHECK(child_task_runner_->BelongsToCurrentThread()); 284 DCHECK(child_task_runner_->BelongsToCurrentThread());
292 285
293 encoder_thread_.message_loop()->PostTask( 286 encoder_thread_.message_loop()->PostTask(
294 FROM_HERE, 287 FROM_HERE,
295 base::Bind( 288 base::Bind(
296 &V4L2VideoEncodeAccelerator::RequestEncodingParametersChangeTask, 289 &V4L2VideoEncodeAccelerator::RequestEncodingParametersChangeTask,
297 base::Unretained(this), 290 base::Unretained(this), bitrate, framerate));
298 bitrate,
299 framerate));
300 } 291 }
301 292
302 void V4L2VideoEncodeAccelerator::Destroy() { 293 void V4L2VideoEncodeAccelerator::Destroy() {
303 DVLOG(3) << "Destroy()"; 294 DVLOG(3) << "Destroy()";
304 DCHECK(child_task_runner_->BelongsToCurrentThread()); 295 DCHECK(child_task_runner_->BelongsToCurrentThread());
305 296
306 // We're destroying; cancel all callbacks. 297 // We're destroying; cancel all callbacks.
307 client_ptr_factory_.reset(); 298 client_ptr_factory_.reset();
308 weak_this_ptr_factory_.InvalidateWeakPtrs(); 299 weak_this_ptr_factory_.InvalidateWeakPtrs();
309 300
310 if (image_processor_.get()) 301 if (image_processor_.get())
311 image_processor_.release()->Destroy(); 302 image_processor_.release()->Destroy();
312 303
313 // If the encoder thread is running, destroy using posted task. 304 // If the encoder thread is running, destroy using posted task.
314 if (encoder_thread_.IsRunning()) { 305 if (encoder_thread_.IsRunning()) {
315 encoder_thread_.message_loop()->PostTask( 306 encoder_thread_.message_loop()->PostTask(
316 FROM_HERE, 307 FROM_HERE, base::Bind(&V4L2VideoEncodeAccelerator::DestroyTask,
317 base::Bind(&V4L2VideoEncodeAccelerator::DestroyTask, 308 base::Unretained(this)));
318 base::Unretained(this)));
319 // DestroyTask() will put the encoder into kError state and cause all tasks 309 // DestroyTask() will put the encoder into kError state and cause all tasks
320 // to no-op. 310 // to no-op.
321 encoder_thread_.Stop(); 311 encoder_thread_.Stop();
322 } else { 312 } else {
323 // Otherwise, call the destroy task directly. 313 // Otherwise, call the destroy task directly.
324 DestroyTask(); 314 DestroyTask();
325 } 315 }
326 316
327 // Set to kError state just in case. 317 // Set to kError state just in case.
328 encoder_state_ = kError; 318 encoder_state_ = kError;
329 319
330 delete this; 320 delete this;
331 } 321 }
332 322
333 media::VideoEncodeAccelerator::SupportedProfiles 323 media::VideoEncodeAccelerator::SupportedProfiles
334 V4L2VideoEncodeAccelerator::GetSupportedProfiles() { 324 V4L2VideoEncodeAccelerator::GetSupportedProfiles() {
335 SupportedProfiles profiles; 325 SupportedProfiles profiles;
336 SupportedProfile profile; 326 SupportedProfile profile;
337 profile.max_framerate_numerator = 30; 327 profile.max_framerate_numerator = 30;
338 profile.max_framerate_denominator = 1; 328 profile.max_framerate_denominator = 1;
339 329
340 gfx::Size min_resolution; 330 gfx::Size min_resolution;
341 v4l2_fmtdesc fmtdesc; 331 v4l2_fmtdesc fmtdesc;
342 memset(&fmtdesc, 0, sizeof(fmtdesc)); 332 memset(&fmtdesc, 0, sizeof(fmtdesc));
343 fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 333 fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
344 for (; device_->Ioctl(VIDIOC_ENUM_FMT, &fmtdesc) == 0; ++fmtdesc.index) { 334 for (; device_->Ioctl(VIDIOC_ENUM_FMT, &fmtdesc) == 0; ++fmtdesc.index) {
345 device_->GetSupportedResolution(fmtdesc.pixelformat, 335 device_->GetSupportedResolution(fmtdesc.pixelformat, &min_resolution,
346 &min_resolution, &profile.max_resolution); 336 &profile.max_resolution);
347 switch (fmtdesc.pixelformat) { 337 switch (fmtdesc.pixelformat) {
348 case V4L2_PIX_FMT_H264: 338 case V4L2_PIX_FMT_H264:
349 profile.profile = media::H264PROFILE_MAIN; 339 profile.profile = media::H264PROFILE_MAIN;
350 profiles.push_back(profile); 340 profiles.push_back(profile);
351 break; 341 break;
352 case V4L2_PIX_FMT_VP8: 342 case V4L2_PIX_FMT_VP8:
353 profile.profile = media::VP8PROFILE_ANY; 343 profile.profile = media::VP8PROFILE_ANY;
354 profiles.push_back(profile); 344 profiles.push_back(profile);
355 break; 345 break;
356 case V4L2_PIX_FMT_VP9: 346 case V4L2_PIX_FMT_VP9:
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
514 504
515 // ServiceDeviceTask() should only ever be scheduled from DevicePollTask(), 505 // ServiceDeviceTask() should only ever be scheduled from DevicePollTask(),
516 // so either: 506 // so either:
517 // * device_poll_thread_ is running normally 507 // * device_poll_thread_ is running normally
518 // * device_poll_thread_ scheduled us, but then a DestroyTask() shut it down, 508 // * device_poll_thread_ scheduled us, but then a DestroyTask() shut it down,
519 // in which case we're in kError state, and we should have early-outed 509 // in which case we're in kError state, and we should have early-outed
520 // already. 510 // already.
521 DCHECK(device_poll_thread_.message_loop()); 511 DCHECK(device_poll_thread_.message_loop());
522 // Queue the DevicePollTask() now. 512 // Queue the DevicePollTask() now.
523 device_poll_thread_.message_loop()->PostTask( 513 device_poll_thread_.message_loop()->PostTask(
524 FROM_HERE, 514 FROM_HERE, base::Bind(&V4L2VideoEncodeAccelerator::DevicePollTask,
525 base::Bind(&V4L2VideoEncodeAccelerator::DevicePollTask, 515 base::Unretained(this), poll_device));
526 base::Unretained(this),
527 poll_device));
528 516
529 DVLOG(2) << __func__ << ": buffer counts: ENC[" 517 DVLOG(2) << __func__ << ": buffer counts: ENC[" << encoder_input_queue_.size()
530 << encoder_input_queue_.size() << "] => DEVICE[" 518 << "] => DEVICE[" << free_input_buffers_.size() << "+"
531 << free_input_buffers_.size() << "+" 519 << input_buffer_queued_count_ << "/" << input_buffer_map_.size()
532 << input_buffer_queued_count_ << "/" 520 << "->" << free_output_buffers_.size() << "+"
533 << input_buffer_map_.size() << "->" 521 << output_buffer_queued_count_ << "/" << output_buffer_map_.size()
534 << free_output_buffers_.size() << "+" 522 << "] => OUT[" << encoder_output_queue_.size() << "]";
535 << output_buffer_queued_count_ << "/"
536 << output_buffer_map_.size() << "] => OUT["
537 << encoder_output_queue_.size() << "]";
538 } 523 }
539 524
540 void V4L2VideoEncodeAccelerator::Enqueue() { 525 void V4L2VideoEncodeAccelerator::Enqueue() {
541 DCHECK_EQ(encoder_thread_.message_loop(), base::MessageLoop::current()); 526 DCHECK_EQ(encoder_thread_.message_loop(), base::MessageLoop::current());
542 527
543 DVLOG(3) << "Enqueue() " 528 DVLOG(3) << "Enqueue() "
544 << "free_input_buffers: " << free_input_buffers_.size() 529 << "free_input_buffers: " << free_input_buffers_.size()
545 << "input_queue: " << encoder_input_queue_.size(); 530 << "input_queue: " << encoder_input_queue_.size();
546 531
547 // Enqueue all the inputs we can. 532 // Enqueue all the inputs we can.
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
666 memcpy(target_data + stream_header_size_, output_data, output_size); 651 memcpy(target_data + stream_header_size_, output_data, output_size);
667 output_size += stream_header_size_; 652 output_size += stream_header_size_;
668 } else { 653 } else {
669 memcpy(target_data, output_data, output_size); 654 memcpy(target_data, output_data, output_size);
670 } 655 }
671 } else { 656 } else {
672 memcpy(target_data, output_data, output_size); 657 memcpy(target_data, output_data, output_size);
673 } 658 }
674 659
675 DVLOG(3) << "Dequeue(): returning " 660 DVLOG(3) << "Dequeue(): returning "
676 "bitstream_buffer_id=" << output_record.buffer_ref->id 661 "bitstream_buffer_id="
677 << ", size=" << output_size << ", key_frame=" << key_frame; 662 << output_record.buffer_ref->id << ", size=" << output_size
663 << ", key_frame=" << key_frame;
678 child_task_runner_->PostTask( 664 child_task_runner_->PostTask(
679 FROM_HERE, 665 FROM_HERE,
680 base::Bind(&Client::BitstreamBufferReady, client_, 666 base::Bind(&Client::BitstreamBufferReady, client_,
681 output_record.buffer_ref->id, output_size, key_frame)); 667 output_record.buffer_ref->id, output_size, key_frame));
682 output_record.at_device = false; 668 output_record.at_device = false;
683 output_record.buffer_ref.reset(); 669 output_record.buffer_ref.reset();
684 free_output_buffers_.push_back(dqbuf.index); 670 free_output_buffers_.push_back(dqbuf.index);
685 output_buffer_queued_count_--; 671 output_buffer_queued_count_--;
686 } 672 }
687 } 673 }
(...skipping 11 matching lines...) Expand all
699 struct v4l2_buffer qbuf; 685 struct v4l2_buffer qbuf;
700 struct v4l2_plane qbuf_planes[VIDEO_MAX_PLANES]; 686 struct v4l2_plane qbuf_planes[VIDEO_MAX_PLANES];
701 memset(&qbuf, 0, sizeof(qbuf)); 687 memset(&qbuf, 0, sizeof(qbuf));
702 memset(qbuf_planes, 0, sizeof(qbuf_planes)); 688 memset(qbuf_planes, 0, sizeof(qbuf_planes));
703 qbuf.index = index; 689 qbuf.index = index;
704 qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 690 qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
705 qbuf.m.planes = qbuf_planes; 691 qbuf.m.planes = qbuf_planes;
706 692
707 DCHECK_EQ(device_input_format_, frame->format()); 693 DCHECK_EQ(device_input_format_, frame->format());
708 for (size_t i = 0; i < input_planes_count_; ++i) { 694 for (size_t i = 0; i < input_planes_count_; ++i) {
709 qbuf.m.planes[i].bytesused = 695 qbuf.m.planes[i].bytesused = base::checked_cast<__u32>(
710 base::checked_cast<__u32>(media::VideoFrame::PlaneSize( 696 media::VideoFrame::PlaneSize(frame->format(), i, input_allocated_size_)
711 frame->format(), i, input_allocated_size_).GetArea()); 697 .GetArea());
712 698
713 switch (input_memory_type_) { 699 switch (input_memory_type_) {
714 case V4L2_MEMORY_USERPTR: 700 case V4L2_MEMORY_USERPTR:
715 qbuf.m.planes[i].length = qbuf.m.planes[i].bytesused; 701 qbuf.m.planes[i].length = qbuf.m.planes[i].bytesused;
716 qbuf.m.planes[i].m.userptr = 702 qbuf.m.planes[i].m.userptr =
717 reinterpret_cast<unsigned long>(frame->data(i)); 703 reinterpret_cast<unsigned long>(frame->data(i));
718 DCHECK(qbuf.m.planes[i].m.userptr); 704 DCHECK(qbuf.m.planes[i].m.userptr);
719 break; 705 break;
720 706
721 case V4L2_MEMORY_DMABUF: 707 case V4L2_MEMORY_DMABUF:
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
777 763
778 // Start up the device poll thread and schedule its first DevicePollTask(). 764 // Start up the device poll thread and schedule its first DevicePollTask().
779 if (!device_poll_thread_.Start()) { 765 if (!device_poll_thread_.Start()) {
780 LOG(ERROR) << "StartDevicePoll(): Device thread failed to start"; 766 LOG(ERROR) << "StartDevicePoll(): Device thread failed to start";
781 NOTIFY_ERROR(kPlatformFailureError); 767 NOTIFY_ERROR(kPlatformFailureError);
782 return false; 768 return false;
783 } 769 }
784 // Enqueue a poll task with no devices to poll on -- it will wait only on the 770 // Enqueue a poll task with no devices to poll on -- it will wait only on the
785 // interrupt fd. 771 // interrupt fd.
786 device_poll_thread_.message_loop()->PostTask( 772 device_poll_thread_.message_loop()->PostTask(
787 FROM_HERE, 773 FROM_HERE, base::Bind(&V4L2VideoEncodeAccelerator::DevicePollTask,
788 base::Bind(&V4L2VideoEncodeAccelerator::DevicePollTask, 774 base::Unretained(this), false));
789 base::Unretained(this),
790 false));
791 775
792 return true; 776 return true;
793 } 777 }
794 778
795 bool V4L2VideoEncodeAccelerator::StopDevicePoll() { 779 bool V4L2VideoEncodeAccelerator::StopDevicePoll() {
796 DVLOG(3) << "StopDevicePoll()"; 780 DVLOG(3) << "StopDevicePoll()";
797 781
798 // Signal the DevicePollTask() to stop, and stop the device poll thread. 782 // Signal the DevicePollTask() to stop, and stop the device poll thread.
799 if (!device_->SetDevicePollInterrupt()) 783 if (!device_->SetDevicePollInterrupt())
800 return false; 784 return false;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
848 832
849 bool event_pending; 833 bool event_pending;
850 if (!device_->Poll(poll_device, &event_pending)) { 834 if (!device_->Poll(poll_device, &event_pending)) {
851 NOTIFY_ERROR(kPlatformFailureError); 835 NOTIFY_ERROR(kPlatformFailureError);
852 return; 836 return;
853 } 837 }
854 838
855 // All processing should happen on ServiceDeviceTask(), since we shouldn't 839 // All processing should happen on ServiceDeviceTask(), since we shouldn't
856 // touch encoder state from this thread. 840 // touch encoder state from this thread.
857 encoder_thread_.message_loop()->PostTask( 841 encoder_thread_.message_loop()->PostTask(
858 FROM_HERE, 842 FROM_HERE, base::Bind(&V4L2VideoEncodeAccelerator::ServiceDeviceTask,
859 base::Bind(&V4L2VideoEncodeAccelerator::ServiceDeviceTask, 843 base::Unretained(this)));
860 base::Unretained(this)));
861 } 844 }
862 845
863 void V4L2VideoEncodeAccelerator::NotifyError(Error error) { 846 void V4L2VideoEncodeAccelerator::NotifyError(Error error) {
864 DVLOG(1) << "NotifyError(): error=" << error; 847 DVLOG(1) << "NotifyError(): error=" << error;
865 848
866 if (!child_task_runner_->BelongsToCurrentThread()) { 849 if (!child_task_runner_->BelongsToCurrentThread()) {
867 child_task_runner_->PostTask( 850 child_task_runner_->PostTask(
868 FROM_HERE, base::Bind(&V4L2VideoEncodeAccelerator::NotifyError, 851 FROM_HERE, base::Bind(&V4L2VideoEncodeAccelerator::NotifyError,
869 weak_this_, error)); 852 weak_this_, error));
870 return; 853 return;
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
1207 struct v4l2_plane planes[1]; 1190 struct v4l2_plane planes[1];
1208 struct v4l2_buffer buffer; 1191 struct v4l2_buffer buffer;
1209 memset(&buffer, 0, sizeof(buffer)); 1192 memset(&buffer, 0, sizeof(buffer));
1210 memset(planes, 0, sizeof(planes)); 1193 memset(planes, 0, sizeof(planes));
1211 buffer.index = i; 1194 buffer.index = i;
1212 buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1195 buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1213 buffer.memory = V4L2_MEMORY_MMAP; 1196 buffer.memory = V4L2_MEMORY_MMAP;
1214 buffer.m.planes = planes; 1197 buffer.m.planes = planes;
1215 buffer.length = arraysize(planes); 1198 buffer.length = arraysize(planes);
1216 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYBUF, &buffer); 1199 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYBUF, &buffer);
1217 void* address = device_->Mmap(NULL, 1200 void* address =
1218 buffer.m.planes[0].length, 1201 device_->Mmap(NULL, buffer.m.planes[0].length, PROT_READ | PROT_WRITE,
1219 PROT_READ | PROT_WRITE, 1202 MAP_SHARED, buffer.m.planes[0].m.mem_offset);
1220 MAP_SHARED,
1221 buffer.m.planes[0].m.mem_offset);
1222 if (address == MAP_FAILED) { 1203 if (address == MAP_FAILED) {
1223 PLOG(ERROR) << "CreateOutputBuffers(): mmap() failed"; 1204 PLOG(ERROR) << "CreateOutputBuffers(): mmap() failed";
1224 return false; 1205 return false;
1225 } 1206 }
1226 output_buffer_map_[i].address = address; 1207 output_buffer_map_[i].address = address;
1227 output_buffer_map_[i].length = buffer.m.planes[0].length; 1208 output_buffer_map_[i].length = buffer.m.planes[0].length;
1228 free_output_buffers_.push_back(i); 1209 free_output_buffers_.push_back(i);
1229 } 1210 }
1230 1211
1231 return true; 1212 return true;
(...skipping 30 matching lines...) Expand all
1262 memset(&reqbufs, 0, sizeof(reqbufs)); 1243 memset(&reqbufs, 0, sizeof(reqbufs));
1263 reqbufs.count = 0; 1244 reqbufs.count = 0;
1264 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1245 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1265 reqbufs.memory = V4L2_MEMORY_MMAP; 1246 reqbufs.memory = V4L2_MEMORY_MMAP;
1266 IOCTL_OR_LOG_ERROR(VIDIOC_REQBUFS, &reqbufs); 1247 IOCTL_OR_LOG_ERROR(VIDIOC_REQBUFS, &reqbufs);
1267 1248
1268 output_buffer_map_.clear(); 1249 output_buffer_map_.clear();
1269 free_output_buffers_.clear(); 1250 free_output_buffers_.clear();
1270 } 1251 }
1271 1252
1272 } // namespace content 1253 } // namespace media
OLDNEW
« no previous file with comments | « media/gpu/v4l2_video_encode_accelerator.h ('k') | media/gpu/va.sigs » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698