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

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: b673f1a3 WIP - for posciak@ Created 7 years, 5 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_
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.
44 //
45 // The threading model of this class is the same as the
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,
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.
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.
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.
131 kEncoding, // Encoding frames.
132 kError, // Error in kEncoding state.
133 };
134
135 // File descriptors we need to poll.
136 enum PollFds {
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_.
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();
176 bool EnqueueGscOutputRecord();
177 bool EnqueueMfcInputRecord();
178 bool EnqueueMfcOutputRecord();
179 // Return completed buffers to the client.
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_).
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();
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.
258 State encoder_state_;
259 // The visible/allocated sizes of the input frame.
260 gfx::Size input_visible_size_;
261 gfx::Size input_allocated_size_;
262 // The visible/allocated sizes of the color-converted frame.
263 gfx::Size converted_visible_size_;
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 // Cached stream header.
271 scoped_ptr<uint8[]> stream_header_;
272 size_t stream_header_size_;
273
274 // Bitstream buffers ready to be used to return encoded output.
275 std::vector<linked_ptr<BitstreamBufferRef> > encoder_bitstream_buffers_;
276
277 // Buffers ready to be encoded.
278 std::list<int> encoder_input_queue_;
279
280 // Encoded buffers ready to return to the client.
281 std::list<int> encoder_output_queue_;
282
283 // Flag if we are encoding the output (and using MFC).
284 bool do_output_encoding_;
285
286 // Flag if we are encoding from the backbuffer (instead of a CPU allocation).
287 const bool do_encode_from_backbuffer_;
288
289 // GSC color conversion device.
290 int gsc_fd_;
291 // GSC input buffer state.
292 bool gsc_input_streamon_;
293 // GSC input buffers enqueued to device.
294 int gsc_input_buffer_queued_count_;
295 // Mapping of int index to GSC input buffer record.
296 std::vector<GscInputRecord> gsc_input_buffer_map_;
297
298 // GSC output buffer state.
299 bool gsc_output_streamon_;
300 // GSC output buffers enqueued to device.
301 int gsc_output_buffer_queued_count_;
302 // Output buffers ready to use, as a LIFO since we don't care about ordering.
303 std::vector<int> gsc_free_output_buffers_;
304 // Mapping of int index to GSC output buffer record.
305 std::vector<GscOutputRecord> gsc_output_buffer_map_;
306
307 // Completed GSC outputs, waiting for GSC.
308 std::list<int> gsc_output_mfc_input_queue_;
309
310 // MFC video encoding device.
311 int mfc_fd_;
312
313 // MFC input buffer state.
314 bool mfc_input_streamon_;
315 // MFC input buffers enqueued to device.
316 int mfc_input_buffer_queued_count_;
317 // Input buffers ready to use, as a LIFO since we don't care about ordering.
318 std::vector<int> mfc_free_input_buffers_;
319 // Mapping of int index to MFC input buffer record.
320 std::vector<MfcInputRecord> mfc_input_buffer_map_;
321
322 // MFC output buffer state.
323 bool mfc_output_streamon_;
324 // MFC output buffers enqueued to device.
325 int mfc_output_buffer_queued_count_;
326 // Output buffers ready to use, as a LIFO since we don't care about ordering.
327 std::vector<int> mfc_free_output_buffers_;
328 // Mapping of int index to MFC output buffer record.
329 std::vector<MfcOutputRecord> mfc_output_buffer_map_;
330
331 //
332 // The device polling thread handles notifications of V4L2 device changes.
333 //
334
335 // The thread.
336 base::Thread device_poll_thread_;
337 // eventfd fd to signal device poll thread when its poll() should be
338 // interrupted.
339 int device_poll_interrupt_fd_;
340
341 //
342 // Other state, held by child (main) thread.
343 //
344
345 // Make our context current before running any EGL entry points.
346 base::Callback<bool(void)> make_context_current_;
347
348 // Input buffers ready to use, as a LIFO since we don't care about ordering.
349 std::vector<int> gsc_free_input_buffers_;
350
351 // EGL state
352 const EGLDisplay egl_display_;
353
354 // The codec we'll be decoding for.
355 media::VideoCodecProfile video_profile_;
356 };
357
358 } // namespace content
359
360 #endif // CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_ENCODE_ACCELERATOR_H_
OLDNEW
« no previous file with comments | « content/common/gpu/gl_surface_encoder.cc ('k') | content/common/gpu/media/exynos_video_encode_accelerator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698