Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(586)

Side by Side Diff: content/renderer/media/rtc_video_encoder.cc

Issue 457733002: Support for H264 HW offload for webRTC. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: More nits from posciak. Updated unittest. Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "content/renderer/media/rtc_video_encoder.h" 5 #include "content/renderer/media/rtc_video_encoder.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/location.h" 8 #include "base/location.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/scoped_vector.h" 10 #include "base/memory/scoped_vector.h"
11 #include "base/message_loop/message_loop_proxy.h" 11 #include "base/message_loop/message_loop_proxy.h"
12 #include "base/metrics/histogram.h" 12 #include "base/metrics/histogram.h"
13 #include "base/rand_util.h" 13 #include "base/rand_util.h"
14 #include "base/synchronization/waitable_event.h" 14 #include "base/synchronization/waitable_event.h"
15 #include "media/base/bitstream_buffer.h" 15 #include "media/base/bitstream_buffer.h"
16 #include "media/base/video_frame.h" 16 #include "media/base/video_frame.h"
17 #include "media/base/video_util.h" 17 #include "media/base/video_util.h"
18 #include "media/filters/gpu_video_accelerator_factories.h" 18 #include "media/filters/gpu_video_accelerator_factories.h"
19 #include "media/filters/h264_parser.h"
19 #include "media/video/video_encode_accelerator.h" 20 #include "media/video/video_encode_accelerator.h"
20 #include "third_party/webrtc/system_wrappers/interface/tick_util.h" 21 #include "third_party/webrtc/system_wrappers/interface/tick_util.h"
21 22
22 #define NOTIFY_ERROR(x) \ 23 #define NOTIFY_ERROR(x) \
23 do { \ 24 do { \
24 DLOG(ERROR) << "calling NotifyError(): " << x; \ 25 DLOG(ERROR) << "calling NotifyError(): " << x; \
25 NotifyError(x); \ 26 NotifyError(x); \
26 } while (0) 27 } while (0)
27 28
28 namespace content { 29 namespace content {
29 30
31 namespace {
32
33 // Populates struct webrtc::RTPFragmentationHeader for H264 codec.
34 // Each entry specifies the offset and length (excluding start code) of a NALU.
35 // Returns true if successful.
36 bool GetRTPFragmentationHeaderH264(
37 webrtc::RTPFragmentationHeader& header, uint8_t* data, uint32_t length) {
38 media::H264Parser parser;
39 parser.SetStream(data, length);
40
41 std::vector<media::H264NALU> nalu_vector;
42 while (true) {
43 media::H264NALU nalu;
44 media::H264Parser::Result result;
45 result = parser.AdvanceToNextNALU(&nalu);
46 if (result == media::H264Parser::kOk) {
47 nalu_vector.push_back(nalu);
48 } else if (result == media::H264Parser::kEOStream) {
49 break;
50 } else {
51 DLOG(ERROR) << "Unexpected H264 parser result";
52 return false;
53 }
54 }
55
56 header.VerifyAndAllocateFragmentationHeader(nalu_vector.size());
57 for (size_t i = 0; i < nalu_vector.size(); ++i) {
58 header.fragmentationOffset[i] = nalu_vector[i].data - data;
59 header.fragmentationLength[i] = nalu_vector[i].size;
60 header.fragmentationPlType[i] = 0;
61 header.fragmentationTimeDiff[i] = 0;
62 }
63 return true;
64 }
65
66 } // namespace
67
30 // This private class of RTCVideoEncoder does the actual work of communicating 68 // This private class of RTCVideoEncoder does the actual work of communicating
31 // with a media::VideoEncodeAccelerator for handling video encoding. It can 69 // with a media::VideoEncodeAccelerator for handling video encoding. It can
32 // be created on any thread, but should subsequently be posted to (and Destroy() 70 // be created on any thread, but should subsequently be posted to (and Destroy()
33 // called on) a single thread. Callbacks to RTCVideoEncoder are posted to the 71 // called on) a single thread. Callbacks to RTCVideoEncoder are posted to the
34 // thread on which the instance was constructed. 72 // thread on which the instance was constructed.
35 // 73 //
36 // This class separates state related to the thread that RTCVideoEncoder 74 // This class separates state related to the thread that RTCVideoEncoder
37 // operates on (presently the libjingle worker thread) from the thread that 75 // operates on (presently the libjingle worker thread) from the thread that
38 // |gpu_factories_| provides for accelerator operations (presently the media 76 // |gpu_factories_| provides for accelerator operations (presently the media
39 // thread). The RTCVideoEncoder class can be deleted directly by WebRTC, while 77 // thread). The RTCVideoEncoder class can be deleted directly by WebRTC, while
(...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 int32 bitstream_buffer_id, 679 int32 bitstream_buffer_id,
642 uint16 picture_id) { 680 uint16 picture_id) {
643 DCHECK(thread_checker_.CalledOnValidThread()); 681 DCHECK(thread_checker_.CalledOnValidThread());
644 DVLOG(3) << "ReturnEncodedImage(): " 682 DVLOG(3) << "ReturnEncodedImage(): "
645 << "bitstream_buffer_id=" << bitstream_buffer_id 683 << "bitstream_buffer_id=" << bitstream_buffer_id
646 << ", picture_id=" << picture_id; 684 << ", picture_id=" << picture_id;
647 685
648 if (!encoded_image_callback_) 686 if (!encoded_image_callback_)
649 return; 687 return;
650 688
689 webrtc::RTPFragmentationHeader header;
690 memset(&header, 0, sizeof(header));
691 switch (video_codec_type_) {
692 case webrtc::kVideoCodecVP8:
693 case webrtc::kVideoCodecGeneric:
694 // Generate a header describing a single fragment.
695 // Note that webrtc treats the generic-type payload as an opaque buffer.
696 header.VerifyAndAllocateFragmentationHeader(1);
697 header.fragmentationOffset[0] = 0;
698 header.fragmentationLength[0] = image->_length;
699 header.fragmentationPlType[0] = 0;
700 header.fragmentationTimeDiff[0] = 0;
701 break;
702 case webrtc::kVideoCodecH264:
703 if (!GetRTPFragmentationHeaderH264(
704 header, image->_buffer, image->_length)) {
705 LOG(ERROR) << "Failed to get RTP fragmentation header for H264";
Pawel Osciak 2014/08/14 10:51:40 s/LOG/DLOG/
hshi1 2014/08/14 17:25:00 Done.
706 NotifyError(WEBRTC_VIDEO_CODEC_ERROR);
Pawel Osciak 2014/08/14 10:51:40 Please use NOTIFY_ERROR()
hshi1 2014/08/14 17:25:00 Actually I can't use the macro NOTIFY_ERROR() beca
707 return;
708 }
709 break;
710 default:
711 NOTREACHED() << "Invalid video codec type";
712 return;
713 }
714
651 webrtc::CodecSpecificInfo info; 715 webrtc::CodecSpecificInfo info;
652 memset(&info, 0, sizeof(info)); 716 memset(&info, 0, sizeof(info));
653 info.codecType = video_codec_type_; 717 info.codecType = video_codec_type_;
654 if (video_codec_type_ == webrtc::kVideoCodecVP8) { 718 if (video_codec_type_ == webrtc::kVideoCodecVP8) {
655 info.codecSpecific.VP8.pictureId = picture_id; 719 info.codecSpecific.VP8.pictureId = picture_id;
656 info.codecSpecific.VP8.tl0PicIdx = -1; 720 info.codecSpecific.VP8.tl0PicIdx = -1;
657 info.codecSpecific.VP8.keyIdx = -1; 721 info.codecSpecific.VP8.keyIdx = -1;
658 } 722 }
659 723
660 // Generate a header describing a single fragment.
661 webrtc::RTPFragmentationHeader header;
662 memset(&header, 0, sizeof(header));
663 header.VerifyAndAllocateFragmentationHeader(1);
664 header.fragmentationOffset[0] = 0;
665 header.fragmentationLength[0] = image->_length;
666 header.fragmentationPlType[0] = 0;
667 header.fragmentationTimeDiff[0] = 0;
668
669 int32_t retval = encoded_image_callback_->Encoded(*image, &info, &header); 724 int32_t retval = encoded_image_callback_->Encoded(*image, &info, &header);
670 if (retval < 0) { 725 if (retval < 0) {
671 DVLOG(2) << "ReturnEncodedImage(): encoded_image_callback_ returned " 726 DVLOG(2) << "ReturnEncodedImage(): encoded_image_callback_ returned "
672 << retval; 727 << retval;
673 } 728 }
674 729
675 // The call through webrtc::EncodedImageCallback is synchronous, so we can 730 // The call through webrtc::EncodedImageCallback is synchronous, so we can
676 // immediately recycle the output buffer back to the Impl. 731 // immediately recycle the output buffer back to the Impl.
677 gpu_factories_->GetTaskRunner()->PostTask( 732 gpu_factories_->GetTaskRunner()->PostTask(
678 FROM_HERE, 733 FROM_HERE,
(...skipping 16 matching lines...) Expand all
695 UMA_HISTOGRAM_BOOLEAN("Media.RTCVideoEncoderInitEncodeSuccess", 750 UMA_HISTOGRAM_BOOLEAN("Media.RTCVideoEncoderInitEncodeSuccess",
696 init_retval == WEBRTC_VIDEO_CODEC_OK); 751 init_retval == WEBRTC_VIDEO_CODEC_OK);
697 if (init_retval == WEBRTC_VIDEO_CODEC_OK) { 752 if (init_retval == WEBRTC_VIDEO_CODEC_OK) {
698 UMA_HISTOGRAM_ENUMERATION("Media.RTCVideoEncoderProfile", 753 UMA_HISTOGRAM_ENUMERATION("Media.RTCVideoEncoderProfile",
699 video_codec_profile_, 754 video_codec_profile_,
700 media::VIDEO_CODEC_PROFILE_MAX + 1); 755 media::VIDEO_CODEC_PROFILE_MAX + 1);
701 } 756 }
702 } 757 }
703 758
704 } // namespace content 759 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/rtc_video_decoder_unittest.cc ('k') | content/renderer/media/rtc_video_encoder_factory.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698