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 #ifndef CONTENT_COMMON_GPU_MEDIA_VT_VIDEO_DECODE_ACCELERATOR_H_ | 5 #ifndef CONTENT_COMMON_GPU_MEDIA_VT_VIDEO_DECODE_ACCELERATOR_H_ |
6 #define CONTENT_COMMON_GPU_MEDIA_VT_VIDEO_DECODE_ACCELERATOR_H_ | 6 #define CONTENT_COMMON_GPU_MEDIA_VT_VIDEO_DECODE_ACCELERATOR_H_ |
7 | 7 |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <map> | 10 #include <map> |
11 #include <queue> | 11 #include <queue> |
12 | 12 |
13 #include "base/mac/scoped_cftyperef.h" | 13 #include "base/mac/scoped_cftyperef.h" |
14 #include "base/memory/ref_counted.h" | 14 #include "base/memory/linked_ptr.h" |
15 #include "base/memory/weak_ptr.h" | 15 #include "base/memory/weak_ptr.h" |
16 #include "base/message_loop/message_loop.h" | 16 #include "base/message_loop/message_loop.h" |
17 #include "base/threading/thread.h" | 17 #include "base/threading/thread.h" |
18 #include "content/common/gpu/media/vt.h" | 18 #include "content/common/gpu/media/vt.h" |
19 #include "media/filters/h264_parser.h" | 19 #include "media/filters/h264_parser.h" |
20 #include "media/video/video_decode_accelerator.h" | 20 #include "media/video/video_decode_accelerator.h" |
21 #include "ui/gfx/geometry/size.h" | 21 #include "ui/gfx/geometry/size.h" |
22 #include "ui/gl/gl_context_cgl.h" | 22 #include "ui/gl/gl_context_cgl.h" |
23 | 23 |
24 namespace base { | 24 namespace base { |
(...skipping 19 matching lines...) Expand all Loading... |
44 void AssignPictureBuffers( | 44 void AssignPictureBuffers( |
45 const std::vector<media::PictureBuffer>& pictures) override; | 45 const std::vector<media::PictureBuffer>& pictures) override; |
46 void ReusePictureBuffer(int32_t picture_id) override; | 46 void ReusePictureBuffer(int32_t picture_id) override; |
47 void Flush() override; | 47 void Flush() override; |
48 void Reset() override; | 48 void Reset() override; |
49 void Destroy() override; | 49 void Destroy() override; |
50 bool CanDecodeOnIOThread() override; | 50 bool CanDecodeOnIOThread() override; |
51 | 51 |
52 // Called by OutputThunk() when VideoToolbox finishes decoding a frame. | 52 // Called by OutputThunk() when VideoToolbox finishes decoding a frame. |
53 void Output( | 53 void Output( |
54 int32_t bitstream_id, | 54 void* source_frame_refcon, |
55 OSStatus status, | 55 OSStatus status, |
56 CVImageBufferRef image_buffer); | 56 CVImageBufferRef image_buffer); |
57 | 57 |
58 private: | 58 private: |
59 struct DecodedFrame { | 59 enum State { |
60 DecodedFrame(int32_t bitstream_id, CVImageBufferRef image_buffer); | 60 STATE_NORMAL, |
61 ~DecodedFrame(); | 61 STATE_DESTROYING, |
| 62 STATE_ERROR, |
| 63 }; |
| 64 |
| 65 enum TaskType { |
| 66 TASK_FRAME, |
| 67 TASK_FLUSH, |
| 68 TASK_RESET, |
| 69 TASK_DESTROY, |
| 70 }; |
| 71 |
| 72 struct Frame { |
| 73 Frame(int32_t bitstream_id); |
| 74 ~Frame(); |
62 | 75 |
63 int32_t bitstream_id; | 76 int32_t bitstream_id; |
64 base::ScopedCFTypeRef<CVImageBufferRef> image_buffer; | 77 base::ScopedCFTypeRef<CVImageBufferRef> image; |
| 78 // TODO(sandersd): visible_rect. |
| 79 gfx::Size coded_size; |
65 }; | 80 }; |
66 | 81 |
67 // Actions are the possible types of pending operations, which are queued | 82 struct Task { |
68 // by Flush(), Reset(), and Destroy(). | 83 Task(TaskType type); |
69 enum Action { | 84 ~Task(); |
70 ACTION_FLUSH, | 85 |
71 ACTION_RESET, | 86 TaskType type; |
72 ACTION_DESTROY | 87 linked_ptr<Frame> frame; |
73 }; | 88 }; |
74 | 89 |
75 // PendingActions contain the |bitstream_id| of a frame that, once decoded and | 90 // |
76 // sent, a particular |action| should be completed at. | 91 // Methods for interacting with VideoToolbox. Run on |decoder_thread_|. |
77 struct PendingAction { | 92 // |
78 PendingAction(Action action, int32_t bitstream_id); | 93 // Set up VideoToolbox using the current SPS and PPS. Returns true or calls |
79 ~PendingAction(); | 94 // NotifyError() before returning false. |
| 95 bool ConfigureDecoder(); |
80 | 96 |
81 Action action; | 97 // Wait for VideoToolbox to output all pending frames. Returns true or calls |
82 int32_t bitstream_id; | 98 // NotifyError() before returning false. |
83 }; | 99 bool FinishDelayedFrames(); |
84 | 100 |
85 // Methods for interacting with VideoToolbox. Run on |decoder_thread_|. | 101 // |frame| is owned by |pending_frames_|. |
86 bool ConfigureDecoder( | 102 void DecodeTask(const media::BitstreamBuffer&, Frame* frame); |
87 const std::vector<const uint8_t*>& nalu_data_ptrs, | 103 void DecodeDone(Frame* frame); |
88 const std::vector<size_t>& nalu_data_sizes); | |
89 void DecodeTask(const media::BitstreamBuffer&); | |
90 void FlushTask(); | |
91 void DropBitstream(int32_t bitstream_id); | |
92 | 104 |
| 105 // |
93 // Methods for interacting with |client_|. Run on |gpu_task_runner_|. | 106 // Methods for interacting with |client_|. Run on |gpu_task_runner_|. |
94 void OutputTask(DecodedFrame frame); | 107 // |
95 void NotifyError(Error error); | 108 void NotifyError(Error error); |
96 | 109 |
97 // Send decoded frames up to and including |up_to_bitstream_id|, and return | 110 // |type| is the type of task that the flush will complete, one of TASK_FLUSH, |
98 // the last sent |bitstream_id|. | 111 // TASK_RESET, or TASK_DESTROY. |
99 int32_t SendPictures(int32_t up_to_bitstream_id); | 112 void QueueFlush(TaskType type); |
| 113 void FlushTask(TaskType type); |
| 114 void FlushDone(TaskType type); |
100 | 115 |
101 // Internal helper for SendPictures(): Drop frames with no image data up to | 116 // Attempt to make progress on |pending_tasks_|. |
102 // a particular bitstream ID, so that if there is still a frame in the queue | 117 void ProcessTasks(); |
103 // when this function returns, it is guaranteed to have image data, and thus | |
104 // it is time to set up the GPU context. Returns the last bitstream ID that | |
105 // was dropped, or |last_sent_bitstream_id| if no frames were dropped. | |
106 int32_t ProcessDroppedFrames( | |
107 int32_t last_sent_bitstream_id, | |
108 int32_t up_to_bitstream_id); | |
109 | 118 |
110 // Internal helper for SendPictures(): Check if the next frame has a size | 119 // These methods returns true if the task was completed, false if it couldn't |
111 // different from the current picture buffers, and request new ones if so. | 120 // be completed yet. |
112 void ProcessSizeChangeIfNeeded(); | 121 bool ProcessTask(const Task& task); |
113 | 122 bool ProcessFrame(const Frame& frame); |
114 // Since VideoToolbox has no reset feature (only flush), and the VDA API | 123 bool SendFrame(const Frame& frame); |
115 // allows Decode() and Flush() calls during a reset operation, it's possible | |
116 // to have multiple pending actions at once. We handle the fully general case | |
117 // of an arbitrary sequence of pending actions (in reality, there should | |
118 // probably be at most one reset and one flush at a time). | |
119 void QueueAction(Action action); | |
120 | |
121 // Process queued decoded frames, usually by sending them (unless there | |
122 // is a pending ACTION_RESET or ACTION_DESTROY, in which case they are | |
123 // dropped), completing queued actions along the way. | |
124 void ProcessDecodedFrames(); | |
125 | |
126 // Complete a particular action, by eg. calling NotifyFlushDone(). | |
127 // Warning: Deletes |this| if |action| is ACTION_DESTROY. | |
128 void CompleteAction(Action action); | |
129 | |
130 // Complete all actions pending for a particular |bitstream_id|. | |
131 // Warning: Do not call if there is a pending ACTION_DESTROY. | |
132 void CompleteActions(int32_t bitstream_id); | |
133 | 124 |
134 // | 125 // |
135 // GPU thread state. | 126 // GPU thread state. |
136 // | 127 // |
137 CGLContextObj cgl_context_; | 128 CGLContextObj cgl_context_; |
138 base::Callback<bool(void)> make_context_current_; | 129 base::Callback<bool(void)> make_context_current_; |
139 media::VideoDecodeAccelerator::Client* client_; | 130 media::VideoDecodeAccelerator::Client* client_; |
| 131 State state_; |
140 | 132 |
141 // client_->NotifyError() called. | 133 // Queue of pending flush tasks. This is used to drop frames when a reset |
142 bool has_error_; | 134 // is pending. |
| 135 std::queue<TaskType> pending_flush_tasks_; |
| 136 |
| 137 // Queue of tasks to complete in the GPU thread. |
| 138 std::queue<Task> pending_tasks_; |
143 | 139 |
144 // Size of assigned picture buffers. | 140 // Size of assigned picture buffers. |
145 gfx::Size picture_size_; | 141 gfx::Size picture_size_; |
146 | 142 |
147 // Queue of actions so that we can quickly discover what the next action will | 143 // Queue of frames that have not yet been decoded; maintains ownership of the |
148 // be; this is useful because we are dropping all frames when the next action | 144 // Frame objects while they flow through VideoToolbox. |
149 // is ACTION_RESET or ACTION_DESTROY. | 145 std::queue<linked_ptr<Frame>> pending_frames_; |
150 std::queue<PendingAction> pending_actions_; | |
151 | 146 |
152 // Queue of bitstreams that have not yet been decoded. This is mostly needed | 147 // Set of assigned bitstream IDs, so that Destroy() can release them all. |
153 // to be sure we free them all in Destroy(). | 148 std::set<int32_t> assigned_bitstream_ids_; |
154 std::queue<int32_t> pending_bitstream_ids_; | |
155 | 149 |
156 // All picture buffers assigned to us. Used to check if reused picture buffers | 150 // All picture buffers assigned to us. Used to check if reused picture buffers |
157 // should be added back to the available list or released. (They are not | 151 // should be added back to the available list or released. (They are not |
158 // released immediately because we need the reuse event to free the binding.) | 152 // released immediately because we need the reuse event to free the binding.) |
159 std::set<int32_t> assigned_picture_ids_; | 153 std::set<int32_t> assigned_picture_ids_; |
160 | 154 |
161 // Texture IDs of assigned pictures. | 155 // Texture IDs of assigned pictures. |
162 std::map<int32_t, uint32_t> texture_ids_; | 156 std::map<int32_t, uint32_t> texture_ids_; |
163 | 157 |
164 // Pictures ready to be rendered to. | 158 // Pictures ready to be rendered to. |
165 std::vector<int32_t> available_picture_ids_; | 159 std::vector<int32_t> available_picture_ids_; |
166 | 160 |
167 // Decoded frames ready to render. | |
168 std::queue<DecodedFrame> decoded_frames_; | |
169 | |
170 // Image buffers kept alive while they are bound to pictures. | 161 // Image buffers kept alive while they are bound to pictures. |
171 std::map<int32_t, base::ScopedCFTypeRef<CVImageBufferRef>> picture_bindings_; | 162 std::map<int32_t, base::ScopedCFTypeRef<CVImageBufferRef>> picture_bindings_; |
172 | 163 |
173 // | 164 // |
174 // Decoder thread state. | 165 // Decoder thread state. |
175 // | 166 // |
176 VTDecompressionOutputCallbackRecord callback_; | 167 VTDecompressionOutputCallbackRecord callback_; |
177 base::ScopedCFTypeRef<CMFormatDescriptionRef> format_; | 168 base::ScopedCFTypeRef<CMFormatDescriptionRef> format_; |
178 base::ScopedCFTypeRef<VTDecompressionSessionRef> session_; | 169 base::ScopedCFTypeRef<VTDecompressionSessionRef> session_; |
179 media::H264Parser parser_; | 170 media::H264Parser parser_; |
| 171 gfx::Size coded_size_; |
180 | 172 |
181 std::vector<uint8_t> last_sps_; | 173 std::vector<uint8_t> last_sps_; |
182 std::vector<uint8_t> last_spsext_; | 174 std::vector<uint8_t> last_spsext_; |
183 std::vector<uint8_t> last_pps_; | 175 std::vector<uint8_t> last_pps_; |
184 | 176 |
185 // | 177 // |
186 // Shared state (set up and torn down on GPU thread). | 178 // Shared state (set up and torn down on GPU thread). |
187 // | 179 // |
188 scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner_; | 180 scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner_; |
189 | 181 |
190 // This WeakPtrFactory does not need to be last as its pointers are bound to | 182 // This WeakPtrFactory does not need to be last as its pointers are bound to |
191 // the same thread it is destructed on (the GPU thread). | 183 // the same thread it is destructed on (the GPU thread). |
192 base::WeakPtrFactory<VTVideoDecodeAccelerator> weak_this_factory_; | 184 base::WeakPtrFactory<VTVideoDecodeAccelerator> weak_this_factory_; |
193 | 185 |
194 // Declared last to ensure that all decoder thread tasks complete before any | 186 // Declared last to ensure that all decoder thread tasks complete before any |
195 // state is destructed. | 187 // state is destructed. |
196 base::Thread decoder_thread_; | 188 base::Thread decoder_thread_; |
197 | 189 |
198 DISALLOW_COPY_AND_ASSIGN(VTVideoDecodeAccelerator); | 190 DISALLOW_COPY_AND_ASSIGN(VTVideoDecodeAccelerator); |
199 }; | 191 }; |
200 | 192 |
201 } // namespace content | 193 } // namespace content |
202 | 194 |
203 #endif // CONTENT_COMMON_GPU_MEDIA_VT_VIDEO_DECODE_ACCELERATOR_H_ | 195 #endif // CONTENT_COMMON_GPU_MEDIA_VT_VIDEO_DECODE_ACCELERATOR_H_ |
OLD | NEW |