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 "media/video/video_encode_accelerator.h"
15 #include "ui/gfx/size.h"
19 class MessageLoopProxy
;
25 class BitstreamBuffer
;
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
{
37 explicit ExynosVideoEncodeAccelerator(
38 media::VideoEncodeAccelerator::Client
* client
);
39 virtual ~ExynosVideoEncodeAccelerator();
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
;
54 static std::vector
<media::VideoEncodeAccelerator::SupportedProfile
>
55 GetSupportedProfiles();
58 // Auto-destroy reference for BitstreamBuffer, for tracking buffers passed to
60 struct BitstreamBufferRef
;
62 // Record for GSC input buffers.
63 struct GscInputRecord
{
66 scoped_refptr
<media::VideoFrame
> frame
;
69 // Record for GSC output buffers.
70 struct GscOutputRecord
{
76 // Record for MFC input buffers.
77 struct MfcInputRecord
{
83 // Record for MFC output buffers.
84 struct MfcOutputRecord
{
87 linked_ptr
<BitstreamBufferRef
> buffer_ref
;
93 kInitialFramerate
= 30,
94 // These are rather subjectively tuned.
95 kGscInputBufferCount
= 2,
96 kGscOutputBufferCount
= 2,
97 kMfcOutputBufferCount
= 2,
98 // MFC hardware does not report required output buffer size correctly.
99 // Use maximum theoretical size to avoid hanging the hardware.
100 kMfcOutputBufferSize
= (2 * 1024 * 1024),
103 // Internal state of the encoder.
105 kUninitialized
, // Initialize() not yet called.
106 kInitialized
, // Initialize() returned true; ready to start encoding.
107 kEncoding
, // Encoding frames.
108 kError
, // Error in encoder state.
112 // Encoding tasks, to be run on encode_thread_.
115 // Encode a GSC input buffer.
116 void EncodeTask(const scoped_refptr
<media::VideoFrame
>& frame
,
117 bool force_keyframe
);
119 // Add a BitstreamBuffer to the queue of buffers ready to be used for encoder
121 void UseOutputBitstreamBufferTask(scoped_ptr
<BitstreamBufferRef
> buffer_ref
);
123 // Device destruction task.
126 // Service I/O on the V4L2 devices. This task should only be scheduled from
128 void ServiceDeviceTask();
130 // Handle the various device queues.
135 // Enqueue a buffer on the corresponding queue. Returns false on fatal error.
136 bool EnqueueGscInputRecord();
137 bool EnqueueGscOutputRecord();
138 bool EnqueueMfcInputRecord();
139 bool EnqueueMfcOutputRecord();
141 // Attempt to start/stop device_poll_thread_.
142 bool StartDevicePoll();
143 bool StopDevicePoll();
144 // Set/clear the device poll interrupt (using device_poll_interrupt_fd_).
145 bool SetDevicePollInterrupt();
146 bool ClearDevicePollInterrupt();
149 // Device tasks, to be run on device_poll_thread_.
153 void DevicePollTask(unsigned int poll_fds
);
156 // Safe from any thread.
159 // Error notification (using PostTask() to child thread, if necessary).
160 void NotifyError(Error error
);
162 // Set the encoder_thread_ state (using PostTask to encoder thread, if
164 void SetEncoderState(State state
);
167 // Other utility functions. Called on encoder_thread_, unless
168 // encoder_thread_ is not yet started, in which case the child thread can call
169 // these (e.g. in Initialize() or Destroy()).
172 // Change the parameters of encoding.
173 void RequestEncodingParametersChangeTask(uint32 bitrate
, uint32 framerate
);
175 // Create the buffers we need.
176 bool CreateGscInputBuffers();
177 bool CreateGscOutputBuffers();
178 bool SetMfcFormats();
179 bool CreateMfcInputBuffers();
180 bool CreateMfcOutputBuffers();
182 // Destroy these buffers.
183 void DestroyGscInputBuffers();
184 void DestroyGscOutputBuffers();
185 void DestroyMfcInputBuffers();
186 void DestroyMfcOutputBuffers();
188 // Our original calling message loop for the child thread.
189 const scoped_refptr
<base::MessageLoopProxy
> child_message_loop_proxy_
;
191 // WeakPtr<> pointing to |this| for use in posting tasks from the encoder or
192 // device worker threads back to the child thread. Because the worker threads
193 // are members of this class, any task running on those threads is guaranteed
194 // that this object is still alive. As a result, tasks posted from the child
195 // thread to the encoder or device thread should use base::Unretained(this),
196 // and tasks posted the other way should use |weak_this_|.
197 base::WeakPtrFactory
<ExynosVideoEncodeAccelerator
> weak_this_ptr_factory_
;
198 base::WeakPtr
<ExynosVideoEncodeAccelerator
> weak_this_
;
200 // To expose client callbacks from VideoEncodeAccelerator.
201 // NOTE: all calls to these objects *MUST* be executed on
202 // child_message_loop_proxy_.
203 base::WeakPtrFactory
<Client
> client_ptr_factory_
;
204 base::WeakPtr
<Client
> client_
;
207 // Encoder state, owned and operated by encoder_thread_.
208 // Before encoder_thread_ has started, the encoder state is managed by
209 // the child (main) thread. After encoder_thread_ has started, the encoder
210 // thread should be the only one managing these.
213 // This thread services tasks posted from the VEA API entry points by the
214 // child thread and device service callbacks posted from the device thread.
215 base::Thread encoder_thread_
;
217 State encoder_state_
;
218 // The visible/allocated sizes of the input frame.
219 gfx::Size input_visible_size_
;
220 gfx::Size input_allocated_size_
;
221 // The visible/allocated sizes of the color-converted intermediate frame.
222 gfx::Size converted_visible_size_
;
223 gfx::Size converted_allocated_size_
;
224 // The logical visible size of the output frame.
225 gfx::Size output_visible_size_
;
226 // The required byte size of output BitstreamBuffers.
227 size_t output_buffer_byte_size_
;
229 // We need to provide the stream header with every keyframe, to allow
230 // midstream decoding restarts. Store it here.
231 scoped_ptr
<uint8
[]> stream_header_
;
232 size_t stream_header_size_
;
234 // V4L2 formats for input frames and the output stream.
235 uint32 input_format_fourcc_
;
236 uint32 output_format_fourcc_
;
238 // Video frames ready to be encoded.
239 std::list
<scoped_refptr
<media::VideoFrame
> > encoder_input_queue_
;
241 // GSC color conversion device.
243 // GSC input queue state.
244 bool gsc_input_streamon_
;
245 // GSC input buffers enqueued to device.
246 int gsc_input_buffer_queued_count_
;
247 // GSC input buffers ready to use; LIFO since we don't care about ordering.
248 std::vector
<int> gsc_free_input_buffers_
;
249 // Mapping of int index to GSC input buffer record.
250 std::vector
<GscInputRecord
> gsc_input_buffer_map_
;
252 // GSC output queue state.
253 bool gsc_output_streamon_
;
254 // GSC output buffers enqueued to device.
255 int gsc_output_buffer_queued_count_
;
256 // GSC output buffers ready to use; LIFO since we don't care about ordering.
257 std::vector
<int> gsc_free_output_buffers_
;
258 // Mapping of int index to GSC output buffer record.
259 std::vector
<GscOutputRecord
> gsc_output_buffer_map_
;
261 // MFC input buffers filled by GSC, waiting to be queued to MFC.
262 std::list
<int> mfc_ready_input_buffers_
;
264 // MFC video encoding device.
267 // MFC input queue state.
268 bool mfc_input_streamon_
;
269 // MFC input buffers enqueued to device.
270 int mfc_input_buffer_queued_count_
;
271 // MFC input buffers ready to use; LIFO since we don't care about ordering.
272 std::vector
<int> mfc_free_input_buffers_
;
273 // Mapping of int index to MFC input buffer record.
274 std::vector
<MfcInputRecord
> mfc_input_buffer_map_
;
276 // MFC output queue state.
277 bool mfc_output_streamon_
;
278 // MFC output buffers enqueued to device.
279 int mfc_output_buffer_queued_count_
;
280 // MFC output buffers ready to use; LIFO since we don't care about ordering.
281 std::vector
<int> mfc_free_output_buffers_
;
282 // Mapping of int index to MFC output buffer record.
283 std::vector
<MfcOutputRecord
> mfc_output_buffer_map_
;
285 // Bitstream buffers ready to be used to return encoded output, as a LIFO
286 // since we don't care about ordering.
287 std::vector
<linked_ptr
<BitstreamBufferRef
> > encoder_output_queue_
;
290 // The device polling thread handles notifications of V4L2 device changes.
291 // TODO(sheu): replace this thread with an TYPE_IO encoder_thread_.
295 base::Thread device_poll_thread_
;
296 // eventfd fd to signal device poll thread when its poll() should be
298 int device_poll_interrupt_fd_
;
300 DISALLOW_COPY_AND_ASSIGN(ExynosVideoEncodeAccelerator
);
303 } // namespace content
305 #endif // CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_ENCODE_ACCELERATOR_H_