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 <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> |
11 #include <sys/eventfd.h> | 11 #include <sys/eventfd.h> |
12 #include <sys/ioctl.h> | 12 #include <sys/ioctl.h> |
13 #include <sys/mman.h> | 13 #include <sys/mman.h> |
14 | 14 |
15 #include "base/bind.h" | 15 #include "base/bind.h" |
16 #include "base/debug/trace_event.h" | 16 #include "base/debug/trace_event.h" |
17 #include "base/memory/shared_memory.h" | 17 #include "base/memory/shared_memory.h" |
18 #include "base/message_loop/message_loop.h" | 18 #include "base/message_loop/message_loop.h" |
19 #include "base/message_loop/message_loop_proxy.h" | 19 #include "base/message_loop/message_loop_proxy.h" |
20 #include "base/posix/eintr_wrapper.h" | 20 #include "base/posix/eintr_wrapper.h" |
21 #include "content/common/gpu/media/exynos_video_decode_accelerator.h" | 21 #include "content/common/gpu/media/exynos_video_decode_accelerator.h" |
22 #include "content/common/gpu/media/h264_parser.h" | 22 #include "media/filters/h264_parser.h" |
23 #include "ui/gl/scoped_binders.h" | 23 #include "ui/gl/scoped_binders.h" |
24 | 24 |
25 namespace content { | 25 namespace content { |
26 | 26 |
27 #define NOTIFY_ERROR(x) \ | 27 #define NOTIFY_ERROR(x) \ |
28 do { \ | 28 do { \ |
29 SetDecoderState(kError); \ | 29 SetDecoderState(kError); \ |
30 DLOG(ERROR) << "calling NotifyError(): " << x; \ | 30 DLOG(ERROR) << "calling NotifyError(): " << x; \ |
31 NotifyError(x); \ | 31 NotifyError(x); \ |
32 } while (0) | 32 } while (0) |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 | 325 |
326 // Subscribe to the resolution change event. | 326 // Subscribe to the resolution change event. |
327 struct v4l2_event_subscription sub; | 327 struct v4l2_event_subscription sub; |
328 memset(&sub, 0, sizeof(sub)); | 328 memset(&sub, 0, sizeof(sub)); |
329 sub.type = V4L2_EVENT_RESOLUTION_CHANGE; | 329 sub.type = V4L2_EVENT_RESOLUTION_CHANGE; |
330 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_SUBSCRIBE_EVENT, &sub); | 330 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_SUBSCRIBE_EVENT, &sub); |
331 | 331 |
332 // Initialize format-specific bits. | 332 // Initialize format-specific bits. |
333 if (video_profile_ >= media::H264PROFILE_MIN && | 333 if (video_profile_ >= media::H264PROFILE_MIN && |
334 video_profile_ <= media::H264PROFILE_MAX) { | 334 video_profile_ <= media::H264PROFILE_MAX) { |
335 decoder_h264_parser_.reset(new content::H264Parser()); | 335 decoder_h264_parser_.reset(new media::H264Parser()); |
336 } | 336 } |
337 | 337 |
338 if (!decoder_thread_.Start()) { | 338 if (!decoder_thread_.Start()) { |
339 DLOG(ERROR) << "Initialize(): decoder thread failed to start"; | 339 DLOG(ERROR) << "Initialize(): decoder thread failed to start"; |
340 NOTIFY_ERROR(PLATFORM_FAILURE); | 340 NOTIFY_ERROR(PLATFORM_FAILURE); |
341 return false; | 341 return false; |
342 } | 342 } |
343 | 343 |
344 SetDecoderState(kInitialized); | 344 SetDecoderState(kInitialized); |
345 | 345 |
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
647 | 647 |
648 bool ExynosVideoDecodeAccelerator::AdvanceFrameFragment( | 648 bool ExynosVideoDecodeAccelerator::AdvanceFrameFragment( |
649 const uint8* data, | 649 const uint8* data, |
650 size_t size, | 650 size_t size, |
651 size_t* endpos) { | 651 size_t* endpos) { |
652 if (video_profile_ >= media::H264PROFILE_MIN && | 652 if (video_profile_ >= media::H264PROFILE_MIN && |
653 video_profile_ <= media::H264PROFILE_MAX) { | 653 video_profile_ <= media::H264PROFILE_MAX) { |
654 // For H264, we need to feed HW one frame at a time. This is going to take | 654 // For H264, we need to feed HW one frame at a time. This is going to take |
655 // some parsing of our input stream. | 655 // some parsing of our input stream. |
656 decoder_h264_parser_->SetStream(data, size); | 656 decoder_h264_parser_->SetStream(data, size); |
657 content::H264NALU nalu; | 657 media::H264NALU nalu; |
658 content::H264Parser::Result result; | 658 media::H264Parser::Result result; |
659 *endpos = 0; | 659 *endpos = 0; |
660 | 660 |
661 // Keep on peeking the next NALs while they don't indicate a frame | 661 // Keep on peeking the next NALs while they don't indicate a frame |
662 // boundary. | 662 // boundary. |
663 for (;;) { | 663 for (;;) { |
664 bool end_of_frame = false; | 664 bool end_of_frame = false; |
665 result = decoder_h264_parser_->AdvanceToNextNALU(&nalu); | 665 result = decoder_h264_parser_->AdvanceToNextNALU(&nalu); |
666 if (result == content::H264Parser::kInvalidStream || | 666 if (result == media::H264Parser::kInvalidStream || |
667 result == content::H264Parser::kUnsupportedStream) | 667 result == media::H264Parser::kUnsupportedStream) |
668 return false; | 668 return false; |
669 if (result == content::H264Parser::kEOStream) { | 669 if (result == media::H264Parser::kEOStream) { |
670 // We've reached the end of the buffer before finding a frame boundary. | 670 // We've reached the end of the buffer before finding a frame boundary. |
671 decoder_partial_frame_pending_ = true; | 671 decoder_partial_frame_pending_ = true; |
672 return true; | 672 return true; |
673 } | 673 } |
674 switch (nalu.nal_unit_type) { | 674 switch (nalu.nal_unit_type) { |
675 case content::H264NALU::kNonIDRSlice: | 675 case media::H264NALU::kNonIDRSlice: |
676 case content::H264NALU::kIDRSlice: | 676 case media::H264NALU::kIDRSlice: |
677 if (nalu.size < 1) | 677 if (nalu.size < 1) |
678 return false; | 678 return false; |
679 // For these two, if the "first_mb_in_slice" field is zero, start a | 679 // For these two, if the "first_mb_in_slice" field is zero, start a |
680 // new frame and return. This field is Exp-Golomb coded starting on | 680 // new frame and return. This field is Exp-Golomb coded starting on |
681 // the eighth data bit of the NAL; a zero value is encoded with a | 681 // the eighth data bit of the NAL; a zero value is encoded with a |
682 // leading '1' bit in the byte, which we can detect as the byte being | 682 // leading '1' bit in the byte, which we can detect as the byte being |
683 // (unsigned) greater than or equal to 0x80. | 683 // (unsigned) greater than or equal to 0x80. |
684 if (nalu.data[1] >= 0x80) { | 684 if (nalu.data[1] >= 0x80) { |
685 end_of_frame = true; | 685 end_of_frame = true; |
686 break; | 686 break; |
687 } | 687 } |
688 break; | 688 break; |
689 case content::H264NALU::kSPS: | 689 case media::H264NALU::kSPS: |
690 case content::H264NALU::kPPS: | 690 case media::H264NALU::kPPS: |
691 case content::H264NALU::kEOSeq: | 691 case media::H264NALU::kEOSeq: |
692 case content::H264NALU::kEOStream: | 692 case media::H264NALU::kEOStream: |
693 // These unconditionally signal a frame boundary. | 693 // These unconditionally signal a frame boundary. |
694 end_of_frame = true; | 694 end_of_frame = true; |
695 break; | 695 break; |
696 default: | 696 default: |
697 // For all others, keep going. | 697 // For all others, keep going. |
698 break; | 698 break; |
699 } | 699 } |
700 if (end_of_frame) { | 700 if (end_of_frame) { |
701 if (!decoder_partial_frame_pending_ && *endpos == 0) { | 701 if (!decoder_partial_frame_pending_ && *endpos == 0) { |
702 // The frame was previously restarted, and we haven't filled the | 702 // The frame was previously restarted, and we haven't filled the |
(...skipping 708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1411 | 1411 |
1412 // We might have received a resolution change event while we were waiting | 1412 // We might have received a resolution change event while we were waiting |
1413 // for the reset to finish. The codec will not post another event if the | 1413 // for the reset to finish. The codec will not post another event if the |
1414 // resolution after reset remains the same as the one to which were just | 1414 // resolution after reset remains the same as the one to which were just |
1415 // about to switch, so preserve the event across reset so we can address | 1415 // about to switch, so preserve the event across reset so we can address |
1416 // it after resuming. | 1416 // it after resuming. |
1417 | 1417 |
1418 // Reset format-specific bits. | 1418 // Reset format-specific bits. |
1419 if (video_profile_ >= media::H264PROFILE_MIN && | 1419 if (video_profile_ >= media::H264PROFILE_MIN && |
1420 video_profile_ <= media::H264PROFILE_MAX) { | 1420 video_profile_ <= media::H264PROFILE_MAX) { |
1421 decoder_h264_parser_.reset(new content::H264Parser()); | 1421 decoder_h264_parser_.reset(new media::H264Parser()); |
1422 } | 1422 } |
1423 | 1423 |
1424 // Jobs drained, we're finished resetting. | 1424 // Jobs drained, we're finished resetting. |
1425 DCHECK_EQ(decoder_state_, kResetting); | 1425 DCHECK_EQ(decoder_state_, kResetting); |
1426 decoder_state_ = kAfterReset; | 1426 decoder_state_ = kAfterReset; |
1427 decoder_partial_frame_pending_ = false; | 1427 decoder_partial_frame_pending_ = false; |
1428 decoder_delay_bitstream_buffer_id_ = -1; | 1428 decoder_delay_bitstream_buffer_id_ = -1; |
1429 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 1429 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
1430 &Client::NotifyResetDone, client_)); | 1430 &Client::NotifyResetDone, client_)); |
1431 | 1431 |
(...skipping 556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1988 | 1988 |
1989 void ExynosVideoDecodeAccelerator::PictureCleared() { | 1989 void ExynosVideoDecodeAccelerator::PictureCleared() { |
1990 DVLOG(3) << "PictureCleared(). clearing count=" << picture_clearing_count_; | 1990 DVLOG(3) << "PictureCleared(). clearing count=" << picture_clearing_count_; |
1991 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 1991 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
1992 DCHECK_GT(picture_clearing_count_, 0); | 1992 DCHECK_GT(picture_clearing_count_, 0); |
1993 picture_clearing_count_--; | 1993 picture_clearing_count_--; |
1994 SendPictureReady(); | 1994 SendPictureReady(); |
1995 } | 1995 } |
1996 | 1996 |
1997 } // namespace content | 1997 } // namespace content |
OLD | NEW |