Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef CONTENT_COMMON_GPU_MEDIA_V4L2_IMAGE_PROCESSOR_H_ | 5 #ifndef CONTENT_COMMON_GPU_MEDIA_V4L2_JPEG_DECODE_ACCELERATOR_H_ |
| 6 #define CONTENT_COMMON_GPU_MEDIA_V4L2_IMAGE_PROCESSOR_H_ | 6 #define CONTENT_COMMON_GPU_MEDIA_V4L2_JPEG_DECODE_ACCELERATOR_H_ |
| 7 | 7 |
| 8 #include <queue> | 8 #include <queue> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "base/memory/linked_ptr.h" | 11 #include "base/memory/linked_ptr.h" |
| 12 #include "base/memory/ref_counted.h" | 12 #include "base/memory/ref_counted.h" |
| 13 #include "base/memory/weak_ptr.h" | 13 #include "base/memory/weak_ptr.h" |
| 14 #include "base/threading/thread.h" | 14 #include "base/threading/thread.h" |
| 15 #include "content/common/content_export.h" | 15 #include "content/common/content_export.h" |
| 16 #include "content/common/gpu/media/v4l2_device.h" | 16 #include "content/common/gpu/media/v4l2_device.h" |
| 17 #include "media/base/bitstream_buffer.h" | |
| 17 #include "media/base/video_frame.h" | 18 #include "media/base/video_frame.h" |
| 19 #include "media/video/jpeg_decode_accelerator.h" | |
| 18 | 20 |
| 19 namespace content { | 21 namespace content { |
| 20 | 22 |
| 21 // Handles image processing accelerators that expose a V4L2 memory-to-memory | 23 class CONTENT_EXPORT V4L2JpegDecodeAccelerator |
| 22 // interface. The threading model of this class is the same as for other V4L2 | 24 : public media::JpegDecodeAccelerator { |
| 23 // hardware accelerators (see V4L2VideoDecodeAccelerator) for more details. | |
| 24 class CONTENT_EXPORT V4L2ImageProcessor { | |
| 25 public: | 25 public: |
| 26 explicit V4L2ImageProcessor(const scoped_refptr<V4L2Device>& device); | 26 V4L2JpegDecodeAccelerator( |
| 27 virtual ~V4L2ImageProcessor(); | 27 const scoped_refptr<V4L2Device>& device, |
| 28 const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy); | |
| 29 ~V4L2JpegDecodeAccelerator() override; | |
| 28 | 30 |
| 29 // Initializes the processor to convert from |input_format| to |output_format| | 31 // Note: Initialize() and Destroy() are synchronous. |
| 30 // and/or scale from |input_visible_size| to |output_visible_size|. | 32 bool Initialize(Client* client) override; |
| 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); | |
| 40 | |
| 41 // Returns allocated size required by the processor to be fed with. | |
| 42 gfx::Size input_allocated_size() { return input_allocated_size_; } | |
| 43 | 33 |
| 44 // Callback to be used to return a processed image to the client. The client | 34 // 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. | 35 // should drop references to |frame| once it's done with it. |
| 46 typedef base::Callback<void(const scoped_refptr<media::VideoFrame>& frame)> | 36 typedef base::Callback<void(const scoped_refptr<media::VideoFrame>& frame)> |
| 47 FrameReadyCB; | 37 FrameReadyCB; |
|
kcwu
2015/05/26 10:47:23
unused
henryhsu
2015/06/05 03:28:56
Done.
| |
| 48 | 38 |
| 49 // Called by client to process |frame|. The resulting processed frame will | 39 // 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| | 40 // be returned via |cb|. The processor will drop all its references to |frame| |
| 51 // after it finishes accessing it. | 41 // after it finishes accessing it. |
| 52 void Process(const scoped_refptr<media::VideoFrame>& frame, | 42 // void Process(const scoped_refptr<media::VideoFrame>& frame, |
| 53 const FrameReadyCB& cb); | 43 // const FrameReadyCB& cb); |
| 44 | |
| 45 void Decode(const media::BitstreamBuffer& bitstream_buffer, | |
| 46 const scoped_refptr<media::VideoFrame>& video_frame); | |
|
kcwu
2015/05/26 10:47:23
override;
henryhsu
2015/06/05 03:28:56
Done.
| |
| 54 | 47 |
| 55 // Stop all processing and clean up. | 48 // Stop all processing and clean up. |
| 56 void Destroy(); | 49 void Destroy() override; |
| 57 | 50 |
| 58 private: | 51 private: |
| 59 // Record for input buffers. | 52 // Record for input buffers. |
| 60 struct InputRecord { | 53 struct InputRecord { |
| 61 InputRecord(); | 54 InputRecord(); |
| 62 ~InputRecord(); | 55 ~InputRecord(); |
| 63 scoped_refptr<media::VideoFrame> frame; | 56 void* address; // mmap() address. |
| 57 size_t length; // mmap() length. | |
| 64 bool at_device; | 58 bool at_device; |
| 65 }; | 59 }; |
| 66 | 60 |
| 67 // Record for output buffers. | 61 // Record for output buffers. |
| 68 struct OutputRecord { | 62 struct OutputRecord { |
| 69 OutputRecord(); | 63 OutputRecord(); |
| 70 ~OutputRecord(); | 64 ~OutputRecord(); |
| 65 void* address; // mmap() address. | |
| 66 size_t length; // mmap() length. | |
| 71 bool at_device; | 67 bool at_device; |
| 72 bool at_client; | |
| 73 std::vector<int> fds; | |
| 74 }; | 68 }; |
| 75 | 69 |
| 76 // Job record. Jobs are processed in a FIFO order. This is separate from | 70 // Job record. Jobs are processed in a FIFO order. This is separate from |
| 77 // InputRecord, because an InputRecord may be returned before we dequeue | 71 // InputRecord, because an InputRecord may be returned before we dequeue |
| 78 // the corresponding output buffer. It can't always be associated with | 72 // the corresponding output buffer. It can't always be associated with |
| 79 // an OutputRecord immediately either, because at the time of submission we | 73 // 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 | 74 // may not have one available (and don't need one to submit input to the |
| 81 // device). | 75 // device). |
| 82 struct JobRecord { | 76 struct JobRecord { |
| 83 JobRecord(); | 77 JobRecord(media::BitstreamBuffer bitstream_buffer, |
| 78 scoped_refptr<media::VideoFrame> video_frame); | |
| 84 ~JobRecord(); | 79 ~JobRecord(); |
| 80 media::BitstreamBuffer bitstream_buffer; | |
| 85 scoped_refptr<media::VideoFrame> frame; | 81 scoped_refptr<media::VideoFrame> frame; |
| 86 FrameReadyCB ready_cb; | |
| 87 }; | 82 }; |
| 88 | 83 |
| 89 enum { | 84 enum { |
| 90 // Arbitrarily tuned. | 85 // Arbitrarily tuned. |
| 91 kInputBufferCount = 2, | 86 kInputBufferCount = 2, |
| 92 kOutputBufferCount = 2, | 87 kOutputBufferCount = 2, |
| 93 }; | 88 }; |
| 94 | 89 |
| 95 void ReuseOutputBuffer(int index); | |
| 96 | |
| 97 void Enqueue(); | 90 void Enqueue(); |
| 98 void Dequeue(); | 91 void Dequeue(); |
| 99 bool EnqueueInputRecord(); | 92 bool EnqueueInputRecord(); |
| 100 bool EnqueueOutputRecord(); | 93 bool EnqueueOutputRecord(); |
| 94 bool CheckBufferAttributes(); | |
| 101 bool CreateInputBuffers(); | 95 bool CreateInputBuffers(); |
| 102 bool CreateOutputBuffers(); | 96 bool CreateOutputBuffers(); |
| 103 void DestroyInputBuffers(); | 97 void DestroyInputBuffers(); |
| 104 void DestroyOutputBuffers(); | 98 void DestroyOutputBuffers(); |
| 105 | 99 |
| 106 void NotifyError(); | 100 void NotifyError(int32_t bitstream_buffer_id, Error error); |
| 107 void DestroyTask(); | 101 void DestroyTask(); |
| 108 | 102 |
| 109 void ProcessTask(scoped_ptr<JobRecord> job_record); | 103 void DecodeTask(scoped_ptr<JobRecord> job_record); |
| 110 void ServiceDeviceTask(); | 104 void ServiceDeviceTask(); |
| 111 | 105 |
| 112 // Attempt to start/stop device_poll_thread_. | 106 // Attempt to start/stop device_poll_thread_. |
| 113 bool StartDevicePoll(); | 107 bool StartDevicePoll(); |
| 114 bool StopDevicePoll(); | 108 bool StopDevicePoll(); |
| 115 | 109 |
| 116 // Ran on device_poll_thread_ to wait for device events. | 110 // Ran on device_poll_thread_ to wait for device events. |
| 117 void DevicePollTask(bool poll_device); | 111 void DevicePollTask(bool poll_device); |
| 118 | 112 |
| 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_; | |
| 123 | |
| 124 // The visible/allocated sizes of the destination frame. | |
| 125 gfx::Size output_visible_size_; | |
| 126 gfx::Size output_allocated_size_; | |
| 127 | |
| 128 media::VideoFrame::Format input_format_; | |
| 129 media::VideoFrame::Format output_format_; | 113 media::VideoFrame::Format output_format_; |
| 130 uint32 input_format_fourcc_; | 114 // Record current image size for checking image size is changed or not. |
| 131 uint32 output_format_fourcc_; | 115 gfx::Size image_coded_size_; |
| 132 | |
| 133 size_t input_planes_count_; | |
| 134 size_t output_planes_count_; | |
| 135 | 116 |
| 136 // Our original calling message loop for the child thread. | 117 // Our original calling message loop for the child thread. |
| 137 const scoped_refptr<base::MessageLoopProxy> child_message_loop_proxy_; | 118 scoped_refptr<base::MessageLoopProxy> child_message_loop_proxy_; |
| 138 | 119 |
| 139 // V4L2 device in use. | 120 // GPU IO message loop. |
| 121 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; | |
| 122 | |
| 123 // To expose client callbacks from JpegDecodeAccelerator. | |
| 124 // NOTE: all calls to these objects *MUST* be executed on | |
| 125 // |child_message_loop_proxy_|. | |
| 126 scoped_ptr<base::WeakPtrFactory<Client>> client_ptr_factory_; | |
| 127 base::WeakPtr<Client> client_; | |
| 128 | |
| 129 // The V4L2Device this class is operating upon. | |
| 140 scoped_refptr<V4L2Device> device_; | 130 scoped_refptr<V4L2Device> device_; |
| 141 | 131 |
| 142 // Thread to communicate with the device on. | 132 // Thread to communicate with the device on. |
| 143 base::Thread device_thread_; | 133 base::Thread device_thread_; |
| 144 // Thread used to poll the V4L2 for events only. | 134 // Thread used to poll the V4L2 for events only. |
| 145 base::Thread device_poll_thread_; | 135 base::Thread device_poll_thread_; |
| 146 | 136 |
| 147 // All the below members are to be accessed from device_thread_ only | 137 // All the below members are to be accessed from device_thread_ only |
| 148 // (if it's running). | 138 // (if it's running). |
| 149 std::queue<linked_ptr<JobRecord> > input_queue_; | 139 std::queue<linked_ptr<JobRecord> > input_queue_; |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 164 int output_buffer_queued_count_; | 154 int output_buffer_queued_count_; |
| 165 // Output buffers ready to use; LIFO since we don't care about ordering. | 155 // Output buffers ready to use; LIFO since we don't care about ordering. |
| 166 std::vector<int> free_output_buffers_; | 156 std::vector<int> free_output_buffers_; |
| 167 // Mapping of int index to an output buffer record. | 157 // Mapping of int index to an output buffer record. |
| 168 std::vector<OutputRecord> output_buffer_map_; | 158 std::vector<OutputRecord> output_buffer_map_; |
| 169 | 159 |
| 170 // Error callback to the client. | 160 // Error callback to the client. |
| 171 base::Closure error_cb_; | 161 base::Closure error_cb_; |
| 172 | 162 |
| 173 // Weak factory for producing weak pointers on the device_thread_ | 163 // Weak factory for producing weak pointers on the device_thread_ |
| 174 base::WeakPtrFactory<V4L2ImageProcessor> device_weak_factory_; | 164 base::WeakPtrFactory<V4L2JpegDecodeAccelerator> device_weak_factory_; |
| 165 // WeakPtr<> pointing to |this| for use in posting tasks from the decoder | |
| 166 // thread back to the ChildThread. Because the decoder thread is a member of | |
| 167 // this class, any task running on the decoder thread is guaranteed that this | |
| 168 // object is still alive. As a result, tasks posted from ChildThread to | |
| 169 // decoder thread should use base::Unretained(this), and tasks posted from | |
| 170 // the decoder thread to the ChildThread should use |device_weak_|. | |
| 171 base::WeakPtr<V4L2JpegDecodeAccelerator> device_weak_; | |
| 175 | 172 |
| 176 DISALLOW_COPY_AND_ASSIGN(V4L2ImageProcessor); | 173 DISALLOW_COPY_AND_ASSIGN(V4L2JpegDecodeAccelerator); |
| 177 }; | 174 }; |
| 178 | 175 |
| 179 } // namespace content | 176 } |
|
kcwu
2015/05/26 10:47:23
} // namespace content
henryhsu
2015/06/05 03:28:56
Done.
| |
| 180 | 177 |
| 181 #endif // CONTENT_COMMON_GPU_MEDIA_V4L2_IMAGE_PROCESSOR_H_ | 178 #endif // CONTENT_COMMON_GPU_MEDIA_V4L2_JPEG_DECODE_ACCELERATOR_H_ |
| OLD | NEW |