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

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

Issue 2398883002: Add support for multiple V4L2 video devices of the same type. (Closed)
Patch Set: Address comments, reorganize V4L2Device::Type. Created 4 years, 2 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "media/gpu/v4l2_jpeg_decode_accelerator.h" 5 #include "media/gpu/v4l2_jpeg_decode_accelerator.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <linux/videodev2.h> 8 #include <linux/videodev2.h>
9 #include <string.h> 9 #include <string.h>
10 #include <sys/mman.h> 10 #include <sys/mman.h>
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 void V4L2JpegDecodeAccelerator::PostNotifyError(int32_t bitstream_buffer_id, 180 void V4L2JpegDecodeAccelerator::PostNotifyError(int32_t bitstream_buffer_id,
181 Error error) { 181 Error error) {
182 child_task_runner_->PostTask( 182 child_task_runner_->PostTask(
183 FROM_HERE, base::Bind(&V4L2JpegDecodeAccelerator::NotifyError, weak_ptr_, 183 FROM_HERE, base::Bind(&V4L2JpegDecodeAccelerator::NotifyError, weak_ptr_,
184 bitstream_buffer_id, error)); 184 bitstream_buffer_id, error));
185 } 185 }
186 186
187 bool V4L2JpegDecodeAccelerator::Initialize(Client* client) { 187 bool V4L2JpegDecodeAccelerator::Initialize(Client* client) {
188 DCHECK(child_task_runner_->BelongsToCurrentThread()); 188 DCHECK(child_task_runner_->BelongsToCurrentThread());
189 189
190 if (!device_->Open(V4L2Device::Type::kJpegDecoder, V4L2_PIX_FMT_JPEG)) {
191 LOG(ERROR) << "Failed to open device";
192 return false;
193 }
194
190 // Capabilities check. 195 // Capabilities check.
191 struct v4l2_capability caps; 196 struct v4l2_capability caps;
192 const __u32 kCapsRequired = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M; 197 const __u32 kCapsRequired = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M;
193 memset(&caps, 0, sizeof(caps)); 198 memset(&caps, 0, sizeof(caps));
194 if (device_->Ioctl(VIDIOC_QUERYCAP, &caps) != 0) { 199 if (device_->Ioctl(VIDIOC_QUERYCAP, &caps) != 0) {
195 PLOG(ERROR) << __func__ << ": ioctl() failed: VIDIOC_QUERYCAP"; 200 PLOG(ERROR) << __func__ << ": ioctl() failed: VIDIOC_QUERYCAP";
196 return false; 201 return false;
197 } 202 }
198 if ((caps.capabilities & kCapsRequired) != kCapsRequired) { 203 if ((caps.capabilities & kCapsRequired) != kCapsRequired) {
199 LOG(ERROR) << __func__ << ": VIDIOC_QUERYCAP, caps check failed: 0x" 204 LOG(ERROR) << __func__ << ": VIDIOC_QUERYCAP, caps check failed: 0x"
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 } 251 }
247 252
248 std::unique_ptr<JobRecord> job_record( 253 std::unique_ptr<JobRecord> job_record(
249 new JobRecord(bitstream_buffer, video_frame)); 254 new JobRecord(bitstream_buffer, video_frame));
250 255
251 decoder_task_runner_->PostTask( 256 decoder_task_runner_->PostTask(
252 FROM_HERE, base::Bind(&V4L2JpegDecodeAccelerator::DecodeTask, 257 FROM_HERE, base::Bind(&V4L2JpegDecodeAccelerator::DecodeTask,
253 base::Unretained(this), base::Passed(&job_record))); 258 base::Unretained(this), base::Passed(&job_record)));
254 } 259 }
255 260
261 // static
256 bool V4L2JpegDecodeAccelerator::IsSupported() { 262 bool V4L2JpegDecodeAccelerator::IsSupported() {
257 v4l2_fmtdesc fmtdesc; 263 scoped_refptr<V4L2Device> device = V4L2Device::Create();
258 memset(&fmtdesc, 0, sizeof(fmtdesc)); 264 if (!device)
259 fmtdesc.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 265 return false;
260 266
261 for (; device_->Ioctl(VIDIOC_ENUM_FMT, &fmtdesc) == 0; ++fmtdesc.index) { 267 return device->IsJpegDecodingSupported();
262 if (fmtdesc.pixelformat == V4L2_PIX_FMT_JPEG)
263 return true;
264 }
265 return false;
266 } 268 }
267 269
268 void V4L2JpegDecodeAccelerator::DecodeTask( 270 void V4L2JpegDecodeAccelerator::DecodeTask(
269 std::unique_ptr<JobRecord> job_record) { 271 std::unique_ptr<JobRecord> job_record) {
270 DCHECK(decoder_task_runner_->BelongsToCurrentThread()); 272 DCHECK(decoder_task_runner_->BelongsToCurrentThread());
271 if (!job_record->shm.Map()) { 273 if (!job_record->shm.Map()) {
272 PLOG(ERROR) << __func__ << ": could not map bitstream_buffer"; 274 PLOG(ERROR) << __func__ << ": could not map bitstream_buffer";
273 PostNotifyError(job_record->bitstream_buffer_id, UNREADABLE_INPUT); 275 PostNotifyError(job_record->bitstream_buffer_id, UNREADABLE_INPUT);
274 return; 276 return;
275 } 277 }
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 } 442 }
441 output_buffer_map_[i].address = address; 443 output_buffer_map_[i].address = address;
442 output_buffer_map_[i].length = buffer.length; 444 output_buffer_map_[i].length = buffer.length;
443 } 445 }
444 446
445 return true; 447 return true;
446 } 448 }
447 449
448 void V4L2JpegDecodeAccelerator::DestroyInputBuffers() { 450 void V4L2JpegDecodeAccelerator::DestroyInputBuffers() {
449 DCHECK(decoder_task_runner_->BelongsToCurrentThread()); 451 DCHECK(decoder_task_runner_->BelongsToCurrentThread());
450 DCHECK(!input_streamon_); 452 DCHECK(!input_streamon_);
kcwu 2016/10/07 11:19:05 I found this check is contradiction to line 459.
Pawel Osciak 2016/10/11 06:13:46 My guess is that the intention here could have bee
451 453
454 free_input_buffers_.clear();
455
456 if (input_buffer_map_.empty())
457 return;
458
452 if (input_streamon_) { 459 if (input_streamon_) {
453 __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 460 __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
454 IOCTL_OR_ERROR_RETURN(VIDIOC_STREAMOFF, &type); 461 IOCTL_OR_ERROR_RETURN(VIDIOC_STREAMOFF, &type);
455 input_streamon_ = false; 462 input_streamon_ = false;
456 } 463 }
457 464
458 for (size_t i = 0; i < input_buffer_map_.size(); ++i) { 465 for (size_t i = 0; i < input_buffer_map_.size(); ++i) {
459 BufferRecord& input_record = input_buffer_map_[i]; 466 BufferRecord& input_record = input_buffer_map_[i];
460 device_->Munmap(input_record.address, input_record.length); 467 device_->Munmap(input_record.address, input_record.length);
461 } 468 }
462 469
463 struct v4l2_requestbuffers reqbufs; 470 struct v4l2_requestbuffers reqbufs;
464 memset(&reqbufs, 0, sizeof(reqbufs)); 471 memset(&reqbufs, 0, sizeof(reqbufs));
465 reqbufs.count = 0; 472 reqbufs.count = 0;
466 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 473 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
467 reqbufs.memory = V4L2_MEMORY_MMAP; 474 reqbufs.memory = V4L2_MEMORY_MMAP;
468 IOCTL_OR_LOG_ERROR(VIDIOC_REQBUFS, &reqbufs); 475 IOCTL_OR_LOG_ERROR(VIDIOC_REQBUFS, &reqbufs);
469 476
470 input_buffer_map_.clear(); 477 input_buffer_map_.clear();
471 free_input_buffers_.clear();
472 } 478 }
473 479
474 void V4L2JpegDecodeAccelerator::DestroyOutputBuffers() { 480 void V4L2JpegDecodeAccelerator::DestroyOutputBuffers() {
475 DCHECK(decoder_task_runner_->BelongsToCurrentThread()); 481 DCHECK(decoder_task_runner_->BelongsToCurrentThread());
476 DCHECK(!output_streamon_); 482 DCHECK(!output_streamon_);
kcwu 2016/10/07 11:19:05 I found this check is contradiction to line 489.
Pawel Osciak 2016/10/11 06:13:46 Please see above.
477 483
484 free_output_buffers_.clear();
485
486 if (output_buffer_map_.empty())
487 return;
488
478 if (output_streamon_) { 489 if (output_streamon_) {
479 __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 490 __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
480 IOCTL_OR_ERROR_RETURN(VIDIOC_STREAMOFF, &type); 491 IOCTL_OR_ERROR_RETURN(VIDIOC_STREAMOFF, &type);
481 output_streamon_ = false; 492 output_streamon_ = false;
482 } 493 }
483 494
484 for (size_t i = 0; i < output_buffer_map_.size(); ++i) { 495 for (size_t i = 0; i < output_buffer_map_.size(); ++i) {
485 BufferRecord& output_record = output_buffer_map_[i]; 496 BufferRecord& output_record = output_buffer_map_[i];
486 device_->Munmap(output_record.address, output_record.length); 497 device_->Munmap(output_record.address, output_record.length);
487 } 498 }
488 499
489 struct v4l2_requestbuffers reqbufs; 500 struct v4l2_requestbuffers reqbufs;
490 memset(&reqbufs, 0, sizeof(reqbufs)); 501 memset(&reqbufs, 0, sizeof(reqbufs));
491 reqbufs.count = 0; 502 reqbufs.count = 0;
492 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 503 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
493 reqbufs.memory = V4L2_MEMORY_MMAP; 504 reqbufs.memory = V4L2_MEMORY_MMAP;
494 IOCTL_OR_LOG_ERROR(VIDIOC_REQBUFS, &reqbufs); 505 IOCTL_OR_LOG_ERROR(VIDIOC_REQBUFS, &reqbufs);
495 506
496 output_buffer_map_.clear(); 507 output_buffer_map_.clear();
497 free_output_buffers_.clear();
498 } 508 }
499 509
500 void V4L2JpegDecodeAccelerator::DevicePollTask() { 510 void V4L2JpegDecodeAccelerator::DevicePollTask() {
501 DCHECK(device_poll_task_runner_->BelongsToCurrentThread()); 511 DCHECK(device_poll_task_runner_->BelongsToCurrentThread());
502 512
503 bool event_pending; 513 bool event_pending;
504 if (!device_->Poll(true, &event_pending)) { 514 if (!device_->Poll(true, &event_pending)) {
505 PLOG(ERROR) << __func__ << ": Poll device error."; 515 PLOG(ERROR) << __func__ << ": Poll device error.";
506 PostNotifyError(kInvalidBitstreamBufferId, PLATFORM_FAILURE); 516 PostNotifyError(kInvalidBitstreamBufferId, PLATFORM_FAILURE);
507 return; 517 return;
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
890 device_poll_thread_.Stop(); 900 device_poll_thread_.Stop();
891 901
892 // Clear the interrupt now, to be sure. 902 // Clear the interrupt now, to be sure.
893 if (!device_->ClearDevicePollInterrupt()) 903 if (!device_->ClearDevicePollInterrupt())
894 return false; 904 return false;
895 905
896 return true; 906 return true;
897 } 907 }
898 908
899 } // namespace media 909 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698