Commit 39e7de24 authored by Dan Sanders's avatar Dan Sanders Committed by Commit Bot

[media] Log to MediaLog from VTVDA.

This moves logging of bitstream errors that were previously in the GPU
log to the media log.

To support async destruction correctly, VdaVideoDecoder now implements
the MediaLog interface and handles thread hopping.

Also includes some additional cleanups in VTVDA: improved log messages,
increase the number of requested picture buffers to match recent changes
in DXVAVD, and returns no supported profiles if VideoToolbox fails to
initialize.

Bug: 522298
Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win_optional_gpu_tests_rel
Change-Id: I7f13deb9e92fdeeeac60479e17081e72c5f22066
Reviewed-on: https://chromium-review.googlesource.com/1038609
Commit-Queue: Dan Sanders <sandersd@chromium.org>
Reviewed-by: default avatarXiaohan Wang <xhwang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#556164}
parent 264eba9c
......@@ -123,7 +123,8 @@ GpuVideoDecodeAcceleratorFactory::CreateVDA(
VideoDecodeAccelerator::Client* client,
const VideoDecodeAccelerator::Config& config,
const gpu::GpuDriverBugWorkarounds& workarounds,
const gpu::GpuPreferences& gpu_preferences) {
const gpu::GpuPreferences& gpu_preferences,
MediaLog* media_log) {
DCHECK(thread_checker_.CalledOnValidThread());
if (gpu_preferences.disable_accelerated_video_decode)
......@@ -135,7 +136,8 @@ GpuVideoDecodeAcceleratorFactory::CreateVDA(
// in GetDecoderCapabilities() above.
using CreateVDAFp = std::unique_ptr<VideoDecodeAccelerator> (
GpuVideoDecodeAcceleratorFactory::*)(const gpu::GpuDriverBugWorkarounds&,
const gpu::GpuPreferences&) const;
const gpu::GpuPreferences&,
MediaLog* media_log) const;
const CreateVDAFp create_vda_fps[] = {
#if defined(OS_WIN)
&GpuVideoDecodeAcceleratorFactory::CreateDXVAVDA,
......@@ -158,7 +160,7 @@ GpuVideoDecodeAcceleratorFactory::CreateVDA(
std::unique_ptr<VideoDecodeAccelerator> vda;
for (const auto& create_vda_function : create_vda_fps) {
vda = (this->*create_vda_function)(workarounds, gpu_preferences);
vda = (this->*create_vda_function)(workarounds, gpu_preferences, media_log);
if (vda && vda->Initialize(config, client))
return vda;
}
......@@ -170,7 +172,8 @@ GpuVideoDecodeAcceleratorFactory::CreateVDA(
std::unique_ptr<VideoDecodeAccelerator>
GpuVideoDecodeAcceleratorFactory::CreateDXVAVDA(
const gpu::GpuDriverBugWorkarounds& workarounds,
const gpu::GpuPreferences& gpu_preferences) const {
const gpu::GpuPreferences& gpu_preferences,
MediaLog* media_log) const {
std::unique_ptr<VideoDecodeAccelerator> decoder;
DVLOG(0) << "Initializing DXVA HW decoder for windows.";
decoder.reset(new DXVAVideoDecodeAccelerator(
......@@ -184,7 +187,8 @@ GpuVideoDecodeAcceleratorFactory::CreateDXVAVDA(
std::unique_ptr<VideoDecodeAccelerator>
GpuVideoDecodeAcceleratorFactory::CreateV4L2VDA(
const gpu::GpuDriverBugWorkarounds& workarounds,
const gpu::GpuPreferences& gpu_preferences) const {
const gpu::GpuPreferences& gpu_preferences,
MediaLog* media_log) const {
std::unique_ptr<VideoDecodeAccelerator> decoder;
scoped_refptr<V4L2Device> device = V4L2Device::Create();
if (device.get()) {
......@@ -198,7 +202,8 @@ GpuVideoDecodeAcceleratorFactory::CreateV4L2VDA(
std::unique_ptr<VideoDecodeAccelerator>
GpuVideoDecodeAcceleratorFactory::CreateV4L2SVDA(
const gpu::GpuDriverBugWorkarounds& workarounds,
const gpu::GpuPreferences& gpu_preferences) const {
const gpu::GpuPreferences& gpu_preferences,
MediaLog* media_log) const {
std::unique_ptr<VideoDecodeAccelerator> decoder;
scoped_refptr<V4L2Device> device = V4L2Device::Create();
if (device.get()) {
......@@ -214,7 +219,8 @@ GpuVideoDecodeAcceleratorFactory::CreateV4L2SVDA(
std::unique_ptr<VideoDecodeAccelerator>
GpuVideoDecodeAcceleratorFactory::CreateVaapiVDA(
const gpu::GpuDriverBugWorkarounds& workarounds,
const gpu::GpuPreferences& gpu_preferences) const {
const gpu::GpuPreferences& gpu_preferences,
MediaLog* media_log) const {
std::unique_ptr<VideoDecodeAccelerator> decoder;
decoder.reset(new VaapiVideoDecodeAccelerator(make_context_current_cb_,
bind_image_cb_));
......@@ -226,9 +232,10 @@ GpuVideoDecodeAcceleratorFactory::CreateVaapiVDA(
std::unique_ptr<VideoDecodeAccelerator>
GpuVideoDecodeAcceleratorFactory::CreateVTVDA(
const gpu::GpuDriverBugWorkarounds& workarounds,
const gpu::GpuPreferences& gpu_preferences) const {
const gpu::GpuPreferences& gpu_preferences,
MediaLog* media_log) const {
std::unique_ptr<VideoDecodeAccelerator> decoder;
decoder.reset(new VTVideoDecodeAccelerator(bind_image_cb_));
decoder.reset(new VTVideoDecodeAccelerator(bind_image_cb_, media_log));
return decoder;
}
#endif
......@@ -237,7 +244,8 @@ GpuVideoDecodeAcceleratorFactory::CreateVTVDA(
std::unique_ptr<VideoDecodeAccelerator>
GpuVideoDecodeAcceleratorFactory::CreateAndroidVDA(
const gpu::GpuDriverBugWorkarounds& workarounds,
const gpu::GpuPreferences& gpu_preferences) const {
const gpu::GpuPreferences& gpu_preferences,
MediaLog* media_log) const {
std::unique_ptr<VideoDecodeAccelerator> decoder;
decoder.reset(new AndroidVideoDecodeAccelerator(
AVDACodecAllocator::GetInstance(base::ThreadTaskRunnerHandle::Get()),
......
......@@ -32,6 +32,8 @@ class ContextGroup;
namespace media {
class MediaLog;
class MEDIA_GPU_EXPORT GpuVideoDecodeAcceleratorFactory {
public:
~GpuVideoDecodeAcceleratorFactory();
......@@ -80,7 +82,8 @@ class MEDIA_GPU_EXPORT GpuVideoDecodeAcceleratorFactory {
VideoDecodeAccelerator::Client* client,
const VideoDecodeAccelerator::Config& config,
const gpu::GpuDriverBugWorkarounds& workarounds,
const gpu::GpuPreferences& gpu_preferences);
const gpu::GpuPreferences& gpu_preferences,
MediaLog* media_log = nullptr);
private:
GpuVideoDecodeAcceleratorFactory(
......@@ -93,33 +96,40 @@ class MEDIA_GPU_EXPORT GpuVideoDecodeAcceleratorFactory {
#if defined(OS_WIN)
std::unique_ptr<VideoDecodeAccelerator> CreateD3D11VDA(
const gpu::GpuDriverBugWorkarounds& workarounds,
const gpu::GpuPreferences& gpu_preferences) const;
const gpu::GpuPreferences& gpu_preferences,
MediaLog* media_log) const;
std::unique_ptr<VideoDecodeAccelerator> CreateDXVAVDA(
const gpu::GpuDriverBugWorkarounds& workarounds,
const gpu::GpuPreferences& gpu_preferences) const;
const gpu::GpuPreferences& gpu_preferences,
MediaLog* media_log) const;
#endif
#if BUILDFLAG(USE_V4L2_CODEC)
std::unique_ptr<VideoDecodeAccelerator> CreateV4L2VDA(
const gpu::GpuDriverBugWorkarounds& workarounds,
const gpu::GpuPreferences& gpu_preferences) const;
const gpu::GpuPreferences& gpu_preferences,
MediaLog* media_log) const;
std::unique_ptr<VideoDecodeAccelerator> CreateV4L2SVDA(
const gpu::GpuDriverBugWorkarounds& workarounds,
const gpu::GpuPreferences& gpu_preferences) const;
const gpu::GpuPreferences& gpu_preferences,
MediaLog* media_log) const;
#endif
#if BUILDFLAG(USE_VAAPI)
std::unique_ptr<VideoDecodeAccelerator> CreateVaapiVDA(
const gpu::GpuDriverBugWorkarounds& workarounds,
const gpu::GpuPreferences& gpu_preferences) const;
const gpu::GpuPreferences& gpu_preferences,
MediaLog* media_log) const;
#endif
#if defined(OS_MACOSX)
std::unique_ptr<VideoDecodeAccelerator> CreateVTVDA(
const gpu::GpuDriverBugWorkarounds& workarounds,
const gpu::GpuPreferences& gpu_preferences) const;
const gpu::GpuPreferences& gpu_preferences,
MediaLog* media_log) const;
#endif
#if defined(OS_ANDROID)
std::unique_ptr<VideoDecodeAccelerator> CreateAndroidVDA(
const gpu::GpuDriverBugWorkarounds& workarounds,
const gpu::GpuPreferences& gpu_preferences) const;
const gpu::GpuPreferences& gpu_preferences,
MediaLog* media_log) const;
#endif
const GetGLContextCallback get_gl_context_cb_;
......
......@@ -64,6 +64,7 @@ std::unique_ptr<VideoDecodeAccelerator> CreateAndInitializeVda(
const gpu::GpuDriverBugWorkarounds& gpu_workarounds,
scoped_refptr<CommandBufferHelper> command_buffer_helper,
VideoDecodeAccelerator::Client* client,
MediaLog* media_log,
const VideoDecodeAccelerator::Config& config) {
std::unique_ptr<GpuVideoDecodeAcceleratorFactory> factory =
GpuVideoDecodeAcceleratorFactory::Create(
......@@ -75,7 +76,8 @@ std::unique_ptr<VideoDecodeAccelerator> CreateAndInitializeVda(
// Note: GpuVideoDecodeAcceleratorFactory may create and initialize more than
// one VDA. It is therefore important that VDAs do not call client methods
// from Initialize().
return factory->CreateVDA(client, config, gpu_workarounds, gpu_preferences);
return factory->CreateVDA(client, config, gpu_workarounds, gpu_preferences,
media_log);
}
bool IsProfileSupported(
......@@ -304,7 +306,7 @@ void VdaVideoDecoder::InitializeOnGpuThread() {
// Create and initialize the VDA.
vda_ = std::move(create_and_initialize_vda_cb_)
.Run(command_buffer_helper, this, vda_config);
.Run(command_buffer_helper, this, this, vda_config);
if (!vda_) {
parent_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&VdaVideoDecoder::InitializeDone,
......@@ -680,6 +682,29 @@ void VdaVideoDecoder::ReusePictureBuffer(int32_t picture_buffer_id) {
vda_->ReusePictureBuffer(picture_buffer_id);
}
void VdaVideoDecoder::AddEvent(std::unique_ptr<MediaLogEvent> event) {
DVLOG(1) << __func__;
if (parent_task_runner_->BelongsToCurrentThread()) {
AddEventOnParentThread(std::move(event));
return;
}
// Hop to the parent thread to be sure we don't call into |media_log_| after
// Destroy() returns.
parent_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&VdaVideoDecoder::AddEventOnParentThread,
parent_weak_this_, std::move(event)));
}
void VdaVideoDecoder::AddEventOnParentThread(
std::unique_ptr<MediaLogEvent> event) {
DVLOG(1) << __func__;
DCHECK(parent_task_runner_->BelongsToCurrentThread());
media_log_->AddEvent(std::move(event));
}
void VdaVideoDecoder::EnterErrorState() {
DVLOG(1) << __func__;
DCHECK(parent_task_runner_->BelongsToCurrentThread());
......
......@@ -18,6 +18,7 @@
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/time/time.h"
#include "media/base/media_log.h"
#include "media/base/video_decoder.h"
#include "media/gpu/command_buffer_helper.h"
#include "media/gpu/ipc/service/picture_buffer_manager.h"
......@@ -33,12 +34,11 @@ struct GpuPreferences;
namespace media {
class MediaLog;
// Implements the VideoDecoder interface backed by a VideoDecodeAccelerator.
// This class expects to run in the GPU process via MojoVideoDecoder.
class VdaVideoDecoder : public VideoDecoder,
public VideoDecodeAccelerator::Client {
public VideoDecodeAccelerator::Client,
public MediaLog {
public:
using GetStubCB = base::RepeatingCallback<gpu::CommandBufferStub*()>;
using CreatePictureBufferManagerCB =
......@@ -50,6 +50,7 @@ class VdaVideoDecoder : public VideoDecoder,
base::OnceCallback<std::unique_ptr<VideoDecodeAccelerator>(
scoped_refptr<CommandBufferHelper>,
VideoDecodeAccelerator::Client*,
MediaLog*,
const VideoDecodeAccelerator::Config&)>;
using GetVdaCapabilitiesCB =
base::OnceCallback<VideoDecodeAccelerator::Capabilities(
......@@ -109,6 +110,9 @@ class VdaVideoDecoder : public VideoDecoder,
bool CanReadWithoutStalling() const override;
int GetMaxDecodeRequests() const override;
// media::MediaLog implementation.
void AddEvent(std::unique_ptr<MediaLogEvent> event) override;
private:
void Destroy() override;
......@@ -150,6 +154,7 @@ class VdaVideoDecoder : public VideoDecoder,
gfx::Size texture_size,
GLenum texture_target);
void ReusePictureBuffer(int32_t picture_buffer_id);
void AddEventOnParentThread(std::unique_ptr<MediaLogEvent> event);
// Error handling.
void EnterErrorState();
......
......@@ -215,6 +215,7 @@ class VdaVideoDecoderTest : public testing::Test {
std::unique_ptr<VideoDecodeAccelerator> CreateAndInitializeVda(
scoped_refptr<CommandBufferHelper> command_buffer_helper,
VideoDecodeAccelerator::Client* client,
MediaLog* media_log,
const VideoDecodeAccelerator::Config& config) {
DCHECK(owned_vda_);
if (!owned_vda_->Initialize(config, client))
......
......@@ -20,6 +20,7 @@
#include "base/threading/thread.h"
#include "base/threading/thread_checker.h"
#include "base/trace_event/memory_dump_provider.h"
#include "media/base/media_log.h"
#include "media/gpu/gpu_video_decode_accelerator_helpers.h"
#include "media/gpu/media_gpu_export.h"
#include "media/video/h264_parser.h"
......@@ -38,7 +39,8 @@ MEDIA_GPU_EXPORT bool InitializeVideoToolbox();
class VTVideoDecodeAccelerator : public VideoDecodeAccelerator,
public base::trace_event::MemoryDumpProvider {
public:
explicit VTVideoDecodeAccelerator(const BindGLImageCallback& bind_image_cb);
VTVideoDecodeAccelerator(const BindGLImageCallback& bind_image_cb,
MediaLog* media_log);
~VTVideoDecodeAccelerator() override;
......@@ -173,6 +175,12 @@ class VTVideoDecodeAccelerator : public VideoDecodeAccelerator,
void NotifyError(Error vda_error_type,
VTVDASessionFailureType session_failure_type);
// Since |media_log_| is invalidated in Destroy() on the GPU thread, the easy
// thing to do is post to the GPU thread to use it. This helper handles the
// thread hop if necessary.
void WriteToMediaLog(MediaLog::MediaLogLevel level,
const std::string& message);
// |type| is the type of task that the flush will complete, one of TASK_FLUSH,
// TASK_RESET, or TASK_DESTROY.
void QueueFlush(TaskType type);
......@@ -193,6 +201,7 @@ class VTVideoDecodeAccelerator : public VideoDecodeAccelerator,
// GPU thread state.
//
BindGLImageCallback bind_image_cb_;
MediaLog* media_log_;
VideoDecodeAccelerator::Client* client_ = nullptr;
State state_ = STATE_DECODING;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment