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

Side by Side Diff: remoting/codec/webrtc_video_encoder.cc

Issue 1846893002: Interface with webrtc through encoded frames (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 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
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "remoting/codec/webrtc_video_encoder.h"
6
7 #include <algorithm>
8 #include <vector>
9
10 #include "base/callback.h"
11 #include "base/logging.h"
12 #include "base/synchronization/lock.h"
13
14 namespace remoting {
15
16 WebRtcVideoEncoder::WebRtcVideoEncoder(webrtc::VideoCodecType codec)
17 : state_(kUninitialized), video_codec_type_(codec) {
18 VLOG(1) << "video codecType " << video_codec_type_;
19 }
20
21 WebRtcVideoEncoder::~WebRtcVideoEncoder() {}
22
23 int32_t WebRtcVideoEncoder::InitEncode(const webrtc::VideoCodec* codec_settings,
24 int32_t number_of_cores,
25 size_t max_payload_size) {
26 base::AutoLock Lock(lock_);
27 DCHECK(codec_settings);
28 VLOG(1) << "video codecType " << codec_settings->codecType << " width "
29 << codec_settings->width << " height " << codec_settings->height
30 << " startBitrate " << codec_settings->startBitrate << " maxBitrate "
31 << codec_settings->maxBitrate << " minBitrate "
32 << codec_settings->minBitrate << " targetBitrate "
33 << codec_settings->targetBitrate << " maxFramerate "
34 << codec_settings->maxFramerate;
35
36 int streamCount = codec_settings->numberOfSimulcastStreams;
37 // Validate request is to support a single stream.
38 if (streamCount > 1) {
39 for (int i = 0; i < streamCount; ++i) {
40 if (codec_settings->simulcastStream[i].maxBitrate != 0) {
41 LOG(ERROR) << "Simulcast unsupported";
42 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
43 }
44 }
45 }
46 target_bitrate_ = codec_settings->startBitrate;
47 state_ = kInitialized;
48 return WEBRTC_VIDEO_CODEC_OK;
49 }
50
51 int32_t WebRtcVideoEncoder::RegisterEncodeCompleteCallback(
52 webrtc::EncodedImageCallback* callback) {
53 base::AutoLock Lock(lock_);
54 DCHECK(callback);
55 encoded_callback_ = callback;
56 return WEBRTC_VIDEO_CODEC_OK;
57 }
58
59 int32_t WebRtcVideoEncoder::Release() {
60 base::AutoLock Lock(lock_);
61 encoded_callback_ = nullptr;
62 return WEBRTC_VIDEO_CODEC_OK;
63 }
64
65 int32_t WebRtcVideoEncoder::Encode(
66 const webrtc::VideoFrame& frame,
67 const webrtc::CodecSpecificInfo* codec_specific_info,
68 const std::vector<webrtc::FrameType>* frame_types) {
69 if (!key_frame_request_.is_null())
70 key_frame_request_.Run();
71 return WEBRTC_VIDEO_CODEC_OK;
72 }
73
74 int32_t WebRtcVideoEncoder::SetChannelParameters(uint32_t packet_loss,
75 int64_t rtt) {
76 VLOG(1) << "WebRtcVideoEncoder::SetChannelParameters "
77 << "loss:RTT " << packet_loss << ":" << rtt;
78 // Unused right now.
79 return WEBRTC_VIDEO_CODEC_OK;
80 }
81
82 int32_t WebRtcVideoEncoder::SetRates(uint32_t bitrate, uint32_t framerate) {
83 VLOG(1) << "WebRtcVideoEncoder::SetRates bitrate:framerate " << bitrate << ":"
84 << framerate;
85 target_bitrate_ = bitrate;
86 // framerate is not expected to be valid given we never report captured
87 // frames
88 return WEBRTC_VIDEO_CODEC_OK;
89 }
90
91 int WebRtcVideoEncoder::SendEncodedFrame(int64_t capture_timestamp_ms,
92 uint8_t* buffer,
93 size_t buffer_size,
94 int width,
95 int height,
96 bool key_frame) {
97 base::AutoLock Lock(lock_);
Sergey Ulanov 2016/03/31 22:06:18 lock with lower-case l
Irfan 2016/04/05 21:23:27 Done.
98 if (state_ == kUninitialized) {
99 LOG(ERROR) << "encoder interface uninitialized";
100 return -1;
101 }
102
103 webrtc::EncodedImage encodedImage(buffer, buffer_size, buffer_size);
Sergey Ulanov 2016/03/31 22:06:18 encoded_image
Irfan 2016/04/05 21:23:27 Done.
104 encodedImage._encodedWidth = width;
105 encodedImage._encodedHeight = height;
106 encodedImage._completeFrame = true;
107 encodedImage._frameType =
108 key_frame ? webrtc::kVideoFrameKey : webrtc::kVideoFrameDelta;
109 encodedImage.capture_time_ms_ = capture_timestamp_ms;
110 encodedImage._timeStamp = static_cast<uint32_t>(capture_timestamp_ms * 90);
111
112 webrtc::CodecSpecificInfo codecSpecificInfo;
Sergey Ulanov 2016/03/31 22:06:18 codec_specific_info
Irfan 2016/04/05 21:23:27 Done.
113 memset(&codecSpecificInfo, 0, sizeof(codecSpecificInfo));
114 codecSpecificInfo.codecType = webrtc::kVideoCodecVP8;
115
116 webrtc::RTPFragmentationHeader header;
117 memset(&header, 0, sizeof(header));
118
119 codecSpecificInfo.codecSpecific.VP8.simulcastIdx = 0;
120 codecSpecificInfo.codecSpecific.VP8.temporalIdx = webrtc::kNoTemporalIdx;
121 codecSpecificInfo.codecSpecific.VP8.tl0PicIdx = webrtc::kNoTl0PicIdx;
122 codecSpecificInfo.codecSpecific.VP8.pictureId = webrtc::kNoPictureId;
123
124 header.VerifyAndAllocateFragmentationHeader(1);
125 header.fragmentationOffset[0] = 0;
126 header.fragmentationLength[0] = buffer_size;
127 header.fragmentationPlType[0] = 0;
128 header.fragmentationTimeDiff[0] = 0;
129
130 int result =
131 encoded_callback_->Encoded(encodedImage, &codecSpecificInfo, &header);
132 if (result < 0) {
133 LOG(ERROR) << "Encoded callback failed: " << result;
134 } else if (result > 0) {
135 VLOG(1) << "Drop request from webrtc";
136 }
137 return result;
138 }
139
140 void WebRtcVideoEncoder::SetKeyFrameRequestCallback(
141 const base::Closure& key_frame_request) {
142 key_frame_request_ = key_frame_request;
143 }
144
145 WebRtcVideoEncoderFactory::WebRtcVideoEncoderFactory() {
146 // TODO(isheriff): These do not really affect anything internally
147 // in webrtc.
148 codecs_.push_back(cricket::WebRtcVideoEncoderFactory::VideoCodec(
149 webrtc::kVideoCodecVP8, "VP8", 1280, 720, 30));
150 }
151
152 WebRtcVideoEncoderFactory::~WebRtcVideoEncoderFactory() {}
Sergey Ulanov 2016/03/31 22:06:18 DCHECK(encoders_.empty())
Irfan 2016/04/05 21:23:27 Done.
153
154 webrtc::VideoEncoder* WebRtcVideoEncoderFactory::CreateVideoEncoder(
155 webrtc::VideoCodecType type) {
156 VLOG(2) << "WebRtcVideoEncoderFactory::CreateVideoEncoder " << type;
157 DCHECK(type == webrtc::kVideoCodecVP8);
158 WebRtcVideoEncoder* encoder = new WebRtcVideoEncoder(type);
159 encoder->SetKeyFrameRequestCallback(key_frame_request_);
160 encoders_.push_back(encoder);
161 return encoder;
162 }
163
164 const std::vector<cricket::WebRtcVideoEncoderFactory::VideoCodec>&
165 WebRtcVideoEncoderFactory::codecs() const {
166 VLOG(2) << "WebRtcVideoEncoderFactory::codecs";
167 return codecs_;
168 }
169
170 bool WebRtcVideoEncoderFactory::EncoderTypeHasInternalSource(
171 webrtc::VideoCodecType type) const {
172 VLOG(2) << "WebRtcVideoEncoderFactory::EncoderTypeHasInternalSource";
173 return true;
174 }
175
176 void WebRtcVideoEncoderFactory::DestroyVideoEncoder(
177 webrtc::VideoEncoder* encoder) {
178 VLOG(2) << "WebRtcVideoEncoderFactory::DestroyVideoEncoder";
179 if (encoder == nullptr) {
180 LOG(ERROR) << "Attempting to destroy null encoder";
181 return;
182 }
183 std::vector<WebRtcVideoEncoder*>::iterator position =
Sergey Ulanov 2016/03/31 22:06:18 auto position =
Irfan 2016/04/05 21:23:27 Done.
184 std::find(encoders_.begin(), encoders_.end(), encoder);
185 if (position != encoders_.end()) {
186 encoders_.erase(position);
187 delete encoder;
Sergey Ulanov 2016/03/31 22:06:18 maybe make change type of encoders_ to std::vector
Irfan 2016/04/05 21:23:27 Done.
188 } else {
189 LOG(ERROR) << "Asked to remove encoder not owned by factory";
Sergey Ulanov 2016/03/31 22:06:18 replace this with DCHECK().
Irfan 2016/04/05 21:23:27 Done.
190 }
191 }
192
193 int WebRtcVideoEncoderFactory::SendEncodedFrame(int64_t capture_timestamp_ms,
194 uint8_t* buffer,
195 size_t buffer_size,
196 int width,
197 int height,
198 bool key_frame) {
199 if (encoders_.size() != 1) {
200 LOG(ERROR) << "Unexpected number of encoders " << encoders_.size();
201 return -1;
202 }
203 return encoders_.front()->SendEncodedFrame(
204 capture_timestamp_ms, buffer, buffer_size, width, height, key_frame);
205 }
206
207 void WebRtcVideoEncoderFactory::SetKeyFrameRequestCallback(
208 const base::Closure& key_frame_request) {
209 key_frame_request_ = key_frame_request;
210 if (encoders_.size() == 1) {
211 encoders_.front()->SetKeyFrameRequestCallback(key_frame_request);
212 } else {
213 LOG(ERROR) << "Dropping key frame request callback with unexpected"
214 " number of encoders"
215 << encoders_.size();
216 }
217 }
218
219 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698