// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef MEDIA_GPU_ANDROID_AVDA_PICTURE_BUFFER_MANAGER_H_ #define MEDIA_GPU_ANDROID_AVDA_PICTURE_BUFFER_MANAGER_H_ #include #include #include "base/macros.h" #include "media/gpu/android/avda_state_provider.h" #include "media/gpu/android/avda_surface_bundle.h" #include "media/gpu/android/surface_texture_gl_owner.h" #include "media/gpu/media_gpu_export.h" namespace gpu { namespace gles2 { class GLStreamTextureImage; } } // namespace gpu namespace media { class AVDACodecImage; class AVDASharedState; class MediaCodecBridge; // AVDAPictureBufferManager is used by AVDA to associate its PictureBuffers with // MediaCodec output buffers. It attaches AVDACodecImages to the PictureBuffer // textures so that when they're used to draw the AVDACodecImage can release the // MediaCodec buffer to the backing Surface. If the Surface is a TextureOwner, // the front buffer can then be used to draw without needing to copy the pixels. // If the Surface is a SurfaceView, the release causes the frame to be displayed // immediately. class MEDIA_GPU_EXPORT AVDAPictureBufferManager { public: using PictureBufferMap = std::map; explicit AVDAPictureBufferManager(AVDAStateProvider* state_provider); virtual ~AVDAPictureBufferManager(); // Call Initialize, providing the surface bundle that holds the surface that // will back the frames. If an overlay is present in the bundle, then this // will set us up to render codec buffers at the appropriate time for display, // but will assume that consuming the resulting buffers is handled elsewhere // (e.g., SurfaceFlinger). We will ensure that any reference to the bundle // is dropped if the overlay sends OnSurfaceDestroyed. // // Without an overlay, we will create a TextureOwner and add it (and its // surface) to |surface_bundle|. We will arrange to consume the buffers at // the right time, in addition to releasing the codec buffers for rendering. // // One may call these multiple times to change between overlay and ST. // // Picture buffers will be updated to reflect the new surface during the call // to UseCodecBufferForPicture(). // // Returns true on success. bool Initialize(scoped_refptr surface_bundle); void Destroy(const PictureBufferMap& buffers); // Sets up |picture_buffer| so that its texture will refer to the image that // is represented by the decoded output buffer at codec_buffer_index. void UseCodecBufferForPictureBuffer(int32_t codec_buffer_index, const PictureBuffer& picture_buffer); // Assigns a picture buffer and attaches an image to its texture. void AssignOnePictureBuffer(const PictureBuffer& picture_buffer, bool have_context); // Reuses a picture buffer to hold a new frame. void ReuseOnePictureBuffer(const PictureBuffer& picture_buffer); // Release MediaCodec buffers. void ReleaseCodecBuffers(const PictureBufferMap& buffers); // Attempts to free up codec output buffers by rendering early. void MaybeRenderEarly(); // Called when the MediaCodec instance changes. If |codec| is nullptr the // MediaCodec is being destroyed. Previously provided codecs should no longer // be referenced. void CodecChanged(MediaCodecBridge* codec); // Whether the pictures buffers are overlayable. bool ArePicturesOverlayable(); // Are there any unrendered picture buffers oustanding? bool HasUnrenderedPictures() const; // Returns the GL texture target that the PictureBuffer textures use. // Always use OES textures even though this will cause flickering in dev tools // when inspecting a fullscreen video. See http://crbug.com/592798 static constexpr GLenum kTextureTarget = GL_TEXTURE_EXTERNAL_OES; private: // Release any codec buffer that is associated with the given picture buffer // back to the codec. It is okay if there is no such buffer. void ReleaseCodecBufferForPicture(const PictureBuffer& picture_buffer); // Sets up the texture references (as found by |picture_buffer|), for the // specified |image|. If |image| is null, clears any ref on the texture // associated with |picture_buffer|. void SetImageForPicture(const PictureBuffer& picture_buffer, gpu::gles2::GLStreamTextureImage* image); AVDACodecImage* GetImageForPicture(int picture_buffer_id) const; scoped_refptr shared_state_; AVDAStateProvider* const state_provider_; // The texture owner to render to. Non-null after Initialize() if // we're not rendering to a SurfaceView. scoped_refptr texture_owner_; MediaCodecBridge* media_codec_; // Picture buffer IDs that are out for display. Stored in order of frames as // they are returned from the decoder. std::vector pictures_out_for_display_; // Maps a picture buffer id to a AVDACodecImage. std::map> codec_images_; DISALLOW_COPY_AND_ASSIGN(AVDAPictureBufferManager); }; } // namespace media #endif // MEDIA_GPU_ANDROID_AVDA_PICTURE_BUFFER_MANAGER_H_