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 <dlfcn.h> | 5 #include <dlfcn.h> |
6 #include <errno.h> | 6 #include <errno.h> |
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> |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 IOCTL_OR_ERROR_RETURN_VALUE(type, arg, false, #type) | 49 IOCTL_OR_ERROR_RETURN_VALUE(type, arg, false, #type) |
50 | 50 |
51 #define IOCTL_OR_LOG_ERROR(type, arg) \ | 51 #define IOCTL_OR_LOG_ERROR(type, arg) \ |
52 do { \ | 52 do { \ |
53 if (device_->Ioctl(type, arg) != 0) \ | 53 if (device_->Ioctl(type, arg) != 0) \ |
54 PLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \ | 54 PLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \ |
55 } while (0) | 55 } while (0) |
56 | 56 |
57 namespace content { | 57 namespace content { |
58 | 58 |
| 59 // static |
| 60 const uint32_t V4L2VideoDecodeAccelerator::supported_input_fourccs_[] = { |
| 61 V4L2_PIX_FMT_H264, V4L2_PIX_FMT_VP8, V4L2_PIX_FMT_VP9, |
| 62 }; |
| 63 |
59 struct V4L2VideoDecodeAccelerator::BitstreamBufferRef { | 64 struct V4L2VideoDecodeAccelerator::BitstreamBufferRef { |
60 BitstreamBufferRef( | 65 BitstreamBufferRef( |
61 base::WeakPtr<Client>& client, | 66 base::WeakPtr<Client>& client, |
62 scoped_refptr<base::SingleThreadTaskRunner>& client_task_runner, | 67 scoped_refptr<base::SingleThreadTaskRunner>& client_task_runner, |
63 base::SharedMemory* shm, | 68 base::SharedMemory* shm, |
64 size_t size, | 69 size_t size, |
65 int32_t input_id); | 70 int32_t input_id); |
66 ~BitstreamBufferRef(); | 71 ~BitstreamBufferRef(); |
67 const base::WeakPtr<Client> client; | 72 const base::WeakPtr<Client> client; |
68 const scoped_refptr<base::SingleThreadTaskRunner> client_task_runner; | 73 const scoped_refptr<base::SingleThreadTaskRunner> client_task_runner; |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
197 | 202 |
198 // These maps have members that should be manually destroyed, e.g. file | 203 // These maps have members that should be manually destroyed, e.g. file |
199 // descriptors, mmap() segments, etc. | 204 // descriptors, mmap() segments, etc. |
200 DCHECK(input_buffer_map_.empty()); | 205 DCHECK(input_buffer_map_.empty()); |
201 DCHECK(output_buffer_map_.empty()); | 206 DCHECK(output_buffer_map_.empty()); |
202 } | 207 } |
203 | 208 |
204 bool V4L2VideoDecodeAccelerator::Initialize(const Config& config, | 209 bool V4L2VideoDecodeAccelerator::Initialize(const Config& config, |
205 Client* client) { | 210 Client* client) { |
206 DVLOG(3) << "Initialize()"; | 211 DVLOG(3) << "Initialize()"; |
| 212 DCHECK(child_task_runner_->BelongsToCurrentThread()); |
| 213 DCHECK_EQ(decoder_state_, kUninitialized); |
| 214 |
207 if (config.is_encrypted) { | 215 if (config.is_encrypted) { |
208 NOTREACHED() << "Encrypted streams are not supported for this VDA"; | 216 NOTREACHED() << "Encrypted streams are not supported for this VDA"; |
209 return false; | 217 return false; |
210 } | 218 } |
211 | 219 |
212 DCHECK(child_task_runner_->BelongsToCurrentThread()); | 220 if (!device_->SupportsDecodeProfileForV4L2PixelFormats( |
213 DCHECK_EQ(decoder_state_, kUninitialized); | 221 config.profile, arraysize(supported_input_fourccs_), |
| 222 supported_input_fourccs_)) { |
| 223 DVLOG(1) << "Initialize(): unsupported profile=" << config.profile; |
| 224 return false; |
| 225 } |
214 | 226 |
215 client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client)); | 227 client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client)); |
216 client_ = client_ptr_factory_->GetWeakPtr(); | 228 client_ = client_ptr_factory_->GetWeakPtr(); |
217 | 229 |
218 switch (config.profile) { | |
219 case media::H264PROFILE_BASELINE: | |
220 DVLOG(2) << "Initialize(): profile H264PROFILE_BASELINE"; | |
221 break; | |
222 case media::H264PROFILE_MAIN: | |
223 DVLOG(2) << "Initialize(): profile H264PROFILE_MAIN"; | |
224 break; | |
225 case media::H264PROFILE_HIGH: | |
226 DVLOG(2) << "Initialize(): profile H264PROFILE_HIGH"; | |
227 break; | |
228 case media::VP8PROFILE_ANY: | |
229 DVLOG(2) << "Initialize(): profile VP8PROFILE_ANY"; | |
230 break; | |
231 case media::VP9PROFILE_ANY: | |
232 DVLOG(2) << "Initialize(): profile VP9PROFILE_ANY"; | |
233 break; | |
234 default: | |
235 DLOG(ERROR) << "Initialize(): unsupported profile=" << config.profile; | |
236 return false; | |
237 }; | |
238 video_profile_ = config.profile; | 230 video_profile_ = config.profile; |
239 | 231 |
240 if (egl_display_ == EGL_NO_DISPLAY) { | 232 if (egl_display_ == EGL_NO_DISPLAY) { |
241 LOG(ERROR) << "Initialize(): could not get EGLDisplay"; | 233 LOG(ERROR) << "Initialize(): could not get EGLDisplay"; |
242 return false; | 234 return false; |
243 } | 235 } |
244 | 236 |
245 // We need the context to be initialized to query extensions. | 237 // We need the context to be initialized to query extensions. |
246 if (!make_context_current_.Run()) { | 238 if (!make_context_current_.Run()) { |
247 LOG(ERROR) << "Initialize(): could not make context current"; | 239 LOG(ERROR) << "Initialize(): could not make context current"; |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
468 | 460 |
469 bool V4L2VideoDecodeAccelerator::CanDecodeOnIOThread() { return true; } | 461 bool V4L2VideoDecodeAccelerator::CanDecodeOnIOThread() { return true; } |
470 | 462 |
471 // static | 463 // static |
472 media::VideoDecodeAccelerator::SupportedProfiles | 464 media::VideoDecodeAccelerator::SupportedProfiles |
473 V4L2VideoDecodeAccelerator::GetSupportedProfiles() { | 465 V4L2VideoDecodeAccelerator::GetSupportedProfiles() { |
474 scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder); | 466 scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder); |
475 if (!device) | 467 if (!device) |
476 return SupportedProfiles(); | 468 return SupportedProfiles(); |
477 | 469 |
478 const uint32_t supported_formats[] = { | 470 return device->GetSupportedDecodeProfiles(arraysize(supported_input_fourccs_), |
479 V4L2_PIX_FMT_H264, V4L2_PIX_FMT_VP8, V4L2_PIX_FMT_VP9}; | 471 supported_input_fourccs_); |
480 return device->GetSupportedDecodeProfiles(arraysize(supported_formats), | |
481 supported_formats); | |
482 } | 472 } |
483 | 473 |
484 void V4L2VideoDecodeAccelerator::DecodeTask( | 474 void V4L2VideoDecodeAccelerator::DecodeTask( |
485 const media::BitstreamBuffer& bitstream_buffer) { | 475 const media::BitstreamBuffer& bitstream_buffer) { |
486 DVLOG(3) << "DecodeTask(): input_id=" << bitstream_buffer.id(); | 476 DVLOG(3) << "DecodeTask(): input_id=" << bitstream_buffer.id(); |
487 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 477 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
488 DCHECK_NE(decoder_state_, kUninitialized); | 478 DCHECK_NE(decoder_state_, kUninitialized); |
489 TRACE_EVENT1("Video Decoder", "V4L2VDA::DecodeTask", "input_id", | 479 TRACE_EVENT1("Video Decoder", "V4L2VDA::DecodeTask", "input_id", |
490 bitstream_buffer.id()); | 480 bitstream_buffer.id()); |
491 | 481 |
(...skipping 1557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2049 | 2039 |
2050 void V4L2VideoDecodeAccelerator::PictureCleared() { | 2040 void V4L2VideoDecodeAccelerator::PictureCleared() { |
2051 DVLOG(3) << "PictureCleared(). clearing count=" << picture_clearing_count_; | 2041 DVLOG(3) << "PictureCleared(). clearing count=" << picture_clearing_count_; |
2052 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 2042 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
2053 DCHECK_GT(picture_clearing_count_, 0); | 2043 DCHECK_GT(picture_clearing_count_, 0); |
2054 picture_clearing_count_--; | 2044 picture_clearing_count_--; |
2055 SendPictureReady(); | 2045 SendPictureReady(); |
2056 } | 2046 } |
2057 | 2047 |
2058 } // namespace content | 2048 } // namespace content |
OLD | NEW |