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

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

Issue 2530493003: V4L2VDA: do not allocate input buffers in GPU child thread. (Closed)
Patch Set: address Pawel's comments Created 4 years 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_decode_accelerator.h ('k') | no next file » | 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 "media/gpu/v4l2_video_decode_accelerator.h" 5 #include "media/gpu/v4l2_video_decode_accelerator.h"
6 6
7 #include <dlfcn.h> 7 #include <dlfcn.h>
8 #include <errno.h> 8 #include <errno.h>
9 #include <fcntl.h> 9 #include <fcntl.h>
10 #include <linux/videodev2.h> 10 #include <linux/videodev2.h>
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 // descriptors, mmap() segments, etc. 196 // descriptors, mmap() segments, etc.
197 DCHECK(input_buffer_map_.empty()); 197 DCHECK(input_buffer_map_.empty());
198 DCHECK(output_buffer_map_.empty()); 198 DCHECK(output_buffer_map_.empty());
199 } 199 }
200 200
201 bool V4L2VideoDecodeAccelerator::Initialize(const Config& config, 201 bool V4L2VideoDecodeAccelerator::Initialize(const Config& config,
202 Client* client) { 202 Client* client) {
203 DVLOGF(3) << "profile: " << config.profile 203 DVLOGF(3) << "profile: " << config.profile
204 << ", output_mode=" << static_cast<int>(config.output_mode); 204 << ", output_mode=" << static_cast<int>(config.output_mode);
205 DCHECK(child_task_runner_->BelongsToCurrentThread()); 205 DCHECK(child_task_runner_->BelongsToCurrentThread());
206 DCHECK_EQ(decoder_state_, kUninitialized); 206 DCHECK_EQ(decoder_state_, kUninitialized);
kcwu 2016/11/28 06:31:14 Two questions, 1. should we add kInitializing stat
wuchengli 2016/11/28 07:04:49 I don't think it's very useful to add a state to j
wuchengli 2016/11/28 09:03:19 As discussed, moved decoder_state_ = kInitialized;
207 207
208 if (config.is_encrypted) { 208 if (config.is_encrypted) {
209 NOTREACHED() << "Encrypted streams are not supported for this VDA"; 209 NOTREACHED() << "Encrypted streams are not supported for this VDA";
210 return false; 210 return false;
211 } 211 }
212 212
213 if (config.output_mode != Config::OutputMode::ALLOCATE && 213 if (config.output_mode != Config::OutputMode::ALLOCATE &&
214 config.output_mode != Config::OutputMode::IMPORT) { 214 config.output_mode != Config::OutputMode::IMPORT) {
215 NOTREACHED() << "Only ALLOCATE and IMPORT OutputModes are supported"; 215 NOTREACHED() << "Only ALLOCATE and IMPORT OutputModes are supported";
216 return false; 216 return false;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps); 267 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps);
268 if ((caps.capabilities & kCapsRequired) != kCapsRequired) { 268 if ((caps.capabilities & kCapsRequired) != kCapsRequired) {
269 LOGF(ERROR) << "ioctl() failed: VIDIOC_QUERYCAP" 269 LOGF(ERROR) << "ioctl() failed: VIDIOC_QUERYCAP"
270 << ", caps check failed: 0x" << std::hex << caps.capabilities; 270 << ", caps check failed: 0x" << std::hex << caps.capabilities;
271 return false; 271 return false;
272 } 272 }
273 273
274 if (!SetupFormats()) 274 if (!SetupFormats())
275 return false; 275 return false;
276 276
277 // Subscribe to the resolution change event.
278 struct v4l2_event_subscription sub;
279 memset(&sub, 0, sizeof(sub));
280 sub.type = V4L2_EVENT_SOURCE_CHANGE;
281 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_SUBSCRIBE_EVENT, &sub);
282
283 if (video_profile_ >= H264PROFILE_MIN && video_profile_ <= H264PROFILE_MAX) { 277 if (video_profile_ >= H264PROFILE_MIN && video_profile_ <= H264PROFILE_MAX) {
284 decoder_h264_parser_.reset(new H264Parser()); 278 decoder_h264_parser_.reset(new H264Parser());
285 } 279 }
286 280
287 if (!CreateInputBuffers())
288 return false;
289
290 decoder_cmd_supported_ = IsDecoderCmdSupported();
291
292 if (!decoder_thread_.Start()) { 281 if (!decoder_thread_.Start()) {
293 LOGF(ERROR) << "decoder thread failed to start"; 282 LOGF(ERROR) << "decoder thread failed to start";
294 return false; 283 return false;
295 } 284 }
296 285
297 decoder_state_ = kInitialized;
298 output_mode_ = config.output_mode; 286 output_mode_ = config.output_mode;
299 287
300 // StartDevicePoll will NOTIFY_ERROR on failure, so IgnoreResult is fine here. 288 // InitializeTask will NOTIFY_ERROR on failure.
301 decoder_thread_.task_runner()->PostTask( 289 decoder_thread_.task_runner()->PostTask(
302 FROM_HERE, base::Bind(base::IgnoreResult( 290 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::InitializeTask,
303 &V4L2VideoDecodeAccelerator::StartDevicePoll),
304 base::Unretained(this))); 291 base::Unretained(this)));
305 292
306 return true; 293 return true;
307 } 294 }
308 295
296 void V4L2VideoDecodeAccelerator::InitializeTask() {
297 DVLOGF(3);
298 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
kcwu 2016/11/28 06:31:14 DCHECK_EQ(decoder_state_, kUninitialized);
wuchengli 2016/11/28 09:03:19 Done.
299
300 // Subscribe to the resolution change event.
301 struct v4l2_event_subscription sub;
302 memset(&sub, 0, sizeof(sub));
303 sub.type = V4L2_EVENT_SOURCE_CHANGE;
304 IOCTL_OR_ERROR_RETURN(VIDIOC_SUBSCRIBE_EVENT, &sub);
305
306 if (!CreateInputBuffers()) {
307 NOTIFY_ERROR(PLATFORM_FAILURE);
308 return;
309 }
310
311 decoder_cmd_supported_ = IsDecoderCmdSupported();
312
313 if (!StartDevicePoll())
314 return;
315
316 decoder_state_ = kInitialized;
317 }
318
309 void V4L2VideoDecodeAccelerator::Decode( 319 void V4L2VideoDecodeAccelerator::Decode(
310 const BitstreamBuffer& bitstream_buffer) { 320 const BitstreamBuffer& bitstream_buffer) {
311 DVLOGF(1) << "input_id=" << bitstream_buffer.id() 321 DVLOGF(1) << "input_id=" << bitstream_buffer.id()
312 << ", size=" << bitstream_buffer.size(); 322 << ", size=" << bitstream_buffer.size();
313 DCHECK(decode_task_runner_->BelongsToCurrentThread()); 323 DCHECK(decode_task_runner_->BelongsToCurrentThread());
314 324
315 if (bitstream_buffer.id() < 0) { 325 if (bitstream_buffer.id() < 0) {
316 LOGF(ERROR) << "Invalid bitstream_buffer, id: " << bitstream_buffer.id(); 326 LOGF(ERROR) << "Invalid bitstream_buffer, id: " << bitstream_buffer.id();
317 if (base::SharedMemory::IsHandleValid(bitstream_buffer.handle())) 327 if (base::SharedMemory::IsHandleValid(bitstream_buffer.handle()))
318 base::SharedMemory::CloseHandle(bitstream_buffer.handle()); 328 base::SharedMemory::CloseHandle(bitstream_buffer.handle());
(...skipping 1803 matching lines...) Expand 10 before | Expand all | Expand 10 after
2122 DLOGF(ERROR) << "Unexpected visible rectangle " << rect.ToString() 2132 DLOGF(ERROR) << "Unexpected visible rectangle " << rect.ToString()
2123 << ", top-left is not origin"; 2133 << ", top-left is not origin";
2124 return coded_size; 2134 return coded_size;
2125 } 2135 }
2126 2136
2127 return rect.size(); 2137 return rect.size();
2128 } 2138 }
2129 2139
2130 bool V4L2VideoDecodeAccelerator::CreateInputBuffers() { 2140 bool V4L2VideoDecodeAccelerator::CreateInputBuffers() {
2131 DVLOGF(3); 2141 DVLOGF(3);
2142 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
2132 // We always run this as we prepare to initialize. 2143 // We always run this as we prepare to initialize.
2133 DCHECK_EQ(decoder_state_, kUninitialized); 2144 DCHECK_EQ(decoder_state_, kUninitialized);
2134 DCHECK(!input_streamon_); 2145 DCHECK(!input_streamon_);
2135 DCHECK(input_buffer_map_.empty()); 2146 DCHECK(input_buffer_map_.empty());
2136 2147
2137 struct v4l2_requestbuffers reqbufs; 2148 struct v4l2_requestbuffers reqbufs;
2138 memset(&reqbufs, 0, sizeof(reqbufs)); 2149 memset(&reqbufs, 0, sizeof(reqbufs));
2139 reqbufs.count = kInputBufferCount; 2150 reqbufs.count = kInputBufferCount;
2140 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 2151 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2141 reqbufs.memory = V4L2_MEMORY_MMAP; 2152 reqbufs.memory = V4L2_MEMORY_MMAP;
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after
2624 StartResolutionChange(); 2635 StartResolutionChange();
2625 } 2636 }
2626 } 2637 }
2627 2638
2628 void V4L2VideoDecodeAccelerator::ImageProcessorError() { 2639 void V4L2VideoDecodeAccelerator::ImageProcessorError() {
2629 LOGF(ERROR) << "Image processor error"; 2640 LOGF(ERROR) << "Image processor error";
2630 NOTIFY_ERROR(PLATFORM_FAILURE); 2641 NOTIFY_ERROR(PLATFORM_FAILURE);
2631 } 2642 }
2632 2643
2633 } // namespace media 2644 } // namespace media
OLDNEW
« no previous file with comments | « media/gpu/v4l2_video_decode_accelerator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698