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

Unified Diff: media/gpu/avda_picture_buffer_manager.cc

Issue 2475133002: Split out AVDA cleanups from SetSurface() change. (Closed)
Patch Set: Cleanup. Created 4 years, 1 month 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
Index: media/gpu/avda_picture_buffer_manager.cc
diff --git a/media/gpu/avda_picture_buffer_manager.cc b/media/gpu/avda_picture_buffer_manager.cc
index 135aa3a23c5fd9ef983e854a4d2248fbbb971b68..e07aae80a67c3fbc13779918473ab56d03f87dc0 100644
--- a/media/gpu/avda_picture_buffer_manager.cc
+++ b/media/gpu/avda_picture_buffer_manager.cc
@@ -40,9 +40,6 @@
} \
} while (0)
-// Return nullptr if !|ptr|.
-#define RETURN_NULL_IF_NULL(ptr) RETURN_IF_NULL(ptr, nullptr)
-
namespace media {
namespace {
@@ -77,79 +74,23 @@ scoped_refptr<gl::SurfaceTexture> CreateAttachedSurfaceTexture(
} // namespace
-// Handle OnFrameAvailable callbacks safely. Since they occur asynchronously,
-// we take care that the object that wants them still exists. WeakPtrs cannot
-// be used because OnFrameAvailable callbacks can occur on any thread. We also
-// can't guarantee when the SurfaceTexture will quit sending callbacks to
-// coordinate with the destruction of the AVDA and PictureBufferManager, so we
-// have a separate object that the callback can own.
-class AVDAPictureBufferManager::OnFrameAvailableHandler
- : public base::RefCountedThreadSafe<OnFrameAvailableHandler> {
- public:
- // We do not retain ownership of |listener|. It must remain valid until after
- // ClearListener() is called. This will register with |surface_texture| to
- // receive OnFrameAvailable callbacks.
- OnFrameAvailableHandler(AVDASharedState* listener,
- gl::SurfaceTexture* surface_texture)
- : listener_(listener) {
- surface_texture->SetFrameAvailableCallbackOnAnyThread(
- base::Bind(&OnFrameAvailableHandler::OnFrameAvailable,
- scoped_refptr<OnFrameAvailableHandler>(this)));
- }
-
- // Forget about |listener_|, which is required before one deletes it.
- // No further callbacks will happen once this completes.
- void ClearListener() {
- base::AutoLock lock(lock_);
- listener_ = nullptr;
- }
-
- // Notify the listener if there is one.
- void OnFrameAvailable() {
- base::AutoLock auto_lock(lock_);
- if (listener_)
- listener_->SignalFrameAvailable();
- }
-
- private:
- friend class base::RefCountedThreadSafe<OnFrameAvailableHandler>;
-
- ~OnFrameAvailableHandler() { DCHECK(!listener_); }
-
- // Protects changes to listener_.
- base::Lock lock_;
-
- // The AVDASharedState that wants the OnFrameAvailable callback.
- AVDASharedState* listener_;
-
- DISALLOW_COPY_AND_ASSIGN(OnFrameAvailableHandler);
-};
-
-AVDAPictureBufferManager::AVDAPictureBufferManager()
- : state_provider_(nullptr), media_codec_(nullptr) {}
+AVDAPictureBufferManager::AVDAPictureBufferManager(
+ AVDAStateProvider* state_provider)
+ : state_provider_(state_provider), media_codec_(nullptr) {}
AVDAPictureBufferManager::~AVDAPictureBufferManager() {}
-gl::ScopedJavaSurface AVDAPictureBufferManager::Initialize(
- AVDAStateProvider* state_provider,
- int surface_view_id) {
- state_provider_ = state_provider;
+gl::ScopedJavaSurface AVDAPictureBufferManager::Initialize(int surface_id) {
shared_state_ = new AVDASharedState();
// Acquire the SurfaceView surface if given a valid id.
- if (surface_view_id != VideoDecodeAccelerator::Config::kNoSurfaceID) {
- return gpu::GpuSurfaceLookup::GetInstance()->AcquireJavaSurface(
- surface_view_id);
- }
+ if (surface_id != SurfaceManager::kNoSurfaceID)
+ return gpu::GpuSurfaceLookup::GetInstance()->AcquireJavaSurface(surface_id);
// Otherwise create a SurfaceTexture.
- GLuint service_id = 0;
+ GLuint service_id;
surface_texture_ = CreateAttachedSurfaceTexture(
state_provider_->GetGlDecoder(), &service_id);
- if (surface_texture_) {
- on_frame_available_handler_ = new OnFrameAvailableHandler(
- shared_state_.get(), surface_texture_.get());
- }
shared_state_->SetSurfaceTexture(surface_texture_, service_id);
return gl::ScopedJavaSurface(surface_texture_.get());
}
@@ -159,11 +100,6 @@ void AVDAPictureBufferManager::Destroy(const PictureBufferMap& buffers) {
if (!shared_state_)
return;
- // If we have an OnFrameAvailable handler, tell it that we no longer want
- // callbacks.
- if (on_frame_available_handler_)
- on_frame_available_handler_->ClearListener();
-
ReleaseCodecBuffers(buffers);
CodecChanged(nullptr);
@@ -192,43 +128,29 @@ gfx::Size AVDAPictureBufferManager::GetPictureBufferSize() const {
return surface_texture_ ? state_provider_->GetSize() : gfx::Size(1, 1);
}
-gpu::gles2::TextureRef* AVDAPictureBufferManager::GetTextureForPicture(
- const PictureBuffer& picture_buffer) {
+void AVDAPictureBufferManager::SetImageForPicture(
+ const PictureBuffer& picture_buffer,
+ gpu::gles2::GLStreamTextureImage* image) {
auto gles_decoder = state_provider_->GetGlDecoder();
- RETURN_NULL_IF_NULL(gles_decoder);
- RETURN_NULL_IF_NULL(gles_decoder->GetContextGroup());
+ RETURN_IF_NULL(gles_decoder);
+ RETURN_IF_NULL(gles_decoder->GetContextGroup());
gpu::gles2::TextureManager* texture_manager =
gles_decoder->GetContextGroup()->texture_manager();
- RETURN_NULL_IF_NULL(texture_manager);
+ RETURN_IF_NULL(texture_manager);
DCHECK_LE(1u, picture_buffer.client_texture_ids().size());
gpu::gles2::TextureRef* texture_ref =
texture_manager->GetTexture(picture_buffer.client_texture_ids()[0]);
- RETURN_NULL_IF_NULL(texture_ref);
-
- return texture_ref;
-}
-
-void AVDAPictureBufferManager::SetImageForPicture(
- const PictureBuffer& picture_buffer,
- const scoped_refptr<gpu::gles2::GLStreamTextureImage>& image) {
- gpu::gles2::TextureRef* texture_ref = GetTextureForPicture(picture_buffer);
RETURN_IF_NULL(texture_ref);
- gpu::gles2::TextureManager* texture_manager =
- state_provider_->GetGlDecoder()->GetContextGroup()->texture_manager();
- RETURN_IF_NULL(texture_manager);
-
// Default to zero which will clear the stream texture service id if one was
// previously set.
GLuint stream_texture_service_id = 0;
if (image) {
- if (shared_state_->surface_texture_service_id() != 0) {
- // Override the Texture's service id, so that it will use the one that is
- // attached to the SurfaceTexture.
- stream_texture_service_id = shared_state_->surface_texture_service_id();
- }
+ // Override the Texture's service id, so that it will use the one that is
+ // attached to the SurfaceTexture.
+ stream_texture_service_id = shared_state_->surface_texture_service_id();
// Also set the parameters for the level if we're not clearing the image.
const gfx::Size size = state_provider_->GetSize();
@@ -236,8 +158,7 @@ void AVDAPictureBufferManager::SetImageForPicture(
size.width(), size.height(), 1, 0, GL_RGBA,
GL_UNSIGNED_BYTE, gfx::Rect());
- static_cast<AVDACodecImage*>(image.get())
- ->set_texture(texture_ref->texture());
+ static_cast<AVDACodecImage*>(image)->set_texture(texture_ref->texture());
}
// If we're clearing the image, or setting a SurfaceTexture backed image, we
@@ -252,10 +173,16 @@ void AVDAPictureBufferManager::SetImageForPicture(
if (image && !surface_texture_)
image_state = gpu::gles2::Texture::BOUND;
texture_manager->SetLevelStreamTextureImage(texture_ref, GetTextureTarget(),
- 0, image.get(), image_state,
+ 0, image, image_state,
stream_texture_service_id);
}
+AVDACodecImage* AVDAPictureBufferManager::GetImageForPicture(
+ int picture_buffer_id) const {
+ auto it = codec_images_.find(picture_buffer_id);
+ return it == codec_images_.end() ? nullptr : it->second.get();
+}
+
void AVDAPictureBufferManager::UseCodecBufferForPictureBuffer(
int32_t codec_buf_index,
const PictureBuffer& picture_buffer) {
@@ -264,8 +191,7 @@ void AVDAPictureBufferManager::UseCodecBufferForPictureBuffer(
// Notify the AVDACodecImage for picture_buffer that it should use the
// decoded buffer codec_buf_index to render this frame.
- AVDACodecImage* avda_image =
- shared_state_->GetImageForPicture(picture_buffer.id());
+ AVDACodecImage* avda_image = GetImageForPicture(picture_buffer.id());
RETURN_IF_NULL(avda_image);
// Note that this is not a race, since we do not re-use a PictureBuffer
@@ -281,11 +207,10 @@ void AVDAPictureBufferManager::AssignOnePictureBuffer(
const PictureBuffer& picture_buffer,
bool have_context) {
// Attach a GLImage to each texture that will use the surface texture.
- // We use a refptr here in case SetImageForPicture fails.
scoped_refptr<gpu::gles2::GLStreamTextureImage> gl_image =
- new AVDACodecImage(picture_buffer.id(), shared_state_, media_codec_,
- state_provider_->GetGlDecoder());
- SetImageForPicture(picture_buffer, gl_image);
+ codec_images_[picture_buffer.id()] = new AVDACodecImage(
+ shared_state_, media_codec_, state_provider_->GetGlDecoder());
+ SetImageForPicture(picture_buffer, gl_image.get());
if (!surface_texture_ && have_context) {
// To make devtools work, we're using a 2D texture. Make it transparent,
@@ -306,8 +231,7 @@ void AVDAPictureBufferManager::AssignOnePictureBuffer(
void AVDAPictureBufferManager::ReleaseCodecBufferForPicture(
const PictureBuffer& picture_buffer) {
- AVDACodecImage* avda_image =
- shared_state_->GetImageForPicture(picture_buffer.id());
+ AVDACodecImage* avda_image = GetImageForPicture(picture_buffer.id());
RETURN_IF_NULL(avda_image);
avda_image->UpdateSurface(AVDACodecImage::UpdateMode::DISCARD_CODEC_BUFFER);
}
@@ -344,7 +268,7 @@ void AVDAPictureBufferManager::MaybeRenderEarly() {
AVDACodecImage* first_renderable_image = nullptr;
for (int i = front_index; i >= 0; --i) {
const int id = pictures_out_for_display_[i];
- AVDACodecImage* avda_image = shared_state_->GetImageForPicture(id);
+ AVDACodecImage* avda_image = GetImageForPicture(id);
if (!avda_image)
continue;
@@ -375,8 +299,8 @@ void AVDAPictureBufferManager::MaybeRenderEarly() {
// See if the back buffer is free. If so, then render the frame adjacent to
// the front buffer. The listing is in render order, so we can just use the
// first unrendered frame if there is back buffer space.
- first_renderable_image = shared_state_->GetImageForPicture(
- pictures_out_for_display_[backbuffer_index]);
+ first_renderable_image =
+ GetImageForPicture(pictures_out_for_display_[backbuffer_index]);
if (!first_renderable_image ||
first_renderable_image->was_rendered_to_back_buffer()) {
return;
@@ -390,7 +314,9 @@ void AVDAPictureBufferManager::MaybeRenderEarly() {
void AVDAPictureBufferManager::CodecChanged(VideoCodecBridge* codec) {
media_codec_ = codec;
- shared_state_->CodecChanged(codec);
+ for (auto& image_kv : codec_images_)
+ image_kv.second->CodecChanged(codec);
+ shared_state_->clear_release_time();
}
bool AVDAPictureBufferManager::ArePicturesOverlayable() {

Powered by Google App Engine
This is Rietveld 408576698