Index: content/renderer/media/rtc_encoding_video_capturer.cc |
diff --git a/content/renderer/media/rtc_encoding_video_capturer.cc b/content/renderer/media/rtc_encoding_video_capturer.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..91fa0cebf8e73fc67d813fbae8d90aaaad91146e |
--- /dev/null |
+++ b/content/renderer/media/rtc_encoding_video_capturer.cc |
@@ -0,0 +1,256 @@ |
+// Copyright (c) 2013 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "content/renderer/media/rtc_encoding_video_capturer.h" |
+ |
+#include "media/base/encoded_bitstream_buffer.h" |
+ |
+namespace content { |
+ |
+// Wrapper to for EncodedVideoBitstream that retains known state information |
+// for incoming bitstream. |
+class RtcEncodingVideoCapturer::Bitstream : |
+ public media::EncodedVideoBitstream::Client, |
Ami GONE FROM CHROMIUM
2013/06/08 00:18:01
This implies the name of the class is poor - it's
hshi1
2013/06/10 21:49:35
How about "BitstreamClient"? See updated CL.
|
+ public base::RefCountedThreadSafe<RtcEncodingVideoCapturer::Bitstream> { |
Ami GONE FROM CHROMIUM
2013/06/08 00:18:01
why refcount?
hshi1
2013/06/10 21:49:35
Refcount is not really needed, I just need it to b
|
+ public: |
+ Bitstream(media::VideoEncodingParameters params, |
+ media::EncodedVideoSource* encoded_video_source); |
Ami GONE FROM CHROMIUM
2013/06/08 00:18:01
doco lifetime
|
+ |
+ // Function to configure runtime encoding parameters. |
Ami GONE FROM CHROMIUM
2013/06/08 00:18:01
Isn't this really just the EVB interface?
hshi1
2013/06/10 21:49:35
... yes, what was I thinking. This is completely b
|
+ void Configure(const media::RuntimeVideoEncodingParameters& params); |
Ami GONE FROM CHROMIUM
2013/06/08 00:18:01
Try?
hshi1
2013/06/10 21:49:35
This is no longer needed.
|
+ |
+ // media::EncodedVideoBitstream::Client implementation. |
+ virtual void OnBitstreamStreaming( |
+ scoped_refptr<media::EncodedVideoBitstream> bitstream, |
+ const media::VideoEncodingParameters& params) OVERRIDE; |
+ virtual void OnBitstreamRemoved( |
+ scoped_refptr<media::EncodedVideoBitstream> bitstream) OVERRIDE; |
+ virtual void OnBitstreamReady( |
+ scoped_refptr<media::EncodedVideoBitstream> bitstream, |
+ scoped_refptr<const media::EncodedBitstreamBuffer> buffer) OVERRIDE; |
+ virtual void OnBitstreamConfigChanged( |
+ scoped_refptr<media::EncodedVideoBitstream> bitstream, |
+ const media::RuntimeVideoEncodingParameters& params) OVERRIDE; |
+ |
+ // Getters and setters for bitstream properties. |
+ bool finished() const; |
+ media::RuntimeVideoEncodingParameters runtime_params() const; |
+ void set_round_trip_time(int rtt_in_ms); |
Ami GONE FROM CHROMIUM
2013/06/08 00:18:01
use TimeDelta for the param
hshi1
2013/06/10 19:12:31
Done.
|
+ void set_callback(webrtc::EncodedImageCallback* callback); |
+ |
+ private: |
+ virtual ~Bitstream(); |
+ friend class base::RefCountedThreadSafe<RtcEncodingVideoCapturer::Bitstream>; |
+ |
+ // Helper to convert buffer to webrtc types in callback. |
+ bool Convert(scoped_refptr<const media::EncodedBitstreamBuffer> buffer, |
+ webrtc::EncodedImage& image, |
+ webrtc::CodecSpecificInfo& codecInfo, |
+ webrtc::RTPFragmentationHeader& fragHeader); |
+ |
+ media::VideoEncodingParameters params_; |
+ bool finished_; |
+ |
+ // Representing incoming stream. |
+ scoped_refptr<media::EncodedVideoBitstream> bitstream_; |
+ |
+ base::Time time_base_; |
+ base::TimeDelta round_trip_time_; |
+ media::EncodedVideoSource* encoded_video_source_; |
+ webrtc::EncodedImageCallback* callback_; |
+ DISALLOW_COPY_AND_ASSIGN(Bitstream); |
Ami GONE FROM CHROMIUM
2013/06/08 00:18:01
nit: extra \n before this
hshi1
2013/06/10 19:12:31
Done.
|
+}; |
+ |
+RtcEncodingVideoCapturer::Bitstream::Bitstream( |
+ media::VideoEncodingParameters params, |
+ media::EncodedVideoSource* encoded_video_source) |
+ : params_(params), |
+ finished_(false), |
+ encoded_video_source_(encoded_video_source) { |
Ami GONE FROM CHROMIUM
2013/06/08 00:18:01
initialize all other members to known-reasonable s
hshi1
2013/06/10 21:49:35
Done.
|
+ if (encoded_video_source_) |
Ami GONE FROM CHROMIUM
2013/06/08 00:18:01
how can this fail?
hshi1
2013/06/10 21:49:35
Done.
|
+ bitstream_ = encoded_video_source_->OpenBitstream(this, params); |
+} |
+ |
+RtcEncodingVideoCapturer::Bitstream::~Bitstream() { |
+ if (encoded_video_source_ && bitstream_) { |
Ami GONE FROM CHROMIUM
2013/06/08 00:18:01
how can this fail?
hshi1
2013/06/10 21:49:35
Well encoded_video_source_ should be valid, but bi
|
+ encoded_video_source_->CloseBitstream(bitstream_); |
+ bitstream_ = NULL; |
Ami GONE FROM CHROMIUM
2013/06/08 00:18:01
why bother?
hshi1
2013/06/10 21:49:35
Done.
|
+ } |
+} |
+ |
+void RtcEncodingVideoCapturer::Bitstream::Configure( |
+ const media::RuntimeVideoEncodingParameters& params) { |
+ if (bitstream_) |
Ami GONE FROM CHROMIUM
2013/06/08 00:18:01
how can this fail?
hshi1
2013/06/10 21:49:35
Can fail if OpenBitstream failed, or bitstream is
|
+ bitstream_->TryConfigure(params); |
+} |
+ |
+bool RtcEncodingVideoCapturer::Bitstream::finished() const { |
+ return finished_; |
+} |
+ |
+media::RuntimeVideoEncodingParameters |
+ RtcEncodingVideoCapturer::Bitstream::runtime_params() const { |
+ return params_.runtime_params; |
+} |
+ |
+void RtcEncodingVideoCapturer::Bitstream::set_round_trip_time(int rtt_in_ms) { |
+ round_trip_time_ = base::TimeDelta::FromMilliseconds(rtt_in_ms); |
+} |
+ |
+void RtcEncodingVideoCapturer::Bitstream::set_callback( |
+ webrtc::EncodedImageCallback* callback) { |
+ callback_ = callback; |
Ami GONE FROM CHROMIUM
2013/06/08 00:18:01
DCHECK(!callback_);
first?
hshi1
2013/06/10 21:49:35
Done.
|
+} |
+ |
+void RtcEncodingVideoCapturer::Bitstream::OnBitstreamStreaming( |
+ scoped_refptr<media::EncodedVideoBitstream> bitstream, |
+ const media::VideoEncodingParameters& params) { |
+ params_ = params; |
+} |
+ |
+void RtcEncodingVideoCapturer::Bitstream::OnBitstreamRemoved( |
+ scoped_refptr<media::EncodedVideoBitstream> bitstream) { |
+ finished_ = true; |
Ami GONE FROM CHROMIUM
2013/06/08 00:18:01
bitstream_ = NULL;
?
hshi1
2013/06/10 21:49:35
Done.
|
+} |
+ |
+void RtcEncodingVideoCapturer::Bitstream::OnBitstreamReady( |
+ scoped_refptr<media::EncodedVideoBitstream> bitstream, |
+ scoped_refptr<const media::EncodedBitstreamBuffer> buffer) { |
+ if (callback_) { |
+ // First buffer constitutes the origin of the time for this bitstream |
Ami GONE FROM CHROMIUM
2013/06/08 00:18:01
Isn't this true regardless of callback_ being set?
hshi1
2013/06/10 21:49:35
Yes but if callback_ is not set then we can't call
|
+ // context. |
+ if (time_base_.is_null()) { |
+ time_base_ = buffer->metadata().timestamp; |
+ } |
+ // Convert EncodedBitstreamBuffer to webrtc types. |
+ webrtc::EncodedImage image; |
+ webrtc::CodecSpecificInfo codecInfo; |
+ webrtc::RTPFragmentationHeader fragInfo; |
+ if (Convert(buffer, image, codecInfo, fragInfo)) { |
Ami GONE FROM CHROMIUM
2013/06/08 00:18:01
style: no non-const ref params. These are output
hshi1
2013/06/10 21:49:35
Done.
|
+ callback_->Encoded(image, &codecInfo, &fragInfo); |
+ } |
+ } |
+ // Return buffer so it can be reused for encoding upcoming bitstream. |
+ if (encoded_video_source_) |
Ami GONE FROM CHROMIUM
2013/06/08 00:18:01
can never be false.
hshi1
2013/06/10 21:49:35
Done.
|
+ encoded_video_source_->ReturnBitstreamBuffer(bitstream, buffer); |
+} |
Ami GONE FROM CHROMIUM
2013/06/08 00:18:01
This collection of comments reduces l.120-136 into
hshi1
2013/06/10 21:49:35
Done.
|
+ |
+void RtcEncodingVideoCapturer::Bitstream::OnBitstreamConfigChanged( |
+ scoped_refptr<media::EncodedVideoBitstream> bitstream, |
+ const media::RuntimeVideoEncodingParameters& params) { |
+ params_.runtime_params = params; |
+} |
+ |
+bool RtcEncodingVideoCapturer::Bitstream::Convert( |
Ami GONE FROM CHROMIUM
2013/06/08 00:18:01
return value is ignored at only callsite and no le
hshi1
2013/06/10 21:49:35
Made it void.
|
+ scoped_refptr<const media::EncodedBitstreamBuffer> buffer, |
+ webrtc::EncodedImage& image, |
+ webrtc::CodecSpecificInfo& codecInfo, |
+ webrtc::RTPFragmentationHeader& fragHeader) { |
+ DCHECK(buffer); |
+ if (!buffer) { |
+ return false; |
+ } |
+ |
+ // TODO: remove this const_cast. Unfortunately webrtc::EncodedImage defines |
Ami GONE FROM CHROMIUM
2013/06/08 00:18:01
TODO's should always be attributed like TODO(hshi)
hshi1
2013/06/10 21:49:35
Done.
|
+ // member |_buffer| of type uint8_t* even though webrtc never modifies the |
+ // buffer contents. |
+ image._buffer = const_cast<uint8_t*>(buffer->buffer()); |
+ image._length = buffer->size(); |
+ image._size = image._length; |
Ami GONE FROM CHROMIUM
2013/06/08 00:18:01
Do you know what the diff is supposed to be betwee
hshi1
2013/06/10 21:49:35
|_size| is supposed to indicate buffer capacity, a
|
+ |
+ const media::BufferEncodingMetadata& metadata = buffer->metadata(); |
+ image.capture_time_ms_ = |
+ (metadata.timestamp - time_base_).InMilliseconds(); // 1 KHz |
Ami GONE FROM CHROMIUM
2013/06/08 00:18:01
Comment doesn't make sense to me.
hshi1
2013/06/10 21:49:35
Done.
|
+ image._timeStamp = image.capture_time_ms_ * 90; // 90kHz |
Ami GONE FROM CHROMIUM
2013/06/08 00:18:01
Once we finalize this CL IWBN to have mflodman@ or
hshi1
2013/06/10 21:49:35
I agree that this is not accurate; please review t
|
+ if (metadata.key_frame) { |
+ image._frameType = webrtc::kKeyFrame; |
+ } else { |
+ image._frameType = webrtc::kDeltaFrame; |
+ } |
+ image._completeFrame = true; |
+ image._encodedWidth = params_.resolution.width(); |
+ image._encodedHeight = params_.resolution.height(); |
+ |
+ // TODO: generate codec specific info for VP8. |
+ codecInfo.codecType = webrtc::kVideoCodecGeneric; |
+ |
+ // Generate header containing a single fragmentation. |
+ fragHeader.VerifyAndAllocateFragmentationHeader(1); |
+ fragHeader.fragmentationOffset[0] = 0; |
+ fragHeader.fragmentationLength[0] = buffer->size(); |
+ fragHeader.fragmentationPlType[0] = 0; |
+ fragHeader.fragmentationTimeDiff[0] = 0; |
+ |
+ return true; |
+} |
+ |
+// RtcEncodingVideoCapturer |
+RtcEncodingVideoCapturer::RtcEncodingVideoCapturer( |
+ int stream_id, |
+ media::EncodedVideoSource* encoded_video_source) |
+ : stream_id_(stream_id), |
+ encoded_video_source_(encoded_video_source) { |
+} |
+ |
+RtcEncodingVideoCapturer::~RtcEncodingVideoCapturer() { |
+} |
+ |
+int32_t RtcEncodingVideoCapturer::InitEncode( |
+ const webrtc::VideoCodec* codecSettings, |
+ int32_t numberOfCores, |
+ uint32_t maxPayloadSize) { |
+ DCHECK(!bitstream_); |
+ if (!bitstream_) { |
Ami GONE FROM CHROMIUM
2013/06/08 00:18:01
How can this fail?
(and if you wanted to handle In
hshi1
2013/06/10 21:49:35
Done.
|
+ // Convert |codecSettings| to |params|. |
+ media::VideoEncodingParameters params; |
+ params.codec_name = codecSettings->plName; |
+ params.resolution = gfx::Size(codecSettings->width, codecSettings->height); |
+ params.frames_per_second = codecSettings->maxFramerate; |
+ params.runtime_params.average_bitrate = codecSettings->maxBitrate; |
Ami GONE FROM CHROMIUM
2013/06/08 00:18:01
s/max/start/ ?
hshi1
2013/06/10 19:12:31
Done.
|
+ params.runtime_params.max_bitrate = codecSettings->maxBitrate; |
+ bitstream_ = new Bitstream(params, encoded_video_source_); |
+ } |
+ return WEBRTC_VIDEO_CODEC_OK; |
+} |
+ |
+int32_t RtcEncodingVideoCapturer::Encode( |
+ const webrtc::I420VideoFrame& inputImage, |
+ const webrtc::CodecSpecificInfo* codecSpecificInfo, |
+ const std::vector<webrtc::VideoFrameType>* frame_types) { |
+ // TODO: request specific frame type. |
Ami GONE FROM CHROMIUM
2013/06/08 00:18:01
TODO(hshi)
hshi1
2013/06/10 19:12:31
Done.
|
+ return WEBRTC_VIDEO_CODEC_OK; |
+} |
+ |
+int32_t RtcEncodingVideoCapturer::RegisterEncodeCompleteCallback( |
+ webrtc::EncodedImageCallback* callback) { |
+ if (!bitstream_) |
+ return WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
+ bitstream_->set_callback(callback); |
Ami GONE FROM CHROMIUM
2013/06/08 00:18:01
Are you really not guaranteed that RECC is called
hshi1
2013/06/10 21:49:35
You're right.
|
+ return WEBRTC_VIDEO_CODEC_OK; |
+} |
+ |
+int32_t RtcEncodingVideoCapturer::Release() { |
+ DCHECK(bitstream_); |
+ bitstream_ = NULL; |
Ami GONE FROM CHROMIUM
2013/06/08 00:18:01
Are you relying on this moving the refcount to 0?
|
+ return WEBRTC_VIDEO_CODEC_OK; |
+} |
+ |
+int32_t RtcEncodingVideoCapturer::SetChannelParameters( |
+ uint32_t packetLoss, |
Ami GONE FROM CHROMIUM
2013/06/08 00:18:01
/* packetLoss */ here & in the header
hshi1
2013/06/10 19:12:31
Done.
|
+ int rtt_in_ms) { |
+ if (!bitstream_) |
+ return WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
+ bitstream_->set_round_trip_time(rtt_in_ms); |
+ return WEBRTC_VIDEO_CODEC_OK; |
+} |
+ |
+int32_t RtcEncodingVideoCapturer::SetRates(uint32_t newBitRate, |
+ uint32_t frameRate) { |
+ if (!bitstream_) |
+ return WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
+ // TODO: wire up runtime rate control. |
Ami GONE FROM CHROMIUM
2013/06/08 00:18:01
TODO(hshi)
hshi1
2013/06/10 19:12:31
Done.
|
+ return WEBRTC_VIDEO_CODEC_OK; |
+} |
+ |
+} // namespace content |