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

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

Issue 1832123002: Revert of Introduce GpuVideoDecodeAcceleratorFactory. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 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 <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>
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 "base/bind.h" 15 #include "base/bind.h"
16 #include "base/command_line.h" 16 #include "base/command_line.h"
17 #include "base/macros.h" 17 #include "base/macros.h"
18 #include "base/message_loop/message_loop.h" 18 #include "base/message_loop/message_loop.h"
19 #include "base/numerics/safe_conversions.h" 19 #include "base/numerics/safe_conversions.h"
20 #include "base/thread_task_runner_handle.h" 20 #include "base/thread_task_runner_handle.h"
21 #include "base/trace_event/trace_event.h" 21 #include "base/trace_event/trace_event.h"
22 #include "build/build_config.h" 22 #include "build/build_config.h"
23 #include "content/common/gpu/media/shared_memory_region.h" 23 #include "content/common/gpu/media/shared_memory_region.h"
24 #include "content/common/gpu/media/v4l2_video_decode_accelerator.h" 24 #include "content/common/gpu/media/v4l2_video_decode_accelerator.h"
25 #include "media/base/media_switches.h" 25 #include "media/base/media_switches.h"
26 #include "media/filters/h264_parser.h" 26 #include "media/filters/h264_parser.h"
27 #include "ui/gfx/geometry/rect.h" 27 #include "ui/gfx/geometry/rect.h"
28 #include "ui/gl/gl_context.h"
29 #include "ui/gl/scoped_binders.h" 28 #include "ui/gl/scoped_binders.h"
30 29
31 #define NOTIFY_ERROR(x) \ 30 #define NOTIFY_ERROR(x) \
32 do { \ 31 do { \
33 LOG(ERROR) << "Setting error state:" << x; \ 32 LOG(ERROR) << "Setting error state:" << x; \
34 SetErrorState(x); \ 33 SetErrorState(x); \
35 } while (0) 34 } while (0)
36 35
37 #define IOCTL_OR_ERROR_RETURN_VALUE(type, arg, value, type_str) \ 36 #define IOCTL_OR_ERROR_RETURN_VALUE(type, arg, value, type_str) \
38 do { \ 37 do { \
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 146
148 V4L2VideoDecodeAccelerator::PictureRecord::PictureRecord( 147 V4L2VideoDecodeAccelerator::PictureRecord::PictureRecord(
149 bool cleared, 148 bool cleared,
150 const media::Picture& picture) 149 const media::Picture& picture)
151 : cleared(cleared), picture(picture) {} 150 : cleared(cleared), picture(picture) {}
152 151
153 V4L2VideoDecodeAccelerator::PictureRecord::~PictureRecord() {} 152 V4L2VideoDecodeAccelerator::PictureRecord::~PictureRecord() {}
154 153
155 V4L2VideoDecodeAccelerator::V4L2VideoDecodeAccelerator( 154 V4L2VideoDecodeAccelerator::V4L2VideoDecodeAccelerator(
156 EGLDisplay egl_display, 155 EGLDisplay egl_display,
157 const GetGLContextCallback& get_gl_context_cb, 156 EGLContext egl_context,
158 const MakeGLContextCurrentCallback& make_context_current_cb, 157 const base::WeakPtr<Client>& io_client,
159 const scoped_refptr<V4L2Device>& device) 158 const base::Callback<bool(void)>& make_context_current,
159 const scoped_refptr<V4L2Device>& device,
160 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
160 : child_task_runner_(base::ThreadTaskRunnerHandle::Get()), 161 : child_task_runner_(base::ThreadTaskRunnerHandle::Get()),
162 io_task_runner_(io_task_runner),
163 io_client_(io_client),
161 decoder_thread_("V4L2DecoderThread"), 164 decoder_thread_("V4L2DecoderThread"),
162 decoder_state_(kUninitialized), 165 decoder_state_(kUninitialized),
163 device_(device), 166 device_(device),
164 decoder_delay_bitstream_buffer_id_(-1), 167 decoder_delay_bitstream_buffer_id_(-1),
165 decoder_current_input_buffer_(-1), 168 decoder_current_input_buffer_(-1),
166 decoder_decode_buffer_tasks_scheduled_(0), 169 decoder_decode_buffer_tasks_scheduled_(0),
167 decoder_frames_at_client_(0), 170 decoder_frames_at_client_(0),
168 decoder_flushing_(false), 171 decoder_flushing_(false),
169 resolution_change_reset_pending_(false), 172 resolution_change_reset_pending_(false),
170 decoder_partial_frame_pending_(false), 173 decoder_partial_frame_pending_(false),
171 input_streamon_(false), 174 input_streamon_(false),
172 input_buffer_queued_count_(0), 175 input_buffer_queued_count_(0),
173 output_streamon_(false), 176 output_streamon_(false),
174 output_buffer_queued_count_(0), 177 output_buffer_queued_count_(0),
175 output_dpb_size_(0), 178 output_dpb_size_(0),
176 output_planes_count_(0), 179 output_planes_count_(0),
177 picture_clearing_count_(0), 180 picture_clearing_count_(0),
178 pictures_assigned_(false, false), 181 pictures_assigned_(false, false),
179 device_poll_thread_("V4L2DevicePollThread"), 182 device_poll_thread_("V4L2DevicePollThread"),
183 make_context_current_(make_context_current),
180 egl_display_(egl_display), 184 egl_display_(egl_display),
181 get_gl_context_cb_(get_gl_context_cb), 185 egl_context_(egl_context),
182 make_context_current_cb_(make_context_current_cb),
183 video_profile_(media::VIDEO_CODEC_PROFILE_UNKNOWN), 186 video_profile_(media::VIDEO_CODEC_PROFILE_UNKNOWN),
184 output_format_fourcc_(0), 187 output_format_fourcc_(0),
185 weak_this_factory_(this) { 188 weak_this_factory_(this) {
186 weak_this_ = weak_this_factory_.GetWeakPtr(); 189 weak_this_ = weak_this_factory_.GetWeakPtr();
187 } 190 }
188 191
189 V4L2VideoDecodeAccelerator::~V4L2VideoDecodeAccelerator() { 192 V4L2VideoDecodeAccelerator::~V4L2VideoDecodeAccelerator() {
190 DCHECK(!decoder_thread_.IsRunning()); 193 DCHECK(!decoder_thread_.IsRunning());
191 DCHECK(!device_poll_thread_.IsRunning()); 194 DCHECK(!device_poll_thread_.IsRunning());
192 195
193 DestroyInputBuffers(); 196 DestroyInputBuffers();
194 DestroyOutputBuffers(); 197 DestroyOutputBuffers();
195 198
196 // These maps have members that should be manually destroyed, e.g. file 199 // These maps have members that should be manually destroyed, e.g. file
197 // descriptors, mmap() segments, etc. 200 // descriptors, mmap() segments, etc.
198 DCHECK(input_buffer_map_.empty()); 201 DCHECK(input_buffer_map_.empty());
199 DCHECK(output_buffer_map_.empty()); 202 DCHECK(output_buffer_map_.empty());
200 } 203 }
201 204
202 bool V4L2VideoDecodeAccelerator::Initialize(const Config& config, 205 bool V4L2VideoDecodeAccelerator::Initialize(const Config& config,
203 Client* client) { 206 Client* client) {
204 DVLOG(3) << "Initialize()"; 207 DVLOG(3) << "Initialize()";
205 DCHECK(child_task_runner_->BelongsToCurrentThread()); 208 DCHECK(child_task_runner_->BelongsToCurrentThread());
206 DCHECK_EQ(decoder_state_, kUninitialized); 209 DCHECK_EQ(decoder_state_, kUninitialized);
207 210
208 if (get_gl_context_cb_.is_null() || make_context_current_cb_.is_null()) {
209 NOTREACHED() << "GL callbacks are required for this VDA";
210 return false;
211 }
212
213 if (config.is_encrypted) { 211 if (config.is_encrypted) {
214 NOTREACHED() << "Encrypted streams are not supported for this VDA"; 212 NOTREACHED() << "Encrypted streams are not supported for this VDA";
215 return false; 213 return false;
216 } 214 }
217 215
218 if (!device_->SupportsDecodeProfileForV4L2PixelFormats( 216 if (!device_->SupportsDecodeProfileForV4L2PixelFormats(
219 config.profile, arraysize(supported_input_fourccs_), 217 config.profile, arraysize(supported_input_fourccs_),
220 supported_input_fourccs_)) { 218 supported_input_fourccs_)) {
221 DVLOG(1) << "Initialize(): unsupported profile=" << config.profile; 219 DVLOG(1) << "Initialize(): unsupported profile=" << config.profile;
222 return false; 220 return false;
223 } 221 }
224 222
225 client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client)); 223 client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client));
226 client_ = client_ptr_factory_->GetWeakPtr(); 224 client_ = client_ptr_factory_->GetWeakPtr();
227 // If we haven't been set up to decode on separate thread via
228 // TryToSetupDecodeOnSeparateThread(), use the main thread/client for
229 // decode tasks.
230 if (!decode_task_runner_) {
231 decode_task_runner_ = child_task_runner_;
232 DCHECK(!decode_client_);
233 decode_client_ = client_;
234 }
235 225
236 video_profile_ = config.profile; 226 video_profile_ = config.profile;
237 227
238 if (egl_display_ == EGL_NO_DISPLAY) { 228 if (egl_display_ == EGL_NO_DISPLAY) {
239 LOG(ERROR) << "Initialize(): could not get EGLDisplay"; 229 LOG(ERROR) << "Initialize(): could not get EGLDisplay";
240 return false; 230 return false;
241 } 231 }
242 232
243 // We need the context to be initialized to query extensions. 233 // We need the context to be initialized to query extensions.
244 if (!make_context_current_cb_.Run()) { 234 if (!make_context_current_.Run()) {
245 LOG(ERROR) << "Initialize(): could not make context current"; 235 LOG(ERROR) << "Initialize(): could not make context current";
246 return false; 236 return false;
247 } 237 }
248 238
249 // TODO(posciak): crbug.com/450898. 239 // TODO(posciak): crbug.com/450898.
250 #if defined(ARCH_CPU_ARMEL) 240 #if defined(ARCH_CPU_ARMEL)
251 if (!gfx::g_driver_egl.ext.b_EGL_KHR_fence_sync) { 241 if (!gfx::g_driver_egl.ext.b_EGL_KHR_fence_sync) {
252 LOG(ERROR) << "Initialize(): context does not have EGL_KHR_fence_sync"; 242 LOG(ERROR) << "Initialize(): context does not have EGL_KHR_fence_sync";
253 return false; 243 return false;
254 } 244 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 base::IgnoreResult(&V4L2VideoDecodeAccelerator::StartDevicePoll), 285 base::IgnoreResult(&V4L2VideoDecodeAccelerator::StartDevicePoll),
296 base::Unretained(this))); 286 base::Unretained(this)));
297 287
298 return true; 288 return true;
299 } 289 }
300 290
301 void V4L2VideoDecodeAccelerator::Decode( 291 void V4L2VideoDecodeAccelerator::Decode(
302 const media::BitstreamBuffer& bitstream_buffer) { 292 const media::BitstreamBuffer& bitstream_buffer) {
303 DVLOG(1) << "Decode(): input_id=" << bitstream_buffer.id() 293 DVLOG(1) << "Decode(): input_id=" << bitstream_buffer.id()
304 << ", size=" << bitstream_buffer.size(); 294 << ", size=" << bitstream_buffer.size();
305 DCHECK(decode_task_runner_->BelongsToCurrentThread()); 295 DCHECK(io_task_runner_->BelongsToCurrentThread());
306 296
307 if (bitstream_buffer.id() < 0) { 297 if (bitstream_buffer.id() < 0) {
308 LOG(ERROR) << "Invalid bitstream_buffer, id: " << bitstream_buffer.id(); 298 LOG(ERROR) << "Invalid bitstream_buffer, id: " << bitstream_buffer.id();
309 if (base::SharedMemory::IsHandleValid(bitstream_buffer.handle())) 299 if (base::SharedMemory::IsHandleValid(bitstream_buffer.handle()))
310 base::SharedMemory::CloseHandle(bitstream_buffer.handle()); 300 base::SharedMemory::CloseHandle(bitstream_buffer.handle());
311 NOTIFY_ERROR(INVALID_ARGUMENT); 301 NOTIFY_ERROR(INVALID_ARGUMENT);
312 return; 302 return;
313 } 303 }
314 304
315 // DecodeTask() will take care of running a DecodeBufferTask(). 305 // DecodeTask() will take care of running a DecodeBufferTask().
(...skipping 11 matching lines...) Expand all
327 output_dpb_size_ + kDpbOutputBufferExtraCount; 317 output_dpb_size_ + kDpbOutputBufferExtraCount;
328 318
329 if (buffers.size() < req_buffer_count) { 319 if (buffers.size() < req_buffer_count) {
330 LOG(ERROR) << "AssignPictureBuffers(): Failed to provide requested picture" 320 LOG(ERROR) << "AssignPictureBuffers(): Failed to provide requested picture"
331 " buffers. (Got " << buffers.size() 321 " buffers. (Got " << buffers.size()
332 << ", requested " << req_buffer_count << ")"; 322 << ", requested " << req_buffer_count << ")";
333 NOTIFY_ERROR(INVALID_ARGUMENT); 323 NOTIFY_ERROR(INVALID_ARGUMENT);
334 return; 324 return;
335 } 325 }
336 326
337 gfx::GLContext* gl_context = get_gl_context_cb_.Run(); 327 if (!make_context_current_.Run()) {
338 if (!gl_context || !make_context_current_cb_.Run()) {
339 LOG(ERROR) << "AssignPictureBuffers(): could not make context current"; 328 LOG(ERROR) << "AssignPictureBuffers(): could not make context current";
340 NOTIFY_ERROR(PLATFORM_FAILURE); 329 NOTIFY_ERROR(PLATFORM_FAILURE);
341 return; 330 return;
342 } 331 }
343 332
344 gfx::ScopedTextureBinder bind_restore(GL_TEXTURE_EXTERNAL_OES, 0); 333 gfx::ScopedTextureBinder bind_restore(GL_TEXTURE_EXTERNAL_OES, 0);
345 334
346 // It's safe to manipulate all the buffer state here, because the decoder 335 // It's safe to manipulate all the buffer state here, because the decoder
347 // thread is waiting on pictures_assigned_. 336 // thread is waiting on pictures_assigned_.
348 337
(...skipping 19 matching lines...) Expand all
368 357
369 OutputRecord& output_record = output_buffer_map_[i]; 358 OutputRecord& output_record = output_buffer_map_[i];
370 DCHECK(!output_record.at_device); 359 DCHECK(!output_record.at_device);
371 DCHECK(!output_record.at_client); 360 DCHECK(!output_record.at_client);
372 DCHECK_EQ(output_record.egl_image, EGL_NO_IMAGE_KHR); 361 DCHECK_EQ(output_record.egl_image, EGL_NO_IMAGE_KHR);
373 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR); 362 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR);
374 DCHECK_EQ(output_record.picture_id, -1); 363 DCHECK_EQ(output_record.picture_id, -1);
375 DCHECK_EQ(output_record.cleared, false); 364 DCHECK_EQ(output_record.cleared, false);
376 365
377 EGLImageKHR egl_image = device_->CreateEGLImage(egl_display_, 366 EGLImageKHR egl_image = device_->CreateEGLImage(egl_display_,
378 gl_context->GetHandle(), 367 egl_context_,
379 buffers[i].texture_id(), 368 buffers[i].texture_id(),
380 coded_size_, 369 coded_size_,
381 i, 370 i,
382 output_format_fourcc_, 371 output_format_fourcc_,
383 output_planes_count_); 372 output_planes_count_);
384 if (egl_image == EGL_NO_IMAGE_KHR) { 373 if (egl_image == EGL_NO_IMAGE_KHR) {
385 LOG(ERROR) << "AssignPictureBuffers(): could not create EGLImageKHR"; 374 LOG(ERROR) << "AssignPictureBuffers(): could not create EGLImageKHR";
386 // Ownership of EGLImages allocated in previous iterations of this loop 375 // Ownership of EGLImages allocated in previous iterations of this loop
387 // has been transferred to output_buffer_map_. After we error-out here 376 // has been transferred to output_buffer_map_. After we error-out here
388 // the destructor will handle their cleanup. 377 // the destructor will handle their cleanup.
389 NOTIFY_ERROR(PLATFORM_FAILURE); 378 NOTIFY_ERROR(PLATFORM_FAILURE);
390 return; 379 return;
391 } 380 }
392 381
393 output_record.egl_image = egl_image; 382 output_record.egl_image = egl_image;
394 output_record.picture_id = buffers[i].id(); 383 output_record.picture_id = buffers[i].id();
395 free_output_buffers_.push(i); 384 free_output_buffers_.push(i);
396 DVLOG(3) << "AssignPictureBuffers(): buffer[" << i 385 DVLOG(3) << "AssignPictureBuffers(): buffer[" << i
397 << "]: picture_id=" << output_record.picture_id; 386 << "]: picture_id=" << output_record.picture_id;
398 } 387 }
399 388
400 pictures_assigned_.Signal(); 389 pictures_assigned_.Signal();
401 } 390 }
402 391
403 void V4L2VideoDecodeAccelerator::ReusePictureBuffer(int32_t picture_buffer_id) { 392 void V4L2VideoDecodeAccelerator::ReusePictureBuffer(int32_t picture_buffer_id) {
404 DVLOG(3) << "ReusePictureBuffer(): picture_buffer_id=" << picture_buffer_id; 393 DVLOG(3) << "ReusePictureBuffer(): picture_buffer_id=" << picture_buffer_id;
405 // Must be run on child thread, as we'll insert a sync in the EGL context. 394 // Must be run on child thread, as we'll insert a sync in the EGL context.
406 DCHECK(child_task_runner_->BelongsToCurrentThread()); 395 DCHECK(child_task_runner_->BelongsToCurrentThread());
407 396
408 if (!make_context_current_cb_.Run()) { 397 if (!make_context_current_.Run()) {
409 LOG(ERROR) << "ReusePictureBuffer(): could not make context current"; 398 LOG(ERROR) << "ReusePictureBuffer(): could not make context current";
410 NOTIFY_ERROR(PLATFORM_FAILURE); 399 NOTIFY_ERROR(PLATFORM_FAILURE);
411 return; 400 return;
412 } 401 }
413 402
414 EGLSyncKHR egl_sync = EGL_NO_SYNC_KHR; 403 EGLSyncKHR egl_sync = EGL_NO_SYNC_KHR;
415 // TODO(posciak): crbug.com/450898. 404 // TODO(posciak): crbug.com/450898.
416 #if defined(ARCH_CPU_ARMEL) 405 #if defined(ARCH_CPU_ARMEL)
417 egl_sync = eglCreateSyncKHR(egl_display_, EGL_SYNC_FENCE_KHR, NULL); 406 egl_sync = eglCreateSyncKHR(egl_display_, EGL_SYNC_FENCE_KHR, NULL);
418 if (egl_sync == EGL_NO_SYNC_KHR) { 407 if (egl_sync == EGL_NO_SYNC_KHR) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 // DestroyTask() will cause the decoder_thread_ to flush all tasks. 448 // DestroyTask() will cause the decoder_thread_ to flush all tasks.
460 decoder_thread_.Stop(); 449 decoder_thread_.Stop();
461 } else { 450 } else {
462 // Otherwise, call the destroy task directly. 451 // Otherwise, call the destroy task directly.
463 DestroyTask(); 452 DestroyTask();
464 } 453 }
465 454
466 delete this; 455 delete this;
467 } 456 }
468 457
469 bool V4L2VideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( 458 bool V4L2VideoDecodeAccelerator::CanDecodeOnIOThread() { return true; }
470 const base::WeakPtr<Client>& decode_client,
471 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) {
472 decode_client_ = decode_client_;
473 decode_task_runner_ = decode_task_runner;
474 return true;
475 }
476 459
477 // static 460 // static
478 media::VideoDecodeAccelerator::SupportedProfiles 461 media::VideoDecodeAccelerator::SupportedProfiles
479 V4L2VideoDecodeAccelerator::GetSupportedProfiles() { 462 V4L2VideoDecodeAccelerator::GetSupportedProfiles() {
480 scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder); 463 scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder);
481 if (!device) 464 if (!device)
482 return SupportedProfiles(); 465 return SupportedProfiles();
483 466
484 return device->GetSupportedDecodeProfiles(arraysize(supported_input_fourccs_), 467 return device->GetSupportedDecodeProfiles(arraysize(supported_input_fourccs_),
485 supported_input_fourccs_); 468 supported_input_fourccs_);
486 } 469 }
487 470
488 void V4L2VideoDecodeAccelerator::DecodeTask( 471 void V4L2VideoDecodeAccelerator::DecodeTask(
489 const media::BitstreamBuffer& bitstream_buffer) { 472 const media::BitstreamBuffer& bitstream_buffer) {
490 DVLOG(3) << "DecodeTask(): input_id=" << bitstream_buffer.id(); 473 DVLOG(3) << "DecodeTask(): input_id=" << bitstream_buffer.id();
491 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 474 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
492 DCHECK_NE(decoder_state_, kUninitialized); 475 DCHECK_NE(decoder_state_, kUninitialized);
493 TRACE_EVENT1("Video Decoder", "V4L2VDA::DecodeTask", "input_id", 476 TRACE_EVENT1("Video Decoder", "V4L2VDA::DecodeTask", "input_id",
494 bitstream_buffer.id()); 477 bitstream_buffer.id());
495 478
496 scoped_ptr<BitstreamBufferRef> bitstream_record(new BitstreamBufferRef( 479 scoped_ptr<BitstreamBufferRef> bitstream_record(new BitstreamBufferRef(
497 decode_client_, decode_task_runner_, 480 io_client_, io_task_runner_,
498 scoped_ptr<SharedMemoryRegion>( 481 scoped_ptr<SharedMemoryRegion>(
499 new SharedMemoryRegion(bitstream_buffer, true)), 482 new SharedMemoryRegion(bitstream_buffer, true)),
500 bitstream_buffer.id())); 483 bitstream_buffer.id()));
501 if (!bitstream_record->shm->Map()) { 484 if (!bitstream_record->shm->Map()) {
502 LOG(ERROR) << "Decode(): could not map bitstream_buffer"; 485 LOG(ERROR) << "Decode(): could not map bitstream_buffer";
503 NOTIFY_ERROR(UNREADABLE_INPUT); 486 NOTIFY_ERROR(UNREADABLE_INPUT);
504 return; 487 return;
505 } 488 }
506 DVLOG(3) << "DecodeTask(): mapped at=" << bitstream_record->shm->memory(); 489 DVLOG(3) << "DecodeTask(): mapped at=" << bitstream_record->shm->memory();
507 490
(...skipping 772 matching lines...) Expand 10 before | Expand all | Expand 10 after
1280 DVLOG(2) << "FlushTask(): early out: kError state"; 1263 DVLOG(2) << "FlushTask(): early out: kError state";
1281 return; 1264 return;
1282 } 1265 }
1283 1266
1284 // We don't support stacked flushing. 1267 // We don't support stacked flushing.
1285 DCHECK(!decoder_flushing_); 1268 DCHECK(!decoder_flushing_);
1286 1269
1287 // Queue up an empty buffer -- this triggers the flush. 1270 // Queue up an empty buffer -- this triggers the flush.
1288 decoder_input_queue_.push( 1271 decoder_input_queue_.push(
1289 linked_ptr<BitstreamBufferRef>(new BitstreamBufferRef( 1272 linked_ptr<BitstreamBufferRef>(new BitstreamBufferRef(
1290 decode_client_, decode_task_runner_, nullptr, kFlushBufferId))); 1273 io_client_, io_task_runner_, nullptr, kFlushBufferId)));
1291 decoder_flushing_ = true; 1274 decoder_flushing_ = true;
1292 SendPictureReady(); // Send all pending PictureReady. 1275 SendPictureReady(); // Send all pending PictureReady.
1293 1276
1294 ScheduleDecodeBufferTaskIfNeeded(); 1277 ScheduleDecodeBufferTaskIfNeeded();
1295 } 1278 }
1296 1279
1297 void V4L2VideoDecodeAccelerator::NotifyFlushDoneIfNeeded() { 1280 void V4L2VideoDecodeAccelerator::NotifyFlushDoneIfNeeded() {
1298 if (!decoder_flushing_) 1281 if (!decoder_flushing_)
1299 return; 1282 return;
1300 1283
(...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after
2003 1986
2004 void V4L2VideoDecodeAccelerator::SendPictureReady() { 1987 void V4L2VideoDecodeAccelerator::SendPictureReady() {
2005 DVLOG(3) << "SendPictureReady()"; 1988 DVLOG(3) << "SendPictureReady()";
2006 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1989 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
2007 bool resetting_or_flushing = 1990 bool resetting_or_flushing =
2008 (decoder_state_ == kResetting || decoder_flushing_); 1991 (decoder_state_ == kResetting || decoder_flushing_);
2009 while (pending_picture_ready_.size() > 0) { 1992 while (pending_picture_ready_.size() > 0) {
2010 bool cleared = pending_picture_ready_.front().cleared; 1993 bool cleared = pending_picture_ready_.front().cleared;
2011 const media::Picture& picture = pending_picture_ready_.front().picture; 1994 const media::Picture& picture = pending_picture_ready_.front().picture;
2012 if (cleared && picture_clearing_count_ == 0) { 1995 if (cleared && picture_clearing_count_ == 0) {
2013 // This picture is cleared. It can be posted to a thread different than 1996 // This picture is cleared. Post it to IO thread to reduce latency. This
2014 // the main GPU thread to reduce latency. This should be the case after 1997 // should be the case after all pictures are cleared at the beginning.
2015 // all pictures are cleared at the beginning. 1998 io_task_runner_->PostTask(
2016 decode_task_runner_->PostTask( 1999 FROM_HERE, base::Bind(&Client::PictureReady, io_client_, picture));
2017 FROM_HERE,
2018 base::Bind(&Client::PictureReady, decode_client_, picture));
2019 pending_picture_ready_.pop(); 2000 pending_picture_ready_.pop();
2020 } else if (!cleared || resetting_or_flushing) { 2001 } else if (!cleared || resetting_or_flushing) {
2021 DVLOG(3) << "SendPictureReady()" 2002 DVLOG(3) << "SendPictureReady()"
2022 << ". cleared=" << pending_picture_ready_.front().cleared 2003 << ". cleared=" << pending_picture_ready_.front().cleared
2023 << ", decoder_state_=" << decoder_state_ 2004 << ", decoder_state_=" << decoder_state_
2024 << ", decoder_flushing_=" << decoder_flushing_ 2005 << ", decoder_flushing_=" << decoder_flushing_
2025 << ", picture_clearing_count_=" << picture_clearing_count_; 2006 << ", picture_clearing_count_=" << picture_clearing_count_;
2026 // If the picture is not cleared, post it to the child thread because it 2007 // If the picture is not cleared, post it to the child thread because it
2027 // has to be cleared in the child thread. A picture only needs to be 2008 // has to be cleared in the child thread. A picture only needs to be
2028 // cleared once. If the decoder is resetting or flushing, send all 2009 // cleared once. If the decoder is resetting or flushing, send all
(...skipping 17 matching lines...) Expand all
2046 2027
2047 void V4L2VideoDecodeAccelerator::PictureCleared() { 2028 void V4L2VideoDecodeAccelerator::PictureCleared() {
2048 DVLOG(3) << "PictureCleared(). clearing count=" << picture_clearing_count_; 2029 DVLOG(3) << "PictureCleared(). clearing count=" << picture_clearing_count_;
2049 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 2030 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
2050 DCHECK_GT(picture_clearing_count_, 0); 2031 DCHECK_GT(picture_clearing_count_, 0);
2051 picture_clearing_count_--; 2032 picture_clearing_count_--;
2052 SendPictureReady(); 2033 SendPictureReady();
2053 } 2034 }
2054 2035
2055 } // namespace content 2036 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/media/v4l2_video_decode_accelerator.h ('k') | content/common/gpu/media/vaapi_drm_picture.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698