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