1 // Copyright 2014 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_V4L2_VIDEO_PROCESSOR_H_
6 #define CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_PROCESSOR_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 "content/common/gpu/media/v4l2_video_device.h"
16 #include "media/base/video_frame.h"
20 // Handles image processing accelerators that expose a V4L2 memory-to-memory
21 // interface. The threading model of this class is the same as for other V4L2
22 // hardware accelerators (see V4L2VideoDecodeAccelerator) for more details.
23 class CONTENT_EXPORT V4L2ImageProcessor
{
25 explicit V4L2ImageProcessor(scoped_ptr
<V4L2Device
> device
);
26 virtual ~V4L2ImageProcessor();
28 // Initializes the processor to convert from |input_format| to |output_format|
29 // and/or scale from |input_visible_size| to |output_visible_size|.
30 // Request the output buffers to be of at least |output_allocated_size|.
31 // Provided |error_cb| will be called if an error occurs.
32 // Return true if the requested configuration is supported.
33 bool Initialize(media::VideoFrame::Format input_format
,
34 media::VideoFrame::Format output_format
,
35 gfx::Size input_visible_size
,
36 gfx::Size output_visible_size
,
37 gfx::Size output_allocated_size
,
38 const base::Closure
& error_cb
);
40 // Returns allocated size required by the processor to be fed with.
41 gfx::Size
input_allocated_size() { return input_allocated_size_
; }
43 // Callback to be used to return a processed image to the client. The client
44 // should drop references to |frame| once it's done with it.
45 typedef base::Callback
<void(const scoped_refptr
<media::VideoFrame
>& frame
)>
48 // Called by client to process |frame|. The resulting processed frame will
49 // be returned via |cb|. The processor will drop all its references to |frame|
50 // after it finishes accessing it.
51 void Process(const scoped_refptr
<media::VideoFrame
>& frame
,
52 const FrameReadyCB
& cb
);
54 // Stop all processing and clean up.
58 // Record for input buffers.
61 scoped_refptr
<media::VideoFrame
> frame
;
65 // Record for output buffers.
73 // Job record. Jobs are processed in a FIFO order. This is separate from
74 // InputRecord, because an InputRecord may be returned before we dequeue
75 // the corresponding output buffer. It can't always be associated with
76 // an OutputRecord immediately either, because at the time of submission we
77 // may not have one available (and don't need one to submit input to the
81 scoped_refptr
<media::VideoFrame
> frame
;
82 FrameReadyCB ready_cb
;
87 kInputBufferCount
= 2,
88 kOutputBufferCount
= 2,
91 void ReuseOutputBuffer(int index
);
95 bool EnqueueInputRecord();
96 bool EnqueueOutputRecord();
97 bool CreateInputBuffers();
98 bool CreateOutputBuffers();
99 void DestroyInputBuffers();
100 void DestroyOutputBuffers();
105 void ProcessTask(scoped_ptr
<JobRecord
> job_record
);
106 void ServiceDeviceTask();
108 // Attempt to start/stop device_poll_thread_.
109 bool StartDevicePoll();
110 bool StopDevicePoll();
112 // Ran on device_poll_thread_ to wait for device events.
113 void DevicePollTask(bool poll_device
);
115 // Size and format-related members remain constant after initialization.
116 // The visible/allocated sizes of the input frame.
117 gfx::Size input_visible_size_
;
118 gfx::Size input_allocated_size_
;
120 // The visible/allocated sizes of the destination frame.
121 gfx::Size output_visible_size_
;
122 gfx::Size output_allocated_size_
;
124 media::VideoFrame::Format input_format_
;
125 media::VideoFrame::Format output_format_
;
126 uint32 input_format_fourcc_
;
127 uint32 output_format_fourcc_
;
129 size_t input_planes_count_
;
130 size_t output_planes_count_
;
132 // Our original calling message loop for the child thread.
133 const scoped_refptr
<base::MessageLoopProxy
> child_message_loop_proxy_
;
135 // V4L2 device in use.
136 scoped_ptr
<V4L2Device
> device_
;
138 // Thread to communicate with the device on.
139 base::Thread device_thread_
;
140 // Thread used to poll the V4L2 for events only.
141 base::Thread device_poll_thread_
;
143 // All the below members are to be accessed from device_thread_ only
144 // (if it's running).
145 std::queue
<linked_ptr
<JobRecord
> > input_queue_
;
146 std::queue
<linked_ptr
<JobRecord
> > running_jobs_
;
148 // Input queue state.
149 bool input_streamon_
;
150 // Number of input buffers enqueued to the device.
151 int input_buffer_queued_count_
;
152 // Input buffers ready to use; LIFO since we don't care about ordering.
153 std::vector
<int> free_input_buffers_
;
154 // Mapping of int index to an input buffer record.
155 std::vector
<InputRecord
> input_buffer_map_
;
157 // Output queue state.
158 bool output_streamon_
;
159 // Number of output buffers enqueued to the device.
160 int output_buffer_queued_count_
;
161 // Output buffers ready to use; LIFO since we don't care about ordering.
162 std::vector
<int> free_output_buffers_
;
163 // Mapping of int index to an output buffer record.
164 std::vector
<OutputRecord
> output_buffer_map_
;
166 // Error callback to the client.
167 base::Closure error_cb_
;
169 // Weak factory for producing weak pointers on the device_thread_
170 base::WeakPtrFactory
<V4L2ImageProcessor
> device_weak_factory_
;
172 DISALLOW_COPY_AND_ASSIGN(V4L2ImageProcessor
);
175 } // namespace content
177 #endif // CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_PROCESSOR_H_