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

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

Issue 1816203003: Add an additional VDA::Flush() mode to return all allocated buffers. (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>
(...skipping 1605 matching lines...) Expand 10 before | Expand all | Expand 10 after
1616 1616
1617 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR); 1617 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR);
1618 DCHECK(!output_record.at_device); 1618 DCHECK(!output_record.at_device);
1619 output_record.at_client = false; 1619 output_record.at_client = false;
1620 output_record.egl_sync = egl_sync_ref->egl_sync; 1620 output_record.egl_sync = egl_sync_ref->egl_sync;
1621 // Take ownership of the EGLSync. 1621 // Take ownership of the EGLSync.
1622 egl_sync_ref->egl_sync = EGL_NO_SYNC_KHR; 1622 egl_sync_ref->egl_sync = EGL_NO_SYNC_KHR;
1623 surfaces_at_display_.erase(it); 1623 surfaces_at_display_.erase(it);
1624 } 1624 }
1625 1625
1626 void V4L2SliceVideoDecodeAccelerator::Flush() { 1626 void V4L2SliceVideoDecodeAccelerator::Flush(bool return_buffers) {
1627 DVLOGF(3); 1627 DVLOGF(3);
1628 DCHECK(child_task_runner_->BelongsToCurrentThread()); 1628 DCHECK(child_task_runner_->BelongsToCurrentThread());
1629 1629
1630 decoder_thread_task_runner_->PostTask( 1630 decoder_thread_task_runner_->PostTask(
1631 FROM_HERE, base::Bind(&V4L2SliceVideoDecodeAccelerator::FlushTask, 1631 FROM_HERE, base::Bind(&V4L2SliceVideoDecodeAccelerator::FlushTask,
1632 base::Unretained(this))); 1632 base::Unretained(this), return_buffers));
1633 } 1633 }
1634 1634
1635 void V4L2SliceVideoDecodeAccelerator::FlushTask() { 1635 void V4L2SliceVideoDecodeAccelerator::FlushTask(bool return_buffers) {
1636 DVLOGF(3); 1636 DVLOGF(3);
1637 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); 1637 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread());
1638 1638
1639 flush_return_all_buffers_ = return_buffers;
1640
1639 if (!decoder_input_queue_.empty()) { 1641 if (!decoder_input_queue_.empty()) {
1640 // We are not done with pending inputs, so queue an empty buffer, 1642 // We are not done with pending inputs, so queue an empty buffer,
1641 // which - when reached - will trigger flush sequence. 1643 // which - when reached - will trigger flush sequence.
1642 decoder_input_queue_.push( 1644 decoder_input_queue_.push(
1643 linked_ptr<BitstreamBufferRef>(new BitstreamBufferRef( 1645 linked_ptr<BitstreamBufferRef>(new BitstreamBufferRef(
1644 io_client_, io_task_runner_, nullptr, kFlushBufferId))); 1646 io_client_, io_task_runner_, nullptr, kFlushBufferId)));
1645 return; 1647 return;
1646 } 1648 }
1647 1649
1648 // No more inputs pending, so just finish flushing here. 1650 // No more inputs pending, so just finish flushing here.
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1690 // respective PictureReady calls have been posted (or they have been queued on 1692 // respective PictureReady calls have been posted (or they have been queued on
1691 // pending_picture_ready_). So at this time, once we SendPictureReady(), 1693 // pending_picture_ready_). So at this time, once we SendPictureReady(),
1692 // we will have all remaining PictureReady() posted to the client and we 1694 // we will have all remaining PictureReady() posted to the client and we
1693 // can post NotifyFlushDone(). 1695 // can post NotifyFlushDone().
1694 DCHECK(decoder_display_queue_.empty()); 1696 DCHECK(decoder_display_queue_.empty());
1695 1697
1696 // Decoder should have already returned all surfaces and all surfaces are 1698 // Decoder should have already returned all surfaces and all surfaces are
1697 // out of hardware. There can be no other owners of input buffers. 1699 // out of hardware. There can be no other owners of input buffers.
1698 DCHECK_EQ(free_input_buffers_.size(), input_buffer_map_.size()); 1700 DCHECK_EQ(free_input_buffers_.size(), input_buffer_map_.size());
1699 1701
1700 SendPictureReady(); 1702 if (flush_return_all_buffers_) {
1703 for (auto& output : free_output_buffers_) {
1704 scoped_refptr<V4L2DecodeSurface> dec_surface = new V4L2DecodeSurface(
1705 -1, -1, output,
1706 base::Bind(&V4L2SliceVideoDecodeAccelerator::ReuseOutputBuffer,
1707 base::Unretained(this)));
1708 OutputSurface(dec_surface);
1709 }
1710
1711 free_output_buffers_.clear();
1712 }
1701 1713
1702 decoder_flushing_ = false; 1714 decoder_flushing_ = false;
1715 flush_return_all_buffers_ = false;
1716
1703 DVLOGF(3) << "Flush finished"; 1717 DVLOGF(3) << "Flush finished";
1704 1718
1705 child_task_runner_->PostTask(FROM_HERE, 1719 child_task_runner_->PostTask(FROM_HERE,
1706 base::Bind(&Client::NotifyFlushDone, client_)); 1720 base::Bind(&Client::NotifyFlushDone, client_));
1707
1708 return true; 1721 return true;
1709 } 1722 }
1710 1723
1711 void V4L2SliceVideoDecodeAccelerator::Reset() { 1724 void V4L2SliceVideoDecodeAccelerator::Reset() {
1712 DVLOGF(3); 1725 DVLOGF(3);
1713 DCHECK(child_task_runner_->BelongsToCurrentThread()); 1726 DCHECK(child_task_runner_->BelongsToCurrentThread());
1714 1727
1715 decoder_thread_task_runner_->PostTask( 1728 decoder_thread_task_runner_->PostTask(
1716 FROM_HERE, base::Bind(&V4L2SliceVideoDecodeAccelerator::ResetTask, 1729 FROM_HERE, base::Bind(&V4L2SliceVideoDecodeAccelerator::ResetTask,
1717 base::Unretained(this))); 1730 base::Unretained(this)));
(...skipping 778 matching lines...) Expand 10 before | Expand all | Expand 10 after
2496 surfaces_at_display_.insert(std::make_pair(output_record.picture_id, 2509 surfaces_at_display_.insert(std::make_pair(output_record.picture_id,
2497 dec_surface)).second; 2510 dec_surface)).second;
2498 DCHECK(inserted); 2511 DCHECK(inserted);
2499 2512
2500 DCHECK(!output_record.at_client); 2513 DCHECK(!output_record.at_client);
2501 DCHECK(!output_record.at_device); 2514 DCHECK(!output_record.at_device);
2502 DCHECK_NE(output_record.egl_image, EGL_NO_IMAGE_KHR); 2515 DCHECK_NE(output_record.egl_image, EGL_NO_IMAGE_KHR);
2503 DCHECK_NE(output_record.picture_id, -1); 2516 DCHECK_NE(output_record.picture_id, -1);
2504 output_record.at_client = true; 2517 output_record.at_client = true;
2505 2518
2519 // If the surface still has a sync object assigned, destroy it. This means
2520 // we didn't use this buffer for decode and we did not need to wait on it
2521 // before enqueuing the buffer to the device.
2522 if (output_record.egl_sync != EGL_NO_SYNC_KHR) {
2523 if (eglDestroySyncKHR(egl_display_, output_record.egl_sync) != EGL_TRUE) {
2524 LOGF(ERROR) << "eglDestroySyncKHR failed!";
2525 NOTIFY_ERROR(PLATFORM_FAILURE);
2526 return;
2527 }
2528 output_record.egl_sync = EGL_NO_SYNC_KHR;
2529 }
2530
2506 // TODO(posciak): Use visible size from decoder here instead 2531 // TODO(posciak): Use visible size from decoder here instead
2507 // (crbug.com/402760). Passing (0, 0) results in the client using the 2532 // (crbug.com/402760). Passing (0, 0) results in the client using the
2508 // visible size extracted from the container instead. 2533 // visible size extracted from the container instead.
2509 media::Picture picture(output_record.picture_id, dec_surface->bitstream_id(), 2534 media::Picture picture(output_record.picture_id, dec_surface->bitstream_id(),
2510 gfx::Rect(0, 0), false); 2535 gfx::Rect(0, 0), false);
2511 DVLOGF(3) << dec_surface->ToString() 2536 DVLOGF(3) << dec_surface->ToString()
2512 << ", bitstream_id: " << picture.bitstream_buffer_id() 2537 << ", bitstream_id: " << picture.bitstream_buffer_id()
2513 << ", picture_id: " << picture.picture_buffer_id(); 2538 << ", picture_id: " << picture.picture_buffer_id();
2514 pending_picture_ready_.push(PictureRecord(output_record.cleared, picture)); 2539 pending_picture_ready_.push(PictureRecord(output_record.cleared, picture));
2515 SendPictureReady(); 2540 SendPictureReady();
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
2604 V4L2SliceVideoDecodeAccelerator::GetSupportedProfiles() { 2629 V4L2SliceVideoDecodeAccelerator::GetSupportedProfiles() {
2605 scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder); 2630 scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder);
2606 if (!device) 2631 if (!device)
2607 return SupportedProfiles(); 2632 return SupportedProfiles();
2608 2633
2609 return device->GetSupportedDecodeProfiles(arraysize(supported_input_fourccs_), 2634 return device->GetSupportedDecodeProfiles(arraysize(supported_input_fourccs_),
2610 supported_input_fourccs_); 2635 supported_input_fourccs_);
2611 } 2636 }
2612 2637
2613 } // namespace content 2638 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698