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

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

Issue 20962003: ExynosVideoEncodeAccelerator (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@screencast_vea
Patch Set: a496697c Nits, rebase. Created 7 years, 4 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
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_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698