OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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_ANDROID_VIDEO_ENCODE_ACCELERATOR_H_ | 5 #ifndef CONTENT_COMMON_GPU_MEDIA_VT_VIDEO_ENCODE_ACCELERATOR_MAC_H_ |
6 #define CONTENT_COMMON_GPU_MEDIA_ANDROID_VIDEO_ENCODE_ACCELERATOR_H_ | 6 #define CONTENT_COMMON_GPU_MEDIA_VT_VIDEO_ENCODE_ACCELERATOR_MAC_H_ |
7 | 7 |
8 #include <stddef.h> | 8 #include "base/mac/scoped_cftyperef.h" |
9 #include <stdint.h> | |
10 | |
11 #include <list> | |
12 #include <queue> | |
13 #include <vector> | |
14 | |
15 #include "base/macros.h" | |
16 #include "base/memory/weak_ptr.h" | |
17 #include "base/threading/thread_checker.h" | |
18 #include "base/timer/timer.h" | |
19 #include "base/tuple.h" | |
20 #include "content/common/content_export.h" | 9 #include "content/common/content_export.h" |
21 #include "media/base/android/sdk_media_codec_bridge.h" | 10 #include "media/base/mac/videotoolbox_glue.h" |
| 11 #include "media/base/mac/videotoolbox_helpers.h" |
22 #include "media/video/video_encode_accelerator.h" | 12 #include "media/video/video_encode_accelerator.h" |
23 | 13 |
24 namespace media { | |
25 class BitstreamBuffer; | |
26 } // namespace media | |
27 | |
28 namespace content { | 14 namespace content { |
29 | 15 |
30 // Android-specific implementation of media::VideoEncodeAccelerator, enabling | 16 // VideoToolbox.framework implementation of the VideoEncodeAccelerator |
31 // hardware-acceleration of video encoding, based on Android's MediaCodec class | 17 // interface for MacOSX. VideoToolbox makes no guarantees that it is thread |
32 // (http://developer.android.com/reference/android/media/MediaCodec.html). This | 18 // safe, so this object is pinned to the thread on which it is constructed. |
33 // class expects to live and be called on a single thread (the GPU process' | 19 class CONTENT_EXPORT VTVideoEncodeAccelerator |
34 // ChildThread). | |
35 class CONTENT_EXPORT AndroidVideoEncodeAccelerator | |
36 : public media::VideoEncodeAccelerator { | 20 : public media::VideoEncodeAccelerator { |
37 public: | 21 public: |
38 AndroidVideoEncodeAccelerator(); | 22 VTVideoEncodeAccelerator(); |
39 ~AndroidVideoEncodeAccelerator() override; | 23 ~VTVideoEncodeAccelerator() override; |
40 | 24 |
41 // media::VideoEncodeAccelerator implementation. | 25 // media::VideoEncodeAccelerator implementation. |
42 media::VideoEncodeAccelerator::SupportedProfiles GetSupportedProfiles() | 26 media::VideoEncodeAccelerator::SupportedProfiles GetSupportedProfiles() |
43 override; | 27 override; |
44 bool Initialize(media::VideoPixelFormat format, | 28 bool Initialize(media::VideoPixelFormat format, |
45 const gfx::Size& input_visible_size, | 29 const gfx::Size& input_visible_size, |
46 media::VideoCodecProfile output_profile, | 30 media::VideoCodecProfile output_profile, |
47 uint32_t initial_bitrate, | 31 uint32_t initial_bitrate, |
48 Client* client) override; | 32 Client* client) override; |
49 void Encode(const scoped_refptr<media::VideoFrame>& frame, | 33 void Encode(const scoped_refptr<media::VideoFrame>& frame, |
50 bool force_keyframe) override; | 34 bool force_keyframe) override; |
51 void UseOutputBitstreamBuffer(const media::BitstreamBuffer& buffer) override; | 35 void UseOutputBitstreamBuffer(const media::BitstreamBuffer& buffer) override; |
52 void RequestEncodingParametersChange(uint32_t bitrate, | 36 void RequestEncodingParametersChange(uint32_t bitrate, |
53 uint32_t framerate) override; | 37 uint32_t framerate) override; |
54 void Destroy() override; | 38 void Destroy() override; |
55 | 39 |
56 private: | 40 private: |
57 enum { | 41 using CMSampleBufferRef = CoreMediaGlue::CMSampleBufferRef; |
58 // Arbitrary choice. | 42 using VTCompressionSessionRef = VideoToolboxGlue::VTCompressionSessionRef; |
59 INITIAL_FRAMERATE = 30, | 43 using VTEncodeInfoFlags = VideoToolboxGlue::VTEncodeInfoFlags; |
60 // Until there are non-realtime users, no need for unrequested I-frames. | |
61 IFRAME_INTERVAL = INT32_MAX, | |
62 }; | |
63 | 44 |
64 // Impedance-mismatch fixers: MediaCodec is a poll-based API but VEA is a | 45 // Holds the associated data of a video frame being processed. |
65 // push-based API; these methods turn the crank to make the two work together. | 46 struct InProgressFrameEncode; |
66 void DoIOTask(); | |
67 void QueueInput(); | |
68 void DequeueOutput(); | |
69 | 47 |
70 // Returns true if we don't need more or bigger output buffers. | 48 // Holds output buffers coming from the client ready to be filled. |
71 bool DoOutputBuffersSuffice(); | 49 struct BitstreamBufferRef; |
72 | 50 |
73 // Start & stop |io_timer_| if the time seems right. | 51 // Compression session callback function to handle compressed frames. |
74 void MaybeStartIOTimer(); | 52 static void CompressionCallback(void* encoder_opaque, |
75 void MaybeStopIOTimer(); | 53 void* request_opaque, |
| 54 OSStatus status, |
| 55 VTEncodeInfoFlags info, |
| 56 CMSampleBufferRef sbuf); |
| 57 void CompressionCallbackTask(VTEncodeInfoFlags info, CMSampleBufferRef sbuf); |
76 | 58 |
77 // Used to DCHECK that we are called on the correct thread. | 59 // Reset the encoder's compression session by destroying the existing one |
| 60 // using DestroyCompressionSession() and creating a new one. The new session |
| 61 // is configured using ConfigureCompressionSession(). |
| 62 bool ResetCompressionSession(); |
| 63 |
| 64 // Configure the current compression session using current encoder settings. |
| 65 bool ConfigureCompressionSession(); |
| 66 |
| 67 // Destroy the current compression session if any. Blocks until all pending |
| 68 // frames have been flushed out (similar to EmitFrames without doing any |
| 69 // encoding work). |
| 70 void DestroyCompressionSession(); |
| 71 |
| 72 // VideoToolboxGlue provides access to VideoToolbox at runtime. |
| 73 const VideoToolboxGlue* videotoolbox_glue_; |
| 74 base::ScopedCFTypeRef<VTCompressionSessionRef> compression_session_; |
| 75 |
| 76 int32_t bitrate_; |
| 77 gfx::Size input_visible_size_; |
| 78 |
| 79 // Set parameters for VTCompressionSession. |
| 80 scoped_ptr<media::video_toolbox::SessionPropertySetter> |
| 81 session_property_setter_; |
| 82 |
| 83 // Bitstream buffers ready to be used to return encoded output as a FIFO. |
| 84 std::deque<scoped_ptr<BitstreamBufferRef>> encoder_output_queue_; |
| 85 |
| 86 // CMSampleBufferRef needs to be copied into a BitstreamBufferRef as a FIFO. |
| 87 std::deque<CMSampleBufferRef> encoder_output_sample_buffer_queue_; |
| 88 |
| 89 // Our original calling task runner for the child thread. |
| 90 const scoped_refptr<base::SingleThreadTaskRunner> client_task_runner_; |
| 91 |
| 92 // To expose client callbacks from VideoEncodeAccelerator. |
| 93 // NOTE: all calls to this object *MUST* be executed on |
| 94 // |client_task_runner_|. |
| 95 scoped_ptr<base::WeakPtrFactory<Client> > client_ptr_factory_; |
| 96 base::WeakPtr<Client> client_; |
| 97 |
| 98 // Thread checker to enforce that this object is used on a specific thread. |
78 base::ThreadChecker thread_checker_; | 99 base::ThreadChecker thread_checker_; |
79 | 100 |
80 // VideoDecodeAccelerator::Client callbacks go here. Invalidated once any | 101 DISALLOW_COPY_AND_ASSIGN(VTVideoEncodeAccelerator); |
81 // error triggers. | |
82 scoped_ptr<base::WeakPtrFactory<Client> > client_ptr_factory_; | |
83 | |
84 scoped_ptr<media::VideoCodecBridge> media_codec_; | |
85 | |
86 // Bitstream buffers waiting to be populated & returned to the client. | |
87 std::vector<media::BitstreamBuffer> available_bitstream_buffers_; | |
88 | |
89 // Frames waiting to be passed to the codec, queued until an input buffer is | |
90 // available. Each element is a tuple of <Frame, key_frame, enqueue_time>. | |
91 typedef std::queue< | |
92 base::Tuple<scoped_refptr<media::VideoFrame>, bool, base::Time>> | |
93 PendingFrames; | |
94 PendingFrames pending_frames_; | |
95 | |
96 // Repeating timer responsible for draining pending IO to the codec. | |
97 base::RepeatingTimer io_timer_; | |
98 | |
99 // The difference between number of buffers queued & dequeued at the codec. | |
100 int32_t num_buffers_at_codec_; | |
101 | |
102 // A monotonically-growing value, used as a fake timestamp just to keep things | |
103 // appearing to move forward. | |
104 base::TimeDelta fake_input_timestamp_; | |
105 | |
106 // Number of requested output buffers and their capacity. | |
107 int num_output_buffers_; // -1 until RequireBitstreamBuffers. | |
108 size_t output_buffers_capacity_; // 0 until RequireBitstreamBuffers. | |
109 | |
110 uint32_t last_set_bitrate_; // In bps. | |
111 | |
112 DISALLOW_COPY_AND_ASSIGN(AndroidVideoEncodeAccelerator); | |
113 }; | 102 }; |
114 | 103 |
115 } // namespace content | 104 } // namespace content |
116 | 105 |
117 #endif // CONTENT_COMMON_GPU_MEDIA_ANDROID_VIDEO_ENCODE_ACCELERATOR_H_ | 106 #endif // CONTENT_COMMON_GPU_MEDIA_VT_VIDEO_ENCODE_ACCELERATOR_MAC_H_ |
OLD | NEW |