blob: 44ce6af47757bc9621684d607f6119f16b404661 [file] [log] [blame]
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/gpu/chromeos/image_processor_backend.h"
#include <memory>
#include <ostream>
#include <sstream>
#include "base/functional/bind.h"
#include "base/notimplemented.h"
#include "base/strings/stringprintf.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/task_traits.h"
#include "media/gpu/chromeos/video_frame_resource.h"
#include "media/gpu/macros.h"
namespace media {
namespace {
template <class T>
std::string VectorToString(const std::vector<T>& vec) {
std::ostringstream result;
std::string delim;
result << "[";
for (const T& v : vec) {
result << delim << v;
if (delim.size() == 0)
delim = ", ";
}
result << "]";
return result.str();
}
// Used to adapt FrameResourceReadyCB to FrameReadyCB. The incoming
// FrameResource gets to converted to VideoFrame and passed to |callback|.
void FrameResourceToFrameReadyCB(ImageProcessorBackend::FrameReadyCB callback,
scoped_refptr<FrameResource> frame) {
VideoFrameResource* video_frame_resource = frame->AsVideoFrameResource();
// This callback only gets called when |frame| is a VideoFrameResource.
CHECK(!!video_frame_resource);
std::move(callback).Run(video_frame_resource->GetMutableVideoFrame());
}
} // namespace
ImageProcessorBackend::PortConfig::PortConfig(const PortConfig&) = default;
ImageProcessorBackend::PortConfig::PortConfig(
Fourcc fourcc,
const gfx::Size& size,
const std::vector<ColorPlaneLayout>& planes,
const gfx::Rect& visible_rect,
VideoFrame::StorageType storage_type)
: fourcc(fourcc),
size(size),
planes(planes),
visible_rect(visible_rect),
storage_type(storage_type) {}
ImageProcessorBackend::PortConfig::~PortConfig() = default;
std::string ImageProcessorBackend::PortConfig::ToString() const {
return base::StringPrintf(
"PortConfig(format:%s, size:%s, planes: %s, visible_rect:%s, "
"storage_types:%s)",
fourcc.ToString().c_str(), size.ToString().c_str(),
VectorToString(planes).c_str(), visible_rect.ToString().c_str(),
VideoFrame::StorageTypeToString(storage_type).c_str());
}
ImageProcessorBackend::ImageProcessorBackend(
const PortConfig& input_config,
const PortConfig& output_config,
OutputMode output_mode,
ErrorCB error_cb,
scoped_refptr<base::SequencedTaskRunner> backend_task_runner)
: input_config_(input_config),
output_config_(output_config),
output_mode_(output_mode),
error_cb_(error_cb),
backend_task_runner_(std::move(backend_task_runner)) {
DETACH_FROM_SEQUENCE(backend_sequence_checker_);
}
ImageProcessorBackend::~ImageProcessorBackend() = default;
void ImageProcessorBackend::Destroy() {
DCHECK_CALLED_ON_VALID_SEQUENCE(backend_sequence_checker_);
delete this;
}
void ImageProcessorBackend::Process(scoped_refptr<VideoFrame> input_frame,
scoped_refptr<VideoFrame> output_frame,
FrameReadyCB cb) {
// Wraps ProcessFrame.
DVLOGF(4);
DCHECK_CALLED_ON_VALID_SEQUENCE(backend_sequence_checker_);
ProcessFrame(VideoFrameResource::Create(std::move(input_frame)),
VideoFrameResource::Create(std::move(output_frame)),
base::BindOnce(&FrameResourceToFrameReadyCB, std::move(cb)));
}
void ImageProcessorBackend::ProcessLegacyFrame(
scoped_refptr<FrameResource> frame,
LegacyFrameResourceReadyCB cb) {
DCHECK_CALLED_ON_VALID_SEQUENCE(backend_sequence_checker_);
NOTIMPLEMENTED();
}
void ImageProcessorBackend::Reset() {
DVLOGF(3);
DCHECK_CALLED_ON_VALID_SEQUENCE(backend_sequence_checker_);
// Do nothing as the default action.
}
bool ImageProcessorBackend::needs_linear_output_buffers() const {
return false;
}
bool ImageProcessorBackend::supports_incoherent_buffers() const {
return false;
}
} // namespace media
namespace std {
void default_delete<media::ImageProcessorBackend>::operator()(
media::ImageProcessorBackend* ptr) const {
CHECK(ptr->backend_task_runner_);
if (!ptr->backend_task_runner_->RunsTasksInCurrentSequence()) {
// base::Unretained() is safe because ImageProcessorBackend::Destroy() *is*
// the thing that destroys *|ptr|.
ptr->backend_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&media::ImageProcessorBackend::Destroy,
base::Unretained(ptr)));
return;
}
ptr->Destroy();
}
} // namespace std