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 #include "content/common/gpu/media/fake_video_decode_accelerator.h" | 5 #include "content/common/gpu/media/fake_video_decode_accelerator.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <string.h> | 8 #include <string.h> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 DCHECK(child_task_runner_->BelongsToCurrentThread()); | 46 DCHECK(child_task_runner_->BelongsToCurrentThread()); |
47 if (config.profile == media::VIDEO_CODEC_PROFILE_UNKNOWN) { | 47 if (config.profile == media::VIDEO_CODEC_PROFILE_UNKNOWN) { |
48 LOG(ERROR) << "unknown codec profile"; | 48 LOG(ERROR) << "unknown codec profile"; |
49 return false; | 49 return false; |
50 } | 50 } |
51 if (config.is_encrypted) { | 51 if (config.is_encrypted) { |
52 NOTREACHED() << "encrypted streams are not supported"; | 52 NOTREACHED() << "encrypted streams are not supported"; |
53 return false; | 53 return false; |
54 } | 54 } |
55 | 55 |
| 56 if (config.flush_mode != Config::FlushMode::KEEP_OUTPUT_BUFFERS && |
| 57 config.flush_mode != Config::FlushMode::RETURN_OUTPUT_BUFFERS) { |
| 58 NOTIMPLEMENTED() << "Unsupported Config::FlushMode"; |
| 59 return false; |
| 60 } |
| 61 |
| 62 config_ = config; |
| 63 |
56 // V4L2VideoDecodeAccelerator waits until first decode call to ask for buffers | 64 // V4L2VideoDecodeAccelerator waits until first decode call to ask for buffers |
57 // This class asks for it on initialization instead. | 65 // This class asks for it on initialization instead. |
58 client_ = client; | 66 client_ = client; |
59 client_->ProvidePictureBuffers(kNumBuffers, 1, frame_buffer_size_, | 67 client_->ProvidePictureBuffers(kNumBuffers, 1, frame_buffer_size_, |
60 kDefaultTextureTarget); | 68 kDefaultTextureTarget); |
61 return true; | 69 return true; |
62 } | 70 } |
63 | 71 |
64 void FakeVideoDecodeAccelerator::Decode( | 72 void FakeVideoDecodeAccelerator::Decode( |
65 const media::BitstreamBuffer& bitstream_buffer) { | 73 const media::BitstreamBuffer& bitstream_buffer) { |
66 // We won't really read from the bitstream_buffer, close the handle. | 74 // We won't really read from the bitstream_buffer, close the handle. |
67 if (base::SharedMemory::IsHandleValid(bitstream_buffer.handle())) | 75 if (base::SharedMemory::IsHandleValid(bitstream_buffer.handle())) |
68 base::SharedMemory::CloseHandle(bitstream_buffer.handle()); | 76 base::SharedMemory::CloseHandle(bitstream_buffer.handle()); |
69 | 77 |
70 if (bitstream_buffer.id() < 0) { | 78 if (bitstream_buffer.id() < 0) { |
71 LOG(ERROR) << "Invalid bitstream: id=" << bitstream_buffer.id(); | 79 LOG(ERROR) << "Invalid bitstream: id=" << bitstream_buffer.id(); |
72 client_->NotifyError(INVALID_ARGUMENT); | 80 client_->NotifyError(INVALID_ARGUMENT); |
73 return; | 81 return; |
74 } | 82 } |
75 | 83 |
76 int bitstream_buffer_id = bitstream_buffer.id(); | 84 int bitstream_buffer_id = bitstream_buffer.id(); |
77 queued_bitstream_ids_.push(bitstream_buffer_id); | 85 queued_bitstream_ids_.push(bitstream_buffer_id); |
78 child_task_runner_->PostTask( | 86 child_task_runner_->PostTask( |
79 FROM_HERE, base::Bind(&FakeVideoDecodeAccelerator::DoPictureReady, | 87 FROM_HERE, base::Bind(&FakeVideoDecodeAccelerator::DoPictureReady, |
80 weak_this_factory_.GetWeakPtr())); | 88 weak_this_factory_.GetWeakPtr())); |
81 } | 89 } |
82 | 90 |
83 // Similar to UseOutputBitstreamBuffer for the encode accelerator. | |
84 void FakeVideoDecodeAccelerator::AssignPictureBuffers( | 91 void FakeVideoDecodeAccelerator::AssignPictureBuffers( |
85 const std::vector<media::PictureBuffer>& buffers) { | 92 const std::vector<media::PictureBuffer>& buffers) { |
86 DCHECK(buffers.size() == kNumBuffers); | 93 DCHECK_GE(buffers.size(), kNumBuffers); |
87 DCHECK(!(buffers.size()%2)); | |
88 | 94 |
89 // Save buffers and mark all buffers as ready for use. | 95 // Save buffers and mark all buffers as ready for use. |
90 std::unique_ptr<uint8_t[]> white_data( | 96 std::unique_ptr<uint8_t[]> white_data( |
91 new uint8_t[frame_buffer_size_.width() * frame_buffer_size_.height() * | 97 new uint8_t[frame_buffer_size_.width() * frame_buffer_size_.height() * |
92 4]); | 98 4]); |
93 memset(white_data.get(), | 99 memset(white_data.get(), |
94 UINT8_MAX, | 100 UINT8_MAX, |
95 frame_buffer_size_.width() * frame_buffer_size_.height() * 4); | 101 frame_buffer_size_.width() * frame_buffer_size_.height() * 4); |
96 std::unique_ptr<uint8_t[]> black_data( | 102 std::unique_ptr<uint8_t[]> black_data( |
97 new uint8_t[frame_buffer_size_.width() * frame_buffer_size_.height() * | 103 new uint8_t[frame_buffer_size_.width() * frame_buffer_size_.height() * |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 } | 164 } |
159 delete this; | 165 delete this; |
160 } | 166 } |
161 | 167 |
162 bool FakeVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( | 168 bool FakeVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( |
163 const base::WeakPtr<Client>& decode_client, | 169 const base::WeakPtr<Client>& decode_client, |
164 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { | 170 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { |
165 return false; | 171 return false; |
166 } | 172 } |
167 | 173 |
| 174 void FakeVideoDecodeAccelerator::ReturnPicture(int32_t picture_buffer_id, |
| 175 int32_t bitstream_buffer_id) { |
| 176 const media::Picture picture = |
| 177 media::Picture(picture_buffer_id, bitstream_buffer_id, |
| 178 gfx::Rect(frame_buffer_size_), false); |
| 179 |
| 180 client_->PictureReady(picture); |
| 181 } |
| 182 |
168 void FakeVideoDecodeAccelerator::DoPictureReady() { | 183 void FakeVideoDecodeAccelerator::DoPictureReady() { |
| 184 while (!free_output_buffers_.empty() && !queued_bitstream_ids_.empty()) { |
| 185 int bitstream_id = queued_bitstream_ids_.front(); |
| 186 queued_bitstream_ids_.pop(); |
| 187 |
| 188 int buffer_id = free_output_buffers_.front(); |
| 189 free_output_buffers_.pop(); |
| 190 |
| 191 ReturnPicture(buffer_id, bitstream_id); |
| 192 client_->NotifyEndOfBitstreamBuffer(bitstream_id); |
| 193 } |
| 194 |
169 if (flushing_ && queued_bitstream_ids_.empty()) { | 195 if (flushing_ && queued_bitstream_ids_.empty()) { |
| 196 if (config_.flush_mode == Config::FlushMode::RETURN_OUTPUT_BUFFERS) { |
| 197 while (!free_output_buffers_.empty()) { |
| 198 int32_t picture_buffer_id = free_output_buffers_.front(); |
| 199 free_output_buffers_.pop(); |
| 200 ReturnPicture(picture_buffer_id, -1); |
| 201 } |
| 202 } |
| 203 |
170 flushing_ = false; | 204 flushing_ = false; |
171 client_->NotifyFlushDone(); | 205 client_->NotifyFlushDone(); |
172 } | 206 } |
173 while (!free_output_buffers_.empty() && !queued_bitstream_ids_.empty()) { | |
174 int bitstream_id = queued_bitstream_ids_.front(); | |
175 queued_bitstream_ids_.pop(); | |
176 int buffer_id = free_output_buffers_.front(); | |
177 free_output_buffers_.pop(); | |
178 | |
179 const media::Picture picture = | |
180 media::Picture(buffer_id, | |
181 bitstream_id, | |
182 gfx::Rect(frame_buffer_size_), | |
183 false); | |
184 client_->PictureReady(picture); | |
185 // Bitstream no longer needed. | |
186 client_->NotifyEndOfBitstreamBuffer(bitstream_id); | |
187 if (flushing_ && queued_bitstream_ids_.empty()) { | |
188 flushing_ = false; | |
189 client_->NotifyFlushDone(); | |
190 } | |
191 } | |
192 } | 207 } |
193 | 208 |
194 } // namespace content | 209 } // namespace content |
OLD | NEW |