Commit 96ac435c authored by liberato@chromium.org's avatar liberato@chromium.org Committed by Commit Bot

Move VideoFrame creation to VideoFrameFactoryImpl.

In preparation for adding a pool of SharedImages, this CL moves most
parts of VideoFrame creation to the MCVD thread.

There aren't supposed to be any functional changes.  The only thing
that might differ slightly is that a scoped refptr to |texture_owner|
is now being sent MCVD => GPU => MCVD thread, while before it was
going MCVD => GPU only.  While TextureOwner is DeleteOnSequence, so
it's okay to drop it on any thread, the small change in lifetime
might do something because threads are weird.

Otherwise, almost everything is identical, just refactored.

Change-Id: Ia0f5ecf393a886e8bc1a0572cbe494f26a9a236b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1612600
Commit-Queue: Frank Liberato <liberato@chromium.org>
Reviewed-by: default avatarDale Curtis <dalecurtis@chromium.org>
Reviewed-by: default avatarvikas soni <vikassoni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#660617}
parent 10a8d9b5
......@@ -853,6 +853,14 @@ void MediaCodecVideoDecoder::ForwardVideoFrame(
scoped_refptr<VideoFrame> frame) {
DVLOG(3) << __func__ << " : "
<< (frame ? frame->AsHumanReadableString() : "null");
// No |frame| indicates an error creating it.
if (!frame) {
DLOG(ERROR) << __func__ << " |frame| is null";
EnterTerminalState(State::kError);
return;
}
if (reset_generation == reset_generation_) {
// TODO(liberato): We might actually have a SW decoder. Consider setting
// this to false if so, especially for higher bitrates.
......
......@@ -34,10 +34,18 @@ class GpuVideoFrameFactory;
// to a helper class hosted on the gpu thread.
class MEDIA_GPU_EXPORT VideoFrameFactoryImpl : public VideoFrameFactory {
public:
// Callback used to return a mailbox and release callback for an image. The
// release callback may be dropped without being run, and the image will be
// cleaned up properly. The releae callback may be called from any thread.
using ImageReadyCB =
base::OnceCallback<void(gpu::Mailbox mailbox,
VideoFrame::ReleaseMailboxCB release_cb)>;
// |get_stub_cb| will be run on |gpu_task_runner|.
VideoFrameFactoryImpl(
scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner,
GetStubCb get_stub_cb);
GetStubCb get_stub_cb,
const gpu::GpuPreferences& gpu_preferences);
~VideoFrameFactoryImpl() override;
void Initialize(OverlayMode overlay_mode, InitCb init_cb) override;
......@@ -52,6 +60,28 @@ class MEDIA_GPU_EXPORT VideoFrameFactoryImpl : public VideoFrameFactory {
void RunAfterPendingVideoFrames(base::OnceClosure closure) override;
private:
// ImageReadyCB that will construct a VideoFrame, and forward it to
// |output_cb| if construction succeeds. This is static for two reasons.
// First, we want to snapshot the state of the world when the request is made,
// in case things like the texture owner change before it's returned. While
// it's unclear that MCVD would actually do this (it drains output buffers
// before switching anything, which guarantees that the VideoFrame has been
// created and sent to the renderer), it's still much simpler to think about
// if this uses the same state as the CreateVideoFrame call.
//
// Second, this way we don't care about the lifetime of |this|; |output_cb|
// can worry about it.
static void OnImageReady(OnceOutputCb output_cb,
base::TimeDelta timestamp,
gfx::Size coded_size,
gfx::Size natural_size,
scoped_refptr<TextureOwner> texture_owner,
VideoPixelFormat pixel_format,
OverlayMode overlay_mode,
bool enable_threaded_texture_mailboxes,
gpu::Mailbox mailbox,
VideoFrame::ReleaseMailboxCB release_cb);
// The gpu thread side of the implementation.
std::unique_ptr<GpuVideoFrameFactory> gpu_video_frame_factory_;
scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner_;
......@@ -60,6 +90,11 @@ class MEDIA_GPU_EXPORT VideoFrameFactoryImpl : public VideoFrameFactory {
// The texture owner that video frames should use, or nullptr.
scoped_refptr<TextureOwner> texture_owner_;
OverlayMode overlay_mode_ = OverlayMode::kDontRequestPromotionHints;
// Is the sync mailbox manager enabled?
bool enable_threaded_texture_mailboxes_ = false;
SEQUENCE_CHECKER(sequence_checker_);
DISALLOW_COPY_AND_ASSIGN(VideoFrameFactoryImpl);
};
......@@ -76,14 +111,12 @@ class GpuVideoFrameFactory
VideoFrameFactory::OverlayMode overlay_mode,
VideoFrameFactory::GetStubCb get_stub_cb);
// Creates and returns a VideoFrame with its ReleaseMailboxCB.
void CreateVideoFrame(
// Creates a SharedImage for |output_buffer|, and returns it via the callback.
void CreateImage(
std::unique_ptr<CodecOutputBuffer> output_buffer,
scoped_refptr<TextureOwner> texture_owner,
base::TimeDelta timestamp,
gfx::Size natural_size,
PromotionHintAggregator::NotifyPromotionHintCB promotion_hint_cb,
VideoFrameFactory::OnceOutputCb output_cb,
VideoFrameFactoryImpl::ImageReadyCB image_ready_cb,
scoped_refptr<base::SingleThreadTaskRunner> task_runner);
// Set our image group. Must be called before the first call to
......@@ -91,15 +124,12 @@ class GpuVideoFrameFactory
void SetImageGroup(scoped_refptr<CodecImageGroup> image_group);
private:
// Creates an AbstractTexture and VideoFrame.
void CreateVideoFrameInternal(
// Creates a SharedImage for |mailbox|, and returns success or failure.
bool CreateImageInternal(
std::unique_ptr<CodecOutputBuffer> output_buffer,
scoped_refptr<TextureOwner> texture_owner,
base::TimeDelta timestamp,
gfx::Size natural_size,
PromotionHintAggregator::NotifyPromotionHintCB promotion_hint_cb,
scoped_refptr<VideoFrame>* video_frame_out,
CodecImage** codec_image_out);
gpu::Mailbox mailbox,
PromotionHintAggregator::NotifyPromotionHintCB promotion_hint_cb);
void OnWillDestroyStub(bool have_context) override;
......@@ -111,12 +141,6 @@ class GpuVideoFrameFactory
gpu::CommandBufferStub* stub_ = nullptr;
// Callback to notify us that an image has been destroyed.
CodecImage::DestructionCb destruction_cb_;
VideoFrameFactory::OverlayMode overlay_mode_ =
VideoFrameFactory::OverlayMode::kDontRequestPromotionHints;
// A helper for creating textures. Only valid while |stub_| is valid.
std::unique_ptr<GLES2DecoderHelper> decoder_helper_;
......
......@@ -196,8 +196,8 @@ std::unique_ptr<VideoDecoder> GpuMojoMediaClient::CreateVideoDecoder(
std::make_unique<AndroidVideoSurfaceChooserImpl>(
DeviceInfo::GetInstance()->IsSetOutputSurfaceSupported()),
android_overlay_factory_cb_, std::move(request_overlay_info_cb),
std::make_unique<VideoFrameFactoryImpl>(gpu_task_runner_,
std::move(get_stub_cb)));
std::make_unique<VideoFrameFactoryImpl>(
gpu_task_runner_, std::move(get_stub_cb), gpu_preferences_));
#elif defined(OS_CHROMEOS) || defined(OS_MACOSX) || defined(OS_WIN) || \
defined(OS_LINUX)
video_decoder = VdaVideoDecoder::Create(
......
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