OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 <errno.h> | 5 #include <errno.h> |
6 #include <fcntl.h> | 6 #include <fcntl.h> |
7 #include <linux/videodev2.h> | 7 #include <linux/videodev2.h> |
8 #include <poll.h> | 8 #include <poll.h> |
9 #include <string.h> | 9 #include <string.h> |
10 #include <sys/eventfd.h> | 10 #include <sys/eventfd.h> |
11 #include <sys/ioctl.h> | 11 #include <sys/ioctl.h> |
12 #include <sys/mman.h> | 12 #include <sys/mman.h> |
13 | 13 |
14 #include "base/bind.h" | 14 #include "base/bind.h" |
15 #include "base/bind_helpers.h" | 15 #include "base/bind_helpers.h" |
16 #include "base/callback.h" | 16 #include "base/callback.h" |
17 #include "base/callback_helpers.h" | 17 #include "base/callback_helpers.h" |
18 #include "base/command_line.h" | 18 #include "base/command_line.h" |
19 #include "base/macros.h" | 19 #include "base/macros.h" |
20 #include "base/numerics/safe_conversions.h" | 20 #include "base/numerics/safe_conversions.h" |
21 #include "base/strings/stringprintf.h" | 21 #include "base/strings/stringprintf.h" |
| 22 #include "content/common/gpu/media/shared_memory_region.h" |
22 #include "content/common/gpu/media/v4l2_slice_video_decode_accelerator.h" | 23 #include "content/common/gpu/media/v4l2_slice_video_decode_accelerator.h" |
23 #include "media/base/bind_to_current_loop.h" | 24 #include "media/base/bind_to_current_loop.h" |
24 #include "media/base/media_switches.h" | 25 #include "media/base/media_switches.h" |
25 #include "ui/gl/scoped_binders.h" | 26 #include "ui/gl/scoped_binders.h" |
26 | 27 |
27 #define LOGF(level) LOG(level) << __FUNCTION__ << "(): " | 28 #define LOGF(level) LOG(level) << __FUNCTION__ << "(): " |
28 #define DVLOGF(level) DVLOG(level) << __FUNCTION__ << "(): " | 29 #define DVLOGF(level) DVLOG(level) << __FUNCTION__ << "(): " |
29 | 30 |
30 #define NOTIFY_ERROR(x) \ | 31 #define NOTIFY_ERROR(x) \ |
31 do { \ | 32 do { \ |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 picture_id(-1), | 163 picture_id(-1), |
163 egl_image(EGL_NO_IMAGE_KHR), | 164 egl_image(EGL_NO_IMAGE_KHR), |
164 egl_sync(EGL_NO_SYNC_KHR), | 165 egl_sync(EGL_NO_SYNC_KHR), |
165 cleared(false) { | 166 cleared(false) { |
166 } | 167 } |
167 | 168 |
168 struct V4L2SliceVideoDecodeAccelerator::BitstreamBufferRef { | 169 struct V4L2SliceVideoDecodeAccelerator::BitstreamBufferRef { |
169 BitstreamBufferRef( | 170 BitstreamBufferRef( |
170 base::WeakPtr<VideoDecodeAccelerator::Client>& client, | 171 base::WeakPtr<VideoDecodeAccelerator::Client>& client, |
171 const scoped_refptr<base::SingleThreadTaskRunner>& client_task_runner, | 172 const scoped_refptr<base::SingleThreadTaskRunner>& client_task_runner, |
172 base::SharedMemory* shm, | 173 SharedMemoryRegion* shm, |
173 size_t size, | |
174 int32_t input_id); | 174 int32_t input_id); |
175 ~BitstreamBufferRef(); | 175 ~BitstreamBufferRef(); |
176 const base::WeakPtr<VideoDecodeAccelerator::Client> client; | 176 const base::WeakPtr<VideoDecodeAccelerator::Client> client; |
177 const scoped_refptr<base::SingleThreadTaskRunner> client_task_runner; | 177 const scoped_refptr<base::SingleThreadTaskRunner> client_task_runner; |
178 const scoped_ptr<base::SharedMemory> shm; | 178 const scoped_ptr<SharedMemoryRegion> shm; |
179 const size_t size; | |
180 off_t bytes_used; | 179 off_t bytes_used; |
181 const int32_t input_id; | 180 const int32_t input_id; |
182 }; | 181 }; |
183 | 182 |
184 V4L2SliceVideoDecodeAccelerator::BitstreamBufferRef::BitstreamBufferRef( | 183 V4L2SliceVideoDecodeAccelerator::BitstreamBufferRef::BitstreamBufferRef( |
185 base::WeakPtr<VideoDecodeAccelerator::Client>& client, | 184 base::WeakPtr<VideoDecodeAccelerator::Client>& client, |
186 const scoped_refptr<base::SingleThreadTaskRunner>& client_task_runner, | 185 const scoped_refptr<base::SingleThreadTaskRunner>& client_task_runner, |
187 base::SharedMemory* shm, | 186 SharedMemoryRegion* shm, |
188 size_t size, | |
189 int32_t input_id) | 187 int32_t input_id) |
190 : client(client), | 188 : client(client), |
191 client_task_runner(client_task_runner), | 189 client_task_runner(client_task_runner), |
192 shm(shm), | 190 shm(shm), |
193 size(size), | |
194 bytes_used(0), | 191 bytes_used(0), |
195 input_id(input_id) {} | 192 input_id(input_id) {} |
196 | 193 |
197 V4L2SliceVideoDecodeAccelerator::BitstreamBufferRef::~BitstreamBufferRef() { | 194 V4L2SliceVideoDecodeAccelerator::BitstreamBufferRef::~BitstreamBufferRef() { |
198 if (input_id >= 0) { | 195 if (input_id >= 0) { |
199 DVLOGF(5) << "returning input_id: " << input_id; | 196 DVLOGF(5) << "returning input_id: " << input_id; |
200 client_task_runner->PostTask( | 197 client_task_runner->PostTask( |
201 FROM_HERE, | 198 FROM_HERE, |
202 base::Bind(&VideoDecodeAccelerator::Client::NotifyEndOfBitstreamBuffer, | 199 base::Bind(&VideoDecodeAccelerator::Client::NotifyEndOfBitstreamBuffer, |
203 client, input_id)); | 200 client, input_id)); |
(...skipping 1000 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1204 } | 1201 } |
1205 | 1202 |
1206 void V4L2SliceVideoDecodeAccelerator::DecodeTask( | 1203 void V4L2SliceVideoDecodeAccelerator::DecodeTask( |
1207 const media::BitstreamBuffer& bitstream_buffer) { | 1204 const media::BitstreamBuffer& bitstream_buffer) { |
1208 DVLOGF(3) << "input_id=" << bitstream_buffer.id() | 1205 DVLOGF(3) << "input_id=" << bitstream_buffer.id() |
1209 << " size=" << bitstream_buffer.size(); | 1206 << " size=" << bitstream_buffer.size(); |
1210 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); | 1207 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); |
1211 | 1208 |
1212 scoped_ptr<BitstreamBufferRef> bitstream_record(new BitstreamBufferRef( | 1209 scoped_ptr<BitstreamBufferRef> bitstream_record(new BitstreamBufferRef( |
1213 io_client_, io_task_runner_, | 1210 io_client_, io_task_runner_, |
1214 new base::SharedMemory(bitstream_buffer.handle(), true), | 1211 new SharedMemoryRegion(bitstream_buffer, true), bitstream_buffer.id())); |
1215 bitstream_buffer.size(), bitstream_buffer.id())); | 1212 if (!bitstream_record->shm->Map()) { |
1216 if (!bitstream_record->shm->Map(bitstream_buffer.size())) { | |
1217 LOGF(ERROR) << "Could not map bitstream_buffer"; | 1213 LOGF(ERROR) << "Could not map bitstream_buffer"; |
1218 NOTIFY_ERROR(UNREADABLE_INPUT); | 1214 NOTIFY_ERROR(UNREADABLE_INPUT); |
1219 return; | 1215 return; |
1220 } | 1216 } |
1221 DVLOGF(3) << "mapped at=" << bitstream_record->shm->memory(); | 1217 DVLOGF(3) << "mapped at=" << bitstream_record->shm->memory(); |
1222 | 1218 |
1223 decoder_input_queue_.push( | 1219 decoder_input_queue_.push( |
1224 linked_ptr<BitstreamBufferRef>(bitstream_record.release())); | 1220 linked_ptr<BitstreamBufferRef>(bitstream_record.release())); |
1225 | 1221 |
1226 ScheduleDecodeBufferTaskIfNeeded(); | 1222 ScheduleDecodeBufferTaskIfNeeded(); |
(...skipping 11 matching lines...) Expand all Loading... |
1238 decoder_input_queue_.pop(); | 1234 decoder_input_queue_.pop(); |
1239 | 1235 |
1240 if (decoder_current_bitstream_buffer_->input_id == kFlushBufferId) { | 1236 if (decoder_current_bitstream_buffer_->input_id == kFlushBufferId) { |
1241 // This is a buffer we queued for ourselves to trigger flush at this time. | 1237 // This is a buffer we queued for ourselves to trigger flush at this time. |
1242 InitiateFlush(); | 1238 InitiateFlush(); |
1243 return false; | 1239 return false; |
1244 } | 1240 } |
1245 | 1241 |
1246 const uint8_t* const data = reinterpret_cast<const uint8_t*>( | 1242 const uint8_t* const data = reinterpret_cast<const uint8_t*>( |
1247 decoder_current_bitstream_buffer_->shm->memory()); | 1243 decoder_current_bitstream_buffer_->shm->memory()); |
1248 const size_t data_size = decoder_current_bitstream_buffer_->size; | 1244 const size_t data_size = decoder_current_bitstream_buffer_->shm->size(); |
1249 decoder_->SetStream(data, data_size); | 1245 decoder_->SetStream(data, data_size); |
1250 | 1246 |
1251 return true; | 1247 return true; |
1252 } | 1248 } |
1253 | 1249 |
1254 void V4L2SliceVideoDecodeAccelerator::ScheduleDecodeBufferTaskIfNeeded() { | 1250 void V4L2SliceVideoDecodeAccelerator::ScheduleDecodeBufferTaskIfNeeded() { |
1255 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); | 1251 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); |
1256 if (state_ == kDecoding) { | 1252 if (state_ == kDecoding) { |
1257 decoder_thread_task_runner_->PostTask( | 1253 decoder_thread_task_runner_->PostTask( |
1258 FROM_HERE, | 1254 FROM_HERE, |
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1638 | 1634 |
1639 void V4L2SliceVideoDecodeAccelerator::FlushTask() { | 1635 void V4L2SliceVideoDecodeAccelerator::FlushTask() { |
1640 DVLOGF(3); | 1636 DVLOGF(3); |
1641 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); | 1637 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); |
1642 | 1638 |
1643 if (!decoder_input_queue_.empty()) { | 1639 if (!decoder_input_queue_.empty()) { |
1644 // We are not done with pending inputs, so queue an empty buffer, | 1640 // We are not done with pending inputs, so queue an empty buffer, |
1645 // which - when reached - will trigger flush sequence. | 1641 // which - when reached - will trigger flush sequence. |
1646 decoder_input_queue_.push( | 1642 decoder_input_queue_.push( |
1647 linked_ptr<BitstreamBufferRef>(new BitstreamBufferRef( | 1643 linked_ptr<BitstreamBufferRef>(new BitstreamBufferRef( |
1648 io_client_, io_task_runner_, nullptr, 0, kFlushBufferId))); | 1644 io_client_, io_task_runner_, nullptr, kFlushBufferId))); |
1649 return; | 1645 return; |
1650 } | 1646 } |
1651 | 1647 |
1652 // No more inputs pending, so just finish flushing here. | 1648 // No more inputs pending, so just finish flushing here. |
1653 InitiateFlush(); | 1649 InitiateFlush(); |
1654 } | 1650 } |
1655 | 1651 |
1656 void V4L2SliceVideoDecodeAccelerator::InitiateFlush() { | 1652 void V4L2SliceVideoDecodeAccelerator::InitiateFlush() { |
1657 DVLOGF(3); | 1653 DVLOGF(3); |
1658 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); | 1654 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); |
(...skipping 949 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2608 V4L2SliceVideoDecodeAccelerator::GetSupportedProfiles() { | 2604 V4L2SliceVideoDecodeAccelerator::GetSupportedProfiles() { |
2609 scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder); | 2605 scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder); |
2610 if (!device) | 2606 if (!device) |
2611 return SupportedProfiles(); | 2607 return SupportedProfiles(); |
2612 | 2608 |
2613 return device->GetSupportedDecodeProfiles(arraysize(supported_input_fourccs_), | 2609 return device->GetSupportedDecodeProfiles(arraysize(supported_input_fourccs_), |
2614 supported_input_fourccs_); | 2610 supported_input_fourccs_); |
2615 } | 2611 } |
2616 | 2612 |
2617 } // namespace content | 2613 } // namespace content |
OLD | NEW |