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

Unified Diff: chrome/gpu/arc_gpu_video_decode_accelerator.cc

Issue 2919193002: ArcBridge: Rename VideoAcceleratorService to VideoDecodeAccelerator. (Closed)
Patch Set: Address review comments Created 3 years, 6 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/gpu/arc_gpu_video_decode_accelerator.h ('k') | chrome/gpu/arc_video_accelerator.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/gpu/arc_gpu_video_decode_accelerator.cc
diff --git a/chrome/gpu/arc_gpu_video_decode_accelerator.cc b/chrome/gpu/arc_gpu_video_decode_accelerator.cc
deleted file mode 100644
index 9abb435ca1864da71dce12c8a67a33011fb7dea8..0000000000000000000000000000000000000000
--- a/chrome/gpu/arc_gpu_video_decode_accelerator.cc
+++ /dev/null
@@ -1,540 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/gpu/arc_gpu_video_decode_accelerator.h"
-
-#include "base/callback_helpers.h"
-#include "base/logging.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/numerics/safe_math.h"
-#include "base/run_loop.h"
-#include "base/unguessable_token.h"
-#include "media/base/video_frame.h"
-#include "media/gpu/gpu_video_decode_accelerator_factory.h"
-
-namespace chromeos {
-namespace arc {
-
-namespace {
-
-// An arbitrary chosen limit of the number of buffers. The number of
-// buffers used is requested from the untrusted client side.
-const size_t kMaxBufferCount = 128;
-
-// Maximum number of concurrent ARC video clients.
-// Currently we have no way to know the resources are not enough to create more
-// VDA. Arbitrarily chosen a reasonable constant as the limit.
-const int kMaxConcurrentClients = 8;
-
-} // anonymous namespace
-
-int ArcGpuVideoDecodeAccelerator::client_count_ = 0;
-
-ArcGpuVideoDecodeAccelerator::InputRecord::InputRecord(
- int32_t bitstream_buffer_id,
- uint32_t buffer_index,
- int64_t timestamp)
- : bitstream_buffer_id(bitstream_buffer_id),
- buffer_index(buffer_index),
- timestamp(timestamp) {}
-
-ArcGpuVideoDecodeAccelerator::InputBufferInfo::InputBufferInfo() = default;
-
-ArcGpuVideoDecodeAccelerator::InputBufferInfo::InputBufferInfo(
- InputBufferInfo&& other) = default;
-
-ArcGpuVideoDecodeAccelerator::InputBufferInfo::~InputBufferInfo() = default;
-
-ArcGpuVideoDecodeAccelerator::OutputBufferInfo::OutputBufferInfo() = default;
-
-ArcGpuVideoDecodeAccelerator::OutputBufferInfo::OutputBufferInfo(
- OutputBufferInfo&& other) = default;
-
-ArcGpuVideoDecodeAccelerator::OutputBufferInfo::~OutputBufferInfo() = default;
-
-ArcGpuVideoDecodeAccelerator::ArcGpuVideoDecodeAccelerator(
- const gpu::GpuPreferences& gpu_preferences)
- : arc_client_(nullptr),
- next_bitstream_buffer_id_(0),
- output_pixel_format_(media::PIXEL_FORMAT_UNKNOWN),
- output_buffer_size_(0),
- requested_num_of_output_buffers_(0),
- gpu_preferences_(gpu_preferences) {}
-
-ArcGpuVideoDecodeAccelerator::~ArcGpuVideoDecodeAccelerator() {
- DCHECK(thread_checker_.CalledOnValidThread());
- if (vda_) {
- client_count_--;
- }
-}
-
-ArcVideoAccelerator::Result ArcGpuVideoDecodeAccelerator::Initialize(
- const Config& config,
- ArcVideoAccelerator::Client* client) {
- auto result = InitializeTask(config, client);
- // Report initialization status to UMA.
- UMA_HISTOGRAM_ENUMERATION(
- "Media.ArcGpuVideoDecodeAccelerator.InitializeResult", result,
- RESULT_MAX);
- return result;
-}
-
-ArcVideoAccelerator::Result ArcGpuVideoDecodeAccelerator::InitializeTask(
- const Config& config,
- ArcVideoAccelerator::Client* client) {
- DVLOG(5) << "Initialize(device=" << config.device_type
- << ", input_pixel_format=" << config.input_pixel_format
- << ", num_input_buffers=" << config.num_input_buffers << ")";
- DCHECK(thread_checker_.CalledOnValidThread());
- if (config.device_type != Config::DEVICE_DECODER)
- return INVALID_ARGUMENT;
- DCHECK(client);
-
- if (arc_client_) {
- DLOG(ERROR) << "Re-Initialize() is not allowed";
- return ILLEGAL_STATE;
- }
-
- if (client_count_ >= kMaxConcurrentClients) {
- LOG(WARNING) << "Reject to Initialize() due to too many clients: "
- << client_count_;
- return INSUFFICIENT_RESOURCES;
- }
-
- arc_client_ = client;
-
- if (config.num_input_buffers > kMaxBufferCount) {
- DLOG(ERROR) << "Request too many buffers: " << config.num_input_buffers;
- return INVALID_ARGUMENT;
- }
- input_buffer_info_.resize(config.num_input_buffers);
-
- media::VideoDecodeAccelerator::Config vda_config;
- switch (config.input_pixel_format) {
- case HAL_PIXEL_FORMAT_H264:
- vda_config.profile = media::H264PROFILE_MAIN;
- break;
- case HAL_PIXEL_FORMAT_VP8:
- vda_config.profile = media::VP8PROFILE_ANY;
- break;
- case HAL_PIXEL_FORMAT_VP9:
- vda_config.profile = media::VP9PROFILE_PROFILE0;
- break;
- default:
- DLOG(ERROR) << "Unsupported input format: " << config.input_pixel_format;
- return INVALID_ARGUMENT;
- }
- vda_config.output_mode =
- media::VideoDecodeAccelerator::Config::OutputMode::IMPORT;
-
- auto vda_factory = media::GpuVideoDecodeAcceleratorFactory::CreateWithNoGL();
- vda_ = vda_factory->CreateVDA(
- this, vda_config, gpu::GpuDriverBugWorkarounds(), gpu_preferences_);
- if (!vda_) {
- DLOG(ERROR) << "Failed to create VDA.";
- return PLATFORM_FAILURE;
- }
-
- client_count_++;
- DVLOG(5) << "Number of concurrent ArcVideoAccelerator clients: "
- << client_count_;
-
- return SUCCESS;
-}
-
-void ArcGpuVideoDecodeAccelerator::SetNumberOfOutputBuffers(size_t number) {
- DVLOG(5) << "SetNumberOfOutputBuffers(" << number << ")";
- DCHECK(thread_checker_.CalledOnValidThread());
- if (!vda_) {
- DLOG(ERROR) << "VDA not initialized";
- return;
- }
-
- if (number > kMaxBufferCount) {
- DLOG(ERROR) << "Too many buffers: " << number;
- arc_client_->OnError(INVALID_ARGUMENT);
- return;
- }
-
- std::vector<media::PictureBuffer> buffers;
- for (size_t id = 0; id < number; ++id) {
- // TODO(owenlin): Make sure the |coded_size| is what we want.
- buffers.push_back(
- media::PictureBuffer(base::checked_cast<int32_t>(id), coded_size_));
- }
- vda_->AssignPictureBuffers(buffers);
-
- buffers_pending_import_.clear();
- buffers_pending_import_.resize(number);
-}
-
-void ArcGpuVideoDecodeAccelerator::BindSharedMemory(PortType port,
- uint32_t index,
- base::ScopedFD ashmem_fd,
- off_t offset,
- size_t length) {
- DVLOG(5) << "ArcGVDA::BindSharedMemory, offset: " << offset
- << ", length: " << length;
- DCHECK(thread_checker_.CalledOnValidThread());
- if (!vda_) {
- DLOG(ERROR) << "VDA not initialized";
- return;
- }
-
- if (port != PORT_INPUT) {
- DLOG(ERROR) << "SharedBuffer is only supported for input";
- arc_client_->OnError(INVALID_ARGUMENT);
- return;
- }
- if (!ValidatePortAndIndex(port, index)) {
- arc_client_->OnError(INVALID_ARGUMENT);
- return;
- }
- InputBufferInfo* input_info = &input_buffer_info_[index];
- input_info->handle = std::move(ashmem_fd);
- input_info->offset = offset;
- input_info->length = length;
-}
-
-bool ArcGpuVideoDecodeAccelerator::VerifyDmabuf(
- const base::ScopedFD& dmabuf_fd,
- const std::vector<::arc::ArcVideoAcceleratorDmabufPlane>& dmabuf_planes)
- const {
- size_t num_planes = media::VideoFrame::NumPlanes(output_pixel_format_);
- if (dmabuf_planes.size() != num_planes) {
- DLOG(ERROR) << "Invalid number of dmabuf planes passed: "
- << dmabuf_planes.size() << ", expected: " << num_planes;
- return false;
- }
-
- off_t size = lseek(dmabuf_fd.get(), 0, SEEK_END);
- lseek(dmabuf_fd.get(), 0, SEEK_SET);
- if (size < 0) {
- DPLOG(ERROR) << "fail to find the size of dmabuf";
- return false;
- }
-
- size_t i = 0;
- for (const auto& plane : dmabuf_planes) {
- DVLOG(4) << "Plane " << i << ", offset: " << plane.offset
- << ", stride: " << plane.stride;
-
- size_t rows =
- media::VideoFrame::Rows(i, output_pixel_format_, coded_size_.height());
- base::CheckedNumeric<off_t> current_size(plane.offset);
- current_size += base::CheckMul(plane.stride, rows);
-
- if (!current_size.IsValid() || current_size.ValueOrDie() > size) {
- DLOG(ERROR) << "Invalid strides/offsets";
- return false;
- }
-
- ++i;
- }
-
- return true;
-}
-
-void ArcGpuVideoDecodeAccelerator::BindDmabuf(
- PortType port,
- uint32_t index,
- base::ScopedFD dmabuf_fd,
- const std::vector<::arc::ArcVideoAcceleratorDmabufPlane>& dmabuf_planes) {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- if (!vda_) {
- DLOG(ERROR) << "VDA not initialized";
- return;
- }
-
- if (port != PORT_OUTPUT) {
- DLOG(ERROR) << "Dmabuf is only supported for input";
- arc_client_->OnError(INVALID_ARGUMENT);
- return;
- }
- if (!ValidatePortAndIndex(port, index)) {
- arc_client_->OnError(INVALID_ARGUMENT);
- return;
- }
- if (!VerifyDmabuf(dmabuf_fd, dmabuf_planes)) {
- arc_client_->OnError(INVALID_ARGUMENT);
- return;
- }
-
- OutputBufferInfo& info = buffers_pending_import_[index];
- info.handle = std::move(dmabuf_fd);
- info.planes = dmabuf_planes;
-}
-
-void ArcGpuVideoDecodeAccelerator::UseBuffer(PortType port,
- uint32_t index,
- const BufferMetadata& metadata) {
- DVLOG(5) << "UseBuffer(port=" << port << ", index=" << index
- << ", metadata=(bytes_used=" << metadata.bytes_used
- << ", timestamp=" << metadata.timestamp << ")";
- DCHECK(thread_checker_.CalledOnValidThread());
- if (!vda_) {
- DLOG(ERROR) << "VDA not initialized";
- return;
- }
- if (!ValidatePortAndIndex(port, index)) {
- arc_client_->OnError(INVALID_ARGUMENT);
- return;
- }
- switch (port) {
- case PORT_INPUT: {
- InputBufferInfo* input_info = &input_buffer_info_[index];
- int32_t bitstream_buffer_id = next_bitstream_buffer_id_;
- // Mask against 30 bits, to avoid (undefined) wraparound on signed
- // integer.
- next_bitstream_buffer_id_ = (next_bitstream_buffer_id_ + 1) & 0x3FFFFFFF;
- int dup_fd = HANDLE_EINTR(dup(input_info->handle.get()));
- if (dup_fd < 0) {
- DLOG(ERROR) << "dup() failed.";
- arc_client_->OnError(PLATFORM_FAILURE);
- return;
- }
- CreateInputRecord(bitstream_buffer_id, index, metadata.timestamp);
- // TODO(rockot): Pass GUIDs through Mojo. https://crbug.com/713763.
- // TODO(rockot): This fd comes from a mojo::ScopedHandle in
- // GpuArcVideoService::BindSharedMemory. That should be passed through,
- // rather than pulling out the fd. https://crbug.com/713763.
- // TODO(rockot): Pass through a real size rather than |0|.
- base::UnguessableToken guid = base::UnguessableToken::Create();
- vda_->Decode(media::BitstreamBuffer(
- bitstream_buffer_id,
- base::SharedMemoryHandle(base::FileDescriptor(dup_fd, true), 0u,
- guid),
- metadata.bytes_used, input_info->offset));
- break;
- }
- case PORT_OUTPUT: {
- // is_valid() is true for the first time the buffer is passed to the VDA.
- // In that case, VDA needs to import the buffer first.
- OutputBufferInfo& info = buffers_pending_import_[index];
- if (info.handle.is_valid()) {
- gfx::GpuMemoryBufferHandle handle;
-#if defined(USE_OZONE)
- handle.native_pixmap_handle.fds.emplace_back(
- base::FileDescriptor(info.handle.release(), true));
- for (const auto& plane : info.planes) {
- handle.native_pixmap_handle.planes.emplace_back(plane.stride,
- plane.offset, 0, 0);
- }
-#endif
- vda_->ImportBufferForPicture(index, handle);
- } else {
- vda_->ReusePictureBuffer(index);
- }
- break;
- }
- default:
- NOTREACHED();
- }
-}
-
-void ArcGpuVideoDecodeAccelerator::Reset() {
- DCHECK(thread_checker_.CalledOnValidThread());
- if (!vda_) {
- DLOG(ERROR) << "VDA not initialized";
- return;
- }
- vda_->Reset();
-}
-
-void ArcGpuVideoDecodeAccelerator::Flush() {
- DCHECK(thread_checker_.CalledOnValidThread());
- if (!vda_) {
- DLOG(ERROR) << "VDA not initialized";
- return;
- }
- vda_->Flush();
-}
-
-void ArcGpuVideoDecodeAccelerator::ProvidePictureBuffers(
- uint32_t requested_num_of_buffers,
- media::VideoPixelFormat output_pixel_format,
- uint32_t textures_per_buffer,
- const gfx::Size& dimensions,
- uint32_t texture_target) {
- DVLOG(5) << "ProvidePictureBuffers("
- << "requested_num_of_buffers=" << requested_num_of_buffers
- << ", dimensions=" << dimensions.ToString() << ")";
- DCHECK(thread_checker_.CalledOnValidThread());
- coded_size_ = dimensions;
-
- // By default, use an empty rect to indicate the visible rectangle is not
- // available.
- visible_rect_ = gfx::Rect();
- if ((output_pixel_format_ != media::PIXEL_FORMAT_UNKNOWN) &&
- (output_pixel_format_ != output_pixel_format)) {
- arc_client_->OnError(PLATFORM_FAILURE);
- return;
- }
- output_pixel_format_ = output_pixel_format;
- requested_num_of_output_buffers_ = requested_num_of_buffers;
- output_buffer_size_ =
- media::VideoFrame::AllocationSize(output_pixel_format_, coded_size_);
-
- NotifyOutputFormatChanged();
-}
-
-void ArcGpuVideoDecodeAccelerator::NotifyOutputFormatChanged() {
- VideoFormat video_format;
- switch (output_pixel_format_) {
- case media::PIXEL_FORMAT_I420:
- case media::PIXEL_FORMAT_YV12:
- case media::PIXEL_FORMAT_NV12:
- case media::PIXEL_FORMAT_NV21:
- // HAL_PIXEL_FORMAT_YCbCr_420_888 is the flexible pixel format in Android
- // which handles all 420 formats, with both orderings of chroma (CbCr and
- // CrCb) as well as planar and semi-planar layouts.
- video_format.pixel_format = HAL_PIXEL_FORMAT_YCbCr_420_888;
- break;
- case media::PIXEL_FORMAT_ARGB:
- video_format.pixel_format = HAL_PIXEL_FORMAT_BGRA_8888;
- break;
- default:
- DLOG(ERROR) << "Format not supported: " << output_pixel_format_;
- arc_client_->OnError(PLATFORM_FAILURE);
- return;
- }
- video_format.buffer_size = output_buffer_size_;
- video_format.min_num_buffers = requested_num_of_output_buffers_;
- video_format.coded_width = coded_size_.width();
- video_format.coded_height = coded_size_.height();
- video_format.crop_top = visible_rect_.y();
- video_format.crop_left = visible_rect_.x();
- video_format.crop_width = visible_rect_.width();
- video_format.crop_height = visible_rect_.height();
- arc_client_->OnOutputFormatChanged(video_format);
-}
-
-void ArcGpuVideoDecodeAccelerator::DismissPictureBuffer(
- int32_t picture_buffer) {
- // no-op
-}
-
-void ArcGpuVideoDecodeAccelerator::PictureReady(const media::Picture& picture) {
- DVLOG(5) << "PictureReady(picture_buffer_id=" << picture.picture_buffer_id()
- << ", bitstream_buffer_id=" << picture.bitstream_buffer_id();
- DCHECK(thread_checker_.CalledOnValidThread());
-
- // Handle visible size change.
- if (visible_rect_ != picture.visible_rect()) {
- DVLOG(5) << "visible size changed: " << picture.visible_rect().ToString();
- visible_rect_ = picture.visible_rect();
- NotifyOutputFormatChanged();
- }
-
- InputRecord* input_record = FindInputRecord(picture.bitstream_buffer_id());
- if (input_record == nullptr) {
- DLOG(ERROR) << "Cannot find for bitstream buffer id: "
- << picture.bitstream_buffer_id();
- arc_client_->OnError(PLATFORM_FAILURE);
- return;
- }
-
- BufferMetadata metadata;
- metadata.timestamp = input_record->timestamp;
- metadata.bytes_used = output_buffer_size_;
- arc_client_->OnBufferDone(PORT_OUTPUT, picture.picture_buffer_id(), metadata);
-}
-
-void ArcGpuVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer(
- int32_t bitstream_buffer_id) {
- DVLOG(5) << "NotifyEndOfBitstreamBuffer(" << bitstream_buffer_id << ")";
- DCHECK(thread_checker_.CalledOnValidThread());
- InputRecord* input_record = FindInputRecord(bitstream_buffer_id);
- if (input_record == nullptr) {
- arc_client_->OnError(PLATFORM_FAILURE);
- return;
- }
- arc_client_->OnBufferDone(PORT_INPUT, input_record->buffer_index,
- BufferMetadata());
-}
-
-void ArcGpuVideoDecodeAccelerator::NotifyFlushDone() {
- DCHECK(thread_checker_.CalledOnValidThread());
- arc_client_->OnFlushDone();
-}
-
-void ArcGpuVideoDecodeAccelerator::NotifyResetDone() {
- DCHECK(thread_checker_.CalledOnValidThread());
- arc_client_->OnResetDone();
-}
-
-static ArcVideoAccelerator::Result ConvertErrorCode(
- media::VideoDecodeAccelerator::Error error) {
- switch (error) {
- case media::VideoDecodeAccelerator::ILLEGAL_STATE:
- return ArcVideoAccelerator::ILLEGAL_STATE;
- case media::VideoDecodeAccelerator::INVALID_ARGUMENT:
- return ArcVideoAccelerator::INVALID_ARGUMENT;
- case media::VideoDecodeAccelerator::UNREADABLE_INPUT:
- return ArcVideoAccelerator::UNREADABLE_INPUT;
- case media::VideoDecodeAccelerator::PLATFORM_FAILURE:
- return ArcVideoAccelerator::PLATFORM_FAILURE;
- default:
- DLOG(ERROR) << "Unknown error: " << error;
- return ArcVideoAccelerator::PLATFORM_FAILURE;
- }
-}
-
-void ArcGpuVideoDecodeAccelerator::NotifyError(
- media::VideoDecodeAccelerator::Error error) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DLOG(ERROR) << "Error notified: " << error;
- arc_client_->OnError(ConvertErrorCode(error));
-}
-
-void ArcGpuVideoDecodeAccelerator::CreateInputRecord(
- int32_t bitstream_buffer_id,
- uint32_t buffer_index,
- int64_t timestamp) {
- input_records_.push_front(
- InputRecord(bitstream_buffer_id, buffer_index, timestamp));
-
- // The same value copied from media::GpuVideoDecoder. The input record is
- // needed when the input buffer or the corresponding output buffer are
- // returned from VDA. However there is no guarantee how much buffers will be
- // kept in the VDA. We kept the last |kMaxNumberOfInputRecords| in
- // |input_records_| and drop the others.
- const size_t kMaxNumberOfInputRecords = 128;
- if (input_records_.size() > kMaxNumberOfInputRecords)
- input_records_.pop_back();
-}
-
-ArcGpuVideoDecodeAccelerator::InputRecord*
-ArcGpuVideoDecodeAccelerator::FindInputRecord(int32_t bitstream_buffer_id) {
- for (auto& record : input_records_) {
- if (record.bitstream_buffer_id == bitstream_buffer_id)
- return &record;
- }
- return nullptr;
-}
-
-bool ArcGpuVideoDecodeAccelerator::ValidatePortAndIndex(PortType port,
- uint32_t index) const {
- switch (port) {
- case PORT_INPUT:
- if (index >= input_buffer_info_.size()) {
- DLOG(ERROR) << "Invalid index: " << index;
- return false;
- }
- return true;
- case PORT_OUTPUT:
- if (index >= buffers_pending_import_.size()) {
- DLOG(ERROR) << "Invalid index: " << index;
- return false;
- }
- return true;
- default:
- DLOG(ERROR) << "Invalid port: " << port;
- return false;
- }
-}
-
-} // namespace arc
-} // namespace chromeos
« no previous file with comments | « chrome/gpu/arc_gpu_video_decode_accelerator.h ('k') | chrome/gpu/arc_video_accelerator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698