OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <dlfcn.h> | 5 #include <dlfcn.h> |
6 #include <errno.h> | 6 #include <errno.h> |
7 #include <fcntl.h> | 7 #include <fcntl.h> |
8 #include <linux/videodev2.h> | 8 #include <linux/videodev2.h> |
9 #include <poll.h> | 9 #include <poll.h> |
10 #include <sys/eventfd.h> | 10 #include <sys/eventfd.h> |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
188 | 188 |
189 ExynosVideoDecodeAccelerator::GscInputRecord::~GscInputRecord() { | 189 ExynosVideoDecodeAccelerator::GscInputRecord::~GscInputRecord() { |
190 } | 190 } |
191 | 191 |
192 ExynosVideoDecodeAccelerator::GscOutputRecord::GscOutputRecord() | 192 ExynosVideoDecodeAccelerator::GscOutputRecord::GscOutputRecord() |
193 : at_device(false), | 193 : at_device(false), |
194 at_client(false), | 194 at_client(false), |
195 fd(-1), | 195 fd(-1), |
196 egl_image(EGL_NO_IMAGE_KHR), | 196 egl_image(EGL_NO_IMAGE_KHR), |
197 egl_sync(EGL_NO_SYNC_KHR), | 197 egl_sync(EGL_NO_SYNC_KHR), |
198 picture_id(-1) { | 198 picture_id(-1), |
199 } | 199 cleared(false) {} |
200 | 200 |
201 ExynosVideoDecodeAccelerator::GscOutputRecord::~GscOutputRecord() { | 201 ExynosVideoDecodeAccelerator::GscOutputRecord::~GscOutputRecord() { |
202 } | 202 } |
203 | 203 |
204 ExynosVideoDecodeAccelerator::ExynosVideoDecodeAccelerator( | 204 ExynosVideoDecodeAccelerator::ExynosVideoDecodeAccelerator( |
205 EGLDisplay egl_display, | 205 EGLDisplay egl_display, |
206 EGLContext egl_context, | 206 EGLContext egl_context, |
207 Client* client, | 207 Client* client, |
208 const base::WeakPtr<Client>& io_client, | 208 const base::WeakPtr<Client>& io_client, |
209 const base::Callback<bool(void)>& make_context_current, | 209 const base::Callback<bool(void)>& make_context_current, |
(...skipping 19 matching lines...) Expand all Loading... | |
229 mfc_input_buffer_queued_count_(0), | 229 mfc_input_buffer_queued_count_(0), |
230 mfc_output_streamon_(false), | 230 mfc_output_streamon_(false), |
231 mfc_output_buffer_queued_count_(0), | 231 mfc_output_buffer_queued_count_(0), |
232 mfc_output_buffer_pixelformat_(0), | 232 mfc_output_buffer_pixelformat_(0), |
233 mfc_output_dpb_size_(0), | 233 mfc_output_dpb_size_(0), |
234 gsc_fd_(-1), | 234 gsc_fd_(-1), |
235 gsc_input_streamon_(false), | 235 gsc_input_streamon_(false), |
236 gsc_input_buffer_queued_count_(0), | 236 gsc_input_buffer_queued_count_(0), |
237 gsc_output_streamon_(false), | 237 gsc_output_streamon_(false), |
238 gsc_output_buffer_queued_count_(0), | 238 gsc_output_buffer_queued_count_(0), |
239 picture_clearing_count_(0), | |
239 device_poll_thread_("ExynosDevicePollThread"), | 240 device_poll_thread_("ExynosDevicePollThread"), |
240 device_poll_interrupt_fd_(-1), | 241 device_poll_interrupt_fd_(-1), |
241 make_context_current_(make_context_current), | 242 make_context_current_(make_context_current), |
242 egl_display_(egl_display), | 243 egl_display_(egl_display), |
243 egl_context_(egl_context), | 244 egl_context_(egl_context), |
244 video_profile_(media::VIDEO_CODEC_PROFILE_UNKNOWN) {} | 245 video_profile_(media::VIDEO_CODEC_PROFILE_UNKNOWN) {} |
245 | 246 |
246 ExynosVideoDecodeAccelerator::~ExynosVideoDecodeAccelerator() { | 247 ExynosVideoDecodeAccelerator::~ExynosVideoDecodeAccelerator() { |
247 DCHECK(!decoder_thread_.IsRunning()); | 248 DCHECK(!decoder_thread_.IsRunning()); |
248 DCHECK(!device_poll_thread_.IsRunning()); | 249 DCHECK(!device_poll_thread_.IsRunning()); |
(...skipping 796 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1045 } | 1046 } |
1046 | 1047 |
1047 DCHECK_EQ(pic_buffers->picture_buffers.size(), gsc_output_buffer_map_.size()); | 1048 DCHECK_EQ(pic_buffers->picture_buffers.size(), gsc_output_buffer_map_.size()); |
1048 for (size_t i = 0; i < gsc_output_buffer_map_.size(); ++i) { | 1049 for (size_t i = 0; i < gsc_output_buffer_map_.size(); ++i) { |
1049 // We should be blank right now. | 1050 // We should be blank right now. |
1050 GscOutputRecord& output_record = gsc_output_buffer_map_[i]; | 1051 GscOutputRecord& output_record = gsc_output_buffer_map_[i]; |
1051 DCHECK_EQ(output_record.fd, -1); | 1052 DCHECK_EQ(output_record.fd, -1); |
1052 DCHECK_EQ(output_record.egl_image, EGL_NO_IMAGE_KHR); | 1053 DCHECK_EQ(output_record.egl_image, EGL_NO_IMAGE_KHR); |
1053 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR); | 1054 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR); |
1054 DCHECK_EQ(output_record.picture_id, -1); | 1055 DCHECK_EQ(output_record.picture_id, -1); |
1056 DCHECK_EQ(output_record.cleared, false); | |
1055 PictureBufferArrayRef::PictureBufferRef& buffer = | 1057 PictureBufferArrayRef::PictureBufferRef& buffer = |
1056 pic_buffers->picture_buffers[i]; | 1058 pic_buffers->picture_buffers[i]; |
1057 output_record.fd = buffer.egl_image_fd; | 1059 output_record.fd = buffer.egl_image_fd; |
1058 output_record.egl_image = buffer.egl_image; | 1060 output_record.egl_image = buffer.egl_image; |
1059 output_record.picture_id = buffer.client_id; | 1061 output_record.picture_id = buffer.client_id; |
1060 | 1062 |
1061 // Take ownership of the EGLImage and fd. | 1063 // Take ownership of the EGLImage and fd. |
1062 buffer.egl_image = EGL_NO_IMAGE_KHR; | 1064 buffer.egl_image = EGL_NO_IMAGE_KHR; |
1063 buffer.egl_image_fd = -1; | 1065 buffer.egl_image_fd = -1; |
1064 // And add this buffer to the free list. | 1066 // And add this buffer to the free list. |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1408 } | 1410 } |
1409 GscOutputRecord& output_record = gsc_output_buffer_map_[dqbuf.index]; | 1411 GscOutputRecord& output_record = gsc_output_buffer_map_[dqbuf.index]; |
1410 DCHECK(output_record.at_device); | 1412 DCHECK(output_record.at_device); |
1411 DCHECK(!output_record.at_client); | 1413 DCHECK(!output_record.at_client); |
1412 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR); | 1414 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR); |
1413 output_record.at_device = false; | 1415 output_record.at_device = false; |
1414 output_record.at_client = true; | 1416 output_record.at_client = true; |
1415 gsc_output_buffer_queued_count_--; | 1417 gsc_output_buffer_queued_count_--; |
1416 DVLOG(3) << "DequeueGsc(): returning input_id=" << dqbuf.timestamp.tv_sec | 1418 DVLOG(3) << "DequeueGsc(): returning input_id=" << dqbuf.timestamp.tv_sec |
1417 << " as picture_id=" << output_record.picture_id; | 1419 << " as picture_id=" << output_record.picture_id; |
1418 io_message_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 1420 const media::Picture& picture = |
1419 &Client::PictureReady, io_client_, media::Picture( | 1421 media::Picture(output_record.picture_id, dqbuf.timestamp.tv_sec); |
1420 output_record.picture_id, dqbuf.timestamp.tv_sec))); | 1422 pending_picture_ready_.push(std::make_pair(output_record.cleared, picture)); |
1423 SendPictureReady(); | |
1424 output_record.cleared = true; | |
1421 decoder_frames_at_client_++; | 1425 decoder_frames_at_client_++; |
1422 } | 1426 } |
1423 | 1427 |
1424 NotifyFlushDoneIfNeeded(); | 1428 NotifyFlushDoneIfNeeded(); |
1425 } | 1429 } |
1426 | 1430 |
1427 bool ExynosVideoDecodeAccelerator::EnqueueMfcInputRecord() { | 1431 bool ExynosVideoDecodeAccelerator::EnqueueMfcInputRecord() { |
1428 DVLOG(3) << "EnqueueMfcInputRecord()"; | 1432 DVLOG(3) << "EnqueueMfcInputRecord()"; |
1429 DCHECK(!mfc_input_ready_queue_.empty()); | 1433 DCHECK(!mfc_input_ready_queue_.empty()); |
1430 | 1434 |
(...skipping 1012 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2443 DestroyGscInputBuffers(); | 2447 DestroyGscInputBuffers(); |
2444 DestroyGscOutputBuffers(); | 2448 DestroyGscOutputBuffers(); |
2445 DestroyMfcOutputBuffers(); | 2449 DestroyMfcOutputBuffers(); |
2446 | 2450 |
2447 // Finish resolution change on decoder thread. | 2451 // Finish resolution change on decoder thread. |
2448 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | 2452 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
2449 &ExynosVideoDecodeAccelerator::FinishResolutionChange, | 2453 &ExynosVideoDecodeAccelerator::FinishResolutionChange, |
2450 base::Unretained(this))); | 2454 base::Unretained(this))); |
2451 } | 2455 } |
2452 | 2456 |
2457 void ExynosVideoDecodeAccelerator::SendPictureReady() { | |
2458 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | |
2459 while (pending_picture_ready_.size() > 0) { | |
2460 bool cleared = pending_picture_ready_.front().first; | |
2461 const media::Picture& picture = pending_picture_ready_.front().second; | |
2462 if (!cleared) { | |
2463 // If the picture is not cleared, post it to the child thread because it | |
2464 // has to be cleared in the child thread. | |
2465 child_message_loop_proxy_->PostTaskAndReply( | |
2466 FROM_HERE, | |
2467 base::Bind(&Client::PictureReady, client_, picture), | |
2468 base::Bind(&ExynosVideoDecodeAccelerator::PictureCleared, | |
2469 weak_this_)); | |
2470 picture_clearing_count_++; | |
2471 pending_picture_ready_.pop(); | |
2472 } else if (picture_clearing_count_ == 0) { | |
2473 // This picture is cleared. Post it to IO thread to reduce latency. | |
2474 io_message_loop_proxy_->PostTask( | |
2475 FROM_HERE, base::Bind(&Client::PictureReady, io_client_, picture)); | |
2476 pending_picture_ready_.pop(); | |
2477 } else { | |
2478 // This picture is cleared. But some pictures are about to be cleared on | |
2479 // the child thread. To preserve the order, do not send this until those | |
2480 // pictures are cleared. | |
2481 break; | |
2482 } | |
2483 } | |
2484 } | |
2485 | |
2486 void ExynosVideoDecodeAccelerator::PictureCleared() { | |
2487 DVLOG(3) << "PictureCleared()"; | |
2488 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | |
2489 DCHECK(picture_clearing_count_ > 0); | |
piman
2013/09/30 21:49:13
nit: DCHECK_GT
wuchengli
2013/10/01 03:49:43
Done.
| |
2490 picture_clearing_count_--; | |
2491 SendPictureReady(); | |
2492 } | |
2493 | |
2453 } // namespace content | 2494 } // namespace content |
OLD | NEW |