Commit 8b444f9f authored by Khushal's avatar Khushal Committed by Commit Bot

media/android: Add plumbing for secure media using AImageReader.

Make sure we use the correct format/usage bits when using AImageReader
with videos requiring a secure surface.

R=liberato@chromium.org

Change-Id: I898535f38e1d2e8d1693c52e1e4c2aa01486cca8
Bug: 889328
Reviewed-on: https://chromium-review.googlesource.com/c/1428407Reviewed-by: default avatarFrank Liberato <liberato@chromium.org>
Reviewed-by: default avatarTommy Nyquist <nyquist@chromium.org>
Commit-Queue: Khushal <khushalsagar@chromium.org>
Auto-Submit: Khushal <khushalsagar@chromium.org>
Cr-Commit-Position: refs/heads/master@{#626255}
parent 9f72579d
......@@ -84,6 +84,9 @@ using pAImageReader_delete = void (*)(AImageReader* reader);
using pAImageReader_getWindow = media_status_t (*)(AImageReader* reader,
ANativeWindow** window);
using pAImageReader_getFormat = media_status_t (*)(const AImageReader* reader,
int32_t* format);
using pAImageReader_acquireLatestImageAsync =
media_status_t (*)(AImageReader* reader,
AImage** image,
......
......@@ -70,6 +70,7 @@ bool AndroidImageReader::LoadFunctions() {
LOAD_FUNCTION(libmediandk, AImageReader_newWithUsage);
LOAD_FUNCTION(libmediandk, AImageReader_setImageListener);
LOAD_FUNCTION(libmediandk, AImageReader_delete);
LOAD_FUNCTION(libmediandk, AImageReader_getFormat);
LOAD_FUNCTION(libmediandk, AImageReader_getWindow);
LOAD_FUNCTION(libmediandk, AImageReader_acquireLatestImageAsync);
......@@ -129,6 +130,12 @@ void AndroidImageReader::AImageReader_delete(AImageReader* reader) {
AImageReader_delete_(reader);
}
media_status_t AndroidImageReader::AImageReader_getFormat(
const AImageReader* reader,
int32_t* format) {
return AImageReader_getFormat_(reader, format);
}
media_status_t AndroidImageReader::AImageReader_getWindow(
AImageReader* reader,
ANativeWindow** window) {
......
......@@ -48,6 +48,8 @@ class BASE_EXPORT AndroidImageReader {
AImageReader* reader,
AImageReader_ImageListener* listener);
void AImageReader_delete(AImageReader* reader);
media_status_t AImageReader_getFormat(const AImageReader* reader,
int32_t* format);
media_status_t AImageReader_getWindow(AImageReader* reader,
ANativeWindow** window);
media_status_t AImageReader_acquireLatestImageAsync(AImageReader* reader,
......@@ -71,6 +73,7 @@ class BASE_EXPORT AndroidImageReader {
pAImageReader_newWithUsage AImageReader_newWithUsage_;
pAImageReader_setImageListener AImageReader_setImageListener_;
pAImageReader_delete AImageReader_delete_;
pAImageReader_getFormat AImageReader_getFormat_;
pAImageReader_getWindow AImageReader_getWindow_;
pAImageReader_acquireLatestImageAsync AImageReader_acquireLatestImageAsync_;
pANativeWindow_toSurface ANativeWindow_toSurface_;
......
......@@ -63,7 +63,8 @@ bool AVDAPictureBufferManager::Initialize(
1, // depth
0, // border
GL_RGBA, GL_UNSIGNED_BYTE);
texture_owner_ = TextureOwner::Create(std::move(texture));
texture_owner_ = TextureOwner::Create(std::move(texture),
TextureOwner::SecureMode::kInsecure);
if (!texture_owner_)
return false;
......
......@@ -69,7 +69,8 @@ class ImageReaderGLOwner::ScopedHardwareBufferImpl
};
ImageReaderGLOwner::ImageReaderGLOwner(
std::unique_ptr<gpu::gles2::AbstractTexture> texture)
std::unique_ptr<gpu::gles2::AbstractTexture> texture,
SecureMode secure_mode)
: TextureOwner(std::move(texture)),
current_image_(nullptr),
loader_(base::android::AndroidImageReader::GetInstance()),
......@@ -79,18 +80,19 @@ ImageReaderGLOwner::ImageReaderGLOwner(
DCHECK(context_);
DCHECK(surface_);
// TODO(khushalsagar): Need plumbing here to select the correct format and
// usage for secure media.
// Set the width, height and format to some default value. This parameters
// are/maybe overriden by the producer sending buffers to this imageReader's
// Surface.
int32_t width = 1, height = 1, max_images = 3;
AIMAGE_FORMATS format = AIMAGE_FORMAT_YUV_420_888;
AIMAGE_FORMATS format = secure_mode == SecureMode::kSecure
? AIMAGE_FORMAT_PRIVATE
: AIMAGE_FORMAT_YUV_420_888;
AImageReader* reader = nullptr;
// The usage flag below should be used when the buffer will be read from by
// the GPU as a texture.
const uint64_t usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
const uint64_t usage = secure_mode == SecureMode::kSecure
? AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT
: AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
// Create a new reader for images of the desired size and format.
media_status_t return_code = loader_.AImageReader_newWithUsage(
......
......@@ -44,6 +44,8 @@ class MEDIA_GPU_EXPORT ImageReaderGLOwner : public TextureOwner {
std::unique_ptr<base::android::ScopedHardwareBufferFenceSync>
GetAHardwareBuffer() override;
const AImageReader* image_reader_for_testing() const { return image_reader_; }
protected:
void OnTextureDestroyed(gpu::gles2::AbstractTexture*) override;
......@@ -52,7 +54,8 @@ class MEDIA_GPU_EXPORT ImageReaderGLOwner : public TextureOwner {
class ScopedHardwareBufferImpl;
ImageReaderGLOwner(std::unique_ptr<gpu::gles2::AbstractTexture> texture);
ImageReaderGLOwner(std::unique_ptr<gpu::gles2::AbstractTexture> texture,
SecureMode secure_mode);
~ImageReaderGLOwner() override;
// Deletes the current image if it has no pending refs. Returns false on
......
......@@ -6,11 +6,13 @@
#include <stdint.h>
#include <memory>
#include <utility>
#include "base/message_loop/message_loop.h"
#include "base/test/scoped_feature_list.h"
#include "gpu/command_buffer/service/abstract_texture.h"
#include "media/base/media_switches.h"
#include "media/gpu/android/image_reader_gl_owner.h"
#include "media/gpu/android/mock_abstract_texture.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gl/gl_bindings.h"
......@@ -27,6 +29,9 @@ class ImageReaderGLOwnerTest : public testing::Test {
protected:
void SetUp() override {
if (!IsImageReaderSupported())
return;
scoped_feature_list_.InitAndEnableFeature(media::kAImageReaderVideoOutput);
gl::init::InitializeGLOneOffImplementation(gl::kGLImplementationEGLGLES2,
false, false, false, true);
......@@ -44,7 +49,11 @@ class ImageReaderGLOwnerTest : public testing::Test {
std::unique_ptr<MockAbstractTexture> texture =
std::make_unique<MockAbstractTexture>(texture_id_);
abstract_texture_ = texture->AsWeakPtr();
image_reader_ = TextureOwner::Create(std::move(texture));
image_reader_ = TextureOwner::Create(std::move(texture), SecureMode());
}
virtual TextureOwner::SecureMode SecureMode() {
return TextureOwner::SecureMode::kInsecure;
}
void TearDown() override {
......@@ -57,6 +66,10 @@ class ImageReaderGLOwnerTest : public testing::Test {
gl::init::ShutdownGL(false);
}
bool IsImageReaderSupported() const {
return base::android::AndroidImageReader::GetInstance().IsSupported();
}
base::test::ScopedFeatureList scoped_feature_list_;
scoped_refptr<TextureOwner> image_reader_;
GLuint texture_id_ = 0;
......@@ -70,10 +83,16 @@ class ImageReaderGLOwnerTest : public testing::Test {
};
TEST_F(ImageReaderGLOwnerTest, ImageReaderObjectCreation) {
if (!IsImageReaderSupported())
return;
ASSERT_TRUE(image_reader_);
}
TEST_F(ImageReaderGLOwnerTest, ScopedJavaSurfaceCreation) {
if (!IsImageReaderSupported())
return;
gl::ScopedJavaSurface temp = image_reader_->CreateJavaSurface();
ASSERT_TRUE(temp.IsValid());
}
......@@ -81,6 +100,9 @@ TEST_F(ImageReaderGLOwnerTest, ScopedJavaSurfaceCreation) {
// Verify that ImageReaderGLOwner creates a bindable GL texture, and deletes
// it during destruction.
TEST_F(ImageReaderGLOwnerTest, GLTextureIsCreatedAndDestroyed) {
if (!IsImageReaderSupported())
return;
// |texture_id| should not work anymore after we delete image_reader_.
image_reader_ = nullptr;
EXPECT_FALSE(abstract_texture_);
......@@ -88,12 +110,18 @@ TEST_F(ImageReaderGLOwnerTest, GLTextureIsCreatedAndDestroyed) {
// Make sure that image_reader_ remembers the correct context and surface.
TEST_F(ImageReaderGLOwnerTest, ContextAndSurfaceAreCaptured) {
if (!IsImageReaderSupported())
return;
ASSERT_EQ(context_, image_reader_->GetContext());
ASSERT_EQ(surface_, image_reader_->GetSurface());
}
// Verify that destruction works even if some other context is current.
TEST_F(ImageReaderGLOwnerTest, DestructionWorksWithWrongContext) {
if (!IsImageReaderSupported())
return;
scoped_refptr<gl::GLSurface> new_surface(
new gl::PbufferGLSurfaceEGL(gfx::Size(320, 240)));
new_surface->Initialize();
......@@ -115,4 +143,24 @@ TEST_F(ImageReaderGLOwnerTest, DestructionWorksWithWrongContext) {
new_surface = nullptr;
}
class ImageReaderGLOwnerSecureTest : public ImageReaderGLOwnerTest {
public:
TextureOwner::SecureMode SecureMode() final {
return TextureOwner::SecureMode::kSecure;
}
};
TEST_F(ImageReaderGLOwnerSecureTest, CreatesSecureAImageReader) {
if (!IsImageReaderSupported())
return;
ASSERT_TRUE(image_reader_);
auto* a_image_reader = static_cast<ImageReaderGLOwner*>(image_reader_.get())
->image_reader_for_testing();
int32_t format = AIMAGE_FORMAT_YUV_420_888;
base::android::AndroidImageReader::GetInstance().AImageReader_getFormat(
a_image_reader, &format);
EXPECT_EQ(format, AIMAGE_FORMAT_PRIVATE);
}
} // namespace media
......@@ -388,19 +388,26 @@ void MediaCodecVideoDecoder::StartLazyInit() {
lazy_init_pending_ = false;
codec_allocator_->StartThread(this);
// SurfaceControl allows TextureOwner to be promoted to an overlay in the
// compositing pipeline itself.
const bool use_texture_owner_as_overlays = is_surface_control_enabled_;
// Only ask for promotion hints if we can actually switch surfaces, since we
// wouldn't be able to do anything with them. Also, if threaded texture
// mailboxes are enabled, then we turn off overlays anyway. And if texture
// owner can be used as an overlay, no promotion hints are necessary.
// mailboxes are enabled, then we turn off overlays anyway.
const bool want_promotion_hints =
device_info_->IsSetOutputSurfaceSupported() &&
!enable_threaded_texture_mailboxes_ && !use_texture_owner_as_overlays;
!enable_threaded_texture_mailboxes_;
VideoFrameFactory::OverlayMode overlay_mode =
VideoFrameFactory::OverlayMode::kDontRequestPromotionHints;
if (is_surface_control_enabled_) {
overlay_mode =
requires_secure_codec_
? VideoFrameFactory::OverlayMode::kSurfaceControlSecure
: VideoFrameFactory::OverlayMode::kSurfaceControlInsecure;
} else if (want_promotion_hints) {
overlay_mode = VideoFrameFactory::OverlayMode::kRequestPromotionHints;
}
video_frame_factory_->Initialize(
want_promotion_hints, use_texture_owner_as_overlays,
overlay_mode,
base::Bind(&MediaCodecVideoDecoder::OnVideoFrameFactoryInitialized,
weak_factory_.GetWeakPtr()));
}
......
......@@ -58,10 +58,7 @@ struct DestructionObservableMCVD : public DestructionObservable,
class MockVideoFrameFactory : public VideoFrameFactory {
public:
MOCK_METHOD3(Initialize,
void(bool wants_promotion_hint,
bool use_texture_owner_as_overlay,
InitCb init_cb));
MOCK_METHOD2(Initialize, void(OverlayMode overlay_mode, InitCb init_cb));
MOCK_METHOD1(MockSetSurfaceBundle, void(scoped_refptr<AVDASurfaceBundle>));
MOCK_METHOD5(
MockCreateVideoFrame,
......@@ -143,10 +140,8 @@ class MediaCodecVideoDecoderTest : public testing::TestWithParam<VideoCodec> {
std::make_unique<NiceMock<MockVideoFrameFactory>>();
video_frame_factory_ = video_frame_factory.get();
// Set up VFF to pass |texture_owner_| via its InitCb.
const bool want_promotion_hint =
device_info_->IsSetOutputSurfaceSupported();
ON_CALL(*video_frame_factory_, Initialize(want_promotion_hint, _, _))
.WillByDefault(RunCallback<2>(texture_owner));
ON_CALL(*video_frame_factory_, Initialize(ExpectedOverlayMode(), _))
.WillByDefault(RunCallback<1>(texture_owner));
auto* observable_mcvd = new DestructionObservableMCVD(
gpu_preferences_, gpu_feature_info_, device_info_.get(),
......@@ -162,6 +157,14 @@ class MediaCodecVideoDecoderTest : public testing::TestWithParam<VideoCodec> {
destruction_observer_->ExpectDestruction();
}
VideoFrameFactory::OverlayMode ExpectedOverlayMode() const {
const bool want_promotion_hint =
device_info_->IsSetOutputSurfaceSupported();
return want_promotion_hint
? VideoFrameFactory::OverlayMode::kRequestPromotionHints
: VideoFrameFactory::OverlayMode::kDontRequestPromotionHints;
}
void CreateCdm(bool has_media_crypto_context,
bool require_secure_video_decoder) {
cdm_ = std::make_unique<MockMediaCryptoContext>(has_media_crypto_context);
......@@ -309,7 +312,8 @@ TEST_P(MediaCodecVideoDecoderVp8Test, SmallVp8IsRejected) {
TEST_P(MediaCodecVideoDecoderTest, InitializeDoesntInitSurfaceOrCodec) {
CreateMcvd();
EXPECT_CALL(*video_frame_factory_, Initialize(_, _, _)).Times(0);
EXPECT_CALL(*video_frame_factory_, Initialize(ExpectedOverlayMode(), _))
.Times(0);
EXPECT_CALL(*surface_chooser_, MockUpdateState()).Times(0);
EXPECT_CALL(*codec_allocator_, MockCreateMediaCodecAsync(_, _)).Times(0);
Initialize(TestVideoConfig::Large(codec_));
......@@ -317,7 +321,7 @@ TEST_P(MediaCodecVideoDecoderTest, InitializeDoesntInitSurfaceOrCodec) {
TEST_P(MediaCodecVideoDecoderTest, FirstDecodeTriggersFrameFactoryInit) {
Initialize(TestVideoConfig::Large(codec_));
EXPECT_CALL(*video_frame_factory_, Initialize(_, _, _));
EXPECT_CALL(*video_frame_factory_, Initialize(ExpectedOverlayMode(), _));
mcvd_->Decode(fake_decoder_buffer_, decode_cb_.Get());
}
......@@ -371,8 +375,8 @@ TEST_P(MediaCodecVideoDecoderTest, CodecIsCreatedAfterSurfaceChosen) {
TEST_P(MediaCodecVideoDecoderTest, FrameFactoryInitFailureIsAnError) {
Initialize(TestVideoConfig::Large(codec_));
ON_CALL(*video_frame_factory_, Initialize(_, _, _))
.WillByDefault(RunCallback<2>(nullptr));
ON_CALL(*video_frame_factory_, Initialize(ExpectedOverlayMode(), _))
.WillByDefault(RunCallback<1>(nullptr));
EXPECT_CALL(decode_cb_, Run(DecodeStatus::DECODE_ERROR)).Times(1);
EXPECT_CALL(*surface_chooser_, MockUpdateState()).Times(0);
mcvd_->Decode(fake_decoder_buffer_, decode_cb_.Get());
......
......@@ -50,7 +50,8 @@ class SurfaceTextureGLOwnerTest : public testing::Test {
std::unique_ptr<MockAbstractTexture> texture =
std::make_unique<MockAbstractTexture>(texture_id_);
abstract_texture_ = texture->AsWeakPtr();
surface_texture_ = SurfaceTextureGLOwner::Create(std::move(texture));
surface_texture_ = SurfaceTextureGLOwner::Create(
std::move(texture), TextureOwner::SecureMode::kInsecure);
texture_id_ = surface_texture_->GetTextureId();
EXPECT_TRUE(abstract_texture_);
}
......
......@@ -36,7 +36,8 @@ TextureOwner::~TextureOwner() {
// static
scoped_refptr<TextureOwner> TextureOwner::Create(
std::unique_ptr<gpu::gles2::AbstractTexture> texture) {
std::unique_ptr<gpu::gles2::AbstractTexture> texture,
SecureMode secure_mode) {
// Set the parameters on the texture.
texture->SetParameteri(GL_TEXTURE_MAG_FILTER, GL_LINEAR);
texture->SetParameteri(GL_TEXTURE_MIN_FILTER, GL_LINEAR);
......@@ -46,10 +47,12 @@ scoped_refptr<TextureOwner> TextureOwner::Create(
// If AImageReader is supported and is enabled by media flag, use it.
if (base::android::AndroidImageReader::GetInstance().IsSupported() &&
base::FeatureList::IsEnabled(media::kAImageReaderVideoOutput)) {
return new ImageReaderGLOwner(std::move(texture));
return new ImageReaderGLOwner(std::move(texture), secure_mode);
}
// If not, fall back to legacy path.
DCHECK_EQ(secure_mode, SecureMode::kInsecure)
<< "Can not use secure mode with SurfaceTexture";
return new SurfaceTextureGLOwner(std::move(texture));
}
......
......@@ -45,8 +45,12 @@ class MEDIA_GPU_EXPORT TextureOwner
// new TextureOwner attached to it. Returns null on failure.
// |texture| should be either from CreateAbstractTexture() or a mock. The
// corresponding GL context must be current.
// SecureMode indicates whether the video textures created using this owner
// should be hardware protected.
enum class SecureMode { kSecure, kInsecure };
static scoped_refptr<TextureOwner> Create(
std::unique_ptr<gpu::gles2::AbstractTexture> texture);
std::unique_ptr<gpu::gles2::AbstractTexture> texture,
SecureMode secure_mode);
// Create a texture that's appropriate for a TextureOwner.
static std::unique_ptr<gpu::gles2::AbstractTexture> CreateTexture(
......
......@@ -41,13 +41,22 @@ class MEDIA_GPU_EXPORT VideoFrameFactory {
// Initializes the factory and runs |init_cb| on the current thread when it's
// complete. If initialization fails, the returned texture owner will be
// null.
// |wants_promotion_hint| tells us whether to mark VideoFrames for compositor
// overlay promotion hints or not.
// |use_texture_owner_as_overlays| tells us whether TextureOwner can be used
// as an overlay, in which case java overlays will never be used.
virtual void Initialize(bool wants_promotion_hint,
bool use_texture_owner_as_overlays,
InitCb init_cb) = 0;
enum class OverlayMode {
// When using java overlays, the compositor can provide hints to the media
// pipeline to indicate whether the video can be promoted to an overlay.
// This indicates whether promotion hints are needed, if framework support
// for overlay promotion is available (requires MediaCodec.setOutputSurface
// support).
kDontRequestPromotionHints,
kRequestPromotionHints,
// When using surface control, the factory should always use a TextureOwner
// since it can directly be promoted to an overlay on a frame-by-frame
// basis. The bits below indicate whether the media uses a secure codec.
kSurfaceControlSecure,
kSurfaceControlInsecure
};
virtual void Initialize(OverlayMode overlay_mode, InitCb init_cb) = 0;
// Notify us about the current surface bundle that subsequent video frames
// should use.
......
......@@ -51,8 +51,7 @@ VideoFrameFactoryImpl::~VideoFrameFactoryImpl() {
gpu_task_runner_->DeleteSoon(FROM_HERE, gpu_video_frame_factory_.release());
}
void VideoFrameFactoryImpl::Initialize(bool wants_promotion_hint,
bool use_texture_owner_as_overlays,
void VideoFrameFactoryImpl::Initialize(OverlayMode overlay_mode,
InitCb init_cb) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(!gpu_video_frame_factory_);
......@@ -60,8 +59,7 @@ void VideoFrameFactoryImpl::Initialize(bool wants_promotion_hint,
base::PostTaskAndReplyWithResult(
gpu_task_runner_.get(), FROM_HERE,
base::Bind(&GpuVideoFrameFactory::Initialize,
base::Unretained(gpu_video_frame_factory_.get()),
wants_promotion_hint, use_texture_owner_as_overlays,
base::Unretained(gpu_video_frame_factory_.get()), overlay_mode,
get_stub_cb_),
std::move(init_cb));
}
......@@ -132,12 +130,10 @@ GpuVideoFrameFactory::~GpuVideoFrameFactory() {
}
scoped_refptr<TextureOwner> GpuVideoFrameFactory::Initialize(
bool wants_promotion_hint,
bool use_texture_owner_as_overlays,
VideoFrameFactoryImpl::OverlayMode overlay_mode,
VideoFrameFactoryImpl::GetStubCb get_stub_cb) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
wants_promotion_hint_ = wants_promotion_hint;
use_texture_owner_as_overlays_ = use_texture_owner_as_overlays;
overlay_mode_ = overlay_mode;
stub_ = get_stub_cb.Run();
if (!MakeContextCurrent(stub_))
return nullptr;
......@@ -147,8 +143,12 @@ scoped_refptr<TextureOwner> GpuVideoFrameFactory::Initialize(
decoder_helper_ = GLES2DecoderHelper::Create(stub_->decoder_context());
auto secure_mode =
overlay_mode_ == VideoFrameFactory::OverlayMode::kSurfaceControlSecure
? TextureOwner::SecureMode::kSecure
: TextureOwner::SecureMode::kInsecure;
return TextureOwner::Create(
TextureOwner::CreateTexture(stub_->decoder_context()));
TextureOwner::CreateTexture(stub_->decoder_context()), secure_mode);
}
void GpuVideoFrameFactory::CreateVideoFrame(
......@@ -283,21 +283,27 @@ void GpuVideoFrameFactory::CreateVideoFrameInternal(
if (group->gpu_preferences().enable_threaded_texture_mailboxes)
frame->metadata()->SetBoolean(VideoFrameMetadata::COPY_REQUIRED, true);
const bool is_surface_control =
overlay_mode_ == VideoFrameFactory::OverlayMode::kSurfaceControlSecure ||
overlay_mode_ == VideoFrameFactory::OverlayMode::kSurfaceControlInsecure;
const bool wants_promotion_hints =
overlay_mode_ == VideoFrameFactory::OverlayMode::kRequestPromotionHints;
bool allow_overlay = false;
if (use_texture_owner_as_overlays_) {
if (is_surface_control) {
DCHECK(texture_owner_);
allow_overlay = true;
} else {
// We unconditionally mark the picture as overlayable, even if
// |!texture_owner_|, if we want to get hints. It's required, else we won't
// get hints.
allow_overlay = !texture_owner_ || wants_promotion_hint_;
allow_overlay = !texture_owner_ || wants_promotion_hints;
}
frame->metadata()->SetBoolean(VideoFrameMetadata::ALLOW_OVERLAY,
allow_overlay);
frame->metadata()->SetBoolean(VideoFrameMetadata::WANTS_PROMOTION_HINT,
wants_promotion_hint_);
wants_promotion_hints);
frame->metadata()->SetBoolean(VideoFrameMetadata::TEXTURE_OWNER,
!!texture_owner_);
......
......@@ -38,9 +38,7 @@ class MEDIA_GPU_EXPORT VideoFrameFactoryImpl : public VideoFrameFactory {
GetStubCb get_stub_cb);
~VideoFrameFactoryImpl() override;
void Initialize(bool wants_promotion_hint,
bool use_texture_owner_as_overlays,
InitCb init_cb) override;
void Initialize(OverlayMode overlay_mode, InitCb init_cb) override;
void SetSurfaceBundle(
scoped_refptr<AVDASurfaceBundle> surface_bundle) override;
void CreateVideoFrame(
......@@ -73,8 +71,7 @@ class GpuVideoFrameFactory
~GpuVideoFrameFactory() override;
scoped_refptr<TextureOwner> Initialize(
bool wants_promotion_hint,
bool use_texture_owner_as_overlays,
VideoFrameFactory::OverlayMode overlay_mode,
VideoFrameFactory::GetStubCb get_stub_cb);
// Creates and returns a VideoFrame with its ReleaseMailboxCB.
......@@ -111,16 +108,13 @@ class GpuVideoFrameFactory
// Outstanding images that should be considered for early rendering.
std::vector<CodecImage*> images_;
gpu::CommandBufferStub* stub_;
gpu::CommandBufferStub* stub_ = nullptr;
// Callback to notify us that an image has been destroyed.
CodecImage::DestructionCb destruction_cb_;
// Do we want promotion hints from the compositor?
bool wants_promotion_hint_ = false;
// Indicates whether texture owner can be promoted to an overlay.
bool use_texture_owner_as_overlays_ = false;
VideoFrameFactory::OverlayMode overlay_mode_ =
VideoFrameFactory::OverlayMode::kDontRequestPromotionHints;
// A helper for creating textures. Only valid while |stub_| is valid.
std::unique_ptr<GLES2DecoderHelper> decoder_helper_;
......
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