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 |