1 // Copyright 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.
5 #ifndef CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_ENCODE_ACCELERATOR_H_
6 #define CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_ENCODE_ACCELERATOR_H_
11 #include "base/memory/linked_ptr.h"
12 #include "base/memory/weak_ptr.h"
13 #include "base/threading/thread.h"
14 #include "content/common/content_export.h"
15 #include "media/video/video_encode_accelerator.h"
16 #include "ui/gfx/size.h"
20 class MessageLoopProxy;
26 class BitstreamBuffer;
32 // This class handles Exynos video encode acceleration by interfacing with the
33 // V4L2 devices exported by the Multi Format Codec and GScaler hardware blocks
34 // on the Exynos platform. The threading model of this class is the same as the
35 // ExynosVideoDecodeAccelerator (from which class this was designed).
36 class CONTENT_EXPORT ExynosVideoEncodeAccelerator
37 : public media::VideoEncodeAccelerator {
39 ExynosVideoEncodeAccelerator();
40 virtual ~ExynosVideoEncodeAccelerator();
42 // media::VideoEncodeAccelerator implementation.
43 virtual void Initialize(media::VideoFrame::Format format,
44 const gfx::Size& input_visible_size,
45 media::VideoCodecProfile output_profile,
46 uint32 initial_bitrate,
47 Client* client) OVERRIDE;
48 virtual void Encode(const scoped_refptr<media::VideoFrame>& frame,
49 bool force_keyframe) OVERRIDE;
50 virtual void UseOutputBitstreamBuffer(
51 const media::BitstreamBuffer& buffer) OVERRIDE;
52 virtual void RequestEncodingParametersChange(uint32 bitrate,
53 uint32 framerate) OVERRIDE;
54 virtual void Destroy() OVERRIDE;
56 static std::vector<media::VideoEncodeAccelerator::SupportedProfile>
57 GetSupportedProfiles();
60 // Auto-destroy reference for BitstreamBuffer, for tracking buffers passed to
62 struct BitstreamBufferRef;
64 // Record for GSC input buffers.
65 struct GscInputRecord {
68 scoped_refptr<media::VideoFrame> frame;
71 // Record for GSC output buffers.
72 struct GscOutputRecord {
78 // Record for MFC input buffers.
79 struct MfcInputRecord {
85 // Record for MFC output buffers.
86 struct MfcOutputRecord {
89 linked_ptr<BitstreamBufferRef> buffer_ref;
95 kInitialFramerate = 30,
96 // These are rather subjectively tuned.
97 kGscInputBufferCount = 2,
98 kGscOutputBufferCount = 2,
99 kMfcOutputBufferCount = 2,
100 // MFC hardware does not report required output buffer size correctly.
101 // Use maximum theoretical size to avoid hanging the hardware.
102 kMfcOutputBufferSize = (2 * 1024 * 1024),
105 // Internal state of the encoder.
107 kUninitialized, // Initialize() not yet called.
108 kInitialized, // Initialize() returned true; ready to start encoding.
109 kEncoding, // Encoding frames.
110 kError, // Error in encoder state.
114 // Encoding tasks, to be run on encode_thread_.
117 // Encode a GSC input buffer.
118 void EncodeTask(const scoped_refptr<media::VideoFrame>& frame,
119 bool force_keyframe);
121 // Add a BitstreamBuffer to the queue of buffers ready to be used for encoder
123 void UseOutputBitstreamBufferTask(scoped_ptr<BitstreamBufferRef> buffer_ref);
125 // Device destruction task.
128 // Service I/O on the V4L2 devices. This task should only be scheduled from
130 void ServiceDeviceTask();
132 // Handle the various device queues.
137 // Enqueue a buffer on the corresponding queue. Returns false on fatal error.
138 bool EnqueueGscInputRecord();
139 bool EnqueueGscOutputRecord();
140 bool EnqueueMfcInputRecord();
141 bool EnqueueMfcOutputRecord();
143 // Attempt to start/stop device_poll_thread_.
144 bool StartDevicePoll();
145 bool StopDevicePoll();
146 // Set/clear the device poll interrupt (using device_poll_interrupt_fd_).
147 bool SetDevicePollInterrupt();
148 bool ClearDevicePollInterrupt();
151 // Device tasks, to be run on device_poll_thread_.
155 void DevicePollTask(unsigned int poll_fds);
158 // Safe from any thread.
161 // Error notification (using PostTask() to child thread, if necessary).
162 void NotifyError(Error error);
164 // Set the encoder_thread_ state (using PostTask to encoder thread, if
166 void SetEncoderState(State state);
169 // Other utility functions. Called on encoder_thread_, unless
170 // encoder_thread_ is not yet started, in which case the child thread can call
171 // these (e.g. in Initialize() or Destroy()).
174 // Change the parameters of encoding.
175 void RequestEncodingParametersChangeTask(uint32 bitrate, uint32 framerate);
177 // Create the buffers we need.
178 bool CreateGscInputBuffers();
179 bool CreateGscOutputBuffers();
180 bool SetMfcFormats();
181 bool InitMfcControls();
182 bool CreateMfcInputBuffers();
183 bool CreateMfcOutputBuffers();
185 // Destroy these buffers.
186 void DestroyGscInputBuffers();
187 void DestroyGscOutputBuffers();
188 void DestroyMfcInputBuffers();
189 void DestroyMfcOutputBuffers();
191 // Our original calling message loop for the child thread.
192 const scoped_refptr<base::MessageLoopProxy> child_message_loop_proxy_;
194 // WeakPtr<> pointing to |this| for use in posting tasks from the encoder or
195 // device worker threads back to the child thread. Because the worker threads
196 // are members of this class, any task running on those threads is guaranteed
197 // that this object is still alive. As a result, tasks posted from the child
198 // thread to the encoder or device thread should use base::Unretained(this),
199 // and tasks posted the other way should use |weak_this_|.
200 base::WeakPtrFactory<ExynosVideoEncodeAccelerator> weak_this_ptr_factory_;
201 base::WeakPtr<ExynosVideoEncodeAccelerator> weak_this_;
203 // To expose client callbacks from VideoEncodeAccelerator.
204 // NOTE: all calls to these objects *MUST* be executed on
205 // child_message_loop_proxy_.
206 scoped_ptr<base::WeakPtrFactory<Client> > client_ptr_factory_;
207 base::WeakPtr<Client> client_;
210 // Encoder state, owned and operated by encoder_thread_.
211 // Before encoder_thread_ has started, the encoder state is managed by
212 // the child (main) thread. After encoder_thread_ has started, the encoder
213 // thread should be the only one managing these.
216 // This thread services tasks posted from the VEA API entry points by the
217 // child thread and device service callbacks posted from the device thread.
218 base::Thread encoder_thread_;
220 State encoder_state_;
221 // The visible/allocated sizes of the input frame.
222 gfx::Size input_visible_size_;
223 gfx::Size input_allocated_size_;
224 // The visible/allocated sizes of the color-converted intermediate frame.
225 gfx::Size converted_visible_size_;
226 gfx::Size converted_allocated_size_;
227 // The logical visible size of the output frame.
228 gfx::Size output_visible_size_;
229 // The required byte size of output BitstreamBuffers.
230 size_t output_buffer_byte_size_;
232 // We need to provide the stream header with every keyframe, to allow
233 // midstream decoding restarts. Store it here.
234 scoped_ptr<uint8[]> stream_header_;
235 size_t stream_header_size_;
237 // V4L2 formats for input frames and the output stream.
238 uint32 input_format_fourcc_;
239 uint32 output_format_fourcc_;
241 // Video frames ready to be encoded.
242 std::list<scoped_refptr<media::VideoFrame> > encoder_input_queue_;
244 // GSC color conversion device.
246 // GSC input queue state.
247 bool gsc_input_streamon_;
248 // GSC input buffers enqueued to device.
249 int gsc_input_buffer_queued_count_;
250 // GSC input buffers ready to use; LIFO since we don't care about ordering.
251 std::vector<int> gsc_free_input_buffers_;
252 // Mapping of int index to GSC input buffer record.
253 std::vector<GscInputRecord> gsc_input_buffer_map_;
255 // GSC output queue state.
256 bool gsc_output_streamon_;
257 // GSC output buffers enqueued to device.
258 int gsc_output_buffer_queued_count_;
259 // GSC output buffers ready to use; LIFO since we don't care about ordering.
260 std::vector<int> gsc_free_output_buffers_;
261 // Mapping of int index to GSC output buffer record.
262 std::vector<GscOutputRecord> gsc_output_buffer_map_;
264 // MFC input buffers filled by GSC, waiting to be queued to MFC.
265 std::list<int> mfc_ready_input_buffers_;
267 // MFC video encoding device.
270 // MFC input queue state.
271 bool mfc_input_streamon_;
272 // MFC input buffers enqueued to device.
273 int mfc_input_buffer_queued_count_;
274 // MFC input buffers ready to use; LIFO since we don't care about ordering.
275 std::vector<int> mfc_free_input_buffers_;
276 // Mapping of int index to MFC input buffer record.
277 std::vector<MfcInputRecord> mfc_input_buffer_map_;
279 // MFC output queue state.
280 bool mfc_output_streamon_;
281 // MFC output buffers enqueued to device.
282 int mfc_output_buffer_queued_count_;
283 // MFC output buffers ready to use; LIFO since we don't care about ordering.
284 std::vector<int> mfc_free_output_buffers_;
285 // Mapping of int index to MFC output buffer record.
286 std::vector<MfcOutputRecord> mfc_output_buffer_map_;
288 // Bitstream buffers ready to be used to return encoded output, as a LIFO
289 // since we don't care about ordering.
290 std::vector<linked_ptr<BitstreamBufferRef> > encoder_output_queue_;
293 // The device polling thread handles notifications of V4L2 device changes.
294 // TODO(sheu): replace this thread with an TYPE_IO encoder_thread_.
298 base::Thread device_poll_thread_;
299 // eventfd fd to signal device poll thread when its poll() should be
301 int device_poll_interrupt_fd_;
303 DISALLOW_COPY_AND_ASSIGN(ExynosVideoEncodeAccelerator);
306 } // namespace content
308 #endif // CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_ENCODE_ACCELERATOR_H_