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 <sys/eventfd.h> | 9 #include <sys/eventfd.h> |
10 #include <sys/ioctl.h> | 10 #include <sys/ioctl.h> |
11 #include <sys/mman.h> | 11 #include <sys/mman.h> |
12 | 12 |
13 #include "base/bind.h" | 13 #include "base/bind.h" |
14 #include "base/bind_helpers.h" | 14 #include "base/bind_helpers.h" |
15 #include "base/callback.h" | 15 #include "base/callback.h" |
16 #include "base/callback_helpers.h" | 16 #include "base/callback_helpers.h" |
17 #include "base/command_line.h" | 17 #include "base/command_line.h" |
18 #include "base/numerics/safe_conversions.h" | 18 #include "base/numerics/safe_conversions.h" |
19 #include "base/strings/stringprintf.h" | 19 #include "base/strings/stringprintf.h" |
| 20 #include "content/common/gpu/media/shared_memory_region.h" |
20 #include "content/common/gpu/media/v4l2_slice_video_decode_accelerator.h" | 21 #include "content/common/gpu/media/v4l2_slice_video_decode_accelerator.h" |
21 #include "media/base/bind_to_current_loop.h" | 22 #include "media/base/bind_to_current_loop.h" |
22 #include "media/base/media_switches.h" | 23 #include "media/base/media_switches.h" |
23 #include "ui/gl/scoped_binders.h" | 24 #include "ui/gl/scoped_binders.h" |
24 | 25 |
25 #define LOGF(level) LOG(level) << __FUNCTION__ << "(): " | 26 #define LOGF(level) LOG(level) << __FUNCTION__ << "(): " |
26 #define DVLOGF(level) DVLOG(level) << __FUNCTION__ << "(): " | 27 #define DVLOGF(level) DVLOG(level) << __FUNCTION__ << "(): " |
27 | 28 |
28 #define NOTIFY_ERROR(x) \ | 29 #define NOTIFY_ERROR(x) \ |
29 do { \ | 30 do { \ |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 picture_id(-1), | 157 picture_id(-1), |
157 egl_image(EGL_NO_IMAGE_KHR), | 158 egl_image(EGL_NO_IMAGE_KHR), |
158 egl_sync(EGL_NO_SYNC_KHR), | 159 egl_sync(EGL_NO_SYNC_KHR), |
159 cleared(false) { | 160 cleared(false) { |
160 } | 161 } |
161 | 162 |
162 struct V4L2SliceVideoDecodeAccelerator::BitstreamBufferRef { | 163 struct V4L2SliceVideoDecodeAccelerator::BitstreamBufferRef { |
163 BitstreamBufferRef( | 164 BitstreamBufferRef( |
164 base::WeakPtr<VideoDecodeAccelerator::Client>& client, | 165 base::WeakPtr<VideoDecodeAccelerator::Client>& client, |
165 const scoped_refptr<base::SingleThreadTaskRunner>& client_task_runner, | 166 const scoped_refptr<base::SingleThreadTaskRunner>& client_task_runner, |
166 base::SharedMemory* shm, | 167 SharedMemoryRegion* shm, |
167 size_t size, | |
168 int32 input_id); | 168 int32 input_id); |
169 ~BitstreamBufferRef(); | 169 ~BitstreamBufferRef(); |
170 const base::WeakPtr<VideoDecodeAccelerator::Client> client; | 170 const base::WeakPtr<VideoDecodeAccelerator::Client> client; |
171 const scoped_refptr<base::SingleThreadTaskRunner> client_task_runner; | 171 const scoped_refptr<base::SingleThreadTaskRunner> client_task_runner; |
172 const scoped_ptr<base::SharedMemory> shm; | 172 const scoped_ptr<SharedMemoryRegion> shm; |
173 const size_t size; | |
174 off_t bytes_used; | 173 off_t bytes_used; |
175 const int32 input_id; | 174 const int32 input_id; |
176 }; | 175 }; |
177 | 176 |
178 V4L2SliceVideoDecodeAccelerator::BitstreamBufferRef::BitstreamBufferRef( | 177 V4L2SliceVideoDecodeAccelerator::BitstreamBufferRef::BitstreamBufferRef( |
179 base::WeakPtr<VideoDecodeAccelerator::Client>& client, | 178 base::WeakPtr<VideoDecodeAccelerator::Client>& client, |
180 const scoped_refptr<base::SingleThreadTaskRunner>& client_task_runner, | 179 const scoped_refptr<base::SingleThreadTaskRunner>& client_task_runner, |
181 base::SharedMemory* shm, | 180 SharedMemoryRegion* shm, |
182 size_t size, | |
183 int32 input_id) | 181 int32 input_id) |
184 : client(client), | 182 : client(client), |
185 client_task_runner(client_task_runner), | 183 client_task_runner(client_task_runner), |
186 shm(shm), | 184 shm(shm), |
187 size(size), | |
188 bytes_used(0), | 185 bytes_used(0), |
189 input_id(input_id) { | 186 input_id(input_id) {} |
190 } | |
191 | 187 |
192 V4L2SliceVideoDecodeAccelerator::BitstreamBufferRef::~BitstreamBufferRef() { | 188 V4L2SliceVideoDecodeAccelerator::BitstreamBufferRef::~BitstreamBufferRef() { |
193 if (input_id >= 0) { | 189 if (input_id >= 0) { |
194 DVLOGF(5) << "returning input_id: " << input_id; | 190 DVLOGF(5) << "returning input_id: " << input_id; |
195 client_task_runner->PostTask( | 191 client_task_runner->PostTask( |
196 FROM_HERE, | 192 FROM_HERE, |
197 base::Bind(&VideoDecodeAccelerator::Client::NotifyEndOfBitstreamBuffer, | 193 base::Bind(&VideoDecodeAccelerator::Client::NotifyEndOfBitstreamBuffer, |
198 client, input_id)); | 194 client, input_id)); |
199 } | 195 } |
200 } | 196 } |
(...skipping 980 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1181 } | 1177 } |
1182 | 1178 |
1183 void V4L2SliceVideoDecodeAccelerator::DecodeTask( | 1179 void V4L2SliceVideoDecodeAccelerator::DecodeTask( |
1184 const media::BitstreamBuffer& bitstream_buffer) { | 1180 const media::BitstreamBuffer& bitstream_buffer) { |
1185 DVLOGF(3) << "input_id=" << bitstream_buffer.id() | 1181 DVLOGF(3) << "input_id=" << bitstream_buffer.id() |
1186 << " size=" << bitstream_buffer.size(); | 1182 << " size=" << bitstream_buffer.size(); |
1187 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); | 1183 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); |
1188 | 1184 |
1189 scoped_ptr<BitstreamBufferRef> bitstream_record(new BitstreamBufferRef( | 1185 scoped_ptr<BitstreamBufferRef> bitstream_record(new BitstreamBufferRef( |
1190 io_client_, io_task_runner_, | 1186 io_client_, io_task_runner_, |
1191 new base::SharedMemory(bitstream_buffer.handle(), true), | 1187 new SharedMemoryRegion(bitstream_buffer, true), bitstream_buffer.id())); |
1192 bitstream_buffer.size(), bitstream_buffer.id())); | 1188 if (!bitstream_record->shm->Map()) { |
1193 if (!bitstream_record->shm->Map(bitstream_buffer.size())) { | |
1194 LOGF(ERROR) << "Could not map bitstream_buffer"; | 1189 LOGF(ERROR) << "Could not map bitstream_buffer"; |
1195 NOTIFY_ERROR(UNREADABLE_INPUT); | 1190 NOTIFY_ERROR(UNREADABLE_INPUT); |
1196 return; | 1191 return; |
1197 } | 1192 } |
1198 DVLOGF(3) << "mapped at=" << bitstream_record->shm->memory(); | 1193 DVLOGF(3) << "mapped at=" << bitstream_record->shm->memory(); |
1199 | 1194 |
1200 decoder_input_queue_.push( | 1195 decoder_input_queue_.push( |
1201 linked_ptr<BitstreamBufferRef>(bitstream_record.release())); | 1196 linked_ptr<BitstreamBufferRef>(bitstream_record.release())); |
1202 | 1197 |
1203 ScheduleDecodeBufferTaskIfNeeded(); | 1198 ScheduleDecodeBufferTaskIfNeeded(); |
(...skipping 11 matching lines...) Expand all Loading... |
1215 decoder_input_queue_.pop(); | 1210 decoder_input_queue_.pop(); |
1216 | 1211 |
1217 if (decoder_current_bitstream_buffer_->input_id == kFlushBufferId) { | 1212 if (decoder_current_bitstream_buffer_->input_id == kFlushBufferId) { |
1218 // This is a buffer we queued for ourselves to trigger flush at this time. | 1213 // This is a buffer we queued for ourselves to trigger flush at this time. |
1219 InitiateFlush(); | 1214 InitiateFlush(); |
1220 return false; | 1215 return false; |
1221 } | 1216 } |
1222 | 1217 |
1223 const uint8_t* const data = reinterpret_cast<const uint8_t*>( | 1218 const uint8_t* const data = reinterpret_cast<const uint8_t*>( |
1224 decoder_current_bitstream_buffer_->shm->memory()); | 1219 decoder_current_bitstream_buffer_->shm->memory()); |
1225 const size_t data_size = decoder_current_bitstream_buffer_->size; | 1220 const size_t data_size = decoder_current_bitstream_buffer_->shm->size(); |
1226 decoder_->SetStream(data, data_size); | 1221 decoder_->SetStream(data, data_size); |
1227 | 1222 |
1228 return true; | 1223 return true; |
1229 } | 1224 } |
1230 | 1225 |
1231 void V4L2SliceVideoDecodeAccelerator::ScheduleDecodeBufferTaskIfNeeded() { | 1226 void V4L2SliceVideoDecodeAccelerator::ScheduleDecodeBufferTaskIfNeeded() { |
1232 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); | 1227 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); |
1233 if (state_ == kDecoding) { | 1228 if (state_ == kDecoding) { |
1234 decoder_thread_task_runner_->PostTask( | 1229 decoder_thread_task_runner_->PostTask( |
1235 FROM_HERE, | 1230 FROM_HERE, |
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1571 | 1566 |
1572 void V4L2SliceVideoDecodeAccelerator::FlushTask() { | 1567 void V4L2SliceVideoDecodeAccelerator::FlushTask() { |
1573 DVLOGF(3); | 1568 DVLOGF(3); |
1574 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); | 1569 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); |
1575 | 1570 |
1576 if (!decoder_input_queue_.empty()) { | 1571 if (!decoder_input_queue_.empty()) { |
1577 // We are not done with pending inputs, so queue an empty buffer, | 1572 // We are not done with pending inputs, so queue an empty buffer, |
1578 // which - when reached - will trigger flush sequence. | 1573 // which - when reached - will trigger flush sequence. |
1579 decoder_input_queue_.push( | 1574 decoder_input_queue_.push( |
1580 linked_ptr<BitstreamBufferRef>(new BitstreamBufferRef( | 1575 linked_ptr<BitstreamBufferRef>(new BitstreamBufferRef( |
1581 io_client_, io_task_runner_, nullptr, 0, kFlushBufferId))); | 1576 io_client_, io_task_runner_, nullptr, kFlushBufferId))); |
1582 return; | 1577 return; |
1583 } | 1578 } |
1584 | 1579 |
1585 // No more inputs pending, so just finish flushing here. | 1580 // No more inputs pending, so just finish flushing here. |
1586 InitiateFlush(); | 1581 InitiateFlush(); |
1587 } | 1582 } |
1588 | 1583 |
1589 void V4L2SliceVideoDecodeAccelerator::InitiateFlush() { | 1584 void V4L2SliceVideoDecodeAccelerator::InitiateFlush() { |
1590 DVLOGF(3); | 1585 DVLOGF(3); |
1591 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); | 1586 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); |
(...skipping 951 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2543 if (!device) | 2538 if (!device) |
2544 return SupportedProfiles(); | 2539 return SupportedProfiles(); |
2545 | 2540 |
2546 const uint32_t supported_formats[] = { | 2541 const uint32_t supported_formats[] = { |
2547 V4L2_PIX_FMT_H264_SLICE, V4L2_PIX_FMT_VP8_FRAME}; | 2542 V4L2_PIX_FMT_H264_SLICE, V4L2_PIX_FMT_VP8_FRAME}; |
2548 return device->GetSupportedDecodeProfiles(arraysize(supported_formats), | 2543 return device->GetSupportedDecodeProfiles(arraysize(supported_formats), |
2549 supported_formats); | 2544 supported_formats); |
2550 } | 2545 } |
2551 | 2546 |
2552 } // namespace content | 2547 } // namespace content |
OLD | NEW |