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_IMAGE_PROCESSOR_H_
6 #define CONTENT_COMMON_GPU_MEDIA_V4L2_IMAGE_PROCESSOR_H_
11 #include "base/memory/linked_ptr.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/threading/thread.h"
15 #include "content/common/content_export.h"
16 #include "content/common/gpu/media/v4l2_device.h"
17 #include "media/base/video_frame.h"
21 // Handles image processing accelerators that expose a V4L2 memory-to-memory
22 // interface. The threading model of this class is the same as for other V4L2
23 // hardware accelerators (see V4L2VideoDecodeAccelerator) for more details.
24 class CONTENT_EXPORT V4L2ImageProcessor
{
26 explicit V4L2ImageProcessor(const scoped_refptr
<V4L2Device
>& device
);
27 virtual ~V4L2ImageProcessor();
29 // Initializes the processor to convert from |input_format| to |output_format|
30 // and/or scale from |input_visible_size| to |output_visible_size|.
31 // Request the output buffers to be of at least |output_allocated_size|.
32 // Provided |error_cb| will be called if an error occurs.
33 // Return true if the requested configuration is supported.
34 bool Initialize(media::VideoFrame::Format input_format
,
35 media::VideoFrame::Format output_format
,
36 gfx::Size input_visible_size
,
37 gfx::Size output_visible_size
,
38 gfx::Size output_allocated_size
,
39 const base::Closure
& error_cb
);
41 // Returns allocated size required by the processor to be fed with.
42 gfx::Size
input_allocated_size() { return input_allocated_size_
; }
44 // Callback to be used to return a processed image to the client. The client
45 // should drop references to |frame| once it's done with it.
46 typedef base::Callback
<void(const scoped_refptr
<media::VideoFrame
>& frame
)>
49 // Called by client to process |frame|. The resulting processed frame will
50 // be returned via |cb|. The processor will drop all its references to |frame|
51 // after it finishes accessing it.
52 void Process(const scoped_refptr
<media::VideoFrame
>& frame
,
53 const FrameReadyCB
& cb
);
55 // Stop all processing and clean up.
59 // Record for input buffers.
63 scoped_refptr
<media::VideoFrame
> frame
;
67 // Record for output buffers.
76 // Job record. Jobs are processed in a FIFO order. This is separate from
77 // InputRecord, because an InputRecord may be returned before we dequeue
78 // the corresponding output buffer. It can't always be associated with
79 // an OutputRecord immediately either, because at the time of submission we
80 // may not have one available (and don't need one to submit input to the
85 scoped_refptr
<media::VideoFrame
> frame
;
86 FrameReadyCB ready_cb
;
91 kInputBufferCount
= 2,
92 kOutputBufferCount
= 2,
95 void ReuseOutputBuffer(int index
);
99 bool EnqueueInputRecord();
100 bool EnqueueOutputRecord();
101 bool CreateInputBuffers();
102 bool CreateOutputBuffers();
103 void DestroyInputBuffers();
104 void DestroyOutputBuffers();
109 void ProcessTask(scoped_ptr
<JobRecord
> job_record
);
110 void ServiceDeviceTask();
112 // Attempt to start/stop device_poll_thread_.
113 bool StartDevicePoll();
114 bool StopDevicePoll();
116 // Ran on device_poll_thread_ to wait for device events.
117 void DevicePollTask(bool poll_device
);
119 // Size and format-related members remain constant after initialization.
120 // The visible/allocated sizes of the input frame.
121 gfx::Size input_visible_size_
;
122 gfx::Size input_allocated_size_
;
124 // The visible/allocated sizes of the destination frame.
125 gfx::Size output_visible_size_
;
126 gfx::Size output_allocated_size_
;
128 media::VideoFrame::Format input_format_
;
129 media::VideoFrame::Format output_format_
;
130 uint32 input_format_fourcc_
;
131 uint32 output_format_fourcc_
;
133 size_t input_planes_count_
;
134 size_t output_planes_count_
;
136 // Our original calling message loop for the child thread.
137 const scoped_refptr
<base::MessageLoopProxy
> child_message_loop_proxy_
;
139 // V4L2 device in use.
140 scoped_refptr
<V4L2Device
> device_
;
142 // Thread to communicate with the device on.
143 base::Thread device_thread_
;
144 // Thread used to poll the V4L2 for events only.
145 base::Thread device_poll_thread_
;
147 // All the below members are to be accessed from device_thread_ only
148 // (if it's running).
149 std::queue
<linked_ptr
<JobRecord
> > input_queue_
;
150 std::queue
<linked_ptr
<JobRecord
> > running_jobs_
;
152 // Input queue state.
153 bool input_streamon_
;
154 // Number of input buffers enqueued to the device.
155 int input_buffer_queued_count_
;
156 // Input buffers ready to use; LIFO since we don't care about ordering.
157 std::vector
<int> free_input_buffers_
;
158 // Mapping of int index to an input buffer record.
159 std::vector
<InputRecord
> input_buffer_map_
;
161 // Output queue state.
162 bool output_streamon_
;
163 // Number of output buffers enqueued to the device.
164 int output_buffer_queued_count_
;
165 // Output buffers ready to use; LIFO since we don't care about ordering.
166 std::vector
<int> free_output_buffers_
;
167 // Mapping of int index to an output buffer record.
168 std::vector
<OutputRecord
> output_buffer_map_
;
170 // Error callback to the client.
171 base::Closure error_cb_
;
173 // Weak factory for producing weak pointers on the device_thread_
174 base::WeakPtrFactory
<V4L2ImageProcessor
> device_weak_factory_
;
176 DISALLOW_COPY_AND_ASSIGN(V4L2ImageProcessor
);
179 } // namespace content
181 #endif // CONTENT_COMMON_GPU_MEDIA_V4L2_IMAGE_PROCESSOR_H_