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