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

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: 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"
11 #include "base/macros.h" 11 #include "base/macros.h"
12 #include "base/synchronization/waitable_event.h"
12 #include "base/sys_info.h" 13 #include "base/sys_info.h"
13 #include "base/task_runner_util.h" 14 #include "base/task_runner_util.h"
14 #include "base/threading/thread.h" 15 #include "base/threading/thread.h"
15 #include "base/threading/thread_task_runner_handle.h" 16 #include "base/threading/thread_task_runner_handle.h"
16 #include "base/time/time.h" 17 #include "base/time/time.h"
17 #include "base/trace_event/trace_event.h" 18 #include "base/trace_event/trace_event.h"
18 #include "content/renderer/media/renderer_gpu_video_accelerator_factories.h" 19 #include "content/renderer/media/renderer_gpu_video_accelerator_factories.h"
19 #include "content/renderer/render_thread_impl.h" 20 #include "content/renderer/render_thread_impl.h"
20 #include "media/base/bind_to_current_loop.h" 21 #include "media/base/bind_to_current_loop.h"
21 #include "media/base/video_frame.h" 22 #include "media/base/video_frame.h"
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 media::H264PROFILE_MAX}}; 65 media::H264PROFILE_MAX}};
65 66
66 // Returns the corresponding codec profile from VEA supported codecs. If no 67 // Returns the corresponding codec profile from VEA supported codecs. If no
67 // profile is found, returns VIDEO_CODEC_PROFILE_UNKNOWN. 68 // profile is found, returns VIDEO_CODEC_PROFILE_UNKNOWN.
68 media::VideoCodecProfile CodecIdToVEAProfile( 69 media::VideoCodecProfile CodecIdToVEAProfile(
69 content::VideoTrackRecorder::CodecId codec) { 70 content::VideoTrackRecorder::CodecId codec) {
70 // See https://crbug.com/616659. 71 // See https://crbug.com/616659.
71 #if defined(OS_CHROMEOS) 72 #if defined(OS_CHROMEOS)
72 return media::VIDEO_CODEC_PROFILE_UNKNOWN; 73 return media::VIDEO_CODEC_PROFILE_UNKNOWN;
73 #endif // defined(OS_CHROMEOS) 74 #endif // defined(OS_CHROMEOS)
74 content::RenderThreadImpl* render_thread_impl = 75 content::RenderThreadImpl* const render_thread_impl =
75 content::RenderThreadImpl::current(); 76 content::RenderThreadImpl::current();
76 if (!render_thread_impl) 77 if (!render_thread_impl) {
78 DVLOG(3) << "Couldn't access the render thread";
77 return media::VIDEO_CODEC_PROFILE_UNKNOWN; 79 return media::VIDEO_CODEC_PROFILE_UNKNOWN;
80 }
78 81
79 media::GpuVideoAcceleratorFactories* gpu_factories = 82 media::GpuVideoAcceleratorFactories* const gpu_factories =
80 content::RenderThreadImpl::current()->GetGpuFactories(); 83 render_thread_impl->GetGpuFactories();
81 if (!gpu_factories || !gpu_factories->IsGpuVideoAcceleratorEnabled()) { 84 if (!gpu_factories || !gpu_factories->IsGpuVideoAcceleratorEnabled()) {
82 DVLOG(3) << "Couldn't initialize GpuVideoAcceleratorFactories"; 85 DVLOG(3) << "Couldn't initialize GpuVideoAcceleratorFactories";
83 return media::VIDEO_CODEC_PROFILE_UNKNOWN; 86 return media::VIDEO_CODEC_PROFILE_UNKNOWN;
84 } 87 }
85 88
86 const media::VideoEncodeAccelerator::SupportedProfiles& vea_profiles = 89 const media::VideoEncodeAccelerator::SupportedProfiles& vea_profiles =
87 gpu_factories->GetVideoEncodeAcceleratorSupportedProfiles(); 90 gpu_factories->GetVideoEncodeAcceleratorSupportedProfiles();
88 for (const auto& vea_profile : vea_profiles) { 91 for (const auto& vea_profile : vea_profiles) {
89 for (const auto& supported_profile : kSupportedVideoCodecIdToProfile) { 92 for (const auto& supported_profile : kSupportedVideoCodecIdToProfile) {
90 if (codec == supported_profile.codec_id && 93 if (codec == supported_profile.codec_id &&
(...skipping 838 matching lines...) Expand 10 before | Expand all | Expand 10 after
929 } 932 }
930 #endif //#if BUILDFLAG(RTC_USE_H264) 933 #endif //#if BUILDFLAG(RTC_USE_H264)
931 934
932 } // anonymous namespace 935 } // anonymous namespace
933 936
934 VideoTrackRecorder::VideoTrackRecorder( 937 VideoTrackRecorder::VideoTrackRecorder(
935 CodecId codec, 938 CodecId codec,
936 const blink::WebMediaStreamTrack& track, 939 const blink::WebMediaStreamTrack& track,
937 const OnEncodedVideoCB& on_encoded_video_callback, 940 const OnEncodedVideoCB& on_encoded_video_callback,
938 int32_t bits_per_second) 941 int32_t bits_per_second)
939 : track_(track) { 942 : main_task_runner_(base::MessageLoop::current()->task_runner()),
943 track_(track),
944 codec_(codec),
945 on_encoded_video_callback_(on_encoded_video_callback),
946 bits_per_second_(bits_per_second),
947 paused_before_init_(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, nullptr);
997 }
998
999 void VideoTrackRecorder::ReceiveFirstFrameOnIOThread(
1000 const scoped_refptr<media::VideoFrame>& frame,
1001 base::TimeTicks capture_time) {
1002 DVLOG(3) << __FUNCTION__;
1003 if (!origin_task_runner_.get())
1004 origin_task_runner_ = base::MessageLoop::current()->task_runner();
1005 DCHECK(origin_task_runner_->BelongsToCurrentThread());
1006
1007 DCHECK(!encoder_);
1008 base::WaitableEvent initialization_waiter(
1009 base::WaitableEvent::ResetPolicy::MANUAL,
1010 base::WaitableEvent::InitialState::NOT_SIGNALED);
1011 main_task_runner_->PostTask(
1012 FROM_HERE, base::Bind(&VideoTrackRecorder::InitializeEncoderOnMainThread,
1013 weak_ptr_factory_.GetWeakPtr(), frame, capture_time,
1014 &initialization_waiter));
1015 initialization_waiter.Wait();
1016 DCHECK(encoder_);
mcasas 2016/06/30 20:42:27 Keep this guy, right?
1017 }
1018
1019 void VideoTrackRecorder::InitializeEncoderOnMainThread(
1020 const scoped_refptr<media::VideoFrame>& frame,
1021 base::TimeTicks capture_time,
1022 base::WaitableEvent* async_waiter) {
1023 DVLOG(3) << __FUNCTION__ << frame->visible_rect().size().ToString();
1024 DCHECK(main_render_thread_checker_.CalledOnValidThread());
1025
1026 MediaStreamVideoSink::DisconnectFromTrack();
1027
1028 const gfx::Size& input_size = frame->visible_rect().size();
1029 const auto& vea_supported_profile = CodecIdToVEAProfile(codec_);
1030 if (vea_supported_profile != media::VIDEO_CODEC_PROFILE_UNKNOWN &&
1031 input_size.width() >= kVEAEncoderMinResolutionWidth &&
1032 input_size.height() >= kVEAEncoderMinResolutionHeight) {
1033 encoder_ = new VEAEncoder(on_encoded_video_callback_, bits_per_second_,
1034 vea_supported_profile);
1035 } else {
1036 switch (codec_) {
1037 #if BUILDFLAG(RTC_USE_H264)
1038 case CodecId::H264:
1039 encoder_ =
1040 new H264Encoder(on_encoded_video_callback_, bits_per_second_);
1041 break;
1042 #endif
1043 case CodecId::VP8:
1044 case CodecId::VP9:
1045 encoder_ = new VpxEncoder(codec_ == CodecId::VP9,
1046 on_encoded_video_callback_, bits_per_second_);
1047 break;
1048 default:
1049 NOTREACHED() << "Unsupported codec";
1050 }
1051 }
1052
1053 if (paused_before_init_) {
1054 encoder_->SetPaused(paused_before_init_);
1055 } else {
1056 // Send the first frame for encode on |origin_task_runner_|.
1057 origin_task_runner_->PostTask(
1058 FROM_HERE, base::Bind(&VideoTrackRecorder::Encoder::StartFrameEncode,
1059 encoder_, frame, capture_time));
1060 }
1061
1062 // StartFrameEncode() will be called on Render IO thread.
1063 MediaStreamVideoSink::ConnectToTrack(
1064 track_,
1065 base::Bind(&VideoTrackRecorder::Encoder::StartFrameEncode, encoder_),
1066 false);
1067
1068 if (async_waiter)
1069 async_waiter->Signal();
995 } 1070 }
996 1071
997 } // namespace content 1072 } // 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