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

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

Issue 1745903002: 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 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 <errno.h> 5 #include <errno.h>
6 #include <fcntl.h> 6 #include <fcntl.h>
7 #include <linux/videodev2.h> 7 #include <linux/videodev2.h>
8 #include <poll.h> 8 #include <poll.h>
9 #include <string.h> 9 #include <string.h>
10 #include <sys/eventfd.h> 10 #include <sys/eventfd.h>
11 #include <sys/ioctl.h> 11 #include <sys/ioctl.h>
12 #include <sys/mman.h> 12 #include <sys/mman.h>
13 13
14 #include "base/bind.h" 14 #include "base/bind.h"
15 #include "base/bind_helpers.h" 15 #include "base/bind_helpers.h"
16 #include "base/callback.h" 16 #include "base/callback.h"
17 #include "base/callback_helpers.h" 17 #include "base/callback_helpers.h"
18 #include "base/command_line.h" 18 #include "base/command_line.h"
19 #include "base/macros.h" 19 #include "base/macros.h"
20 #include "base/numerics/safe_conversions.h" 20 #include "base/numerics/safe_conversions.h"
21 #include "base/strings/stringprintf.h" 21 #include "base/strings/stringprintf.h"
22 #include "content/common/gpu/media/v4l2_slice_video_decode_accelerator.h" 22 #include "content/common/gpu/media/v4l2_slice_video_decode_accelerator.h"
23 #include "content/public/common/gpu_video_decode_accelerator_helpers.h"
23 #include "media/base/bind_to_current_loop.h" 24 #include "media/base/bind_to_current_loop.h"
24 #include "media/base/media_switches.h" 25 #include "media/base/media_switches.h"
26 #include "ui/gl/gl_context.h"
25 #include "ui/gl/scoped_binders.h" 27 #include "ui/gl/scoped_binders.h"
26 28
27 #define LOGF(level) LOG(level) << __FUNCTION__ << "(): " 29 #define LOGF(level) LOG(level) << __FUNCTION__ << "(): "
28 #define DVLOGF(level) DVLOG(level) << __FUNCTION__ << "(): " 30 #define DVLOGF(level) DVLOG(level) << __FUNCTION__ << "(): "
29 31
30 #define NOTIFY_ERROR(x) \ 32 #define NOTIFY_ERROR(x) \
31 do { \ 33 do { \
32 LOG(ERROR) << "Setting error state:" << x; \ 34 LOG(ERROR) << "Setting error state:" << x; \
33 SetErrorState(x); \ 35 SetErrorState(x); \
34 } while (0) 36 } while (0)
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface>& dec_surface) 377 V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface>& dec_surface)
376 : dec_surface_(dec_surface) { 378 : dec_surface_(dec_surface) {
377 } 379 }
378 380
379 V4L2VP8Picture::~V4L2VP8Picture() { 381 V4L2VP8Picture::~V4L2VP8Picture() {
380 } 382 }
381 383
382 V4L2SliceVideoDecodeAccelerator::V4L2SliceVideoDecodeAccelerator( 384 V4L2SliceVideoDecodeAccelerator::V4L2SliceVideoDecodeAccelerator(
383 const scoped_refptr<V4L2Device>& device, 385 const scoped_refptr<V4L2Device>& device,
384 EGLDisplay egl_display, 386 EGLDisplay egl_display,
385 EGLContext egl_context, 387 const gpu_vda_helpers::GetGLContextCb& get_gl_context_cb,
386 const base::WeakPtr<Client>& io_client, 388 const gpu_vda_helpers::MakeGLContextCurrentCb& make_context_current_cb)
387 const base::Callback<bool(void)>& make_context_current,
388 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
389 : input_planes_count_(0), 389 : input_planes_count_(0),
390 output_planes_count_(0), 390 output_planes_count_(0),
391 child_task_runner_(base::ThreadTaskRunnerHandle::Get()), 391 child_task_runner_(base::ThreadTaskRunnerHandle::Get()),
392 io_task_runner_(io_task_runner),
393 io_client_(io_client),
394 device_(device), 392 device_(device),
395 decoder_thread_("V4L2SliceVideoDecodeAcceleratorThread"), 393 decoder_thread_("V4L2SliceVideoDecodeAcceleratorThread"),
396 device_poll_thread_("V4L2SliceVideoDecodeAcceleratorDevicePollThread"), 394 device_poll_thread_("V4L2SliceVideoDecodeAcceleratorDevicePollThread"),
397 input_streamon_(false), 395 input_streamon_(false),
398 input_buffer_queued_count_(0), 396 input_buffer_queued_count_(0),
399 output_streamon_(false), 397 output_streamon_(false),
400 output_buffer_queued_count_(0), 398 output_buffer_queued_count_(0),
401 video_profile_(media::VIDEO_CODEC_PROFILE_UNKNOWN), 399 video_profile_(media::VIDEO_CODEC_PROFILE_UNKNOWN),
402 output_format_fourcc_(0), 400 output_format_fourcc_(0),
403 state_(kUninitialized), 401 state_(kUninitialized),
404 decoder_flushing_(false), 402 decoder_flushing_(false),
405 decoder_resetting_(false), 403 decoder_resetting_(false),
406 surface_set_change_pending_(false), 404 surface_set_change_pending_(false),
407 picture_clearing_count_(0), 405 picture_clearing_count_(0),
408 make_context_current_(make_context_current),
409 egl_display_(egl_display), 406 egl_display_(egl_display),
410 egl_context_(egl_context), 407 get_gl_context_cb_(get_gl_context_cb),
408 make_context_current_cb_(make_context_current_cb),
411 weak_this_factory_(this) { 409 weak_this_factory_(this) {
412 weak_this_ = weak_this_factory_.GetWeakPtr(); 410 weak_this_ = weak_this_factory_.GetWeakPtr();
413 } 411 }
414 412
415 V4L2SliceVideoDecodeAccelerator::~V4L2SliceVideoDecodeAccelerator() { 413 V4L2SliceVideoDecodeAccelerator::~V4L2SliceVideoDecodeAccelerator() {
416 DVLOGF(2); 414 DVLOGF(2);
417 415
418 DCHECK(child_task_runner_->BelongsToCurrentThread()); 416 DCHECK(child_task_runner_->BelongsToCurrentThread());
419 DCHECK(!decoder_thread_.IsRunning()); 417 DCHECK(!decoder_thread_.IsRunning());
420 DCHECK(!device_poll_thread_.IsRunning()); 418 DCHECK(!device_poll_thread_.IsRunning());
(...skipping 30 matching lines...) Expand all
451 if (!device_->SupportsDecodeProfileForV4L2PixelFormats( 449 if (!device_->SupportsDecodeProfileForV4L2PixelFormats(
452 config.profile, arraysize(supported_input_fourccs_), 450 config.profile, arraysize(supported_input_fourccs_),
453 supported_input_fourccs_)) { 451 supported_input_fourccs_)) {
454 DVLOGF(1) << "unsupported profile " << config.profile; 452 DVLOGF(1) << "unsupported profile " << config.profile;
455 return false; 453 return false;
456 } 454 }
457 455
458 client_ptr_factory_.reset( 456 client_ptr_factory_.reset(
459 new base::WeakPtrFactory<VideoDecodeAccelerator::Client>(client)); 457 new base::WeakPtrFactory<VideoDecodeAccelerator::Client>(client));
460 client_ = client_ptr_factory_->GetWeakPtr(); 458 client_ = client_ptr_factory_->GetWeakPtr();
459 // If we haven't been set up to decode on separate thread via
460 // TryInitializeDecodeOnSeparateThread(), use the main thread/client for
461 // decode tasks.
462 if (!decode_task_runner_) {
463 decode_task_runner_ = child_task_runner_;
464 DCHECK(!decode_client_);
465 decode_client_ = client_;
466 }
461 467
462 video_profile_ = config.profile; 468 video_profile_ = config.profile;
463 469
464 if (video_profile_ >= media::H264PROFILE_MIN && 470 if (video_profile_ >= media::H264PROFILE_MIN &&
465 video_profile_ <= media::H264PROFILE_MAX) { 471 video_profile_ <= media::H264PROFILE_MAX) {
466 h264_accelerator_.reset(new V4L2H264Accelerator(this)); 472 h264_accelerator_.reset(new V4L2H264Accelerator(this));
467 decoder_.reset(new H264Decoder(h264_accelerator_.get())); 473 decoder_.reset(new H264Decoder(h264_accelerator_.get()));
468 } else if (video_profile_ >= media::VP8PROFILE_MIN && 474 } else if (video_profile_ >= media::VP8PROFILE_MIN &&
469 video_profile_ <= media::VP8PROFILE_MAX) { 475 video_profile_ <= media::VP8PROFILE_MAX) {
470 vp8_accelerator_.reset(new V4L2VP8Accelerator(this)); 476 vp8_accelerator_.reset(new V4L2VP8Accelerator(this));
471 decoder_.reset(new VP8Decoder(vp8_accelerator_.get())); 477 decoder_.reset(new VP8Decoder(vp8_accelerator_.get()));
472 } else { 478 } else {
473 NOTREACHED() << "Unsupported profile " << video_profile_; 479 NOTREACHED() << "Unsupported profile " << video_profile_;
474 return false; 480 return false;
475 } 481 }
476 482
477 // TODO(posciak): This needs to be queried once supported. 483 // TODO(posciak): This needs to be queried once supported.
478 input_planes_count_ = 1; 484 input_planes_count_ = 1;
479 output_planes_count_ = 1; 485 output_planes_count_ = 1;
480 486
481 if (egl_display_ == EGL_NO_DISPLAY) { 487 if (egl_display_ == EGL_NO_DISPLAY) {
482 LOG(ERROR) << "Initialize(): could not get EGLDisplay"; 488 LOG(ERROR) << "Initialize(): could not get EGLDisplay";
483 return false; 489 return false;
484 } 490 }
485 491
486 // We need the context to be initialized to query extensions. 492 // We need the context to be initialized to query extensions.
487 if (!make_context_current_.Run()) { 493 if (!make_context_current_cb_.Run()) {
488 LOG(ERROR) << "Initialize(): could not make context current"; 494 LOG(ERROR) << "Initialize(): could not make context current";
489 return false; 495 return false;
490 } 496 }
491 497
492 if (!gfx::g_driver_egl.ext.b_EGL_KHR_fence_sync) { 498 if (!gfx::g_driver_egl.ext.b_EGL_KHR_fence_sync) {
493 LOG(ERROR) << "Initialize(): context does not have EGL_KHR_fence_sync"; 499 LOG(ERROR) << "Initialize(): context does not have EGL_KHR_fence_sync";
494 return false; 500 return false;
495 } 501 }
496 502
497 // Capabilities check. 503 // Capabilities check.
(...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after
1181 decoder_display_queue_.pop(); 1187 decoder_display_queue_.pop();
1182 1188
1183 DVLOGF(3) << "Device poll stopped"; 1189 DVLOGF(3) << "Device poll stopped";
1184 return true; 1190 return true;
1185 } 1191 }
1186 1192
1187 void V4L2SliceVideoDecodeAccelerator::Decode( 1193 void V4L2SliceVideoDecodeAccelerator::Decode(
1188 const media::BitstreamBuffer& bitstream_buffer) { 1194 const media::BitstreamBuffer& bitstream_buffer) {
1189 DVLOGF(3) << "input_id=" << bitstream_buffer.id() 1195 DVLOGF(3) << "input_id=" << bitstream_buffer.id()
1190 << ", size=" << bitstream_buffer.size(); 1196 << ", size=" << bitstream_buffer.size();
1191 DCHECK(io_task_runner_->BelongsToCurrentThread()); 1197 DCHECK(decode_task_runner_->BelongsToCurrentThread());
1192 1198
1193 if (bitstream_buffer.id() < 0) { 1199 if (bitstream_buffer.id() < 0) {
1194 LOG(ERROR) << "Invalid bitstream_buffer, id: " << bitstream_buffer.id(); 1200 LOG(ERROR) << "Invalid bitstream_buffer, id: " << bitstream_buffer.id();
1195 if (base::SharedMemory::IsHandleValid(bitstream_buffer.handle())) 1201 if (base::SharedMemory::IsHandleValid(bitstream_buffer.handle()))
1196 base::SharedMemory::CloseHandle(bitstream_buffer.handle()); 1202 base::SharedMemory::CloseHandle(bitstream_buffer.handle());
1197 NOTIFY_ERROR(INVALID_ARGUMENT); 1203 NOTIFY_ERROR(INVALID_ARGUMENT);
1198 return; 1204 return;
1199 } 1205 }
1200 1206
1201 decoder_thread_task_runner_->PostTask( 1207 decoder_thread_task_runner_->PostTask(
1202 FROM_HERE, base::Bind(&V4L2SliceVideoDecodeAccelerator::DecodeTask, 1208 FROM_HERE, base::Bind(&V4L2SliceVideoDecodeAccelerator::DecodeTask,
1203 base::Unretained(this), bitstream_buffer)); 1209 base::Unretained(this), bitstream_buffer));
1204 } 1210 }
1205 1211
1206 void V4L2SliceVideoDecodeAccelerator::DecodeTask( 1212 void V4L2SliceVideoDecodeAccelerator::DecodeTask(
1207 const media::BitstreamBuffer& bitstream_buffer) { 1213 const media::BitstreamBuffer& bitstream_buffer) {
1208 DVLOGF(3) << "input_id=" << bitstream_buffer.id() 1214 DVLOGF(3) << "input_id=" << bitstream_buffer.id()
1209 << " size=" << bitstream_buffer.size(); 1215 << " size=" << bitstream_buffer.size();
1210 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); 1216 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread());
1211 1217
1212 scoped_ptr<BitstreamBufferRef> bitstream_record(new BitstreamBufferRef( 1218 scoped_ptr<BitstreamBufferRef> bitstream_record(new BitstreamBufferRef(
1213 io_client_, io_task_runner_, 1219 decode_client_, decode_task_runner_,
1214 new base::SharedMemory(bitstream_buffer.handle(), true), 1220 new base::SharedMemory(bitstream_buffer.handle(), true),
1215 bitstream_buffer.size(), bitstream_buffer.id())); 1221 bitstream_buffer.size(), bitstream_buffer.id()));
1216 if (!bitstream_record->shm->Map(bitstream_buffer.size())) { 1222 if (!bitstream_record->shm->Map(bitstream_buffer.size())) {
1217 LOGF(ERROR) << "Could not map bitstream_buffer"; 1223 LOGF(ERROR) << "Could not map bitstream_buffer";
1218 NOTIFY_ERROR(UNREADABLE_INPUT); 1224 NOTIFY_ERROR(UNREADABLE_INPUT);
1219 return; 1225 return;
1220 } 1226 }
1221 DVLOGF(3) << "mapped at=" << bitstream_record->shm->memory(); 1227 DVLOGF(3) << "mapped at=" << bitstream_record->shm->memory();
1222 1228
1223 decoder_input_queue_.push( 1229 decoder_input_queue_.push(
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
1485 output_planes_count_)); 1491 output_planes_count_));
1486 } 1492 }
1487 1493
1488 void V4L2SliceVideoDecodeAccelerator::CreateEGLImages( 1494 void V4L2SliceVideoDecodeAccelerator::CreateEGLImages(
1489 const std::vector<media::PictureBuffer>& buffers, 1495 const std::vector<media::PictureBuffer>& buffers,
1490 uint32_t output_format_fourcc, 1496 uint32_t output_format_fourcc,
1491 size_t output_planes_count) { 1497 size_t output_planes_count) {
1492 DVLOGF(3); 1498 DVLOGF(3);
1493 DCHECK(child_task_runner_->BelongsToCurrentThread()); 1499 DCHECK(child_task_runner_->BelongsToCurrentThread());
1494 1500
1495 if (!make_context_current_.Run()) { 1501 gfx::GLContext* gl_context = get_gl_context_cb_.Run();
1496 DLOG(ERROR) << "could not make context current"; 1502 if (!gl_context || !make_context_current_cb_.Run()) {
1503 DLOG(ERROR) << "No GL context";
1497 NOTIFY_ERROR(PLATFORM_FAILURE); 1504 NOTIFY_ERROR(PLATFORM_FAILURE);
1498 return; 1505 return;
1499 } 1506 }
1500 1507
1501 gfx::ScopedTextureBinder bind_restore(GL_TEXTURE_EXTERNAL_OES, 0); 1508 gfx::ScopedTextureBinder bind_restore(GL_TEXTURE_EXTERNAL_OES, 0);
1502 1509
1503 std::vector<EGLImageKHR> egl_images; 1510 std::vector<EGLImageKHR> egl_images;
1504 for (size_t i = 0; i < buffers.size(); ++i) { 1511 for (size_t i = 0; i < buffers.size(); ++i) {
1505 EGLImageKHR egl_image = device_->CreateEGLImage(egl_display_, 1512 EGLImageKHR egl_image = device_->CreateEGLImage(egl_display_,
1506 egl_context_, 1513 gl_context->GetHandle(),
1507 buffers[i].texture_id(), 1514 buffers[i].texture_id(),
1508 buffers[i].size(), 1515 buffers[i].size(),
1509 i, 1516 i,
1510 output_format_fourcc, 1517 output_format_fourcc,
1511 output_planes_count); 1518 output_planes_count);
1512 if (egl_image == EGL_NO_IMAGE_KHR) { 1519 if (egl_image == EGL_NO_IMAGE_KHR) {
1513 LOGF(ERROR) << "Could not create EGLImageKHR"; 1520 LOGF(ERROR) << "Could not create EGLImageKHR";
1514 for (const auto& image_to_destroy : egl_images) 1521 for (const auto& image_to_destroy : egl_images)
1515 device_->DestroyEGLImage(egl_display_, image_to_destroy); 1522 device_->DestroyEGLImage(egl_display_, image_to_destroy);
1516 1523
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1562 } 1569 }
1563 1570
1564 ProcessPendingEventsIfNeeded(); 1571 ProcessPendingEventsIfNeeded();
1565 } 1572 }
1566 1573
1567 void V4L2SliceVideoDecodeAccelerator::ReusePictureBuffer( 1574 void V4L2SliceVideoDecodeAccelerator::ReusePictureBuffer(
1568 int32_t picture_buffer_id) { 1575 int32_t picture_buffer_id) {
1569 DCHECK(child_task_runner_->BelongsToCurrentThread()); 1576 DCHECK(child_task_runner_->BelongsToCurrentThread());
1570 DVLOGF(4) << "picture_buffer_id=" << picture_buffer_id; 1577 DVLOGF(4) << "picture_buffer_id=" << picture_buffer_id;
1571 1578
1572 if (!make_context_current_.Run()) { 1579 if (!make_context_current_cb_.Run()) {
1573 LOGF(ERROR) << "could not make context current"; 1580 LOGF(ERROR) << "could not make context current";
1574 NOTIFY_ERROR(PLATFORM_FAILURE); 1581 NOTIFY_ERROR(PLATFORM_FAILURE);
1575 return; 1582 return;
1576 } 1583 }
1577 1584
1578 EGLSyncKHR egl_sync = 1585 EGLSyncKHR egl_sync =
1579 eglCreateSyncKHR(egl_display_, EGL_SYNC_FENCE_KHR, NULL); 1586 eglCreateSyncKHR(egl_display_, EGL_SYNC_FENCE_KHR, NULL);
1580 if (egl_sync == EGL_NO_SYNC_KHR) { 1587 if (egl_sync == EGL_NO_SYNC_KHR) {
1581 LOGF(ERROR) << "eglCreateSyncKHR() failed"; 1588 LOGF(ERROR) << "eglCreateSyncKHR() failed";
1582 NOTIFY_ERROR(PLATFORM_FAILURE); 1589 NOTIFY_ERROR(PLATFORM_FAILURE);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1638 1645
1639 void V4L2SliceVideoDecodeAccelerator::FlushTask() { 1646 void V4L2SliceVideoDecodeAccelerator::FlushTask() {
1640 DVLOGF(3); 1647 DVLOGF(3);
1641 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); 1648 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread());
1642 1649
1643 if (!decoder_input_queue_.empty()) { 1650 if (!decoder_input_queue_.empty()) {
1644 // We are not done with pending inputs, so queue an empty buffer, 1651 // We are not done with pending inputs, so queue an empty buffer,
1645 // which - when reached - will trigger flush sequence. 1652 // which - when reached - will trigger flush sequence.
1646 decoder_input_queue_.push( 1653 decoder_input_queue_.push(
1647 linked_ptr<BitstreamBufferRef>(new BitstreamBufferRef( 1654 linked_ptr<BitstreamBufferRef>(new BitstreamBufferRef(
1648 io_client_, io_task_runner_, nullptr, 0, kFlushBufferId))); 1655 decode_client_, decode_task_runner_, nullptr, 0, kFlushBufferId)));
1649 return; 1656 return;
1650 } 1657 }
1651 1658
1652 // No more inputs pending, so just finish flushing here. 1659 // No more inputs pending, so just finish flushing here.
1653 InitiateFlush(); 1660 InitiateFlush();
1654 } 1661 }
1655 1662
1656 void V4L2SliceVideoDecodeAccelerator::InitiateFlush() { 1663 void V4L2SliceVideoDecodeAccelerator::InitiateFlush() {
1657 DVLOGF(3); 1664 DVLOGF(3);
1658 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); 1665 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread());
(...skipping 890 matching lines...) Expand 10 before | Expand all | Expand 10 after
2549 } 2556 }
2550 2557
2551 void V4L2SliceVideoDecodeAccelerator::SendPictureReady() { 2558 void V4L2SliceVideoDecodeAccelerator::SendPictureReady() {
2552 DVLOGF(3); 2559 DVLOGF(3);
2553 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); 2560 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread());
2554 bool resetting_or_flushing = (decoder_resetting_ || decoder_flushing_); 2561 bool resetting_or_flushing = (decoder_resetting_ || decoder_flushing_);
2555 while (!pending_picture_ready_.empty()) { 2562 while (!pending_picture_ready_.empty()) {
2556 bool cleared = pending_picture_ready_.front().cleared; 2563 bool cleared = pending_picture_ready_.front().cleared;
2557 const media::Picture& picture = pending_picture_ready_.front().picture; 2564 const media::Picture& picture = pending_picture_ready_.front().picture;
2558 if (cleared && picture_clearing_count_ == 0) { 2565 if (cleared && picture_clearing_count_ == 0) {
2559 DVLOGF(4) << "Posting picture ready to IO for: " 2566 DVLOGF(4) << "Posting picture ready to decode task runner for: "
2560 << picture.picture_buffer_id(); 2567 << picture.picture_buffer_id();
2561 // This picture is cleared. Post it to IO thread to reduce latency. This 2568 // This picture is cleared. It can be posted to a thread different than
2562 // should be the case after all pictures are cleared at the beginning. 2569 // the main GPU thread to reduce latency. This should be the case after
2563 io_task_runner_->PostTask( 2570 // all pictures are cleared at the beginning.
2564 FROM_HERE, base::Bind(&Client::PictureReady, io_client_, picture)); 2571 decode_task_runner_->PostTask(
2572 FROM_HERE,
2573 base::Bind(&Client::PictureReady, decode_client_, picture));
2565 pending_picture_ready_.pop(); 2574 pending_picture_ready_.pop();
2566 } else if (!cleared || resetting_or_flushing) { 2575 } else if (!cleared || resetting_or_flushing) {
2567 DVLOGF(3) << "cleared=" << pending_picture_ready_.front().cleared 2576 DVLOGF(3) << "cleared=" << pending_picture_ready_.front().cleared
2568 << ", decoder_resetting_=" << decoder_resetting_ 2577 << ", decoder_resetting_=" << decoder_resetting_
2569 << ", decoder_flushing_=" << decoder_flushing_ 2578 << ", decoder_flushing_=" << decoder_flushing_
2570 << ", picture_clearing_count_=" << picture_clearing_count_; 2579 << ", picture_clearing_count_=" << picture_clearing_count_;
2571 DVLOGF(4) << "Posting picture ready to GPU for: " 2580 DVLOGF(4) << "Posting picture ready to GPU for: "
2572 << picture.picture_buffer_id(); 2581 << picture.picture_buffer_id();
2573 // If the picture is not cleared, post it to the child thread because it 2582 // If the picture is not cleared, post it to the child thread because it
2574 // has to be cleared in the child thread. A picture only needs to be 2583 // has to be cleared in the child thread. A picture only needs to be
(...skipping 17 matching lines...) Expand all
2592 } 2601 }
2593 2602
2594 void V4L2SliceVideoDecodeAccelerator::PictureCleared() { 2603 void V4L2SliceVideoDecodeAccelerator::PictureCleared() {
2595 DVLOGF(3) << "clearing count=" << picture_clearing_count_; 2604 DVLOGF(3) << "clearing count=" << picture_clearing_count_;
2596 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); 2605 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread());
2597 DCHECK_GT(picture_clearing_count_, 0); 2606 DCHECK_GT(picture_clearing_count_, 0);
2598 picture_clearing_count_--; 2607 picture_clearing_count_--;
2599 SendPictureReady(); 2608 SendPictureReady();
2600 } 2609 }
2601 2610
2602 bool V4L2SliceVideoDecodeAccelerator::CanDecodeOnIOThread() { 2611 bool V4L2SliceVideoDecodeAccelerator::TryInitializeDecodeOnSeparateThread(
2612 const base::WeakPtr<Client>& decode_client,
2613 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) {
2614 decode_client_ = decode_client_;
2615 decode_task_runner_ = decode_task_runner;
2603 return true; 2616 return true;
2604 } 2617 }
2605 2618
2606 // static 2619 // static
2607 media::VideoDecodeAccelerator::SupportedProfiles 2620 media::VideoDecodeAccelerator::SupportedProfiles
2608 V4L2SliceVideoDecodeAccelerator::GetSupportedProfiles() { 2621 V4L2SliceVideoDecodeAccelerator::GetSupportedProfiles() {
2609 scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder); 2622 scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder);
2610 if (!device) 2623 if (!device)
2611 return SupportedProfiles(); 2624 return SupportedProfiles();
2612 2625
2613 return device->GetSupportedDecodeProfiles(arraysize(supported_input_fourccs_), 2626 return device->GetSupportedDecodeProfiles(arraysize(supported_input_fourccs_),
2614 supported_input_fourccs_); 2627 supported_input_fourccs_);
2615 } 2628 }
2616 2629
2617 } // namespace content 2630 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698