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