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 <dlfcn.h> | 5 #include <dlfcn.h> |
6 #include <errno.h> | 6 #include <errno.h> |
7 #include <fcntl.h> | 7 #include <fcntl.h> |
8 #include <libdrm/drm_fourcc.h> | 8 #include <libdrm/drm_fourcc.h> |
9 #include <linux/videodev2.h> | 9 #include <linux/videodev2.h> |
10 #include <poll.h> | 10 #include <poll.h> |
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
350 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR); | 350 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR); |
351 DCHECK_EQ(output_record.picture_id, -1); | 351 DCHECK_EQ(output_record.picture_id, -1); |
352 DCHECK_EQ(output_record.cleared, false); | 352 DCHECK_EQ(output_record.cleared, false); |
353 | 353 |
354 attrs[7] = output_record.fds[0]; | 354 attrs[7] = output_record.fds[0]; |
355 attrs[9] = 0; | 355 attrs[9] = 0; |
356 attrs[11] = frame_buffer_size_.width(); | 356 attrs[11] = frame_buffer_size_.width(); |
357 attrs[13] = output_record.fds[1]; | 357 attrs[13] = output_record.fds[1]; |
358 attrs[15] = 0; | 358 attrs[15] = 0; |
359 attrs[17] = frame_buffer_size_.width(); | 359 attrs[17] = frame_buffer_size_.width(); |
360 | 360 EGLImageKHR egl_image = device_->CreateEGLImage( |
361 EGLImageKHR egl_image = eglCreateImageKHR( | 361 egl_display_, attrs, buffers[i].texture_id(), i); |
362 egl_display_, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attrs); | |
363 if (egl_image == EGL_NO_IMAGE_KHR) { | 362 if (egl_image == EGL_NO_IMAGE_KHR) { |
364 DLOG(ERROR) << "AssignPictureBuffers(): could not create EGLImageKHR"; | 363 DLOG(ERROR) << "AssignPictureBuffers(): could not create EGLImageKHR"; |
365 // Ownership of EGLImages allocated in previous iterations of this loop | 364 // Ownership of EGLImages allocated in previous iterations of this loop |
366 // has been transferred to output_buffer_map_. After we error-out here | 365 // has been transferred to output_buffer_map_. After we error-out here |
367 // the destructor will handle their cleanup. | 366 // the destructor will handle their cleanup. |
368 NOTIFY_ERROR(PLATFORM_FAILURE); | 367 NOTIFY_ERROR(PLATFORM_FAILURE); |
369 return; | 368 return; |
370 } | 369 } |
371 | 370 |
372 glBindTexture(GL_TEXTURE_EXTERNAL_OES, buffers[i].texture_id()); | |
373 glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, egl_image); | |
374 | |
375 output_record.egl_image = egl_image; | 371 output_record.egl_image = egl_image; |
376 output_record.picture_id = buffers[i].id(); | 372 output_record.picture_id = buffers[i].id(); |
377 free_output_buffers_.push(i); | 373 free_output_buffers_.push(i); |
378 DVLOG(3) << "AssignPictureBuffers(): buffer[" << i | 374 DVLOG(3) << "AssignPictureBuffers(): buffer[" << i |
379 << "]: picture_id=" << output_record.picture_id; | 375 << "]: picture_id=" << output_record.picture_id; |
380 } | 376 } |
381 | 377 |
382 pictures_assigned_.Signal(); | 378 pictures_assigned_.Signal(); |
383 } | 379 } |
384 | 380 |
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
705 | 701 |
706 bool V4L2VideoDecodeAccelerator::DecodeBufferInitial( | 702 bool V4L2VideoDecodeAccelerator::DecodeBufferInitial( |
707 const void* data, size_t size, size_t* endpos) { | 703 const void* data, size_t size, size_t* endpos) { |
708 DVLOG(3) << "DecodeBufferInitial(): data=" << data << ", size=" << size; | 704 DVLOG(3) << "DecodeBufferInitial(): data=" << data << ", size=" << size; |
709 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 705 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
710 DCHECK_NE(decoder_state_, kUninitialized); | 706 DCHECK_NE(decoder_state_, kUninitialized); |
711 DCHECK_NE(decoder_state_, kDecoding); | 707 DCHECK_NE(decoder_state_, kDecoding); |
712 DCHECK(!device_poll_thread_.IsRunning()); | 708 DCHECK(!device_poll_thread_.IsRunning()); |
713 // Initial decode. We haven't been able to get output stream format info yet. | 709 // Initial decode. We haven't been able to get output stream format info yet. |
714 // Get it, and start decoding. | 710 // Get it, and start decoding. |
711 bool no_free_input_buffers = false; | |
715 | 712 |
716 // Copy in and send to HW. | 713 // Copy in and send to HW. |
717 if (!AppendToInputFrame(data, size)) | 714 if (!AppendToInputFrame(data, size)) { |
715 if (free_input_buffers_.empty()) { | |
716 DVLOG(2) << "AppendToInputFrame(): no free input buffers"; | |
717 // No free input buffers, try and see if format info is set. | |
718 no_free_input_buffers = true; | |
719 goto chk_format_info; | |
sheu
2014/03/07 00:18:08
We seem to be allergic to "goto" statements in Chr
shivdasp
2014/03/07 17:31:40
Jumping to GetFormatInfo() will move us out of kIn
sheu
2014/03/07 20:31:50
Ah, i see how it is. So if I have this right: the
sheu
2014/03/07 21:36:29
Random thought for posciak@: if we make the decode
shivdasp
2014/03/10 05:58:13
Ohh that's why this never happens on Exynos.
Alrig
| |
720 } | |
718 return false; | 721 return false; |
722 } | |
719 | 723 |
720 // If we only have a partial frame, don't flush and process yet. | 724 // If we only have a partial frame, don't flush and process yet. |
721 if (decoder_partial_frame_pending_) | 725 if (decoder_partial_frame_pending_) |
722 return true; | 726 return true; |
723 | 727 |
724 if (!FlushInputFrame()) | 728 if (!FlushInputFrame()) |
725 return false; | 729 return false; |
726 | 730 |
727 // Recycle buffers. | 731 // Recycle buffers. |
728 Dequeue(); | 732 Dequeue(); |
729 | 733 |
734 chk_format_info: | |
730 // Check and see if we have format info yet. | 735 // Check and see if we have format info yet. |
731 struct v4l2_format format; | 736 struct v4l2_format format; |
732 bool again = false; | 737 bool again = false; |
733 if (!GetFormatInfo(&format, &again)) | 738 if (!GetFormatInfo(&format, &again)) |
734 return false; | 739 return false; |
735 | 740 |
736 if (again) { | 741 if (again) { |
737 // Need more stream to decode format, return true and schedule next buffer. | 742 // Need more stream to decode format, return true and schedule next buffer. |
743 if (no_free_input_buffers) { | |
744 // This buffer has not been consumed, so schedule another one. | |
745 *endpos = 0; | |
746 return true; | |
747 } | |
738 *endpos = size; | 748 *endpos = size; |
739 return true; | 749 return true; |
740 } | 750 } |
741 | 751 |
742 // Run this initialization only on first startup. | 752 // Run this initialization only on first startup. |
743 if (decoder_state_ == kInitialized) { | 753 if (decoder_state_ == kInitialized) { |
744 DVLOG(3) << "DecodeBufferInitial(): running initialization"; | 754 DVLOG(3) << "DecodeBufferInitial(): running initialization"; |
745 // Success! Setup our parameters. | 755 // Success! Setup our parameters. |
746 if (!CreateBuffersForFormat(format)) | 756 if (!CreateBuffersForFormat(format)) |
747 return false; | 757 return false; |
(...skipping 1003 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1751 | 1761 |
1752 DVLOG(3) << "CreateOutputBuffers(): ProvidePictureBuffers(): " | 1762 DVLOG(3) << "CreateOutputBuffers(): ProvidePictureBuffers(): " |
1753 << "buffer_count=" << output_buffer_map_.size() | 1763 << "buffer_count=" << output_buffer_map_.size() |
1754 << ", width=" << frame_buffer_size_.width() | 1764 << ", width=" << frame_buffer_size_.width() |
1755 << ", height=" << frame_buffer_size_.height(); | 1765 << ", height=" << frame_buffer_size_.height(); |
1756 child_message_loop_proxy_->PostTask(FROM_HERE, | 1766 child_message_loop_proxy_->PostTask(FROM_HERE, |
1757 base::Bind(&Client::ProvidePictureBuffers, | 1767 base::Bind(&Client::ProvidePictureBuffers, |
1758 client_, | 1768 client_, |
1759 output_buffer_map_.size(), | 1769 output_buffer_map_.size(), |
1760 frame_buffer_size_, | 1770 frame_buffer_size_, |
1761 GL_TEXTURE_EXTERNAL_OES)); | 1771 device_->GetTextureTarget())); |
1762 | 1772 |
1763 // Wait for the client to call AssignPictureBuffers() on the Child thread. | 1773 // Wait for the client to call AssignPictureBuffers() on the Child thread. |
1764 // We do this, because if we continue decoding without finishing buffer | 1774 // We do this, because if we continue decoding without finishing buffer |
1765 // allocation, we may end up Resetting before AssignPictureBuffers arrives, | 1775 // allocation, we may end up Resetting before AssignPictureBuffers arrives, |
1766 // resulting in unnecessary complications and subtle bugs. | 1776 // resulting in unnecessary complications and subtle bugs. |
1767 // For example, if the client calls Decode(Input1), Reset(), Decode(Input2) | 1777 // For example, if the client calls Decode(Input1), Reset(), Decode(Input2) |
1768 // in a sequence, and Decode(Input1) results in us getting here and exiting | 1778 // in a sequence, and Decode(Input1) results in us getting here and exiting |
1769 // without waiting, we might end up running Reset{,Done}Task() before | 1779 // without waiting, we might end up running Reset{,Done}Task() before |
1770 // AssignPictureBuffers is scheduled, thus cleaning up and pushing buffers | 1780 // AssignPictureBuffers is scheduled, thus cleaning up and pushing buffers |
1771 // to the free_output_buffers_ map twice. If we somehow marked buffers as | 1781 // to the free_output_buffers_ map twice. If we somehow marked buffers as |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1919 | 1929 |
1920 void V4L2VideoDecodeAccelerator::PictureCleared() { | 1930 void V4L2VideoDecodeAccelerator::PictureCleared() { |
1921 DVLOG(3) << "PictureCleared(). clearing count=" << picture_clearing_count_; | 1931 DVLOG(3) << "PictureCleared(). clearing count=" << picture_clearing_count_; |
1922 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 1932 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
1923 DCHECK_GT(picture_clearing_count_, 0); | 1933 DCHECK_GT(picture_clearing_count_, 0); |
1924 picture_clearing_count_--; | 1934 picture_clearing_count_--; |
1925 SendPictureReady(); | 1935 SendPictureReady(); |
1926 } | 1936 } |
1927 | 1937 |
1928 } // namespace content | 1938 } // namespace content |
OLD | NEW |