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

Unified 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: Drop first frames. 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 side-by-side diff with in-line comments
Download patch
Index: content/renderer/media/video_track_recorder.cc
diff --git a/content/renderer/media/video_track_recorder.cc b/content/renderer/media/video_track_recorder.cc
index d65e238e8795e5d07b6ffcba163d6c135fb684c0..5e9b22e6466537e779b5a2b8a63b5886343a077e 100644
--- a/content/renderer/media/video_track_recorder.cc
+++ b/content/renderer/media/video_track_recorder.cc
@@ -71,13 +71,15 @@ media::VideoCodecProfile CodecIdToVEAProfile(
#if defined(OS_CHROMEOS)
return media::VIDEO_CODEC_PROFILE_UNKNOWN;
#endif // defined(OS_CHROMEOS)
- content::RenderThreadImpl* render_thread_impl =
+ content::RenderThreadImpl* const render_thread_impl =
content::RenderThreadImpl::current();
- if (!render_thread_impl)
+ if (!render_thread_impl) {
+ DVLOG(3) << "Couldn't access the render thread";
return media::VIDEO_CODEC_PROFILE_UNKNOWN;
+ }
- media::GpuVideoAcceleratorFactories* gpu_factories =
- content::RenderThreadImpl::current()->GetGpuFactories();
+ media::GpuVideoAcceleratorFactories* const gpu_factories =
+ render_thread_impl->GetGpuFactories();
if (!gpu_factories || !gpu_factories->IsGpuVideoAcceleratorEnabled()) {
DVLOG(3) << "Couldn't initialize GpuVideoAcceleratorFactories";
return media::VIDEO_CODEC_PROFILE_UNKNOWN;
@@ -250,7 +252,8 @@ class VEAEncoder final : public VideoTrackRecorder::Encoder,
VEAEncoder(
const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_callback,
int32_t bits_per_second,
- media::VideoCodecProfile codec);
+ media::VideoCodecProfile codec,
+ const gfx::Size& size);
// media::VideoEncodeAccelerator::Client implementation.
void RequireBitstreamBuffers(unsigned int input_count,
@@ -291,8 +294,8 @@ class VEAEncoder final : public VideoTrackRecorder::Encoder,
// Tracks error status.
bool error_notified_;
- // Tracks the first frame to encode.
- std::unique_ptr<VideoFrameAndTimestamp> first_frame_;
+ // Tracks the last frame that we delay the encode.
+ std::unique_ptr<VideoFrameAndTimestamp> last_frame_;
// Size used to initialize encoder.
gfx::Size input_size_;
@@ -392,7 +395,8 @@ class H264Encoder final : public VideoTrackRecorder::Encoder {
VEAEncoder::VEAEncoder(
const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_callback,
int32_t bits_per_second,
- media::VideoCodecProfile codec)
+ media::VideoCodecProfile codec,
+ const gfx::Size& size)
: Encoder(on_encoded_video_callback,
bits_per_second,
RenderThreadImpl::current()->GetGpuFactories()->GetTaskRunner()),
@@ -400,6 +404,10 @@ VEAEncoder::VEAEncoder(
codec_(codec),
error_notified_(false) {
DCHECK(gpu_factories_);
+
mcasas 2016/07/08 22:59:27 DCHECK_GE(size.width(), kVEAEncoderMinResolutionWi
emircan 2016/07/12 01:00:35 Done.
+ encoding_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&VEAEncoder::ConfigureEncoderOnEncodingTaskRunner,
+ this, size));
}
VEAEncoder::~VEAEncoder() {
@@ -485,12 +493,8 @@ void VEAEncoder::EncodeOnEncodingTaskRunner(
video_encoder_.reset();
}
- if (!video_encoder_) {
+ if (!video_encoder_)
ConfigureEncoderOnEncodingTaskRunner(frame->visible_rect().size());
- first_frame_.reset(
- new std::pair<scoped_refptr<VideoFrame>, base::TimeTicks>(
- frame, capture_timestamp));
- }
if (error_notified_) {
DVLOG(3) << "An error occurred in VEA encoder";
@@ -500,14 +504,17 @@ void VEAEncoder::EncodeOnEncodingTaskRunner(
// Drop frames if there is no output buffers available.
if (output_buffers_.empty()) {
// TODO(emircan): Investigate if resetting encoder would help.
- DVLOG(3) << "Dropped frame.";
+ DVLOG(3) << "Might drop frame.";
+ last_frame_.reset(
+ new std::pair<scoped_refptr<VideoFrame>, base::TimeTicks>(
+ frame, capture_timestamp));
return;
}
// If first frame hasn't been encoded, do it first.
- if (first_frame_) {
- std::unique_ptr<VideoFrameAndTimestamp> first_frame(first_frame_.release());
- EncodeOnEncodingTaskRunner(first_frame->first, first_frame->second);
+ if (last_frame_) {
+ std::unique_ptr<VideoFrameAndTimestamp> last_frame(last_frame_.release());
+ EncodeOnEncodingTaskRunner(last_frame->first, last_frame->second);
}
// Lower resolutions may fall back to SW encoder in some platforms, i.e. Mac.
@@ -936,37 +943,23 @@ VideoTrackRecorder::VideoTrackRecorder(
const blink::WebMediaStreamTrack& track,
const OnEncodedVideoCB& on_encoded_video_callback,
int32_t bits_per_second)
- : track_(track) {
+ : track_(track),
+ codec_(codec),
+ on_encoded_video_callback_(on_encoded_video_callback),
+ bits_per_second_(bits_per_second),
+ paused_before_init_(false),
+ weak_ptr_factory_(this) {
DCHECK(main_render_thread_checker_.CalledOnValidThread());
DCHECK(!track_.isNull());
DCHECK(track_.getTrackData());
- const auto& vea_supported_profile = CodecIdToVEAProfile(codec);
- // TODO(emircan): Prioritize software based encoders in lower resolutions.
- if (vea_supported_profile != media::VIDEO_CODEC_PROFILE_UNKNOWN) {
- encoder_ = new VEAEncoder(on_encoded_video_callback, bits_per_second,
- vea_supported_profile);
- } else {
- switch (codec) {
-#if BUILDFLAG(RTC_USE_H264)
- case CodecId::H264:
- encoder_ = new H264Encoder(on_encoded_video_callback, bits_per_second);
- break;
-#endif
- case CodecId::VP8:
- case CodecId::VP9:
- encoder_ = new VpxEncoder(codec == CodecId::VP9,
- on_encoded_video_callback, bits_per_second);
- break;
- default:
- NOTREACHED() << "Unsupported codec";
- }
- }
-
- // StartFrameEncode() will be called on Render IO thread.
+ // InitializeEncoder() will be called on Render Main thread.
+ // It is safe to use Unretained, because the class gets disconnected from
+ // track in dtor.
MediaStreamVideoSink::ConnectToTrack(
track_,
- base::Bind(&VideoTrackRecorder::Encoder::StartFrameEncode, encoder_),
+ media::BindToCurrentLoop(base::Bind(
+ &VideoTrackRecorder::InitializeEncoder, base::Unretained(this))),
false);
}
@@ -978,20 +971,73 @@ VideoTrackRecorder::~VideoTrackRecorder() {
void VideoTrackRecorder::Pause() {
DCHECK(main_render_thread_checker_.CalledOnValidThread());
- DCHECK(encoder_);
- encoder_->SetPaused(true);
+ if (encoder_)
+ encoder_->SetPaused(true);
+ else
+ paused_before_init_ = true;
}
void VideoTrackRecorder::Resume() {
DCHECK(main_render_thread_checker_.CalledOnValidThread());
- DCHECK(encoder_);
- encoder_->SetPaused(false);
+ if (encoder_)
+ encoder_->SetPaused(false);
+ else
+ paused_before_init_ = false;
}
void VideoTrackRecorder::OnVideoFrameForTesting(
const scoped_refptr<media::VideoFrame>& frame,
base::TimeTicks timestamp) {
+ DVLOG(3) << __FUNCTION__;
+
+ if (!encoder_)
+ InitializeEncoder(frame, timestamp);
+
encoder_->StartFrameEncode(frame, timestamp);
}
+
+void VideoTrackRecorder::InitializeEncoder(
+ const scoped_refptr<media::VideoFrame>& frame,
+ base::TimeTicks capture_time) {
+ DVLOG(3) << __FUNCTION__ << frame->visible_rect().size().ToString();
+ DCHECK(main_render_thread_checker_.CalledOnValidThread());
+
+ MediaStreamVideoSink::DisconnectFromTrack();
+
+ const gfx::Size& input_size = frame->visible_rect().size();
+ const auto& vea_supported_profile = CodecIdToVEAProfile(codec_);
+ if (vea_supported_profile != media::VIDEO_CODEC_PROFILE_UNKNOWN &&
+ input_size.width() >= kVEAEncoderMinResolutionWidth &&
+ input_size.height() >= kVEAEncoderMinResolutionHeight) {
+ encoder_ = new VEAEncoder(on_encoded_video_callback_, bits_per_second_,
+ vea_supported_profile, input_size);
+ } else {
+ switch (codec_) {
+#if BUILDFLAG(RTC_USE_H264)
+ case CodecId::H264:
+ encoder_ =
+ new H264Encoder(on_encoded_video_callback_, bits_per_second_);
+ break;
+#endif
+ case CodecId::VP8:
+ case CodecId::VP9:
+ encoder_ = new VpxEncoder(codec_ == CodecId::VP9,
+ on_encoded_video_callback_, bits_per_second_);
+ break;
+ default:
+ NOTREACHED() << "Unsupported codec";
+ }
+ }
+
+ if (paused_before_init_)
+ encoder_->SetPaused(paused_before_init_);
+
+ // StartFrameEncode() will be called on Render IO thread.
+ MediaStreamVideoSink::ConnectToTrack(
+ track_,
+ base::Bind(&VideoTrackRecorder::Encoder::StartFrameEncode, encoder_),
+ false);
+}
+
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698