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

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

Powered by Google App Engine
This is Rietveld 408576698