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

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

Issue 2000003002: Initialize based on frame sizes in VideoTrackRecorder (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@mrgpu2
Patch Set: Retake using bool. Created 4 years, 5 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
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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/video_track_recorder.h" 5 #include "content/renderer/media/video_track_recorder.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 media::H264PROFILE_MAX}}; 64 media::H264PROFILE_MAX}};
65 65
66 // Returns the corresponding codec profile from VEA supported codecs. If no 66 // Returns the corresponding codec profile from VEA supported codecs. If no
67 // profile is found, returns VIDEO_CODEC_PROFILE_UNKNOWN. 67 // profile is found, returns VIDEO_CODEC_PROFILE_UNKNOWN.
68 media::VideoCodecProfile CodecIdToVEAProfile( 68 media::VideoCodecProfile CodecIdToVEAProfile(
69 content::VideoTrackRecorder::CodecId codec) { 69 content::VideoTrackRecorder::CodecId codec) {
70 // See https://crbug.com/616659. 70 // See https://crbug.com/616659.
71 #if defined(OS_CHROMEOS) 71 #if defined(OS_CHROMEOS)
72 return media::VIDEO_CODEC_PROFILE_UNKNOWN; 72 return media::VIDEO_CODEC_PROFILE_UNKNOWN;
73 #endif // defined(OS_CHROMEOS) 73 #endif // defined(OS_CHROMEOS)
74 content::RenderThreadImpl* render_thread_impl = 74 content::RenderThreadImpl* const render_thread_impl =
75 content::RenderThreadImpl::current(); 75 content::RenderThreadImpl::current();
76 if (!render_thread_impl) 76 if (!render_thread_impl) {
77 DVLOG(3) << "Couldn't access the render thread";
77 return media::VIDEO_CODEC_PROFILE_UNKNOWN; 78 return media::VIDEO_CODEC_PROFILE_UNKNOWN;
79 }
78 80
79 media::GpuVideoAcceleratorFactories* gpu_factories = 81 media::GpuVideoAcceleratorFactories* const gpu_factories =
80 content::RenderThreadImpl::current()->GetGpuFactories(); 82 render_thread_impl->GetGpuFactories();
81 if (!gpu_factories || !gpu_factories->IsGpuVideoAcceleratorEnabled()) { 83 if (!gpu_factories || !gpu_factories->IsGpuVideoAcceleratorEnabled()) {
82 DVLOG(3) << "Couldn't initialize GpuVideoAcceleratorFactories"; 84 DVLOG(3) << "Couldn't initialize GpuVideoAcceleratorFactories";
83 return media::VIDEO_CODEC_PROFILE_UNKNOWN; 85 return media::VIDEO_CODEC_PROFILE_UNKNOWN;
84 } 86 }
85 87
86 const media::VideoEncodeAccelerator::SupportedProfiles& vea_profiles = 88 const media::VideoEncodeAccelerator::SupportedProfiles& vea_profiles =
87 gpu_factories->GetVideoEncodeAcceleratorSupportedProfiles(); 89 gpu_factories->GetVideoEncodeAcceleratorSupportedProfiles();
88 for (const auto& vea_profile : vea_profiles) { 90 for (const auto& vea_profile : vea_profiles) {
89 for (const auto& supported_profile : kSupportedVideoCodecIdToProfile) { 91 for (const auto& supported_profile : kSupportedVideoCodecIdToProfile) {
90 if (codec == supported_profile.codec_id && 92 if (codec == supported_profile.codec_id &&
(...skipping 838 matching lines...) Expand 10 before | Expand all | Expand 10 after
929 } 931 }
930 #endif //#if BUILDFLAG(RTC_USE_H264) 932 #endif //#if BUILDFLAG(RTC_USE_H264)
931 933
932 } // anonymous namespace 934 } // anonymous namespace
933 935
934 VideoTrackRecorder::VideoTrackRecorder( 936 VideoTrackRecorder::VideoTrackRecorder(
935 CodecId codec, 937 CodecId codec,
936 const blink::WebMediaStreamTrack& track, 938 const blink::WebMediaStreamTrack& track,
937 const OnEncodedVideoCB& on_encoded_video_callback, 939 const OnEncodedVideoCB& on_encoded_video_callback,
938 int32_t bits_per_second) 940 int32_t bits_per_second)
939 : track_(track) { 941 : main_task_runner_(base::MessageLoop::current()->task_runner()),
942 track_(track),
943 codec_(codec),
944 on_encoded_video_callback_(on_encoded_video_callback),
945 bits_per_second_(bits_per_second),
946 paused_before_init_(false),
947 is_first_frame_received_for_initialization_(false),
948 weak_ptr_factory_(this) {
940 DCHECK(main_render_thread_checker_.CalledOnValidThread()); 949 DCHECK(main_render_thread_checker_.CalledOnValidThread());
941 DCHECK(!track_.isNull()); 950 DCHECK(!track_.isNull());
942 DCHECK(track_.getTrackData()); 951 DCHECK(track_.getTrackData());
943 952
944 const auto& vea_supported_profile = CodecIdToVEAProfile(codec); 953 // ReceiveFirstFrameOnIOThread() will be called on Render IO thread.
945 // TODO(emircan): Prioritize software based encoders in lower resolutions. 954 // It is safe to use Unretained, because the class gets disconnected from
946 if (vea_supported_profile != media::VIDEO_CODEC_PROFILE_UNKNOWN) { 955 // track in dtor.
947 encoder_ = new VEAEncoder(on_encoded_video_callback, bits_per_second,
948 vea_supported_profile);
949 } else {
950 switch (codec) {
951 #if BUILDFLAG(RTC_USE_H264)
952 case CodecId::H264:
953 encoder_ = new H264Encoder(on_encoded_video_callback, bits_per_second);
954 break;
955 #endif
956 case CodecId::VP8:
957 case CodecId::VP9:
958 encoder_ = new VpxEncoder(codec == CodecId::VP9,
959 on_encoded_video_callback, bits_per_second);
960 break;
961 default:
962 NOTREACHED() << "Unsupported codec";
963 }
964 }
965
966 // StartFrameEncode() will be called on Render IO thread.
967 MediaStreamVideoSink::ConnectToTrack( 956 MediaStreamVideoSink::ConnectToTrack(
968 track_, 957 track_, base::Bind(&VideoTrackRecorder::ReceiveFirstFrameOnIOThread,
969 base::Bind(&VideoTrackRecorder::Encoder::StartFrameEncode, encoder_), 958 base::Unretained(this)),
970 false); 959 false);
971 } 960 }
972 961
973 VideoTrackRecorder::~VideoTrackRecorder() { 962 VideoTrackRecorder::~VideoTrackRecorder() {
974 DCHECK(main_render_thread_checker_.CalledOnValidThread()); 963 DCHECK(main_render_thread_checker_.CalledOnValidThread());
975 MediaStreamVideoSink::DisconnectFromTrack(); 964 MediaStreamVideoSink::DisconnectFromTrack();
976 track_.reset(); 965 track_.reset();
977 } 966 }
978 967
979 void VideoTrackRecorder::Pause() { 968 void VideoTrackRecorder::Pause() {
980 DCHECK(main_render_thread_checker_.CalledOnValidThread()); 969 DCHECK(main_render_thread_checker_.CalledOnValidThread());
981 DCHECK(encoder_); 970 if (encoder_)
982 encoder_->SetPaused(true); 971 encoder_->SetPaused(true);
972 else
973 paused_before_init_ = true;
983 } 974 }
984 975
985 void VideoTrackRecorder::Resume() { 976 void VideoTrackRecorder::Resume() {
986 DCHECK(main_render_thread_checker_.CalledOnValidThread()); 977 DCHECK(main_render_thread_checker_.CalledOnValidThread());
987 DCHECK(encoder_); 978 if (encoder_)
988 encoder_->SetPaused(false); 979 encoder_->SetPaused(false);
980 else
981 paused_before_init_ = false;
989 } 982 }
990 983
991 void VideoTrackRecorder::OnVideoFrameForTesting( 984 void VideoTrackRecorder::OnVideoFrameForTesting(
992 const scoped_refptr<media::VideoFrame>& frame, 985 const scoped_refptr<media::VideoFrame>& frame,
993 base::TimeTicks timestamp) { 986 base::TimeTicks timestamp) {
994 encoder_->StartFrameEncode(frame, timestamp); 987 DVLOG(3) << __FUNCTION__;
988 // We run on a single thread for tests. However, we still need to initialize
989 // these variables for checks.
990 if (!origin_task_runner_.get())
991 origin_task_runner_ = base::MessageLoop::current()->task_runner();
992
993 if (encoder_)
994 encoder_->StartFrameEncode(frame, timestamp);
995 else
996 InitializeEncoderOnMainThread(frame, timestamp);
997 }
998
999 void VideoTrackRecorder::ReceiveFirstFrameOnIOThread(
1000 const scoped_refptr<media::VideoFrame>& frame,
1001 base::TimeTicks capture_time) {
1002 DVLOG(3) << __FUNCTION__;
1003
1004 // We use the first frame for initialization and drop the frames coming after
1005 // until the new sink is connected to th track.
mcasas 2016/06/30 22:55:12 s/th/the/ Also you could say "...and drop eventua
1006 if (is_first_frame_received_for_initialization_)
1007 return;
1008
1009 is_first_frame_received_for_initialization_ = true;
1010 origin_task_runner_ = base::MessageLoop::current()->task_runner();
1011 main_task_runner_->PostTask(
1012 FROM_HERE,
1013 base::Bind(&VideoTrackRecorder::InitializeEncoderOnMainThread,
1014 weak_ptr_factory_.GetWeakPtr(), frame, capture_time));
1015 }
1016
1017 void VideoTrackRecorder::InitializeEncoderOnMainThread(
1018 const scoped_refptr<media::VideoFrame>& frame,
1019 base::TimeTicks capture_time) {
1020 DVLOG(3) << __FUNCTION__ << frame->visible_rect().size().ToString();
1021 DCHECK(main_render_thread_checker_.CalledOnValidThread());
1022
1023 MediaStreamVideoSink::DisconnectFromTrack();
1024
1025 const gfx::Size& input_size = frame->visible_rect().size();
1026 const auto& vea_supported_profile = CodecIdToVEAProfile(codec_);
1027 if (vea_supported_profile != media::VIDEO_CODEC_PROFILE_UNKNOWN &&
1028 input_size.width() >= kVEAEncoderMinResolutionWidth &&
1029 input_size.height() >= kVEAEncoderMinResolutionHeight) {
1030 encoder_ = new VEAEncoder(on_encoded_video_callback_, bits_per_second_,
1031 vea_supported_profile);
1032 } else {
1033 switch (codec_) {
1034 #if BUILDFLAG(RTC_USE_H264)
1035 case CodecId::H264:
1036 encoder_ =
1037 new H264Encoder(on_encoded_video_callback_, bits_per_second_);
1038 break;
1039 #endif
1040 case CodecId::VP8:
1041 case CodecId::VP9:
1042 encoder_ = new VpxEncoder(codec_ == CodecId::VP9,
1043 on_encoded_video_callback_, bits_per_second_);
1044 break;
1045 default:
1046 NOTREACHED() << "Unsupported codec";
1047 }
1048 }
1049
1050 if (paused_before_init_) {
1051 encoder_->SetPaused(paused_before_init_);
1052 } else {
1053 // Send the first frame for encode on |origin_task_runner_|.
1054 origin_task_runner_->PostTask(
1055 FROM_HERE, base::Bind(&VideoTrackRecorder::Encoder::StartFrameEncode,
1056 encoder_, frame, capture_time));
mcasas 2016/06/30 22:55:12 I'm not sure we should do this. Rationale: If this
1057 }
1058
1059 // StartFrameEncode() will be called on Render IO thread.
1060 MediaStreamVideoSink::ConnectToTrack(
1061 track_,
1062 base::Bind(&VideoTrackRecorder::Encoder::StartFrameEncode, encoder_),
1063 false);
995 } 1064 }
996 1065
997 } // namespace content 1066 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/video_track_recorder.h ('k') | content/renderer/media/video_track_recorder_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698