Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(369)

Side by Side Diff: content/common/gpu/media/exynos_video_encode_accelerator.h

Issue 16693005: Add ExynosVideoEncodeAccelerator (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@screencast_cl_5
Patch Set: a1d2f2c4 Bitrate settings. Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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_
Ami GONE FROM CHROMIUM 2013/06/18 01:09:25 TODO+crbug to add a vea_test.
6 #define CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_ENCODE_ACCELERATOR_H_
7
8 #include <list>
9 #include <vector>
10
11 #include "base/callback_forward.h"
12 #include "base/memory/linked_ptr.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/threading/thread.h"
15 #include "content/common/gpu/gl_surface_encoder.h"
16 #include "media/base/video_decoder_config.h"
17 #include "media/video/video_encode_accelerator.h"
18 #include "ui/gfx/size.h"
19 #include "ui/gl/gl_bindings.h"
20
21 namespace base {
22
23 class MessageLoopProxy;
24
25 } // namespace base
26
27 namespace gfx {
28
29 class GLSurface;
30
31 } // namespace gfx
32
33 namespace media {
34
35 class BitstreamBuffer;
36
37 } // namespace media
38
39 namespace content {
40
41 // This class handles Exynos video encode acceleration by interfacing with the
42 // V4L2 devices exported by the Multi Format Codec and GScaler hardware blocks
43 // on the Exynos platform.
Ami GONE FROM CHROMIUM 2013/06/18 01:09:25 Can this be V4L2VEA instead of ExynosVEA? (what ex
Ami GONE FROM CHROMIUM 2013/06/18 01:09:25 sanity check: no dlopen/dlsym's necessary for enco
44 //
45 // The threading model of this class is the same as the
Ami GONE FROM CHROMIUM 2013/06/18 01:09:25 Much like EVDA IWBN to have the poll thread replac
46 // ExynosVideoDecodeAccelerator (from which class this was designed). The one
47 // notable difference is in the thread "ownership" of the GSC free input buffers
48 // queue (gsc_free_input_buffers_). As this queue needs to be queried and
49 // dequeued from the child thread (to obtain a texture to copy the backbuffer
50 // to in Encode()), it is owned by the child thread.
51 class ExynosVideoEncodeAccelerator : public media::VideoEncodeAccelerator {
52 public:
53 ExynosVideoEncodeAccelerator(
54 EGLDisplay egl_display,
55 media::VideoEncodeAccelerator::Client* client,
56 const base::Callback<bool(void)>& make_context_current,
57 bool encode_from_backbuffer);
58 ~ExynosVideoEncodeAccelerator();
59
60 // media::VideoEncodeAccelerator implementation.
61 virtual void Initialize(media::VideoCodecProfile profile,
62 const gfx::Size& input_resolution,
Pawel Osciak 2013/06/17 23:21:56 Do you know if the codec supports in-flight resolu
63 const gfx::Size& output_resolution,
64 int32 initial_bitrate) OVERRIDE;
65 virtual void Encode(
66 const scoped_refptr<media::VideoFrame>& frame,
67 int32 frame_id,
68 bool force_keyframe) OVERRIDE;
69 virtual void UseBitstreamBuffer(
70 const media::BitstreamBuffer& buffer) OVERRIDE;
71 virtual void RequestEncodingParameterChange(int32 bitrate) OVERRIDE;
72 virtual void Destroy() OVERRIDE;
73
74 private:
75 // Auto-destroy reference for BitstreamBuffer, for tracking buffers passed as
76 // input to UseBitstreamBuffer.
77 struct BitstreamBufferRef;
78
79 // Record for GSC input buffers.
Ami GONE FROM CHROMIUM 2013/06/18 01:09:25 :'( for GSC staying in our lives. I take it there
80 struct GscInputRecord {
81 GscInputRecord();
82 bool at_device;
83 int frame_id;
84 EGLSyncKHR egl_sync;
85 EGLImageKHR egl_image;
86 GLuint texture_id;
87 void* address;
88 size_t length;
89 };
90
91 // Record for GSC output buffers.
92 struct GscOutputRecord {
93 GscOutputRecord();
94 bool at_device;
95 int mfc_input;
96 void* address[3];
97 size_t length[3];
98 size_t bytes_used[3];
99 };
100
101 // Record for MFC input buffers.
102 struct MfcInputRecord {
103 MfcInputRecord();
104 bool at_device;
105 int fd[2];
106 };
107
108 // Record for MFC output buffers.
109 struct MfcOutputRecord {
110 MfcOutputRecord();
111 bool at_device;
112 void* address;
113 size_t length;
114 size_t bytes_used;
115 };
116
117 enum {
118 // These are rather subjectively tuned.
119 kGscInputBufferCount = 2,
120 kGscOutputBufferCount = 2,
121 kMfcOutputBufferCount = 3,
122 // MFC hardware does not report required output buffer size correctly.
123 // Use maximum theoretical size to avoid hanging the hardware.
Ami GONE FROM CHROMIUM 2013/06/18 01:09:25 TODO/crbug pointer
Ami GONE FROM CHROMIUM 2013/06/18 01:09:25 What theory makes 2MB the "max theoretical size"?
124 kMfcOutputBufferSize = (2 * 1024 * 1024),
125 };
126
127 // Internal state of the encoder.
128 enum State {
129 kUninitialized, // Initialize() not yet called.
130 kInitialized, // Initialize() returned true; ready to start decoding.
Ami GONE FROM CHROMIUM 2013/06/18 01:09:25 "decoding"
131 kEncoding, // Encoding frames.
132 kError, // Error in kEncoding state.
133 };
134
135 // File descriptors we need to poll.
Ami GONE FROM CHROMIUM 2013/06/18 01:09:25 Reword to avoid implying that the actual FDs are 0
136 enum PollFds {
Ami GONE FROM CHROMIUM 2013/06/18 01:09:25 can live in the .cc file
137 kPollGsc = (1 << 0),
138 kPollMfc = (1 << 1),
139 };
140
141 //
142 // Child thread utility functions, supporting API entry points.
143 //
144
145 // Return a buffer to gsc_free_input_buffers_.
146 void ReturnFreeGscInputBuffer(int index);
147
148 //
149 // Decoding tasks, to be run on encode_thread_.
Pawel Osciak 2013/06/17 23:21:56 s/encode_thread_/encoder_thread_/
Ami GONE FROM CHROMIUM 2013/06/18 01:09:25 lol Decoding...encode...
150 //
151
152 // Encode a GSC input buffer.
153 void EncodeTask(int gsc_input_index);
154
155 // Copy a media::VideoFrame to the GSC input buffer, then encode it.
156 void CopyFrameAndEncodeTask(const scoped_refptr<media::VideoFrame>& frame,
157 int gsc_input_index);
158
159 // Add a BitstreamBuffer to out queue of buffers ready to be used for client
160 // output.
161 void UseBitstreamBufferTask(scoped_ptr<BitstreamBufferRef> buffer_ref);
162
163 // Device destruction task.
164 void DestroyTask();
165
166 // Service I/O on the V4L2 devices. This task should only be scheduled from
167 // DevicePollTask().
168 void ServiceDeviceTask();
169 // Handle the various device queues.
170 void EnqueueGsc();
171 void DequeueGsc();
172 void EnqueueMfc();
173 void DequeueMfc();
174 // Enqueue a buffer on the corresponding queue.
175 bool EnqueueGscInputRecord();
Ami GONE FROM CHROMIUM 2013/06/18 01:09:25 here and below, doco that a false return means fat
176 bool EnqueueGscOutputRecord();
177 bool EnqueueMfcInputRecord();
178 bool EnqueueMfcOutputRecord();
179 // Return completed buffers to the client.
Pawel Osciak 2013/06/17 23:21:56 Doco which buffers (bitstream buffers)?
180 void ReturnCompleteBuffers();
181
182 // Attempt to start/stop device_poll_thread_.
183 bool StartDevicePoll();
184 bool StopDevicePoll();
185 // Set/clear the device poll interrupt (using device_ooll_interrupt_fd_).
Ami GONE FROM CHROMIUM 2013/06/18 01:09:25 typo: ooll
186 bool SetDevicePollInterrupt();
187 bool ClearDevicePollInterrupt();
188
189 //
190 // Device tasks, to be run on device_poll_thread_.
191 //
192
193 // The device task.
194 void DevicePollTask(unsigned int poll_fds);
195
196 //
197 // Safe from any thread.
198 //
199
200 // Error notification (using PostTask() to child thread, if necessary).
201 void NotifyError(Error error);
202
203 // Set the encoder_thread_ state (using PostTask to encoder thread, if
204 // necessary).
205 void SetEncoderState(State state);
206
207 //
208 // Other utility functions. Called on encoder_thread_, unless
209 // encoder_thread_ is not yet started, in which case the child thread can call
210 // these (e.g. in Initialize() or Destroy()).
211 //
212
213 // Create the buffers we need.
214 bool CreateGscInputBuffers();
215 bool CreateGscOutputBuffers();
216 bool SetMfcFormats();
Ami GONE FROM CHROMIUM 2013/06/18 01:09:25 Not really "creat[ing] the buffers we need".
217 bool CreateMfcInputBuffers();
218 bool CreateMfcOutputBuffers();
219
220 // Set encoding parameters.
221 void SetBitrate(int32 bitrate);
222
223 // Destroy these buffers.
224 void DestroyGscInputBuffers();
225 void DestroyGscOutputBuffers();
226 void DestroyMfcInputBuffers();
227 void DestroyMfcOutputBuffers();
228
229 // Our original calling message loop for the child thread.
230 const scoped_refptr<base::MessageLoopProxy> child_message_loop_proxy_;
231
232 // WeakPtr<> pointing to |this| for use in posting tasks from the encoder or
233 // device worker threads back to the child thread. Because the worker threads
234 // are members of this class, any task running on those threads is guaranteed
235 // that this object is still alive. As a result, tasks posted from the child
236 // thread to the encoder or device thread should use base::Unretained(this),
237 // and tasks posted the other way should use |weak_this_|.
238 base::WeakPtrFactory<ExynosVideoEncodeAccelerator> weak_this_ptr_factory_;
239 base::WeakPtr<ExynosVideoEncodeAccelerator> weak_this_;
240
241 // To expose client callbacks from VideoEncodeAccelerator.
242 // NOTE: all calls to these objects *MUST* be executed on
243 // child_message_loop_proxy_.
244 base::WeakPtrFactory<Client> client_ptr_factory_;
245 base::WeakPtr<Client> client_;
246
247 //
248 // Encoder state, owned and operated by encoder_thread_.
249 // Before encoder_thread_ has started, the encoder state is managed by
250 // the child (main) thread. After encoder_thread_ has started, the encoder
251 // thread should be the only one managing these.
252 //
253
254 // This thread services tasks posted from the VEA API entry points by the
255 // child thread and device service callbacks posted from the device thread.
256 base::Thread encoder_thread_;
257 // Encoder state machine state.
Ami GONE FROM CHROMIUM 2013/06/18 01:09:25 There's no explicit "machine" so drop "machine st
258 State encoder_state_;
259 // The visible/allocated sizes of the input frame.
260 gfx::Size input_visible_size_;
Ami GONE FROM CHROMIUM 2013/06/18 01:09:25 "visible" is usually a Rect, not a Size, and it ca
261 gfx::Size input_allocated_size_;
262 // The visible/allocated sizes of the color-converted frame.
263 gfx::Size converted_visible_size_;
Pawel Osciak 2013/06/17 23:21:56 Perhaps I'm misunderstanding the intentions here,
264 gfx::Size converted_allocated_size_;
265 // The visible/allocated sizes of the output frame.
266 gfx::Size output_visible_size_;
267 // The required byte size of output BitstreamBuffers.
268 size_t output_buffer_byte_size_;
269
270 // Bitstream buffers ready to be used to return encoded output.
271 std::vector<linked_ptr<BitstreamBufferRef> > encoder_bitstream_buffers_;
272
273 // Buffers ready to be encoded.
Ami GONE FROM CHROMIUM 2013/06/18 01:09:25 Here and elsewhere, doco what the int is an index
274 std::list<int> encoder_input_queue_;
275
276 // Encoded buffers ready to return to the client.
277 std::list<int> encoder_output_queue_;
278
279 // Flag if we are encoding the output (and using MFC).
Pawel Osciak 2013/06/17 23:21:56 In what scenario we'd not want to encode? Is this
280 bool do_output_encoding_;
281
282 // Flag if we are encoding from the backbuffer (instead of a CPU allocation).
283 const bool do_encode_from_backbuffer_;
284
285 // GSC color conversion device.
286 int gsc_fd_;
287 // GSC input buffer state.
288 bool gsc_input_streamon_;
289 // GSC input buffers enqueued to device.
290 int gsc_input_buffer_queued_count_;
291 // Mapping of int index to GSC input buffer record.
292 std::vector<GscInputRecord> gsc_input_buffer_map_;
Ami GONE FROM CHROMIUM 2013/06/18 01:09:25 s/_map_/s_/ and similarly update comment since thi
293
294 // GSC output buffer state.
295 bool gsc_output_streamon_;
296 // GSC output buffers enqueued to device.
297 int gsc_output_buffer_queued_count_;
298 // Output buffers ready to use, as a LIFO since we don't care about ordering.
299 std::vector<int> gsc_free_output_buffers_;
300 // Mapping of int index to GSC output buffer record.
301 std::vector<GscOutputRecord> gsc_output_buffer_map_;
302
303 // Completed GSC outputs, waiting for GSC.
Ami GONE FROM CHROMIUM 2013/06/18 01:09:25 lolwat?
304 std::list<int> gsc_output_mfc_input_queue_;
Pawel Osciak 2013/06/17 23:21:56 s/waiting for GSC/waiting for MFC/ ?
305
306 // MFC video encoding device.
307 int mfc_fd_;
308
309 // MFC input buffer state.
310 bool mfc_input_streamon_;
311 // MFC input buffers enqueued to device.
312 int mfc_input_buffer_queued_count_;
313 // Input buffers ready to use, as a LIFO since we don't care about ordering.
314 std::vector<int> mfc_free_input_buffers_;
315 // Mapping of int index to MFC input buffer record.
316 std::vector<MfcInputRecord> mfc_input_buffer_map_;
317
318 // MFC output buffer state.
319 bool mfc_output_streamon_;
320 // MFC output buffers enqueued to device.
321 int mfc_output_buffer_queued_count_;
322 // Output buffers ready to use, as a LIFO since we don't care about ordering.
323 std::vector<int> mfc_free_output_buffers_;
324 // Mapping of int index to MFC output buffer record.
325 std::vector<MfcOutputRecord> mfc_output_buffer_map_;
326
327 //
328 // The device polling thread handles notifications of V4L2 device changes.
329 //
330
331 // The thread.
332 base::Thread device_poll_thread_;
333 // eventfd fd to signal device poll thread when its poll() should be
334 // interrupted.
335 int device_poll_interrupt_fd_;
336
337 //
338 // Other state, held by child (main) thread.
339 //
340
341 // Make our context current before running any EGL entry points.
342 base::Callback<bool(void)> make_context_current_;
343
344 // Input buffers ready to use, as a LIFO since we don't care about ordering.
345 std::vector<int> gsc_free_input_buffers_;
Ami GONE FROM CHROMIUM 2013/06/18 01:09:25 This is both read & written on both the child thre
346
347 // EGL state
348 const EGLDisplay egl_display_;
349
350 // The codec we'll be decoding for.
Ami GONE FROM CHROMIUM 2013/06/18 01:09:25 encoding
351 media::VideoCodecProfile video_profile_;
352 };
353
354 } // namespace content
355
356 #endif // CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_ENCODE_ACCELERATOR_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698