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. 4 5 #ifndef CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_PROCESSOR_H_ 6 #define CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_PROCESSOR_H_ 7 8 #include <queue> 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 "content/common/content_export.h" 15 #include "content/common/gpu/media/v4l2_video_device.h" 16 #include "media/base/video_frame.h" 17 18 namespace content { 19 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 { 24 public: 25 explicit V4L2ImageProcessor(scoped_ptr<V4L2Device> device); 26 virtual ~V4L2ImageProcessor(); 27 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); 39 40 // Returns allocated size required by the processor to be fed with. 41 gfx::Size input_allocated_size() { return input_allocated_size_; } 42 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)> 46 FrameReadyCB; 47 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); 53 54 // Stop all processing and clean up. 55 void Destroy(); 56 57 private: 58 // Record for input buffers. 59 struct InputRecord { 60 InputRecord(); 61 scoped_refptr<media::VideoFrame> frame; 62 bool at_device; 63 }; 64 65 // Record for output buffers. 66 struct OutputRecord { 67 OutputRecord(); 68 bool at_device; 69 bool at_client; 70 std::vector<int> fds; 71 }; 72 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 78 // device). 79 struct JobRecord { 80 JobRecord(); 81 scoped_refptr<media::VideoFrame> frame; 82 FrameReadyCB ready_cb; 83 }; 84 85 enum { 86 // Arbitrarily tuned. 87 kInputBufferCount = 2, 88 kOutputBufferCount = 2, 89 }; 90 91 void ReuseOutputBuffer(int index); 92 93 void Enqueue(); 94 void Dequeue(); 95 bool EnqueueInputRecord(); 96 bool EnqueueOutputRecord(); 97 bool CreateInputBuffers(); 98 bool CreateOutputBuffers(); 99 void DestroyInputBuffers(); 100 void DestroyOutputBuffers(); 101 102 void NotifyError(); 103 void DestroyTask(); 104 105 void ProcessTask(scoped_ptr<JobRecord> job_record); 106 void ServiceDeviceTask(); 107 108 // Attempt to start/stop device_poll_thread_. 109 bool StartDevicePoll(); 110 bool StopDevicePoll(); 111 112 // Ran on device_poll_thread_ to wait for device events. 113 void DevicePollTask(bool poll_device); 114 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_; 119 120 // The visible/allocated sizes of the destination frame. 121 gfx::Size output_visible_size_; 122 gfx::Size output_allocated_size_; 123 124 media::VideoFrame::Format input_format_; 125 media::VideoFrame::Format output_format_; 126 uint32 input_format_fourcc_; 127 uint32 output_format_fourcc_; 128 129 size_t input_planes_count_; 130 size_t output_planes_count_; 131 132 // Our original calling message loop for the child thread. 133 const scoped_refptr<base::MessageLoopProxy> child_message_loop_proxy_; 134 135 // V4L2 device in use. 136 scoped_ptr<V4L2Device> device_; 137 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_; 142 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_; 147 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_; 156 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_; 165 166 // Error callback to the client. 167 base::Closure error_cb_; 168 169 // Weak factory for producing weak pointers on the device_thread_ 170 base::WeakPtrFactory<V4L2ImageProcessor> device_weak_factory_; 171 172 DISALLOW_COPY_AND_ASSIGN(V4L2ImageProcessor); 173 }; 174 175 } // namespace content 176 177 #endif // CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_PROCESSOR_H_ 178