| 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..86d0e2d008bf2436db52c3c8b79fcd77fb570afa
|
| --- /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() are synchronous.
|
| + 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();
|
| +
|
| + 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_
|
|
|