| Index: media/gpu/avda_shared_state.cc
|
| diff --git a/media/gpu/avda_shared_state.cc b/media/gpu/avda_shared_state.cc
|
| index 86f0633a6e1e83cad5ab809d631b2ff1c6bccd4e..3e71e5a527c22e676d57d355a9b7d32e0bc00d5d 100644
|
| --- a/media/gpu/avda_shared_state.cc
|
| +++ b/media/gpu/avda_shared_state.cc
|
| @@ -13,6 +13,54 @@
|
|
|
| namespace media {
|
|
|
| +// 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 AVDASharedState::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);
|
| +};
|
| +
|
| AVDASharedState::AVDASharedState()
|
| : surface_texture_service_id_(0),
|
| frame_available_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
|
| @@ -29,6 +77,7 @@ AVDASharedState::~AVDASharedState() {
|
| if (!surface_texture_service_id_)
|
| return;
|
|
|
| + on_frame_available_handler_->ClearListener();
|
| ui::ScopedMakeCurrent scoped_make_current(context_.get(), surface_.get());
|
| if (scoped_make_current.Succeeded()) {
|
| glDeleteTextures(1, &surface_texture_service_id_);
|
| @@ -73,36 +122,14 @@ void AVDASharedState::WaitForFrameAvailable() {
|
| void AVDASharedState::SetSurfaceTexture(
|
| scoped_refptr<gl::SurfaceTexture> surface_texture,
|
| GLuint attached_service_id) {
|
| + DCHECK(surface_texture);
|
| + DCHECK(attached_service_id);
|
| surface_texture_ = surface_texture;
|
| surface_texture_service_id_ = attached_service_id;
|
| context_ = gl::GLContext::GetCurrent();
|
| surface_ = gl::GLSurface::GetCurrent();
|
| - DCHECK(context_);
|
| - DCHECK(surface_);
|
| -}
|
| -
|
| -void AVDASharedState::CodecChanged(MediaCodecBridge* codec) {
|
| - for (auto& image_kv : codec_images_)
|
| - image_kv.second->CodecChanged(codec);
|
| - release_time_ = base::TimeTicks();
|
| -}
|
| -
|
| -void AVDASharedState::SetImageForPicture(int picture_buffer_id,
|
| - AVDACodecImage* image) {
|
| - if (!image) {
|
| - DCHECK(codec_images_.find(picture_buffer_id) != codec_images_.end());
|
| - codec_images_.erase(picture_buffer_id);
|
| - return;
|
| - }
|
| -
|
| - DCHECK(codec_images_.find(picture_buffer_id) == codec_images_.end());
|
| - codec_images_[picture_buffer_id] = image;
|
| -}
|
| -
|
| -AVDACodecImage* AVDASharedState::GetImageForPicture(
|
| - int picture_buffer_id) const {
|
| - auto it = codec_images_.find(picture_buffer_id);
|
| - return it == codec_images_.end() ? nullptr : it->second;
|
| + on_frame_available_handler_ =
|
| + new OnFrameAvailableHandler(this, surface_texture_.get());
|
| }
|
|
|
| void AVDASharedState::RenderCodecBufferToSurfaceTexture(
|
|
|