1 // Copyright 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_EXYNOS_VIDEO_ENCODE_ACCELERATOR_H_ 6 #define CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_ENCODE_ACCELERATOR_H_ 7 8 #include <list> 9 #include <vector> 10 11 #include "base/memory/linked_ptr.h" 12 #include "base/memory/weak_ptr.h" 13 #include "base/threading/thread.h" 14 #include "content/common/content_export.h" 15 #include "media/video/video_encode_accelerator.h" 16 #include "ui/gfx/size.h" 17 18 namespace base { 19 20 class MessageLoopProxy; 21 22 } // namespace base 23 24 namespace media { 25 26 class BitstreamBuffer; 27 28 } // namespace media 29 30 namespace content { 31 32 // This class handles Exynos video encode acceleration by interfacing with the 33 // V4L2 devices exported by the Multi Format Codec and GScaler hardware blocks 34 // on the Exynos platform. The threading model of this class is the same as the 35 // ExynosVideoDecodeAccelerator (from which class this was designed). 36 class CONTENT_EXPORT ExynosVideoEncodeAccelerator 37 : public media::VideoEncodeAccelerator { 38 public: 39 explicit ExynosVideoEncodeAccelerator( 40 media::VideoEncodeAccelerator::Client* client); 41 virtual ~ExynosVideoEncodeAccelerator(); 42 43 // media::VideoEncodeAccelerator implementation. 44 virtual void Initialize(media::VideoFrame::Format format, 45 const gfx::Size& input_visible_size, 46 media::VideoCodecProfile output_profile, 47 uint32 initial_bitrate) OVERRIDE; 48 virtual void Encode(const scoped_refptr<media::VideoFrame>& frame, 49 bool force_keyframe) OVERRIDE; 50 virtual void UseOutputBitstreamBuffer( 51 const media::BitstreamBuffer& buffer) OVERRIDE; 52 virtual void RequestEncodingParametersChange(uint32 bitrate, 53 uint32 framerate) OVERRIDE; 54 virtual void Destroy() OVERRIDE; 55 56 static std::vector<media::VideoEncodeAccelerator::SupportedProfile> 57 GetSupportedProfiles(); 58 59 private: 60 // Auto-destroy reference for BitstreamBuffer, for tracking buffers passed to 61 // this instance. 62 struct BitstreamBufferRef; 63 64 // Record for GSC input buffers. 65 struct GscInputRecord { 66 GscInputRecord(); 67 bool at_device; 68 scoped_refptr<media::VideoFrame> frame; 69 }; 70 71 // Record for GSC output buffers. 72 struct GscOutputRecord { 73 GscOutputRecord(); 74 bool at_device; 75 int mfc_input; 76 }; 77 78 // Record for MFC input buffers. 79 struct MfcInputRecord { 80 MfcInputRecord(); 81 bool at_device; 82 int fd[2]; 83 }; 84 85 // Record for MFC output buffers. 86 struct MfcOutputRecord { 87 MfcOutputRecord(); 88 bool at_device; 89 linked_ptr<BitstreamBufferRef> buffer_ref; 90 void* address; 91 size_t length; 92 }; 93 94 enum { 95 kInitialFramerate = 30, 96 // These are rather subjectively tuned. 97 kGscInputBufferCount = 2, 98 kGscOutputBufferCount = 2, 99 kMfcOutputBufferCount = 2, 100 // MFC hardware does not report required output buffer size correctly. 101 // Use maximum theoretical size to avoid hanging the hardware. 102 kMfcOutputBufferSize = (2 * 1024 * 1024), 103 }; 104 105 // Internal state of the encoder. 106 enum State { 107 kUninitialized, // Initialize() not yet called. 108 kInitialized, // Initialize() returned true; ready to start encoding. 109 kEncoding, // Encoding frames. 110 kError, // Error in encoder state. 111 }; 112 113 // 114 // Encoding tasks, to be run on encode_thread_. 115 // 116 117 // Encode a GSC input buffer. 118 void EncodeTask(const scoped_refptr<media::VideoFrame>& frame, 119 bool force_keyframe); 120 121 // Add a BitstreamBuffer to the queue of buffers ready to be used for encoder 122 // output. 123 void UseOutputBitstreamBufferTask(scoped_ptr<BitstreamBufferRef> buffer_ref); 124 125 // Device destruction task. 126 void DestroyTask(); 127 128 // Service I/O on the V4L2 devices. This task should only be scheduled from 129 // DevicePollTask(). 130 void ServiceDeviceTask(); 131 132 // Handle the various device queues. 133 void EnqueueGsc(); 134 void DequeueGsc(); 135 void EnqueueMfc(); 136 void DequeueMfc(); 137 // Enqueue a buffer on the corresponding queue. Returns false on fatal error. 138 bool EnqueueGscInputRecord(); 139 bool EnqueueGscOutputRecord(); 140 bool EnqueueMfcInputRecord(); 141 bool EnqueueMfcOutputRecord(); 142 143 // Attempt to start/stop device_poll_thread_. 144 bool StartDevicePoll(); 145 bool StopDevicePoll(); 146 // Set/clear the device poll interrupt (using device_poll_interrupt_fd_). 147 bool SetDevicePollInterrupt(); 148 bool ClearDevicePollInterrupt(); 149 150 // 151 // Device tasks, to be run on device_poll_thread_. 152 // 153 154 // The device task. 155 void DevicePollTask(unsigned int poll_fds); 156 157 // 158 // Safe from any thread. 159 // 160 161 // Error notification (using PostTask() to child thread, if necessary). 162 void NotifyError(Error error); 163 164 // Set the encoder_thread_ state (using PostTask to encoder thread, if 165 // necessary). 166 void SetEncoderState(State state); 167 168 // 169 // Other utility functions. Called on encoder_thread_, unless 170 // encoder_thread_ is not yet started, in which case the child thread can call 171 // these (e.g. in Initialize() or Destroy()). 172 // 173 174 // Change the parameters of encoding. 175 void RequestEncodingParametersChangeTask(uint32 bitrate, uint32 framerate); 176 177 // Create the buffers we need. 178 bool CreateGscInputBuffers(); 179 bool CreateGscOutputBuffers(); 180 bool SetMfcFormats(); 181 bool InitMfcControls(); 182 bool CreateMfcInputBuffers(); 183 bool CreateMfcOutputBuffers(); 184 185 // Destroy these buffers. 186 void DestroyGscInputBuffers(); 187 void DestroyGscOutputBuffers(); 188 void DestroyMfcInputBuffers(); 189 void DestroyMfcOutputBuffers(); 190 191 // Our original calling message loop for the child thread. 192 const scoped_refptr<base::MessageLoopProxy> child_message_loop_proxy_; 193 194 // WeakPtr<> pointing to |this| for use in posting tasks from the encoder or 195 // device worker threads back to the child thread. Because the worker threads 196 // are members of this class, any task running on those threads is guaranteed 197 // that this object is still alive. As a result, tasks posted from the child 198 // thread to the encoder or device thread should use base::Unretained(this), 199 // and tasks posted the other way should use |weak_this_|. 200 base::WeakPtrFactory<ExynosVideoEncodeAccelerator> weak_this_ptr_factory_; 201 base::WeakPtr<ExynosVideoEncodeAccelerator> weak_this_; 202 203 // To expose client callbacks from VideoEncodeAccelerator. 204 // NOTE: all calls to these objects *MUST* be executed on 205 // child_message_loop_proxy_. 206 base::WeakPtrFactory<Client> client_ptr_factory_; 207 base::WeakPtr<Client> client_; 208 209 // 210 // Encoder state, owned and operated by encoder_thread_. 211 // Before encoder_thread_ has started, the encoder state is managed by 212 // the child (main) thread. After encoder_thread_ has started, the encoder 213 // thread should be the only one managing these. 214 // 215 216 // This thread services tasks posted from the VEA API entry points by the 217 // child thread and device service callbacks posted from the device thread. 218 base::Thread encoder_thread_; 219 // Encoder state. 220 State encoder_state_; 221 // The visible/allocated sizes of the input frame. 222 gfx::Size input_visible_size_; 223 gfx::Size input_allocated_size_; 224 // The visible/allocated sizes of the color-converted intermediate frame. 225 gfx::Size converted_visible_size_; 226 gfx::Size converted_allocated_size_; 227 // The logical visible size of the output frame. 228 gfx::Size output_visible_size_; 229 // The required byte size of output BitstreamBuffers. 230 size_t output_buffer_byte_size_; 231 232 // We need to provide the stream header with every keyframe, to allow 233 // midstream decoding restarts. Store it here. 234 scoped_ptr<uint8[]> stream_header_; 235 size_t stream_header_size_; 236 237 // V4L2 formats for input frames and the output stream. 238 uint32 input_format_fourcc_; 239 uint32 output_format_fourcc_; 240 241 // Video frames ready to be encoded. 242 std::list<scoped_refptr<media::VideoFrame> > encoder_input_queue_; 243 244 // GSC color conversion device. 245 int gsc_fd_; 246 // GSC input queue state. 247 bool gsc_input_streamon_; 248 // GSC input buffers enqueued to device. 249 int gsc_input_buffer_queued_count_; 250 // GSC input buffers ready to use; LIFO since we don't care about ordering. 251 std::vector<int> gsc_free_input_buffers_; 252 // Mapping of int index to GSC input buffer record. 253 std::vector<GscInputRecord> gsc_input_buffer_map_; 254 255 // GSC output queue state. 256 bool gsc_output_streamon_; 257 // GSC output buffers enqueued to device. 258 int gsc_output_buffer_queued_count_; 259 // GSC output buffers ready to use; LIFO since we don't care about ordering. 260 std::vector<int> gsc_free_output_buffers_; 261 // Mapping of int index to GSC output buffer record. 262 std::vector<GscOutputRecord> gsc_output_buffer_map_; 263 264 // MFC input buffers filled by GSC, waiting to be queued to MFC. 265 std::list<int> mfc_ready_input_buffers_; 266 267 // MFC video encoding device. 268 int mfc_fd_; 269 270 // MFC input queue state. 271 bool mfc_input_streamon_; 272 // MFC input buffers enqueued to device. 273 int mfc_input_buffer_queued_count_; 274 // MFC input buffers ready to use; LIFO since we don't care about ordering. 275 std::vector<int> mfc_free_input_buffers_; 276 // Mapping of int index to MFC input buffer record. 277 std::vector<MfcInputRecord> mfc_input_buffer_map_; 278 279 // MFC output queue state. 280 bool mfc_output_streamon_; 281 // MFC output buffers enqueued to device. 282 int mfc_output_buffer_queued_count_; 283 // MFC output buffers ready to use; LIFO since we don't care about ordering. 284 std::vector<int> mfc_free_output_buffers_; 285 // Mapping of int index to MFC output buffer record. 286 std::vector<MfcOutputRecord> mfc_output_buffer_map_; 287 288 // Bitstream buffers ready to be used to return encoded output, as a LIFO 289 // since we don't care about ordering. 290 std::vector<linked_ptr<BitstreamBufferRef> > encoder_output_queue_; 291 292 // 293 // The device polling thread handles notifications of V4L2 device changes. 294 // TODO(sheu): replace this thread with an TYPE_IO encoder_thread_. 295 // 296 297 // The thread. 298 base::Thread device_poll_thread_; 299 // eventfd fd to signal device poll thread when its poll() should be 300 // interrupted. 301 int device_poll_interrupt_fd_; 302 303 DISALLOW_COPY_AND_ASSIGN(ExynosVideoEncodeAccelerator); 304 }; 305 306 } // namespace content 307 308 #endif // CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_ENCODE_ACCELERATOR_H_ 309