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 986 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1190 } | 1187 } |
1191 | 1188 |
1192 void V4L2SliceVideoDecodeAccelerator::DecodeTask( | 1189 void V4L2SliceVideoDecodeAccelerator::DecodeTask( |
1193 const media::BitstreamBuffer& bitstream_buffer) { | 1190 const media::BitstreamBuffer& bitstream_buffer) { |
1194 DVLOGF(3) << "input_id=" << bitstream_buffer.id() | 1191 DVLOGF(3) << "input_id=" << bitstream_buffer.id() |
1195 << " size=" << bitstream_buffer.size(); | 1192 << " size=" << bitstream_buffer.size(); |
1196 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); | 1193 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); |
1197 | 1194 |
1198 scoped_ptr<BitstreamBufferRef> bitstream_record(new BitstreamBufferRef( | 1195 scoped_ptr<BitstreamBufferRef> bitstream_record(new BitstreamBufferRef( |
1199 io_client_, io_task_runner_, | 1196 io_client_, io_task_runner_, |
1200 new base::SharedMemory(bitstream_buffer.handle(), true), | 1197 new SharedMemoryRegion(bitstream_buffer, true), bitstream_buffer.id())); |
1201 bitstream_buffer.size(), bitstream_buffer.id())); | 1198 if (!bitstream_record->shm->Map()) { |
1202 if (!bitstream_record->shm->Map(bitstream_buffer.size())) { | |
1203 LOGF(ERROR) << "Could not map bitstream_buffer"; | 1199 LOGF(ERROR) << "Could not map bitstream_buffer"; |
1204 NOTIFY_ERROR(UNREADABLE_INPUT); | 1200 NOTIFY_ERROR(UNREADABLE_INPUT); |
1205 return; | 1201 return; |
1206 } | 1202 } |
1207 DVLOGF(3) << "mapped at=" << bitstream_record->shm->memory(); | 1203 DVLOGF(3) << "mapped at=" << bitstream_record->shm->memory(); |
1208 | 1204 |
1209 decoder_input_queue_.push( | 1205 decoder_input_queue_.push( |
1210 linked_ptr<BitstreamBufferRef>(bitstream_record.release())); | 1206 linked_ptr<BitstreamBufferRef>(bitstream_record.release())); |
1211 | 1207 |
1212 ScheduleDecodeBufferTaskIfNeeded(); | 1208 ScheduleDecodeBufferTaskIfNeeded(); |
(...skipping 11 matching lines...) Expand all Loading... |
1224 decoder_input_queue_.pop(); | 1220 decoder_input_queue_.pop(); |
1225 | 1221 |
1226 if (decoder_current_bitstream_buffer_->input_id == kFlushBufferId) { | 1222 if (decoder_current_bitstream_buffer_->input_id == kFlushBufferId) { |
1227 // This is a buffer we queued for ourselves to trigger flush at this time. | 1223 // This is a buffer we queued for ourselves to trigger flush at this time. |
1228 InitiateFlush(); | 1224 InitiateFlush(); |
1229 return false; | 1225 return false; |
1230 } | 1226 } |
1231 | 1227 |
1232 const uint8_t* const data = reinterpret_cast<const uint8_t*>( | 1228 const uint8_t* const data = reinterpret_cast<const uint8_t*>( |
1233 decoder_current_bitstream_buffer_->shm->memory()); | 1229 decoder_current_bitstream_buffer_->shm->memory()); |
1234 const size_t data_size = decoder_current_bitstream_buffer_->size; | 1230 const size_t data_size = decoder_current_bitstream_buffer_->shm->size(); |
1235 decoder_->SetStream(data, data_size); | 1231 decoder_->SetStream(data, data_size); |
1236 | 1232 |
1237 return true; | 1233 return true; |
1238 } | 1234 } |
1239 | 1235 |
1240 void V4L2SliceVideoDecodeAccelerator::ScheduleDecodeBufferTaskIfNeeded() { | 1236 void V4L2SliceVideoDecodeAccelerator::ScheduleDecodeBufferTaskIfNeeded() { |
1241 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); | 1237 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); |
1242 if (state_ == kDecoding) { | 1238 if (state_ == kDecoding) { |
1243 decoder_thread_task_runner_->PostTask( | 1239 decoder_thread_task_runner_->PostTask( |
1244 FROM_HERE, | 1240 FROM_HERE, |
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1580 | 1576 |
1581 void V4L2SliceVideoDecodeAccelerator::FlushTask() { | 1577 void V4L2SliceVideoDecodeAccelerator::FlushTask() { |
1582 DVLOGF(3); | 1578 DVLOGF(3); |
1583 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); | 1579 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); |
1584 | 1580 |
1585 if (!decoder_input_queue_.empty()) { | 1581 if (!decoder_input_queue_.empty()) { |
1586 // We are not done with pending inputs, so queue an empty buffer, | 1582 // We are not done with pending inputs, so queue an empty buffer, |
1587 // which - when reached - will trigger flush sequence. | 1583 // which - when reached - will trigger flush sequence. |
1588 decoder_input_queue_.push( | 1584 decoder_input_queue_.push( |
1589 linked_ptr<BitstreamBufferRef>(new BitstreamBufferRef( | 1585 linked_ptr<BitstreamBufferRef>(new BitstreamBufferRef( |
1590 io_client_, io_task_runner_, nullptr, 0, kFlushBufferId))); | 1586 io_client_, io_task_runner_, nullptr, kFlushBufferId))); |
1591 return; | 1587 return; |
1592 } | 1588 } |
1593 | 1589 |
1594 // No more inputs pending, so just finish flushing here. | 1590 // No more inputs pending, so just finish flushing here. |
1595 InitiateFlush(); | 1591 InitiateFlush(); |
1596 } | 1592 } |
1597 | 1593 |
1598 void V4L2SliceVideoDecodeAccelerator::InitiateFlush() { | 1594 void V4L2SliceVideoDecodeAccelerator::InitiateFlush() { |
1599 DVLOGF(3); | 1595 DVLOGF(3); |
1600 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); | 1596 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); |
(...skipping 952 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2553 V4L2SliceVideoDecodeAccelerator::GetSupportedProfiles() { | 2549 V4L2SliceVideoDecodeAccelerator::GetSupportedProfiles() { |
2554 scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder); | 2550 scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder); |
2555 if (!device) | 2551 if (!device) |
2556 return SupportedProfiles(); | 2552 return SupportedProfiles(); |
2557 | 2553 |
2558 return device->GetSupportedDecodeProfiles(arraysize(supported_input_fourccs_), | 2554 return device->GetSupportedDecodeProfiles(arraysize(supported_input_fourccs_), |
2559 supported_input_fourccs_); | 2555 supported_input_fourccs_); |
2560 } | 2556 } |
2561 | 2557 |
2562 } // namespace content | 2558 } // namespace content |
OLD | NEW |