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

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

Issue 1882373004: Migrate content/common/gpu/media code to media/gpu (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix several more bot-identified build issues Created 4 years, 8 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
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 <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 <string.h> 8 #include <string.h>
9 #include <sys/eventfd.h> 9 #include <sys/eventfd.h>
10 #include <sys/ioctl.h> 10 #include <sys/ioctl.h>
11 #include <sys/mman.h> 11 #include <sys/mman.h>
12 #include <utility> 12 #include <utility>
13 13
14 #include "base/callback.h" 14 #include "base/callback.h"
15 #include "base/command_line.h" 15 #include "base/command_line.h"
16 #include "base/macros.h" 16 #include "base/macros.h"
17 #include "base/numerics/safe_conversions.h" 17 #include "base/numerics/safe_conversions.h"
18 #include "base/thread_task_runner_handle.h" 18 #include "base/thread_task_runner_handle.h"
19 #include "base/trace_event/trace_event.h" 19 #include "base/trace_event/trace_event.h"
20 #include "content/common/gpu/media/shared_memory_region.h"
21 #include "content/common/gpu/media/v4l2_video_encode_accelerator.h"
22 #include "media/base/bind_to_current_loop.h" 20 #include "media/base/bind_to_current_loop.h"
23 #include "media/base/bitstream_buffer.h" 21 #include "media/base/bitstream_buffer.h"
22 #include "media/gpu/shared_memory_region.h"
23 #include "media/gpu/v4l2_video_encode_accelerator.h"
24 24
25 #define NOTIFY_ERROR(x) \ 25 #define NOTIFY_ERROR(x) \
26 do { \ 26 do { \
27 LOG(ERROR) << "Setting error state:" << x; \ 27 LOG(ERROR) << "Setting error state:" << x; \
28 SetErrorState(x); \ 28 SetErrorState(x); \
29 } while (0) 29 } while (0)
30 30
31 #define IOCTL_OR_ERROR_RETURN_VALUE(type, arg, value, type_str) \ 31 #define IOCTL_OR_ERROR_RETURN_VALUE(type, arg, value, type_str) \
32 do { \ 32 do { \
33 if (device_->Ioctl(type, arg) != 0) { \ 33 if (device_->Ioctl(type, arg) != 0) { \
34 PLOG(ERROR) << __func__ << "(): ioctl() failed: " << type_str; \ 34 PLOG(ERROR) << __func__ << "(): ioctl() failed: " << type_str; \
35 NOTIFY_ERROR(kPlatformFailureError); \ 35 NOTIFY_ERROR(kPlatformFailureError); \
36 return value; \ 36 return value; \
37 } \ 37 } \
38 } while (0) 38 } while (0)
39 39
40 #define IOCTL_OR_ERROR_RETURN(type, arg) \ 40 #define IOCTL_OR_ERROR_RETURN(type, arg) \
41 IOCTL_OR_ERROR_RETURN_VALUE(type, arg, ((void)0), #type) 41 IOCTL_OR_ERROR_RETURN_VALUE(type, arg, ((void)0), #type)
42 42
43 #define IOCTL_OR_ERROR_RETURN_FALSE(type, arg) \ 43 #define IOCTL_OR_ERROR_RETURN_FALSE(type, arg) \
44 IOCTL_OR_ERROR_RETURN_VALUE(type, arg, false, #type) 44 IOCTL_OR_ERROR_RETURN_VALUE(type, arg, false, #type)
45 45
46 #define IOCTL_OR_LOG_ERROR(type, arg) \ 46 #define IOCTL_OR_LOG_ERROR(type, arg) \
47 do { \ 47 do { \
48 if (device_->Ioctl(type, arg) != 0) \ 48 if (device_->Ioctl(type, arg) != 0) \
49 PLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \ 49 PLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \
50 } while (0) 50 } while (0)
51 51
52 namespace content { 52 namespace media {
53 53
54 struct V4L2VideoEncodeAccelerator::BitstreamBufferRef { 54 struct V4L2VideoEncodeAccelerator::BitstreamBufferRef {
55 BitstreamBufferRef(int32_t id, std::unique_ptr<SharedMemoryRegion> shm) 55 BitstreamBufferRef(int32_t id, std::unique_ptr<SharedMemoryRegion> shm)
56 : id(id), shm(std::move(shm)) {} 56 : id(id), shm(std::move(shm)) {}
57 const int32_t id; 57 const int32_t id;
58 const std::unique_ptr<SharedMemoryRegion> shm; 58 const std::unique_ptr<SharedMemoryRegion> shm;
59 }; 59 };
60 60
61 V4L2VideoEncodeAccelerator::InputRecord::InputRecord() : at_device(false) { 61 V4L2VideoEncodeAccelerator::InputRecord::InputRecord() : at_device(false) {}
62 }
63 62
64 V4L2VideoEncodeAccelerator::InputRecord::~InputRecord() { 63 V4L2VideoEncodeAccelerator::InputRecord::~InputRecord() {}
65 }
66 64
67 V4L2VideoEncodeAccelerator::OutputRecord::OutputRecord() 65 V4L2VideoEncodeAccelerator::OutputRecord::OutputRecord()
68 : at_device(false), address(NULL), length(0) { 66 : at_device(false), address(NULL), length(0) {}
69 }
70 67
71 V4L2VideoEncodeAccelerator::OutputRecord::~OutputRecord() { 68 V4L2VideoEncodeAccelerator::OutputRecord::~OutputRecord() {}
72 }
73 69
74 V4L2VideoEncodeAccelerator::ImageProcessorInputRecord:: 70 V4L2VideoEncodeAccelerator::ImageProcessorInputRecord::
75 ImageProcessorInputRecord() 71 ImageProcessorInputRecord()
76 : force_keyframe(false) {} 72 : force_keyframe(false) {}
77 73
78 V4L2VideoEncodeAccelerator::ImageProcessorInputRecord:: 74 V4L2VideoEncodeAccelerator::ImageProcessorInputRecord::
79 ~ImageProcessorInputRecord() {} 75 ~ImageProcessorInputRecord() {}
80 76
81 V4L2VideoEncodeAccelerator::V4L2VideoEncodeAccelerator( 77 V4L2VideoEncodeAccelerator::V4L2VideoEncodeAccelerator(
82 const scoped_refptr<V4L2Device>& device) 78 const scoped_refptr<V4L2Device>& device)
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 123
128 DCHECK(child_task_runner_->BelongsToCurrentThread()); 124 DCHECK(child_task_runner_->BelongsToCurrentThread());
129 DCHECK_EQ(encoder_state_, kUninitialized); 125 DCHECK_EQ(encoder_state_, kUninitialized);
130 126
131 struct v4l2_capability caps; 127 struct v4l2_capability caps;
132 memset(&caps, 0, sizeof(caps)); 128 memset(&caps, 0, sizeof(caps));
133 const __u32 kCapsRequired = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; 129 const __u32 kCapsRequired = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
134 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps); 130 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps);
135 if ((caps.capabilities & kCapsRequired) != kCapsRequired) { 131 if ((caps.capabilities & kCapsRequired) != kCapsRequired) {
136 LOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP: " 132 LOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP: "
137 "caps check failed: 0x" << std::hex << caps.capabilities; 133 "caps check failed: 0x"
134 << std::hex << caps.capabilities;
138 return false; 135 return false;
139 } 136 }
140 137
141 if (!SetFormats(input_format, output_profile)) { 138 if (!SetFormats(input_format, output_profile)) {
142 DLOG(ERROR) << "Failed setting up formats"; 139 DLOG(ERROR) << "Failed setting up formats";
143 return false; 140 return false;
144 } 141 }
145 142
146 if (input_format != device_input_format_) { 143 if (input_format != device_input_format_) {
147 DVLOG(1) << "Input format not supported by the HW, will convert to " 144 DVLOG(1) << "Input format not supported by the HW, will convert to "
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 base::Bind(&V4L2VideoEncodeAccelerator::FrameProcessed, weak_this_, 217 base::Bind(&V4L2VideoEncodeAccelerator::FrameProcessed, weak_this_,
221 force_keyframe, frame->timestamp())); 218 force_keyframe, frame->timestamp()));
222 } else { 219 } else {
223 ImageProcessorInputRecord record; 220 ImageProcessorInputRecord record;
224 record.frame = frame; 221 record.frame = frame;
225 record.force_keyframe = force_keyframe; 222 record.force_keyframe = force_keyframe;
226 image_processor_input_queue_.push(record); 223 image_processor_input_queue_.push(record);
227 } 224 }
228 } else { 225 } else {
229 encoder_thread_.message_loop()->PostTask( 226 encoder_thread_.message_loop()->PostTask(
230 FROM_HERE, 227 FROM_HERE, base::Bind(&V4L2VideoEncodeAccelerator::EncodeTask,
231 base::Bind(&V4L2VideoEncodeAccelerator::EncodeTask, 228 base::Unretained(this), frame, force_keyframe));
232 base::Unretained(this),
233 frame,
234 force_keyframe));
235 } 229 }
236 } 230 }
237 231
238 void V4L2VideoEncodeAccelerator::UseOutputBitstreamBuffer( 232 void V4L2VideoEncodeAccelerator::UseOutputBitstreamBuffer(
239 const media::BitstreamBuffer& buffer) { 233 const media::BitstreamBuffer& buffer) {
240 DVLOG(3) << "UseOutputBitstreamBuffer(): id=" << buffer.id(); 234 DVLOG(3) << "UseOutputBitstreamBuffer(): id=" << buffer.id();
241 DCHECK(child_task_runner_->BelongsToCurrentThread()); 235 DCHECK(child_task_runner_->BelongsToCurrentThread());
242 236
243 if (buffer.size() < output_buffer_byte_size_) { 237 if (buffer.size() < output_buffer_byte_size_) {
244 NOTIFY_ERROR(kInvalidArgumentError); 238 NOTIFY_ERROR(kInvalidArgumentError);
245 return; 239 return;
246 } 240 }
247 241
248 std::unique_ptr<SharedMemoryRegion> shm( 242 std::unique_ptr<SharedMemoryRegion> shm(
249 new SharedMemoryRegion(buffer, false)); 243 new SharedMemoryRegion(buffer, false));
250 if (!shm->Map()) { 244 if (!shm->Map()) {
251 NOTIFY_ERROR(kPlatformFailureError); 245 NOTIFY_ERROR(kPlatformFailureError);
252 return; 246 return;
253 } 247 }
254 248
255 std::unique_ptr<BitstreamBufferRef> buffer_ref( 249 std::unique_ptr<BitstreamBufferRef> buffer_ref(
256 new BitstreamBufferRef(buffer.id(), std::move(shm))); 250 new BitstreamBufferRef(buffer.id(), std::move(shm)));
257 encoder_thread_.message_loop()->PostTask( 251 encoder_thread_.message_loop()->PostTask(
258 FROM_HERE, 252 FROM_HERE,
259 base::Bind(&V4L2VideoEncodeAccelerator::UseOutputBitstreamBufferTask, 253 base::Bind(&V4L2VideoEncodeAccelerator::UseOutputBitstreamBufferTask,
260 base::Unretained(this), 254 base::Unretained(this), base::Passed(&buffer_ref)));
261 base::Passed(&buffer_ref)));
262 } 255 }
263 256
264 void V4L2VideoEncodeAccelerator::RequestEncodingParametersChange( 257 void V4L2VideoEncodeAccelerator::RequestEncodingParametersChange(
265 uint32_t bitrate, 258 uint32_t bitrate,
266 uint32_t framerate) { 259 uint32_t framerate) {
267 DVLOG(3) << "RequestEncodingParametersChange(): bitrate=" << bitrate 260 DVLOG(3) << "RequestEncodingParametersChange(): bitrate=" << bitrate
268 << ", framerate=" << framerate; 261 << ", framerate=" << framerate;
269 DCHECK(child_task_runner_->BelongsToCurrentThread()); 262 DCHECK(child_task_runner_->BelongsToCurrentThread());
270 263
271 encoder_thread_.message_loop()->PostTask( 264 encoder_thread_.message_loop()->PostTask(
272 FROM_HERE, 265 FROM_HERE,
273 base::Bind( 266 base::Bind(
274 &V4L2VideoEncodeAccelerator::RequestEncodingParametersChangeTask, 267 &V4L2VideoEncodeAccelerator::RequestEncodingParametersChangeTask,
275 base::Unretained(this), 268 base::Unretained(this), bitrate, framerate));
276 bitrate,
277 framerate));
278 } 269 }
279 270
280 void V4L2VideoEncodeAccelerator::Destroy() { 271 void V4L2VideoEncodeAccelerator::Destroy() {
281 DVLOG(3) << "Destroy()"; 272 DVLOG(3) << "Destroy()";
282 DCHECK(child_task_runner_->BelongsToCurrentThread()); 273 DCHECK(child_task_runner_->BelongsToCurrentThread());
283 274
284 // We're destroying; cancel all callbacks. 275 // We're destroying; cancel all callbacks.
285 client_ptr_factory_.reset(); 276 client_ptr_factory_.reset();
286 weak_this_ptr_factory_.InvalidateWeakPtrs(); 277 weak_this_ptr_factory_.InvalidateWeakPtrs();
287 278
288 if (image_processor_.get()) 279 if (image_processor_.get())
289 image_processor_.release()->Destroy(); 280 image_processor_.release()->Destroy();
290 281
291 // If the encoder thread is running, destroy using posted task. 282 // If the encoder thread is running, destroy using posted task.
292 if (encoder_thread_.IsRunning()) { 283 if (encoder_thread_.IsRunning()) {
293 encoder_thread_.message_loop()->PostTask( 284 encoder_thread_.message_loop()->PostTask(
294 FROM_HERE, 285 FROM_HERE, base::Bind(&V4L2VideoEncodeAccelerator::DestroyTask,
295 base::Bind(&V4L2VideoEncodeAccelerator::DestroyTask, 286 base::Unretained(this)));
296 base::Unretained(this)));
297 // DestroyTask() will put the encoder into kError state and cause all tasks 287 // DestroyTask() will put the encoder into kError state and cause all tasks
298 // to no-op. 288 // to no-op.
299 encoder_thread_.Stop(); 289 encoder_thread_.Stop();
300 } else { 290 } else {
301 // Otherwise, call the destroy task directly. 291 // Otherwise, call the destroy task directly.
302 DestroyTask(); 292 DestroyTask();
303 } 293 }
304 294
305 // Set to kError state just in case. 295 // Set to kError state just in case.
306 encoder_state_ = kError; 296 encoder_state_ = kError;
307 297
308 delete this; 298 delete this;
309 } 299 }
310 300
311 media::VideoEncodeAccelerator::SupportedProfiles 301 media::VideoEncodeAccelerator::SupportedProfiles
312 V4L2VideoEncodeAccelerator::GetSupportedProfiles() { 302 V4L2VideoEncodeAccelerator::GetSupportedProfiles() {
313 SupportedProfiles profiles; 303 SupportedProfiles profiles;
314 SupportedProfile profile; 304 SupportedProfile profile;
315 profile.max_framerate_numerator = 30; 305 profile.max_framerate_numerator = 30;
316 profile.max_framerate_denominator = 1; 306 profile.max_framerate_denominator = 1;
317 307
318 gfx::Size min_resolution; 308 gfx::Size min_resolution;
319 v4l2_fmtdesc fmtdesc; 309 v4l2_fmtdesc fmtdesc;
320 memset(&fmtdesc, 0, sizeof(fmtdesc)); 310 memset(&fmtdesc, 0, sizeof(fmtdesc));
321 fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 311 fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
322 for (; device_->Ioctl(VIDIOC_ENUM_FMT, &fmtdesc) == 0; ++fmtdesc.index) { 312 for (; device_->Ioctl(VIDIOC_ENUM_FMT, &fmtdesc) == 0; ++fmtdesc.index) {
323 device_->GetSupportedResolution(fmtdesc.pixelformat, 313 device_->GetSupportedResolution(fmtdesc.pixelformat, &min_resolution,
324 &min_resolution, &profile.max_resolution); 314 &profile.max_resolution);
325 switch (fmtdesc.pixelformat) { 315 switch (fmtdesc.pixelformat) {
326 case V4L2_PIX_FMT_H264: 316 case V4L2_PIX_FMT_H264:
327 profile.profile = media::H264PROFILE_MAIN; 317 profile.profile = media::H264PROFILE_MAIN;
328 profiles.push_back(profile); 318 profiles.push_back(profile);
329 break; 319 break;
330 case V4L2_PIX_FMT_VP8: 320 case V4L2_PIX_FMT_VP8:
331 profile.profile = media::VP8PROFILE_ANY; 321 profile.profile = media::VP8PROFILE_ANY;
332 profiles.push_back(profile); 322 profiles.push_back(profile);
333 break; 323 break;
334 case V4L2_PIX_FMT_VP9: 324 case V4L2_PIX_FMT_VP9:
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 481
492 // ServiceDeviceTask() should only ever be scheduled from DevicePollTask(), 482 // ServiceDeviceTask() should only ever be scheduled from DevicePollTask(),
493 // so either: 483 // so either:
494 // * device_poll_thread_ is running normally 484 // * device_poll_thread_ is running normally
495 // * device_poll_thread_ scheduled us, but then a DestroyTask() shut it down, 485 // * device_poll_thread_ scheduled us, but then a DestroyTask() shut it down,
496 // in which case we're in kError state, and we should have early-outed 486 // in which case we're in kError state, and we should have early-outed
497 // already. 487 // already.
498 DCHECK(device_poll_thread_.message_loop()); 488 DCHECK(device_poll_thread_.message_loop());
499 // Queue the DevicePollTask() now. 489 // Queue the DevicePollTask() now.
500 device_poll_thread_.message_loop()->PostTask( 490 device_poll_thread_.message_loop()->PostTask(
501 FROM_HERE, 491 FROM_HERE, base::Bind(&V4L2VideoEncodeAccelerator::DevicePollTask,
502 base::Bind(&V4L2VideoEncodeAccelerator::DevicePollTask, 492 base::Unretained(this), poll_device));
503 base::Unretained(this),
504 poll_device));
505 493
506 DVLOG(2) << __func__ << ": buffer counts: ENC[" 494 DVLOG(2) << __func__ << ": buffer counts: ENC[" << encoder_input_queue_.size()
507 << encoder_input_queue_.size() << "] => DEVICE[" 495 << "] => DEVICE[" << free_input_buffers_.size() << "+"
508 << free_input_buffers_.size() << "+" 496 << input_buffer_queued_count_ << "/" << input_buffer_map_.size()
509 << input_buffer_queued_count_ << "/" 497 << "->" << free_output_buffers_.size() << "+"
510 << input_buffer_map_.size() << "->" 498 << output_buffer_queued_count_ << "/" << output_buffer_map_.size()
511 << free_output_buffers_.size() << "+" 499 << "] => OUT[" << encoder_output_queue_.size() << "]";
512 << output_buffer_queued_count_ << "/"
513 << output_buffer_map_.size() << "] => OUT["
514 << encoder_output_queue_.size() << "]";
515 } 500 }
516 501
517 void V4L2VideoEncodeAccelerator::Enqueue() { 502 void V4L2VideoEncodeAccelerator::Enqueue() {
518 DCHECK_EQ(encoder_thread_.message_loop(), base::MessageLoop::current()); 503 DCHECK_EQ(encoder_thread_.message_loop(), base::MessageLoop::current());
519 504
520 DVLOG(3) << "Enqueue() " 505 DVLOG(3) << "Enqueue() "
521 << "free_input_buffers: " << free_input_buffers_.size() 506 << "free_input_buffers: " << free_input_buffers_.size()
522 << "input_queue: " << encoder_input_queue_.size(); 507 << "input_queue: " << encoder_input_queue_.size();
523 508
524 // Enqueue all the inputs we can. 509 // Enqueue all the inputs we can.
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
643 memcpy(target_data + stream_header_size_, output_data, output_size); 628 memcpy(target_data + stream_header_size_, output_data, output_size);
644 output_size += stream_header_size_; 629 output_size += stream_header_size_;
645 } else { 630 } else {
646 memcpy(target_data, output_data, output_size); 631 memcpy(target_data, output_data, output_size);
647 } 632 }
648 } else { 633 } else {
649 memcpy(target_data, output_data, output_size); 634 memcpy(target_data, output_data, output_size);
650 } 635 }
651 636
652 DVLOG(3) << "Dequeue(): returning " 637 DVLOG(3) << "Dequeue(): returning "
653 "bitstream_buffer_id=" << output_record.buffer_ref->id 638 "bitstream_buffer_id="
654 << ", size=" << output_size << ", key_frame=" << key_frame; 639 << output_record.buffer_ref->id << ", size=" << output_size
640 << ", key_frame=" << key_frame;
655 child_task_runner_->PostTask( 641 child_task_runner_->PostTask(
656 FROM_HERE, 642 FROM_HERE,
657 base::Bind(&Client::BitstreamBufferReady, client_, 643 base::Bind(&Client::BitstreamBufferReady, client_,
658 output_record.buffer_ref->id, output_size, key_frame)); 644 output_record.buffer_ref->id, output_size, key_frame));
659 output_record.at_device = false; 645 output_record.at_device = false;
660 output_record.buffer_ref.reset(); 646 output_record.buffer_ref.reset();
661 free_output_buffers_.push_back(dqbuf.index); 647 free_output_buffers_.push_back(dqbuf.index);
662 output_buffer_queued_count_--; 648 output_buffer_queued_count_--;
663 } 649 }
664 } 650 }
(...skipping 11 matching lines...) Expand all
676 struct v4l2_buffer qbuf; 662 struct v4l2_buffer qbuf;
677 struct v4l2_plane qbuf_planes[VIDEO_MAX_PLANES]; 663 struct v4l2_plane qbuf_planes[VIDEO_MAX_PLANES];
678 memset(&qbuf, 0, sizeof(qbuf)); 664 memset(&qbuf, 0, sizeof(qbuf));
679 memset(qbuf_planes, 0, sizeof(qbuf_planes)); 665 memset(qbuf_planes, 0, sizeof(qbuf_planes));
680 qbuf.index = index; 666 qbuf.index = index;
681 qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 667 qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
682 qbuf.m.planes = qbuf_planes; 668 qbuf.m.planes = qbuf_planes;
683 669
684 DCHECK_EQ(device_input_format_, frame->format()); 670 DCHECK_EQ(device_input_format_, frame->format());
685 for (size_t i = 0; i < input_planes_count_; ++i) { 671 for (size_t i = 0; i < input_planes_count_; ++i) {
686 qbuf.m.planes[i].bytesused = 672 qbuf.m.planes[i].bytesused = base::checked_cast<__u32>(
687 base::checked_cast<__u32>(media::VideoFrame::PlaneSize( 673 media::VideoFrame::PlaneSize(frame->format(), i, input_allocated_size_)
688 frame->format(), i, input_allocated_size_).GetArea()); 674 .GetArea());
689 675
690 switch (input_memory_type_) { 676 switch (input_memory_type_) {
691 case V4L2_MEMORY_USERPTR: 677 case V4L2_MEMORY_USERPTR:
692 qbuf.m.planes[i].length = qbuf.m.planes[i].bytesused; 678 qbuf.m.planes[i].length = qbuf.m.planes[i].bytesused;
693 qbuf.m.planes[i].m.userptr = 679 qbuf.m.planes[i].m.userptr =
694 reinterpret_cast<unsigned long>(frame->data(i)); 680 reinterpret_cast<unsigned long>(frame->data(i));
695 DCHECK(qbuf.m.planes[i].m.userptr); 681 DCHECK(qbuf.m.planes[i].m.userptr);
696 break; 682 break;
697 683
698 case V4L2_MEMORY_DMABUF: 684 case V4L2_MEMORY_DMABUF:
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
754 740
755 // Start up the device poll thread and schedule its first DevicePollTask(). 741 // Start up the device poll thread and schedule its first DevicePollTask().
756 if (!device_poll_thread_.Start()) { 742 if (!device_poll_thread_.Start()) {
757 LOG(ERROR) << "StartDevicePoll(): Device thread failed to start"; 743 LOG(ERROR) << "StartDevicePoll(): Device thread failed to start";
758 NOTIFY_ERROR(kPlatformFailureError); 744 NOTIFY_ERROR(kPlatformFailureError);
759 return false; 745 return false;
760 } 746 }
761 // Enqueue a poll task with no devices to poll on -- it will wait only on the 747 // Enqueue a poll task with no devices to poll on -- it will wait only on the
762 // interrupt fd. 748 // interrupt fd.
763 device_poll_thread_.message_loop()->PostTask( 749 device_poll_thread_.message_loop()->PostTask(
764 FROM_HERE, 750 FROM_HERE, base::Bind(&V4L2VideoEncodeAccelerator::DevicePollTask,
765 base::Bind(&V4L2VideoEncodeAccelerator::DevicePollTask, 751 base::Unretained(this), false));
766 base::Unretained(this),
767 false));
768 752
769 return true; 753 return true;
770 } 754 }
771 755
772 bool V4L2VideoEncodeAccelerator::StopDevicePoll() { 756 bool V4L2VideoEncodeAccelerator::StopDevicePoll() {
773 DVLOG(3) << "StopDevicePoll()"; 757 DVLOG(3) << "StopDevicePoll()";
774 758
775 // Signal the DevicePollTask() to stop, and stop the device poll thread. 759 // Signal the DevicePollTask() to stop, and stop the device poll thread.
776 if (!device_->SetDevicePollInterrupt()) 760 if (!device_->SetDevicePollInterrupt())
777 return false; 761 return false;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
825 809
826 bool event_pending; 810 bool event_pending;
827 if (!device_->Poll(poll_device, &event_pending)) { 811 if (!device_->Poll(poll_device, &event_pending)) {
828 NOTIFY_ERROR(kPlatformFailureError); 812 NOTIFY_ERROR(kPlatformFailureError);
829 return; 813 return;
830 } 814 }
831 815
832 // All processing should happen on ServiceDeviceTask(), since we shouldn't 816 // All processing should happen on ServiceDeviceTask(), since we shouldn't
833 // touch encoder state from this thread. 817 // touch encoder state from this thread.
834 encoder_thread_.message_loop()->PostTask( 818 encoder_thread_.message_loop()->PostTask(
835 FROM_HERE, 819 FROM_HERE, base::Bind(&V4L2VideoEncodeAccelerator::ServiceDeviceTask,
836 base::Bind(&V4L2VideoEncodeAccelerator::ServiceDeviceTask, 820 base::Unretained(this)));
837 base::Unretained(this)));
838 } 821 }
839 822
840 void V4L2VideoEncodeAccelerator::NotifyError(Error error) { 823 void V4L2VideoEncodeAccelerator::NotifyError(Error error) {
841 DVLOG(1) << "NotifyError(): error=" << error; 824 DVLOG(1) << "NotifyError(): error=" << error;
842 825
843 if (!child_task_runner_->BelongsToCurrentThread()) { 826 if (!child_task_runner_->BelongsToCurrentThread()) {
844 child_task_runner_->PostTask( 827 child_task_runner_->PostTask(
845 FROM_HERE, base::Bind(&V4L2VideoEncodeAccelerator::NotifyError, 828 FROM_HERE, base::Bind(&V4L2VideoEncodeAccelerator::NotifyError,
846 weak_this_, error)); 829 weak_this_, error));
847 return; 830 return;
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
1184 struct v4l2_plane planes[1]; 1167 struct v4l2_plane planes[1];
1185 struct v4l2_buffer buffer; 1168 struct v4l2_buffer buffer;
1186 memset(&buffer, 0, sizeof(buffer)); 1169 memset(&buffer, 0, sizeof(buffer));
1187 memset(planes, 0, sizeof(planes)); 1170 memset(planes, 0, sizeof(planes));
1188 buffer.index = i; 1171 buffer.index = i;
1189 buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1172 buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1190 buffer.memory = V4L2_MEMORY_MMAP; 1173 buffer.memory = V4L2_MEMORY_MMAP;
1191 buffer.m.planes = planes; 1174 buffer.m.planes = planes;
1192 buffer.length = arraysize(planes); 1175 buffer.length = arraysize(planes);
1193 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYBUF, &buffer); 1176 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYBUF, &buffer);
1194 void* address = device_->Mmap(NULL, 1177 void* address =
1195 buffer.m.planes[0].length, 1178 device_->Mmap(NULL, buffer.m.planes[0].length, PROT_READ | PROT_WRITE,
1196 PROT_READ | PROT_WRITE, 1179 MAP_SHARED, buffer.m.planes[0].m.mem_offset);
1197 MAP_SHARED,
1198 buffer.m.planes[0].m.mem_offset);
1199 if (address == MAP_FAILED) { 1180 if (address == MAP_FAILED) {
1200 PLOG(ERROR) << "CreateOutputBuffers(): mmap() failed"; 1181 PLOG(ERROR) << "CreateOutputBuffers(): mmap() failed";
1201 return false; 1182 return false;
1202 } 1183 }
1203 output_buffer_map_[i].address = address; 1184 output_buffer_map_[i].address = address;
1204 output_buffer_map_[i].length = buffer.m.planes[0].length; 1185 output_buffer_map_[i].length = buffer.m.planes[0].length;
1205 free_output_buffers_.push_back(i); 1186 free_output_buffers_.push_back(i);
1206 } 1187 }
1207 1188
1208 return true; 1189 return true;
(...skipping 30 matching lines...) Expand all
1239 memset(&reqbufs, 0, sizeof(reqbufs)); 1220 memset(&reqbufs, 0, sizeof(reqbufs));
1240 reqbufs.count = 0; 1221 reqbufs.count = 0;
1241 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1222 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1242 reqbufs.memory = V4L2_MEMORY_MMAP; 1223 reqbufs.memory = V4L2_MEMORY_MMAP;
1243 IOCTL_OR_LOG_ERROR(VIDIOC_REQBUFS, &reqbufs); 1224 IOCTL_OR_LOG_ERROR(VIDIOC_REQBUFS, &reqbufs);
1244 1225
1245 output_buffer_map_.clear(); 1226 output_buffer_map_.clear();
1246 free_output_buffers_.clear(); 1227 free_output_buffers_.clear();
1247 } 1228 }
1248 1229
1249 } // namespace content 1230 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698