| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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 // This file contains an implementation of VideoDecodeAccelerator | 5 // This file contains an implementation of VideoDecodeAccelerator |
| 6 // that utilizes hardware video decoders, which expose Video4Linux 2 API | 6 // that utilizes hardware video decoders, which expose Video4Linux 2 API |
| 7 // (http://linuxtv.org/downloads/v4l-dvb-apis/). | 7 // (http://linuxtv.org/downloads/v4l-dvb-apis/). |
| 8 | 8 |
| 9 #ifndef CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_DECODE_ACCELERATOR_H_ | 9 #ifndef MEDIA_GPU_V4L2_VIDEO_DECODE_ACCELERATOR_H_ |
| 10 #define CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_DECODE_ACCELERATOR_H_ | 10 #define MEDIA_GPU_V4L2_VIDEO_DECODE_ACCELERATOR_H_ |
| 11 | 11 |
| 12 #include <stddef.h> | 12 #include <stddef.h> |
| 13 #include <stdint.h> | 13 #include <stdint.h> |
| 14 | 14 |
| 15 #include <memory> | 15 #include <memory> |
| 16 #include <queue> | 16 #include <queue> |
| 17 #include <vector> | 17 #include <vector> |
| 18 | 18 |
| 19 #include "base/callback_forward.h" | 19 #include "base/callback_forward.h" |
| 20 #include "base/macros.h" | 20 #include "base/macros.h" |
| 21 #include "base/memory/linked_ptr.h" | 21 #include "base/memory/linked_ptr.h" |
| 22 #include "base/memory/ref_counted.h" | 22 #include "base/memory/ref_counted.h" |
| 23 #include "base/synchronization/waitable_event.h" | 23 #include "base/synchronization/waitable_event.h" |
| 24 #include "base/threading/thread.h" | 24 #include "base/threading/thread.h" |
| 25 #include "content/common/content_export.h" | |
| 26 #include "content/common/gpu/media/gpu_video_decode_accelerator_helpers.h" | |
| 27 #include "content/common/gpu/media/v4l2_device.h" | |
| 28 #include "content/common/gpu/media/v4l2_image_processor.h" | |
| 29 #include "media/base/limits.h" | 25 #include "media/base/limits.h" |
| 30 #include "media/base/video_decoder_config.h" | 26 #include "media/base/video_decoder_config.h" |
| 27 #include "media/gpu/gpu_video_decode_accelerator_helpers.h" |
| 28 #include "media/gpu/media_gpu_export.h" |
| 29 #include "media/gpu/v4l2_device.h" |
| 30 #include "media/gpu/v4l2_image_processor.h" |
| 31 #include "media/video/picture.h" | 31 #include "media/video/picture.h" |
| 32 #include "media/video/video_decode_accelerator.h" | 32 #include "media/video/video_decode_accelerator.h" |
| 33 #include "ui/gfx/geometry/size.h" | 33 #include "ui/gfx/geometry/size.h" |
| 34 #include "ui/gl/gl_bindings.h" | 34 #include "ui/gl/gl_bindings.h" |
| 35 | 35 |
| 36 namespace media { | 36 namespace media { |
| 37 |
| 37 class H264Parser; | 38 class H264Parser; |
| 38 } // namespace media | |
| 39 | 39 |
| 40 namespace content { | |
| 41 // This class handles video accelerators directly through a V4L2 device exported | 40 // This class handles video accelerators directly through a V4L2 device exported |
| 42 // by the hardware blocks. | 41 // by the hardware blocks. |
| 43 // | 42 // |
| 44 // The threading model of this class is driven by the fact that it needs to | 43 // The threading model of this class is driven by the fact that it needs to |
| 45 // interface two fundamentally different event queues -- the one Chromium | 44 // interface two fundamentally different event queues -- the one Chromium |
| 46 // provides through MessageLoop, and the one driven by the V4L2 devices which | 45 // provides through MessageLoop, and the one driven by the V4L2 devices which |
| 47 // is waited on with epoll(). There are three threads involved in this class: | 46 // is waited on with epoll(). There are three threads involved in this class: |
| 48 // | 47 // |
| 49 // * The child thread, which is the main GPU process thread which calls the | 48 // * The child thread, which is the main GPU process thread which calls the |
| 50 // media::VideoDecodeAccelerator entry points. Calls from this thread | 49 // media::VideoDecodeAccelerator entry points. Calls from this thread |
| (...skipping 27 matching lines...) Expand all Loading... |
| 78 // | 77 // |
| 79 // V4L2VideoDecodeAccelerator may use image processor to convert the output. | 78 // V4L2VideoDecodeAccelerator may use image processor to convert the output. |
| 80 // There are three cases: | 79 // There are three cases: |
| 81 // Flush: V4L2VDA should wait until image processor returns all processed | 80 // Flush: V4L2VDA should wait until image processor returns all processed |
| 82 // frames. | 81 // frames. |
| 83 // Reset: V4L2VDA doesn't need to wait for image processor. When image processor | 82 // Reset: V4L2VDA doesn't need to wait for image processor. When image processor |
| 84 // returns an old frame, drop it. | 83 // returns an old frame, drop it. |
| 85 // Resolution change: V4L2VDA destroy image processor when destroying output | 84 // Resolution change: V4L2VDA destroy image processor when destroying output |
| 86 // buffrers. We cannot drop any frame during resolution change. So V4L2VDA | 85 // buffrers. We cannot drop any frame during resolution change. So V4L2VDA |
| 87 // should destroy output buffers after image processor returns all the frames. | 86 // should destroy output buffers after image processor returns all the frames. |
| 88 class CONTENT_EXPORT V4L2VideoDecodeAccelerator | 87 class MEDIA_GPU_EXPORT V4L2VideoDecodeAccelerator |
| 89 : public media::VideoDecodeAccelerator { | 88 : public media::VideoDecodeAccelerator { |
| 90 public: | 89 public: |
| 91 V4L2VideoDecodeAccelerator( | 90 V4L2VideoDecodeAccelerator( |
| 92 EGLDisplay egl_display, | 91 EGLDisplay egl_display, |
| 93 const GetGLContextCallback& get_gl_context_cb, | 92 const GetGLContextCallback& get_gl_context_cb, |
| 94 const MakeGLContextCurrentCallback& make_context_current_cb, | 93 const MakeGLContextCurrentCallback& make_context_current_cb, |
| 95 const scoped_refptr<V4L2Device>& device); | 94 const scoped_refptr<V4L2Device>& device); |
| 96 ~V4L2VideoDecodeAccelerator() override; | 95 ~V4L2VideoDecodeAccelerator() override; |
| 97 | 96 |
| 98 // media::VideoDecodeAccelerator implementation. | 97 // media::VideoDecodeAccelerator implementation. |
| 99 // Note: Initialize() and Destroy() are synchronous. | 98 // Note: Initialize() and Destroy() are synchronous. |
| 100 bool Initialize(const Config& config, Client* client) override; | 99 bool Initialize(const Config& config, Client* client) override; |
| 101 void Decode(const media::BitstreamBuffer& bitstream_buffer) override; | 100 void Decode(const media::BitstreamBuffer& bitstream_buffer) override; |
| 102 void AssignPictureBuffers( | 101 void AssignPictureBuffers( |
| 103 const std::vector<media::PictureBuffer>& buffers) override; | 102 const std::vector<media::PictureBuffer>& buffers) override; |
| 104 void ReusePictureBuffer(int32_t picture_buffer_id) override; | 103 void ReusePictureBuffer(int32_t picture_buffer_id) override; |
| 105 void Flush() override; | 104 void Flush() override; |
| 106 void Reset() override; | 105 void Reset() override; |
| 107 void Destroy() override; | 106 void Destroy() override; |
| 108 bool TryToSetupDecodeOnSeparateThread( | 107 bool TryToSetupDecodeOnSeparateThread( |
| 109 const base::WeakPtr<Client>& decode_client, | 108 const base::WeakPtr<Client>& decode_client, |
| 110 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) | 109 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) |
| 111 override; | 110 override; |
| 112 media::VideoPixelFormat GetOutputFormat() const override; | 111 media::VideoPixelFormat GetOutputFormat() const override; |
| 113 | 112 |
| 114 static media::VideoDecodeAccelerator::SupportedProfiles | 113 static media::VideoDecodeAccelerator::SupportedProfiles |
| 115 GetSupportedProfiles(); | 114 GetSupportedProfiles(); |
| 116 | 115 |
| 117 private: | 116 private: |
| 118 // These are rather subjectively tuned. | 117 // These are rather subjectively tuned. |
| 119 enum { | 118 enum { |
| 120 kInputBufferCount = 8, | 119 kInputBufferCount = 8, |
| 121 // TODO(posciak): determine input buffer size based on level limits. | 120 // TODO(posciak): determine input buffer size based on level limits. |
| 122 // See http://crbug.com/255116. | 121 // See http://crbug.com/255116. |
| 123 // Input bitstream buffer size for up to 1080p streams. | 122 // Input bitstream buffer size for up to 1080p streams. |
| 124 kInputBufferMaxSizeFor1080p = 1024 * 1024, | 123 kInputBufferMaxSizeFor1080p = 1024 * 1024, |
| 125 // Input bitstream buffer size for up to 4k streams. | 124 // Input bitstream buffer size for up to 4k streams. |
| 126 kInputBufferMaxSizeFor4k = 4 * kInputBufferMaxSizeFor1080p, | 125 kInputBufferMaxSizeFor4k = 4 * kInputBufferMaxSizeFor1080p, |
| 127 // Number of output buffers to use for each VDA stage above what's required | 126 // Number of output buffers to use for each VDA stage above what's required |
| 128 // by the decoder (e.g. DPB size, in H264). We need | 127 // by the decoder (e.g. DPB size, in H264). We need |
| 129 // media::limits::kMaxVideoFrames to fill up the GpuVideoDecode pipeline, | 128 // media::limits::kMaxVideoFrames to fill up the GpuVideoDecode pipeline, |
| 130 // and +1 for a frame in transit. | 129 // and +1 for a frame in transit. |
| 131 kDpbOutputBufferExtraCount = media::limits::kMaxVideoFrames + 1, | 130 kDpbOutputBufferExtraCount = media::limits::kMaxVideoFrames + 1, |
| 132 }; | 131 }; |
| 133 | 132 |
| 134 // Internal state of the decoder. | 133 // Internal state of the decoder. |
| 135 enum State { | 134 enum State { |
| 136 kUninitialized, // Initialize() not yet called. | 135 kUninitialized, // Initialize() not yet called. |
| 137 kInitialized, // Initialize() returned true; ready to start decoding. | 136 kInitialized, // Initialize() returned true; ready to start decoding. |
| 138 kDecoding, // DecodeBufferInitial() successful; decoding frames. | 137 kDecoding, // DecodeBufferInitial() successful; decoding frames. |
| 139 kResetting, // Presently resetting. | 138 kResetting, // Presently resetting. |
| 140 kAfterReset, // After Reset(), ready to start decoding again. | 139 kAfterReset, // After Reset(), ready to start decoding again. |
| 141 kChangingResolution, // Performing resolution change, all remaining | 140 kChangingResolution, // Performing resolution change, all remaining |
| 142 // pre-change frames decoded and processed. | 141 // pre-change frames decoded and processed. |
| 143 kError, // Error in kDecoding state. | 142 kError, // Error in kDecoding state. |
| 144 }; | 143 }; |
| 145 | 144 |
| 146 enum OutputRecordState { | 145 enum OutputRecordState { |
| 147 kFree, // Ready to be queued to the device. | 146 kFree, // Ready to be queued to the device. |
| 148 kAtDevice, // Held by device. | 147 kAtDevice, // Held by device. |
| 149 kAtProcessor, // Held by image processor. | 148 kAtProcessor, // Held by image processor. |
| 150 kAtClient, // Held by client of V4L2VideoDecodeAccelerator. | 149 kAtClient, // Held by client of V4L2VideoDecodeAccelerator. |
| 151 }; | 150 }; |
| 152 | 151 |
| 153 enum BufferId { | 152 enum BufferId { |
| 154 kFlushBufferId = -2 // Buffer id for flush buffer, queued by FlushTask(). | 153 kFlushBufferId = -2 // Buffer id for flush buffer, queued by FlushTask(). |
| 155 }; | 154 }; |
| 156 | 155 |
| 157 // Auto-destruction reference for BitstreamBuffer, for message-passing from | 156 // Auto-destruction reference for BitstreamBuffer, for message-passing from |
| 158 // Decode() to DecodeTask(). | 157 // Decode() to DecodeTask(). |
| 159 struct BitstreamBufferRef; | 158 struct BitstreamBufferRef; |
| 160 | 159 |
| 161 // Auto-destruction reference for EGLSync (for message-passing). | 160 // Auto-destruction reference for EGLSync (for message-passing). |
| 162 struct EGLSyncKHRRef; | 161 struct EGLSyncKHRRef; |
| 163 | 162 |
| 164 // Record for decoded pictures that can be sent to PictureReady. | 163 // Record for decoded pictures that can be sent to PictureReady. |
| 165 struct PictureRecord; | 164 struct PictureRecord; |
| 166 | 165 |
| 167 // Record for input buffers. | 166 // Record for input buffers. |
| 168 struct InputRecord { | 167 struct InputRecord { |
| 169 InputRecord(); | 168 InputRecord(); |
| 170 ~InputRecord(); | 169 ~InputRecord(); |
| 171 bool at_device; // held by device. | 170 bool at_device; // held by device. |
| 172 void* address; // mmap() address. | 171 void* address; // mmap() address. |
| 173 size_t length; // mmap() length. | 172 size_t length; // mmap() length. |
| 174 off_t bytes_used; // bytes filled in the mmap() segment. | 173 off_t bytes_used; // bytes filled in the mmap() segment. |
| 175 int32_t input_id; // triggering input_id as given to Decode(). | 174 int32_t input_id; // triggering input_id as given to Decode(). |
| 176 }; | 175 }; |
| 177 | 176 |
| 178 // Record for output buffers. | 177 // Record for output buffers. |
| 179 struct OutputRecord { | 178 struct OutputRecord { |
| 180 OutputRecord(); | 179 OutputRecord(); |
| 181 OutputRecord(OutputRecord&&) = default; | 180 OutputRecord(OutputRecord&&) = default; |
| 182 ~OutputRecord(); | 181 ~OutputRecord(); |
| 183 OutputRecordState state; | 182 OutputRecordState state; |
| 184 EGLImageKHR egl_image; // EGLImageKHR for the output buffer. | 183 EGLImageKHR egl_image; // EGLImageKHR for the output buffer. |
| 185 EGLSyncKHR egl_sync; // sync the compositor's use of the EGLImage. | 184 EGLSyncKHR egl_sync; // sync the compositor's use of the EGLImage. |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 395 // task execution should complete one buffer. If we fall behind (due to | 394 // task execution should complete one buffer. If we fall behind (due to |
| 396 // resource backpressure, etc.), we'll have to schedule more to catch up. | 395 // resource backpressure, etc.), we'll have to schedule more to catch up. |
| 397 int decoder_decode_buffer_tasks_scheduled_; | 396 int decoder_decode_buffer_tasks_scheduled_; |
| 398 // Picture buffers held by the client. | 397 // Picture buffers held by the client. |
| 399 int decoder_frames_at_client_; | 398 int decoder_frames_at_client_; |
| 400 // Are we flushing? | 399 // Are we flushing? |
| 401 bool decoder_flushing_; | 400 bool decoder_flushing_; |
| 402 // Got a reset request while we were performing resolution change. | 401 // Got a reset request while we were performing resolution change. |
| 403 bool resolution_change_reset_pending_; | 402 bool resolution_change_reset_pending_; |
| 404 // Input queue for decoder_thread_: BitstreamBuffers in. | 403 // Input queue for decoder_thread_: BitstreamBuffers in. |
| 405 std::queue<linked_ptr<BitstreamBufferRef> > decoder_input_queue_; | 404 std::queue<linked_ptr<BitstreamBufferRef>> decoder_input_queue_; |
| 406 // For H264 decode, hardware requires that we send it frame-sized chunks. | 405 // For H264 decode, hardware requires that we send it frame-sized chunks. |
| 407 // We'll need to parse the stream. | 406 // We'll need to parse the stream. |
| 408 std::unique_ptr<media::H264Parser> decoder_h264_parser_; | 407 std::unique_ptr<media::H264Parser> decoder_h264_parser_; |
| 409 // Set if the decoder has a pending incomplete frame in an input buffer. | 408 // Set if the decoder has a pending incomplete frame in an input buffer. |
| 410 bool decoder_partial_frame_pending_; | 409 bool decoder_partial_frame_pending_; |
| 411 | 410 |
| 412 // | 411 // |
| 413 // Hardware state and associated queues. Since decoder_thread_ services | 412 // Hardware state and associated queues. Since decoder_thread_ services |
| 414 // the hardware, decoder_thread_ owns these too. | 413 // the hardware, decoder_thread_ owns these too. |
| 415 // output_buffer_map_, free_output_buffers_ and output_planes_count_ are an | 414 // output_buffer_map_, free_output_buffers_ and output_planes_count_ are an |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 506 | 505 |
| 507 // Input format V4L2 fourccs this class supports. | 506 // Input format V4L2 fourccs this class supports. |
| 508 static const uint32_t supported_input_fourccs_[]; | 507 static const uint32_t supported_input_fourccs_[]; |
| 509 | 508 |
| 510 // The WeakPtrFactory for |weak_this_|. | 509 // The WeakPtrFactory for |weak_this_|. |
| 511 base::WeakPtrFactory<V4L2VideoDecodeAccelerator> weak_this_factory_; | 510 base::WeakPtrFactory<V4L2VideoDecodeAccelerator> weak_this_factory_; |
| 512 | 511 |
| 513 DISALLOW_COPY_AND_ASSIGN(V4L2VideoDecodeAccelerator); | 512 DISALLOW_COPY_AND_ASSIGN(V4L2VideoDecodeAccelerator); |
| 514 }; | 513 }; |
| 515 | 514 |
| 516 } // namespace content | 515 } // namespace media |
| 517 | 516 |
| 518 #endif // CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_DECODE_ACCELERATOR_H_ | 517 #endif // MEDIA_GPU_V4L2_VIDEO_DECODE_ACCELERATOR_H_ |
| OLD | NEW |