Chromium Code Reviews| Index: content/common/gpu/media/v4l2_jpeg_decode_accelerator.h |
| diff --git a/content/common/gpu/media/v4l2_jpeg_decode_accelerator.h b/content/common/gpu/media/v4l2_jpeg_decode_accelerator.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..c9611ce8e0509187b35553bbd646b538a9ccf475 |
| --- /dev/null |
| +++ b/content/common/gpu/media/v4l2_jpeg_decode_accelerator.h |
| @@ -0,0 +1,172 @@ |
| +// Copyright 2015 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#ifndef CONTENT_COMMON_GPU_MEDIA_V4L2_JPEG_DECODE_ACCELERATOR_H_ |
| +#define CONTENT_COMMON_GPU_MEDIA_V4L2_JPEG_DECODE_ACCELERATOR_H_ |
| + |
| +#include <queue> |
| +#include <vector> |
| + |
| +#include "base/memory/linked_ptr.h" |
| +#include "base/memory/ref_counted.h" |
| +#include "base/memory/weak_ptr.h" |
| +#include "base/single_thread_task_runner.h" |
| +#include "base/threading/thread.h" |
| +#include "content/common/content_export.h" |
| +#include "content/common/gpu/media/v4l2_device.h" |
| +#include "media/base/bitstream_buffer.h" |
| +#include "media/base/video_frame.h" |
| +#include "media/video/jpeg_decode_accelerator.h" |
| + |
| +namespace content { |
| + |
| +class CONTENT_EXPORT V4L2JpegDecodeAccelerator |
| + : public media::JpegDecodeAccelerator { |
| + public: |
| + V4L2JpegDecodeAccelerator( |
| + const scoped_refptr<V4L2Device>& device, |
| + const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner); |
| + ~V4L2JpegDecodeAccelerator() override; |
| + |
| + // Note: Initialize() and Destroy() are synchronous. |
|
kcwu
2015/06/08 10:04:29
no Destroy()
henryhsu
2015/06/09 10:20:05
Done.
|
| + bool Initialize(Client* client) override; |
| + |
| + void Decode(const media::BitstreamBuffer& bitstream_buffer, |
| + const scoped_refptr<media::VideoFrame>& video_frame) override; |
| + |
| + private: |
| + // Record for input buffers. |
| + struct InputRecord { |
| + InputRecord(); |
| + ~InputRecord(); |
| + void* address; // mmap() address. |
| + size_t length; // mmap() length. |
| + bool at_device; |
| + }; |
| + |
| + // Record for output buffers. |
| + struct OutputRecord { |
| + OutputRecord(); |
| + ~OutputRecord(); |
| + void* address; // mmap() address. |
| + size_t length; // mmap() length. |
| + bool at_device; |
| + }; |
| + |
| + // Job record. Jobs are processed in a FIFO order. This is separate from |
| + // InputRecord, because an InputRecord may be returned before we dequeue |
| + // the corresponding output buffer. It can't always be associated with |
| + // an OutputRecord immediately either, because at the time of submission we |
| + // may not have one available (and don't need one to submit input to the |
| + // device). |
| + struct JobRecord { |
| + JobRecord(media::BitstreamBuffer bitstream_buffer, |
| + scoped_refptr<media::VideoFrame> video_frame); |
| + ~JobRecord(); |
| + media::BitstreamBuffer bitstream_buffer; |
| + scoped_refptr<media::VideoFrame> frame; |
| + }; |
| + |
| + enum { |
| + // Arbitrarily tuned. |
| + kInputBufferCount = 2, |
| + kOutputBufferCount = 2, |
| + }; |
| + |
| + enum { |
| + kResetInputBuffer = 1 << 0, |
| + kResetOutputBuffer = 1 << 1, |
| + }; |
| + |
| + void Enqueue(); |
| + void Dequeue(); |
| + bool EnqueueInputRecord(); |
| + bool EnqueueOutputRecord(); |
| + bool CheckBufferAttributes(); |
| + bool CreateInputBuffers(); |
| + bool CreateOutputBuffers(); |
| + void DestroyInputBuffers(); |
| + void DestroyOutputBuffers(); |
| + void ResetBuffers(); |
| + |
| + void NotifyError(int32_t bitstream_buffer_id, Error error); |
| + void NotifyErrorFromDecoderThread(int32_t bitstream_buffer_id, Error error); |
| + void DestroyTask(); |
| + |
| + void DecodeTask(scoped_ptr<JobRecord> job_record); |
| + void ServiceDeviceTask(); |
| + |
| + // Attempt to start/stop device_poll_thread_. |
| + void StartDevicePoll(); |
| + bool StopDevicePoll(bool keep_input_queue); |
| + |
| + // Ran on device_poll_thread_ to wait for device events. |
| + void DevicePollTask(bool poll_device); |
| + |
| + media::VideoFrame::Format output_format_; |
| + // Record current image size for checking image size is changed or not. |
| + gfx::Size image_coded_size_; |
| + // Set to true when input or output buffer have to re-allocate. |
| + uint32_t reset_buffer_flag_; |
| + |
| + // ChildThread's task runner. |
| + scoped_refptr<base::SingleThreadTaskRunner> child_task_runner_; |
| + |
| + // GPU IO task runner. |
| + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; |
| + |
| + // The client of this class. |
| + Client* client_; |
| + |
| + // The V4L2Device this class is operating upon. |
| + scoped_refptr<V4L2Device> device_; |
| + |
| + // Thread to communicate with the device on. |
| + base::Thread decoder_thread_; |
| + // Decode task runner. |
| + scoped_refptr<base::SingleThreadTaskRunner> decoder_task_runner_; |
| + // Thread used to poll the V4L2 for events only. |
| + base::Thread device_poll_thread_; |
| + // Device poll task runner. |
| + scoped_refptr<base::SingleThreadTaskRunner> device_poll_task_runner_; |
| + |
| + // All the below members are to be accessed from decoder_thread_ only |
| + // (if it's running). |
| + std::queue<linked_ptr<JobRecord> > input_queue_; |
| + std::queue<linked_ptr<JobRecord> > running_jobs_; |
| + |
| + // Input queue state. |
| + bool input_streamon_; |
| + // Number of input buffers enqueued to the device. |
| + int input_buffer_queued_count_; |
| + // Input buffers ready to use; LIFO since we don't care about ordering. |
| + std::vector<int> free_input_buffers_; |
| + // Mapping of int index to an input buffer record. |
| + std::vector<InputRecord> input_buffer_map_; |
| + |
| + // Output queue state. |
| + bool output_streamon_; |
| + // Number of output buffers enqueued to the device. |
| + int output_buffer_queued_count_; |
| + // Output buffers ready to use; LIFO since we don't care about ordering. |
| + std::vector<int> free_output_buffers_; |
| + // Mapping of int index to an output buffer record. |
| + std::vector<OutputRecord> output_buffer_map_; |
| + |
| + // Weak factory for producing weak pointers on the decoder_thread_ |
| + base::WeakPtrFactory<V4L2JpegDecodeAccelerator> device_weak_factory_; |
| + // WeakPtr<> pointing to |this| for use in posting tasks from the decoder |
| + // thread back to the ChildThread. Because the decoder thread is a member of |
| + // this class, any task running on the decoder thread is guaranteed that this |
| + // object is still alive. As a result, tasks posted from ChildThread to |
| + // decoder thread should use base::Unretained(this), and tasks posted from |
| + // the decoder thread to the ChildThread should use |device_weak_|. |
| + base::WeakPtr<V4L2JpegDecodeAccelerator> device_weak_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(V4L2JpegDecodeAccelerator); |
| +}; |
| + |
| +} // namespace content |
| + |
| +#endif // CONTENT_COMMON_GPU_MEDIA_V4L2_JPEG_DECODE_ACCELERATOR_H_ |