| 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 |