1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CONTENT_COMMON_GPU_MEDIA_ANDROID_VIDEO_DECODE_ACCELERATOR_H_ 6 #define CONTENT_COMMON_GPU_MEDIA_ANDROID_VIDEO_DECODE_ACCELERATOR_H_ 7 8 #include <list> 9 #include <map> 10 #include <queue> 11 #include <string> 12 #include <vector> 13 14 #include "base/compiler_specific.h" 15 #include "base/threading/thread_checker.h" 16 #include "base/timer/timer.h" 17 #include "content/common/content_export.h" 18 #include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h" 19 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" 20 #include "media/base/android/media_codec_bridge.h" 21 #include "media/video/video_decode_accelerator.h" 22 23 namespace gfx { 24 class SurfaceTexture; 25 } 26 27 namespace content { 28 // A VideoDecodeAccelerator implementation for Android. 29 // This class decodes the input encoded stream by using Android's MediaCodec 30 // class. http://developer.android.com/reference/android/media/MediaCodec.html 31 class CONTENT_EXPORT AndroidVideoDecodeAccelerator 32 : public media::VideoDecodeAccelerator { 33 public: 34 // Does not take ownership of |client| which must outlive |*this|. 35 AndroidVideoDecodeAccelerator( 36 const base::WeakPtr<gpu::gles2::GLES2Decoder> decoder, 37 const base::Callback<bool(void)>& make_context_current); 38 39 // media::VideoDecodeAccelerator implementation. 40 virtual bool Initialize(media::VideoCodecProfile profile, 41 Client* client) OVERRIDE; 42 virtual void Decode(const media::BitstreamBuffer& bitstream_buffer) OVERRIDE; 43 virtual void AssignPictureBuffers( 44 const std::vector<media::PictureBuffer>& buffers) OVERRIDE; 45 virtual void ReusePictureBuffer(int32 picture_buffer_id) OVERRIDE; 46 virtual void Flush() OVERRIDE; 47 virtual void Reset() OVERRIDE; 48 virtual void Destroy() OVERRIDE; 49 virtual bool CanDecodeOnIOThread() OVERRIDE; 50 51 private: 52 enum State { 53 NO_ERROR, 54 ERROR, 55 }; 56 57 static const base::TimeDelta kDecodePollDelay; 58 59 virtual ~AndroidVideoDecodeAccelerator(); 60 61 // Configures |media_codec_| with the given codec parameters from the client. 62 bool ConfigureMediaCodec(); 63 64 // Sends the current picture on the surface to the client. 65 void SendCurrentSurfaceToClient(int32 bitstream_id); 66 67 // Does pending IO tasks if any. Once this is called, it polls |media_codec_| 68 // until it finishes pending tasks. For the polling, |kDecodePollDelay| is 69 // used. 70 void DoIOTask(); 71 72 // Feeds input data to |media_codec_|. This checks 73 // |pending_bitstream_buffers_| and queues a buffer to |media_codec_|. 74 void QueueInput(); 75 76 // Dequeues output from |media_codec_| and feeds the decoded frame to the 77 // client. 78 void DequeueOutput(); 79 80 // Requests picture buffers from the client. 81 void RequestPictureBuffers(); 82 83 // Notifies the client about the availability of a picture. 84 void NotifyPictureReady(const media::Picture& picture); 85 86 // Notifies the client that the input buffer identifed by input_buffer_id has 87 // been processed. 88 void NotifyEndOfBitstreamBuffer(int input_buffer_id); 89 90 // Notifies the client that the decoder was flushed. 91 void NotifyFlushDone(); 92 93 // Notifies the client that the decoder was reset. 94 void NotifyResetDone(); 95 96 // Notifies about decoding errors. 97 void NotifyError(media::VideoDecodeAccelerator::Error error); 98 99 // Used to DCHECK that we are called on the correct thread. 100 base::ThreadChecker thread_checker_; 101 102 // To expose client callbacks from VideoDecodeAccelerator. 103 Client* client_; 104 105 // Callback to set the correct gl context. 106 base::Callback<bool(void)> make_context_current_; 107 108 // Codec type. Used when we configure media codec. 109 media::VideoCodec codec_; 110 111 // The current state of this class. For now, this is used only for setting 112 // error state. 113 State state_; 114 115 // This map maintains the picture buffers passed to the client for decoding. 116 // The key is the picture buffer id. 117 typedef std::map<int32, media::PictureBuffer> OutputBufferMap; 118 OutputBufferMap output_picture_buffers_; 119 120 // This keeps the free picture buffer ids which can be used for sending 121 // decoded frames to the client. 122 std::queue<int32> free_picture_ids_; 123 124 // Picture buffer ids which have been dismissed and not yet re-assigned. Used 125 // to ignore ReusePictureBuffer calls that were in flight when the 126 // DismissPictureBuffer call was made. 127 std::set<int32> dismissed_picture_ids_; 128 129 // The low-level decoder which Android SDK provides. 130 scoped_ptr<media::VideoCodecBridge> media_codec_; 131 132 // A container of texture. Used to set a texture to |media_codec_|. 133 scoped_refptr<gfx::SurfaceTexture> surface_texture_; 134 135 // The texture id which is set to |surface_texture_|. 136 uint32 surface_texture_id_; 137 138 // Set to true after requesting picture buffers to the client. 139 bool picturebuffers_requested_; 140 141 // The resolution of the stream. 142 gfx::Size size_; 143 144 // Encoded bitstream buffers to be passed to media codec, queued until an 145 // input buffer is available, along with the time when they were first 146 // enqueued. 147 typedef std::queue<std::pair<media::BitstreamBuffer, base::Time> > 148 PendingBitstreamBuffers; 149 PendingBitstreamBuffers pending_bitstream_buffers_; 150 151 // Keeps track of bitstream ids notified to the client with 152 // NotifyEndOfBitstreamBuffer() before getting output from the bitstream. 153 std::list<int32> bitstreams_notified_in_advance_; 154 155 // Owner of the GL context. Used to restore the context state. 156 base::WeakPtr<gpu::gles2::GLES2Decoder> gl_decoder_; 157 158 // Used for copy the texture from |surface_texture_| to picture buffers. 159 scoped_ptr<gpu::CopyTextureCHROMIUMResourceManager> copier_; 160 161 // Repeating timer responsible for draining pending IO to the codec. 162 base::RepeatingTimer<AndroidVideoDecodeAccelerator> io_timer_; 163 164 // WeakPtrFactory for posting tasks back to |this|. 165 base::WeakPtrFactory<AndroidVideoDecodeAccelerator> weak_this_factory_; 166 167 friend class AndroidVideoDecodeAcceleratorTest; 168 }; 169 170 } // namespace content 171 172 #endif // CONTENT_COMMON_GPU_MEDIA_ANDROID_VIDEO_DECODE_ACCELERATOR_H_ 173