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

Side by Side Diff: webrtc/modules/video_coding/video_receiver.cc

Issue 1853813002: Add support for writing raw encoder output to .ivf files. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Changed out path for test files 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
1 /* 1 /*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/base/checks.h" 11 #include "webrtc/base/checks.h"
12 #include "webrtc/base/logging.h" 12 #include "webrtc/base/logging.h"
13 #include "webrtc/base/trace_event.h" 13 #include "webrtc/base/trace_event.h"
14 #include "webrtc/common_types.h" 14 #include "webrtc/common_types.h"
15 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" 15 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
16 #include "webrtc/modules/video_coding/include/video_codec_interface.h" 16 #include "webrtc/modules/video_coding/include/video_codec_interface.h"
17 #include "webrtc/modules/video_coding/encoded_frame.h" 17 #include "webrtc/modules/video_coding/encoded_frame.h"
18 #include "webrtc/modules/video_coding/jitter_buffer.h" 18 #include "webrtc/modules/video_coding/jitter_buffer.h"
19 #include "webrtc/modules/video_coding/packet.h" 19 #include "webrtc/modules/video_coding/packet.h"
20 #include "webrtc/modules/video_coding/video_coding_impl.h" 20 #include "webrtc/modules/video_coding/video_coding_impl.h"
21 #include "webrtc/system_wrappers/include/clock.h" 21 #include "webrtc/system_wrappers/include/clock.h"
22 22
23 // #define DEBUG_DECODER_BIT_STREAM
24
25 namespace webrtc { 23 namespace webrtc {
26 namespace vcm { 24 namespace vcm {
27 25
28 VideoReceiver::VideoReceiver(Clock* clock, 26 VideoReceiver::VideoReceiver(Clock* clock,
29 EventFactory* event_factory, 27 EventFactory* event_factory,
30 NackSender* nack_sender, 28 NackSender* nack_sender,
31 KeyFrameRequestSender* keyframe_request_sender) 29 KeyFrameRequestSender* keyframe_request_sender)
32 : clock_(clock), 30 : clock_(clock),
33 process_crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
34 _receiveCritSect(CriticalSectionWrapper::CreateCriticalSection()),
35 _timing(clock_), 31 _timing(clock_),
36 _receiver(&_timing, 32 _receiver(&_timing,
37 clock_, 33 clock_,
38 event_factory, 34 event_factory,
39 nack_sender, 35 nack_sender,
40 keyframe_request_sender), 36 keyframe_request_sender),
41 _decodedFrameCallback(&_timing, clock_), 37 _decodedFrameCallback(&_timing, clock_),
42 _frameTypeCallback(NULL), 38 _frameTypeCallback(nullptr),
43 _receiveStatsCallback(NULL), 39 _receiveStatsCallback(nullptr),
44 _decoderTimingCallback(NULL), 40 _decoderTimingCallback(nullptr),
45 _packetRequestCallback(NULL), 41 _packetRequestCallback(nullptr),
46 render_buffer_callback_(NULL), 42 render_buffer_callback_(nullptr),
47 _decoder(NULL), 43 _decoder(nullptr),
48 #ifdef DEBUG_DECODER_BIT_STREAM
49 _bitStreamBeforeDecoder(NULL),
50 #endif
51 _frameFromFile(), 44 _frameFromFile(),
52 _scheduleKeyRequest(false), 45 _scheduleKeyRequest(false),
53 drop_frames_until_keyframe_(false), 46 drop_frames_until_keyframe_(false),
54 max_nack_list_size_(0), 47 max_nack_list_size_(0),
55 _codecDataBase(nullptr, nullptr), 48 _codecDataBase(nullptr, nullptr),
56 pre_decode_image_callback_(NULL), 49 pre_decode_image_callback_(nullptr),
57 _receiveStatsTimer(1000, clock_), 50 _receiveStatsTimer(1000, clock_),
58 _retransmissionTimer(10, clock_), 51 _retransmissionTimer(10, clock_),
59 _keyRequestTimer(500, clock_) { 52 _keyRequestTimer(500, clock_),
60 assert(clock_); 53 ssrc_(0) {}
61 #ifdef DEBUG_DECODER_BIT_STREAM
62 _bitStreamBeforeDecoder = fopen("decoderBitStream.bit", "wb");
63 #endif
64 }
65 54
66 VideoReceiver::~VideoReceiver() { 55 VideoReceiver::~VideoReceiver() {}
67 delete _receiveCritSect;
68 #ifdef DEBUG_DECODER_BIT_STREAM
69 fclose(_bitStreamBeforeDecoder);
70 #endif
71 }
72 56
73 void VideoReceiver::Process() { 57 void VideoReceiver::Process() {
74 // Receive-side statistics 58 // Receive-side statistics
75 if (_receiveStatsTimer.TimeUntilProcess() == 0) { 59 if (_receiveStatsTimer.TimeUntilProcess() == 0) {
76 _receiveStatsTimer.Processed(); 60 _receiveStatsTimer.Processed();
77 CriticalSectionScoped cs(process_crit_sect_.get()); 61 rtc::CritScope cs(&process_lock_);
78 if (_receiveStatsCallback != NULL) { 62 if (_receiveStatsCallback != nullptr) {
79 uint32_t bitRate; 63 uint32_t bitRate;
80 uint32_t frameRate; 64 uint32_t frameRate;
81 _receiver.ReceiveStatistics(&bitRate, &frameRate); 65 _receiver.ReceiveStatistics(&bitRate, &frameRate);
82 _receiveStatsCallback->OnReceiveRatesUpdated(bitRate, frameRate); 66 _receiveStatsCallback->OnReceiveRatesUpdated(bitRate, frameRate);
83 } 67 }
84 68
85 if (_decoderTimingCallback != NULL) { 69 if (_decoderTimingCallback != nullptr) {
86 int decode_ms; 70 int decode_ms;
87 int max_decode_ms; 71 int max_decode_ms;
88 int current_delay_ms; 72 int current_delay_ms;
89 int target_delay_ms; 73 int target_delay_ms;
90 int jitter_buffer_ms; 74 int jitter_buffer_ms;
91 int min_playout_delay_ms; 75 int min_playout_delay_ms;
92 int render_delay_ms; 76 int render_delay_ms;
93 _timing.GetTimings(&decode_ms, &max_decode_ms, &current_delay_ms, 77 _timing.GetTimings(&decode_ms, &max_decode_ms, &current_delay_ms,
94 &target_delay_ms, &jitter_buffer_ms, 78 &target_delay_ms, &jitter_buffer_ms,
95 &min_playout_delay_ms, &render_delay_ms); 79 &min_playout_delay_ms, &render_delay_ms);
96 _decoderTimingCallback->OnDecoderTiming( 80 _decoderTimingCallback->OnDecoderTiming(
97 decode_ms, max_decode_ms, current_delay_ms, target_delay_ms, 81 decode_ms, max_decode_ms, current_delay_ms, target_delay_ms,
98 jitter_buffer_ms, min_playout_delay_ms, render_delay_ms); 82 jitter_buffer_ms, min_playout_delay_ms, render_delay_ms);
99 } 83 }
100 84
101 // Size of render buffer. 85 // Size of render buffer.
102 if (render_buffer_callback_) { 86 if (render_buffer_callback_) {
103 int buffer_size_ms = _receiver.RenderBufferSizeMs(); 87 int buffer_size_ms = _receiver.RenderBufferSizeMs();
104 render_buffer_callback_->RenderBufferSizeMs(buffer_size_ms); 88 render_buffer_callback_->RenderBufferSizeMs(buffer_size_ms);
105 } 89 }
106 } 90 }
107 91
108 // Key frame requests 92 // Key frame requests
109 if (_keyRequestTimer.TimeUntilProcess() == 0) { 93 if (_keyRequestTimer.TimeUntilProcess() == 0) {
110 _keyRequestTimer.Processed(); 94 _keyRequestTimer.Processed();
111 bool request_key_frame = false; 95 bool request_key_frame = false;
112 { 96 {
113 CriticalSectionScoped cs(process_crit_sect_.get()); 97 rtc::CritScope cs(&process_lock_);
114 request_key_frame = _scheduleKeyRequest && _frameTypeCallback != NULL; 98 request_key_frame = _scheduleKeyRequest && _frameTypeCallback != nullptr;
115 } 99 }
116 if (request_key_frame) 100 if (request_key_frame)
117 RequestKeyFrame(); 101 RequestKeyFrame();
118 } 102 }
119 103
120 if (_receiver.TimeUntilNextProcess() == 0) { 104 if (_receiver.TimeUntilNextProcess() == 0) {
121 _receiver.Process(); 105 _receiver.Process();
122 } 106 }
123 107
124 // Packet retransmission requests 108 // Packet retransmission requests
125 // TODO(holmer): Add API for changing Process interval and make sure it's 109 // TODO(holmer): Add API for changing Process interval and make sure it's
126 // disabled when NACK is off. 110 // disabled when NACK is off.
127 if (_retransmissionTimer.TimeUntilProcess() == 0) { 111 if (_retransmissionTimer.TimeUntilProcess() == 0) {
128 _retransmissionTimer.Processed(); 112 _retransmissionTimer.Processed();
129 bool callback_registered = false; 113 bool callback_registered = false;
130 uint16_t length; 114 uint16_t length;
131 { 115 {
132 CriticalSectionScoped cs(process_crit_sect_.get()); 116 rtc::CritScope cs(&process_lock_);
133 length = max_nack_list_size_; 117 length = max_nack_list_size_;
134 callback_registered = _packetRequestCallback != NULL; 118 callback_registered = _packetRequestCallback != nullptr;
135 } 119 }
136 if (callback_registered && length > 0) { 120 if (callback_registered && length > 0) {
137 // Collect sequence numbers from the default receiver. 121 // Collect sequence numbers from the default receiver.
138 bool request_key_frame = false; 122 bool request_key_frame = false;
139 std::vector<uint16_t> nackList = _receiver.NackList(&request_key_frame); 123 std::vector<uint16_t> nackList = _receiver.NackList(&request_key_frame);
140 int32_t ret = VCM_OK; 124 int32_t ret = VCM_OK;
141 if (request_key_frame) { 125 if (request_key_frame) {
142 ret = RequestKeyFrame(); 126 ret = RequestKeyFrame();
143 } 127 }
144 if (ret == VCM_OK && !nackList.empty()) { 128 if (ret == VCM_OK && !nackList.empty()) {
145 CriticalSectionScoped cs(process_crit_sect_.get()); 129 rtc::CritScope cs(&process_lock_);
146 if (_packetRequestCallback != NULL) { 130 if (_packetRequestCallback != nullptr) {
147 _packetRequestCallback->ResendPackets(&nackList[0], nackList.size()); 131 _packetRequestCallback->ResendPackets(&nackList[0], nackList.size());
148 } 132 }
149 } 133 }
150 } 134 }
151 } 135 }
152 } 136 }
153 137
154 int64_t VideoReceiver::TimeUntilNextProcess() { 138 int64_t VideoReceiver::TimeUntilNextProcess() {
155 int64_t timeUntilNextProcess = _receiveStatsTimer.TimeUntilProcess(); 139 int64_t timeUntilNextProcess = _receiveStatsTimer.TimeUntilProcess();
156 if (_receiver.NackMode() != kNoNack) { 140 if (_receiver.NackMode() != kNoNack) {
157 // We need a Process call more often if we are relying on 141 // We need a Process call more often if we are relying on
158 // retransmissions 142 // retransmissions
159 timeUntilNextProcess = 143 timeUntilNextProcess =
160 VCM_MIN(timeUntilNextProcess, _retransmissionTimer.TimeUntilProcess()); 144 VCM_MIN(timeUntilNextProcess, _retransmissionTimer.TimeUntilProcess());
161 } 145 }
162 timeUntilNextProcess = 146 timeUntilNextProcess =
163 VCM_MIN(timeUntilNextProcess, _keyRequestTimer.TimeUntilProcess()); 147 VCM_MIN(timeUntilNextProcess, _keyRequestTimer.TimeUntilProcess());
164 timeUntilNextProcess = 148 timeUntilNextProcess =
165 VCM_MIN(timeUntilNextProcess, _receiver.TimeUntilNextProcess()); 149 VCM_MIN(timeUntilNextProcess, _receiver.TimeUntilNextProcess());
166 150
167 return timeUntilNextProcess; 151 return timeUntilNextProcess;
168 } 152 }
169 153
170 int32_t VideoReceiver::SetReceiveChannelParameters(int64_t rtt) { 154 int32_t VideoReceiver::SetReceiveChannelParameters(int64_t rtt) {
171 CriticalSectionScoped receiveCs(_receiveCritSect); 155 rtc::CritScope cs(&receive_lock_);
172 _receiver.UpdateRtt(rtt); 156 _receiver.UpdateRtt(rtt);
173 return 0; 157 return 0;
174 } 158 }
175 159
176 // Enable or disable a video protection method. 160 // Enable or disable a video protection method.
177 // Note: This API should be deprecated, as it does not offer a distinction 161 // Note: This API should be deprecated, as it does not offer a distinction
178 // between the protection method and decoding with or without errors. If such a 162 // between the protection method and decoding with or without errors. If such a
179 // behavior is desired, use the following API: SetReceiverRobustnessMode. 163 // behavior is desired, use the following API: SetReceiverRobustnessMode.
180 int32_t VideoReceiver::SetVideoProtection(VCMVideoProtection videoProtection, 164 int32_t VideoReceiver::SetVideoProtection(VCMVideoProtection videoProtection,
181 bool enable) { 165 bool enable) {
182 // By default, do not decode with errors. 166 // By default, do not decode with errors.
183 _receiver.SetDecodeErrorMode(kNoErrors); 167 _receiver.SetDecodeErrorMode(kNoErrors);
184 switch (videoProtection) { 168 switch (videoProtection) {
185 case kProtectionNack: { 169 case kProtectionNack: {
186 RTC_DCHECK(enable); 170 RTC_DCHECK(enable);
187 _receiver.SetNackMode(kNack, -1, -1); 171 _receiver.SetNackMode(kNack, -1, -1);
188 break; 172 break;
189 } 173 }
190 174
191 case kProtectionNackFEC: { 175 case kProtectionNackFEC: {
192 CriticalSectionScoped cs(_receiveCritSect); 176 rtc::CritScope cs(&receive_lock_);
193 RTC_DCHECK(enable); 177 RTC_DCHECK(enable);
194 _receiver.SetNackMode(kNack, media_optimization::kLowRttNackMs, -1); 178 _receiver.SetNackMode(kNack, media_optimization::kLowRttNackMs, -1);
195 _receiver.SetDecodeErrorMode(kNoErrors); 179 _receiver.SetDecodeErrorMode(kNoErrors);
196 break; 180 break;
197 } 181 }
198 case kProtectionFEC: 182 case kProtectionFEC:
199 case kProtectionNone: 183 case kProtectionNone:
200 // No receiver-side protection. 184 // No receiver-side protection.
201 RTC_DCHECK(enable); 185 RTC_DCHECK(enable);
202 _receiver.SetNackMode(kNoNack, -1, -1); 186 _receiver.SetNackMode(kNoNack, -1, -1);
203 _receiver.SetDecodeErrorMode(kWithErrors); 187 _receiver.SetDecodeErrorMode(kWithErrors);
204 break; 188 break;
205 } 189 }
206 return VCM_OK; 190 return VCM_OK;
207 } 191 }
208 192
209 // Register a receive callback. Will be called whenever there is a new frame 193 // Register a receive callback. Will be called whenever there is a new frame
210 // ready for rendering. 194 // ready for rendering.
211 int32_t VideoReceiver::RegisterReceiveCallback( 195 int32_t VideoReceiver::RegisterReceiveCallback(
212 VCMReceiveCallback* receiveCallback) { 196 VCMReceiveCallback* receiveCallback) {
213 CriticalSectionScoped cs(_receiveCritSect); 197 rtc::CritScope cs(&receive_lock_);
214 _decodedFrameCallback.SetUserReceiveCallback(receiveCallback); 198 _decodedFrameCallback.SetUserReceiveCallback(receiveCallback);
215 return VCM_OK; 199 return VCM_OK;
216 } 200 }
217 201
218 int32_t VideoReceiver::RegisterReceiveStatisticsCallback( 202 int32_t VideoReceiver::RegisterReceiveStatisticsCallback(
219 VCMReceiveStatisticsCallback* receiveStats) { 203 VCMReceiveStatisticsCallback* receiveStats) {
220 CriticalSectionScoped cs(process_crit_sect_.get()); 204 rtc::CritScope cs(&process_lock_);
221 _receiver.RegisterStatsCallback(receiveStats); 205 _receiver.RegisterStatsCallback(receiveStats);
222 _receiveStatsCallback = receiveStats; 206 _receiveStatsCallback = receiveStats;
223 return VCM_OK; 207 return VCM_OK;
224 } 208 }
225 209
226 int32_t VideoReceiver::RegisterDecoderTimingCallback( 210 int32_t VideoReceiver::RegisterDecoderTimingCallback(
227 VCMDecoderTimingCallback* decoderTiming) { 211 VCMDecoderTimingCallback* decoderTiming) {
228 CriticalSectionScoped cs(process_crit_sect_.get()); 212 rtc::CritScope cs(&process_lock_);
229 _decoderTimingCallback = decoderTiming; 213 _decoderTimingCallback = decoderTiming;
230 return VCM_OK; 214 return VCM_OK;
231 } 215 }
232 216
233 // Register an externally defined decoder object. 217 // Register an externally defined decoder object.
234 void VideoReceiver::RegisterExternalDecoder(VideoDecoder* externalDecoder, 218 void VideoReceiver::RegisterExternalDecoder(VideoDecoder* externalDecoder,
235 uint8_t payloadType) { 219 uint8_t payloadType) {
236 CriticalSectionScoped cs(_receiveCritSect); 220 rtc::CritScope cs(&receive_lock_);
237 if (externalDecoder == NULL) { 221 if (externalDecoder == nullptr) {
238 // Make sure the VCM updates the decoder next time it decodes. 222 // Make sure the VCM updates the decoder next time it decodes.
239 _decoder = NULL; 223 _decoder = nullptr;
240 RTC_CHECK(_codecDataBase.DeregisterExternalDecoder(payloadType)); 224 RTC_CHECK(_codecDataBase.DeregisterExternalDecoder(payloadType));
241 return; 225 return;
242 } 226 }
243 _codecDataBase.RegisterExternalDecoder(externalDecoder, payloadType); 227 _codecDataBase.RegisterExternalDecoder(externalDecoder, payloadType);
244 } 228 }
245 229
246 // Register a frame type request callback. 230 // Register a frame type request callback.
247 int32_t VideoReceiver::RegisterFrameTypeCallback( 231 int32_t VideoReceiver::RegisterFrameTypeCallback(
248 VCMFrameTypeCallback* frameTypeCallback) { 232 VCMFrameTypeCallback* frameTypeCallback) {
249 CriticalSectionScoped cs(process_crit_sect_.get()); 233 rtc::CritScope cs(&process_lock_);
250 _frameTypeCallback = frameTypeCallback; 234 _frameTypeCallback = frameTypeCallback;
251 return VCM_OK; 235 return VCM_OK;
252 } 236 }
253 237
254 int32_t VideoReceiver::RegisterPacketRequestCallback( 238 int32_t VideoReceiver::RegisterPacketRequestCallback(
255 VCMPacketRequestCallback* callback) { 239 VCMPacketRequestCallback* callback) {
256 CriticalSectionScoped cs(process_crit_sect_.get()); 240 rtc::CritScope cs(&process_lock_);
257 _packetRequestCallback = callback; 241 _packetRequestCallback = callback;
258 return VCM_OK; 242 return VCM_OK;
259 } 243 }
260 244
261 int VideoReceiver::RegisterRenderBufferSizeCallback( 245 int VideoReceiver::RegisterRenderBufferSizeCallback(
262 VCMRenderBufferSizeCallback* callback) { 246 VCMRenderBufferSizeCallback* callback) {
263 CriticalSectionScoped cs(process_crit_sect_.get()); 247 rtc::CritScope cs(&process_lock_);
264 render_buffer_callback_ = callback; 248 render_buffer_callback_ = callback;
265 return VCM_OK; 249 return VCM_OK;
266 } 250 }
267 251
268 void VideoReceiver::TriggerDecoderShutdown() { 252 void VideoReceiver::TriggerDecoderShutdown() {
269 _receiver.TriggerDecoderShutdown(); 253 _receiver.TriggerDecoderShutdown();
270 } 254 }
271 255
272 // Decode next frame, blocking. 256 // Decode next frame, blocking.
273 // Should be called as often as possible to get the most out of the decoder. 257 // Should be called as often as possible to get the most out of the decoder.
274 int32_t VideoReceiver::Decode(uint16_t maxWaitTimeMs) { 258 int32_t VideoReceiver::Decode(uint16_t maxWaitTimeMs) {
275 int64_t nextRenderTimeMs; 259 int64_t nextRenderTimeMs;
276 bool prefer_late_decoding = false; 260 bool prefer_late_decoding = false;
277 { 261 {
278 CriticalSectionScoped cs(_receiveCritSect); 262 rtc::CritScope cs(&receive_lock_);
279 prefer_late_decoding = _codecDataBase.PrefersLateDecoding(); 263 prefer_late_decoding = _codecDataBase.PrefersLateDecoding();
280 } 264 }
281 265
282 VCMEncodedFrame* frame = _receiver.FrameForDecoding( 266 VCMEncodedFrame* frame = _receiver.FrameForDecoding(
283 maxWaitTimeMs, &nextRenderTimeMs, prefer_late_decoding); 267 maxWaitTimeMs, &nextRenderTimeMs, prefer_late_decoding);
284 268
285 if (!frame) 269 if (!frame)
286 return VCM_FRAME_NOT_READY; 270 return VCM_FRAME_NOT_READY;
287 271
288 { 272 {
289 CriticalSectionScoped cs(process_crit_sect_.get()); 273 rtc::CritScope cs(&process_lock_);
290 if (drop_frames_until_keyframe_) { 274 if (drop_frames_until_keyframe_) {
291 // Still getting delta frames, schedule another keyframe request as if 275 // Still getting delta frames, schedule another keyframe request as if
292 // decode failed. 276 // decode failed.
293 if (frame->FrameType() != kVideoFrameKey) { 277 if (frame->FrameType() != kVideoFrameKey) {
294 _scheduleKeyRequest = true; 278 _scheduleKeyRequest = true;
295 _receiver.ReleaseFrame(frame); 279 _receiver.ReleaseFrame(frame);
296 return VCM_FRAME_NOT_READY; 280 return VCM_FRAME_NOT_READY;
297 } 281 }
298 drop_frames_until_keyframe_ = false; 282 drop_frames_until_keyframe_ = false;
299 } 283 }
300 } 284 }
301 CriticalSectionScoped cs(_receiveCritSect);
302 285
286 rtc::CritScope cs(&receive_lock_);
303 // If this frame was too late, we should adjust the delay accordingly 287 // If this frame was too late, we should adjust the delay accordingly
304 _timing.UpdateCurrentDelay(frame->RenderTimeMs(), 288 _timing.UpdateCurrentDelay(frame->RenderTimeMs(),
305 clock_->TimeInMilliseconds()); 289 clock_->TimeInMilliseconds());
306 290
307 if (pre_decode_image_callback_) { 291 if (pre_decode_image_callback_) {
308 EncodedImage encoded_image(frame->EncodedImage()); 292 EncodedImage encoded_image(frame->EncodedImage());
309 int qp = -1; 293 int qp = -1;
310 if (qp_parser_.GetQp(*frame, &qp)) { 294 if (qp_parser_.GetQp(*frame, &qp)) {
311 encoded_image.qp_ = qp; 295 encoded_image.qp_ = qp;
312 } 296 }
313 pre_decode_image_callback_->Encoded(encoded_image, frame->CodecSpecific(), 297 pre_decode_image_callback_->Encoded(encoded_image, frame->CodecSpecific(),
pbos-webrtc 2016/04/12 11:20:55 Can you wire up this through here instead? Then yo
sprang_webrtc 2016/04/12 14:06:17 Done.
314 NULL); 298 nullptr);
315 } 299 }
316 300
317 #ifdef DEBUG_DECODER_BIT_STREAM
318 if (_bitStreamBeforeDecoder != NULL) {
319 // Write bit stream to file for debugging purposes
320 if (fwrite(frame->Buffer(), 1, frame->Length(), _bitStreamBeforeDecoder) !=
321 frame->Length()) {
322 return -1;
323 }
324 }
325 #endif
326
327 if (first_frame_received_()) { 301 if (first_frame_received_()) {
328 LOG(LS_INFO) << "Received first " 302 LOG(LS_INFO) << "Received first "
329 << (frame->Complete() ? "complete" : "incomplete") 303 << (frame->Complete() ? "complete" : "incomplete")
330 << " decodable video frame"; 304 << " decodable video frame";
331 } 305 }
332 306
333 const int32_t ret = Decode(*frame); 307 const int32_t ret = Decode(*frame);
334 _receiver.ReleaseFrame(frame); 308 _receiver.ReleaseFrame(frame);
335 return ret; 309 return ret;
336 } 310 }
337 311
338 int32_t VideoReceiver::RequestSliceLossIndication( 312 int32_t VideoReceiver::RequestSliceLossIndication(
339 const uint64_t pictureID) const { 313 const uint64_t pictureID) const {
340 TRACE_EVENT1("webrtc", "RequestSLI", "picture_id", pictureID); 314 TRACE_EVENT1("webrtc", "RequestSLI", "picture_id", pictureID);
341 CriticalSectionScoped cs(process_crit_sect_.get()); 315 rtc::CritScope cs(&process_lock_);
342 if (_frameTypeCallback != NULL) { 316 if (_frameTypeCallback != nullptr) {
343 const int32_t ret = 317 const int32_t ret =
344 _frameTypeCallback->SliceLossIndicationRequest(pictureID); 318 _frameTypeCallback->SliceLossIndicationRequest(pictureID);
345 if (ret < 0) { 319 if (ret < 0) {
346 return ret; 320 return ret;
347 } 321 }
348 } else { 322 } else {
349 return VCM_MISSING_CALLBACK; 323 return VCM_MISSING_CALLBACK;
350 } 324 }
351 return VCM_OK; 325 return VCM_OK;
352 } 326 }
353 327
354 int32_t VideoReceiver::RequestKeyFrame() { 328 int32_t VideoReceiver::RequestKeyFrame() {
355 TRACE_EVENT0("webrtc", "RequestKeyFrame"); 329 TRACE_EVENT0("webrtc", "RequestKeyFrame");
356 CriticalSectionScoped process_cs(process_crit_sect_.get()); 330 rtc::CritScope cs(&process_lock_);
357 if (_frameTypeCallback != NULL) { 331 if (_frameTypeCallback != nullptr) {
358 const int32_t ret = _frameTypeCallback->RequestKeyFrame(); 332 const int32_t ret = _frameTypeCallback->RequestKeyFrame();
359 if (ret < 0) { 333 if (ret < 0) {
360 return ret; 334 return ret;
361 } 335 }
362 _scheduleKeyRequest = false; 336 _scheduleKeyRequest = false;
363 } else { 337 } else {
364 return VCM_MISSING_CALLBACK; 338 return VCM_MISSING_CALLBACK;
365 } 339 }
366 return VCM_OK; 340 return VCM_OK;
367 } 341 }
368 342
369 // Must be called from inside the receive side critical section. 343 // Must be called from inside the receive side critical section.
370 int32_t VideoReceiver::Decode(const VCMEncodedFrame& frame) { 344 int32_t VideoReceiver::Decode(const VCMEncodedFrame& frame) {
345 if (kEnableFrameRecording) {
346 rtc::CritScope cs(&file_write_lock_);
347 if (!file_writer_.get()) {
348 RTC_DCHECK(frame.CodecSpecific());
349 RtpVideoCodecTypes rtp_codec_type;
350 switch (frame.CodecSpecific()->codecType) {
351 case kVideoCodecVP8:
352 rtp_codec_type = kRtpVideoVp8;
353 break;
354 case kVideoCodecVP9:
355 rtp_codec_type = kRtpVideoVp9;
356 break;
357 case kVideoCodecH264:
358 rtp_codec_type = kRtpVideoH264;
359 break;
360 default:
361 rtp_codec_type = kRtpVideoNone;
362 RTC_NOTREACHED() << "Unsupported codec "
363 << frame.CodecSpecific()->codecType;
364 }
365 std::ostringstream oss;
366 oss << "receive_bitstream_ssrc_" << ssrc_ << ".ivf";
367 file_writer_ = IvfFileWriter::Open(oss.str(), rtp_codec_type);
368 }
369 if (file_writer_.get()) {
370 bool ok = file_writer_->WriteFrame(frame.EncodedImage());
pbos-webrtc 2016/04/12 11:20:55 This is now done under the receive critsect?
sprang_webrtc 2016/04/12 14:06:17 Yes.
371 RTC_DCHECK(ok);
372 }
373 }
374
371 TRACE_EVENT_ASYNC_STEP1("webrtc", "Video", frame.TimeStamp(), "Decode", 375 TRACE_EVENT_ASYNC_STEP1("webrtc", "Video", frame.TimeStamp(), "Decode",
372 "type", frame.FrameType()); 376 "type", frame.FrameType());
373 // Change decoder if payload type has changed 377 // Change decoder if payload type has changed
374 _decoder = _codecDataBase.GetDecoder(frame, &_decodedFrameCallback); 378 _decoder = _codecDataBase.GetDecoder(frame, &_decodedFrameCallback);
375 if (_decoder == NULL) { 379 if (_decoder == nullptr) {
376 return VCM_NO_CODEC_REGISTERED; 380 return VCM_NO_CODEC_REGISTERED;
377 } 381 }
378 // Decode a frame 382 // Decode a frame
379 int32_t ret = _decoder->Decode(frame, clock_->TimeInMilliseconds()); 383 int32_t ret = _decoder->Decode(frame, clock_->TimeInMilliseconds());
380 384
381 // Check for failed decoding, run frame type request callback if needed. 385 // Check for failed decoding, run frame type request callback if needed.
382 bool request_key_frame = false; 386 bool request_key_frame = false;
383 if (ret < 0) { 387 if (ret < 0) {
384 if (ret == VCM_ERROR_REQUEST_SLI) { 388 if (ret == VCM_ERROR_REQUEST_SLI) {
385 return RequestSliceLossIndication( 389 return RequestSliceLossIndication(
386 _decodedFrameCallback.LastReceivedPictureID() + 1); 390 _decodedFrameCallback.LastReceivedPictureID() + 1);
387 } else { 391 } else {
388 request_key_frame = true; 392 request_key_frame = true;
389 } 393 }
390 } else if (ret == VCM_REQUEST_SLI) { 394 } else if (ret == VCM_REQUEST_SLI) {
391 ret = RequestSliceLossIndication( 395 ret = RequestSliceLossIndication(
392 _decodedFrameCallback.LastReceivedPictureID() + 1); 396 _decodedFrameCallback.LastReceivedPictureID() + 1);
393 } 397 }
394 if (!frame.Complete() || frame.MissingFrame()) { 398 if (!frame.Complete() || frame.MissingFrame()) {
395 request_key_frame = true; 399 request_key_frame = true;
396 ret = VCM_OK; 400 ret = VCM_OK;
397 } 401 }
398 if (request_key_frame) { 402 if (request_key_frame) {
399 CriticalSectionScoped cs(process_crit_sect_.get()); 403 rtc::CritScope cs(&process_lock_);
400 _scheduleKeyRequest = true; 404 _scheduleKeyRequest = true;
401 } 405 }
402 TRACE_EVENT_ASYNC_END0("webrtc", "Video", frame.TimeStamp()); 406 TRACE_EVENT_ASYNC_END0("webrtc", "Video", frame.TimeStamp());
403 return ret; 407 return ret;
404 } 408 }
405 409
406 // Register possible receive codecs, can be called multiple times 410 // Register possible receive codecs, can be called multiple times
407 int32_t VideoReceiver::RegisterReceiveCodec(const VideoCodec* receiveCodec, 411 int32_t VideoReceiver::RegisterReceiveCodec(const VideoCodec* receiveCodec,
408 int32_t numberOfCores, 412 int32_t numberOfCores,
409 bool requireKeyFrame) { 413 bool requireKeyFrame) {
410 CriticalSectionScoped cs(_receiveCritSect); 414 rtc::CritScope cs(&receive_lock_);
411 if (receiveCodec == NULL) { 415 if (receiveCodec == nullptr) {
412 return VCM_PARAMETER_ERROR; 416 return VCM_PARAMETER_ERROR;
413 } 417 }
414 if (!_codecDataBase.RegisterReceiveCodec(receiveCodec, numberOfCores, 418 if (!_codecDataBase.RegisterReceiveCodec(receiveCodec, numberOfCores,
415 requireKeyFrame)) { 419 requireKeyFrame)) {
416 return -1; 420 return -1;
417 } 421 }
418 return 0; 422 return 0;
419 } 423 }
420 424
421 // Get current received codec 425 // Get current received codec
422 int32_t VideoReceiver::ReceiveCodec(VideoCodec* currentReceiveCodec) const { 426 int32_t VideoReceiver::ReceiveCodec(VideoCodec* currentReceiveCodec) const {
423 CriticalSectionScoped cs(_receiveCritSect); 427 rtc::CritScope cs(&receive_lock_);
424 if (currentReceiveCodec == NULL) { 428 if (currentReceiveCodec == nullptr) {
425 return VCM_PARAMETER_ERROR; 429 return VCM_PARAMETER_ERROR;
426 } 430 }
427 return _codecDataBase.ReceiveCodec(currentReceiveCodec) ? 0 : -1; 431 return _codecDataBase.ReceiveCodec(currentReceiveCodec) ? 0 : -1;
428 } 432 }
429 433
430 // Get current received codec 434 // Get current received codec
431 VideoCodecType VideoReceiver::ReceiveCodec() const { 435 VideoCodecType VideoReceiver::ReceiveCodec() const {
432 CriticalSectionScoped cs(_receiveCritSect); 436 rtc::CritScope cs(&receive_lock_);
433 return _codecDataBase.ReceiveCodec(); 437 return _codecDataBase.ReceiveCodec();
434 } 438 }
435 439
436 // Incoming packet from network parsed and ready for decode, non blocking. 440 // Incoming packet from network parsed and ready for decode, non blocking.
437 int32_t VideoReceiver::IncomingPacket(const uint8_t* incomingPayload, 441 int32_t VideoReceiver::IncomingPacket(const uint8_t* incomingPayload,
438 size_t payloadLength, 442 size_t payloadLength,
439 const WebRtcRTPHeader& rtpInfo) { 443 const WebRtcRTPHeader& rtpInfo) {
440 if (rtpInfo.frameType == kVideoFrameKey) { 444 if (rtpInfo.frameType == kVideoFrameKey) {
441 TRACE_EVENT1("webrtc", "VCM::PacketKeyFrame", "seqnum", 445 TRACE_EVENT1("webrtc", "VCM::PacketKeyFrame", "seqnum",
442 rtpInfo.header.sequenceNumber); 446 rtpInfo.header.sequenceNumber);
443 } 447 }
444 if (incomingPayload == NULL) { 448 if (incomingPayload == nullptr) {
445 // The jitter buffer doesn't handle non-zero payload lengths for packets 449 // The jitter buffer doesn't handle non-zero payload lengths for packets
446 // without payload. 450 // without payload.
447 // TODO(holmer): We should fix this in the jitter buffer. 451 // TODO(holmer): We should fix this in the jitter buffer.
448 payloadLength = 0; 452 payloadLength = 0;
449 } 453 }
450 const VCMPacket packet(incomingPayload, payloadLength, rtpInfo); 454 const VCMPacket packet(incomingPayload, payloadLength, rtpInfo);
451 int32_t ret = _receiver.InsertPacket(packet, rtpInfo.type.Video.width, 455 int32_t ret = _receiver.InsertPacket(packet, rtpInfo.type.Video.width,
452 rtpInfo.type.Video.height); 456 rtpInfo.type.Video.height);
457
458 if (kEnableFrameRecording) {
459 rtc::CritScope cs(&file_write_lock_);
460 ssrc_ = rtpInfo.header.ssrc;
461 }
462
453 // TODO(holmer): Investigate if this somehow should use the key frame 463 // TODO(holmer): Investigate if this somehow should use the key frame
454 // request scheduling to throttle the requests. 464 // request scheduling to throttle the requests.
455 if (ret == VCM_FLUSH_INDICATOR) { 465 if (ret == VCM_FLUSH_INDICATOR) {
456 { 466 {
457 CriticalSectionScoped process_cs(process_crit_sect_.get()); 467 rtc::CritScope cs(&process_lock_);
458 drop_frames_until_keyframe_ = true; 468 drop_frames_until_keyframe_ = true;
459 } 469 }
460 RequestKeyFrame(); 470 RequestKeyFrame();
461 } else if (ret < 0) { 471 } else if (ret < 0) {
462 return ret; 472 return ret;
463 } 473 }
464 return VCM_OK; 474 return VCM_OK;
465 } 475 }
466 476
467 // Minimum playout delay (used for lip-sync). This is the minimum delay required 477 // Minimum playout delay (used for lip-sync). This is the minimum delay required
(...skipping 16 matching lines...) Expand all
484 return _timing.TargetVideoDelay(); 494 return _timing.TargetVideoDelay();
485 } 495 }
486 496
487 uint32_t VideoReceiver::DiscardedPackets() const { 497 uint32_t VideoReceiver::DiscardedPackets() const {
488 return _receiver.DiscardedPackets(); 498 return _receiver.DiscardedPackets();
489 } 499 }
490 500
491 int VideoReceiver::SetReceiverRobustnessMode( 501 int VideoReceiver::SetReceiverRobustnessMode(
492 ReceiverRobustness robustnessMode, 502 ReceiverRobustness robustnessMode,
493 VCMDecodeErrorMode decode_error_mode) { 503 VCMDecodeErrorMode decode_error_mode) {
494 CriticalSectionScoped cs(_receiveCritSect); 504 rtc::CritScope cs(&receive_lock_);
495 switch (robustnessMode) { 505 switch (robustnessMode) {
496 case VideoCodingModule::kNone: 506 case VideoCodingModule::kNone:
497 _receiver.SetNackMode(kNoNack, -1, -1); 507 _receiver.SetNackMode(kNoNack, -1, -1);
498 break; 508 break;
499 case VideoCodingModule::kHardNack: 509 case VideoCodingModule::kHardNack:
500 // Always wait for retransmissions (except when decoding with errors). 510 // Always wait for retransmissions (except when decoding with errors).
501 _receiver.SetNackMode(kNack, -1, -1); 511 _receiver.SetNackMode(kNack, -1, -1);
502 break; 512 break;
503 case VideoCodingModule::kSoftNack: 513 case VideoCodingModule::kSoftNack:
504 #if 1 514 #if 1
(...skipping 15 matching lines...) Expand all
520 } 530 }
521 _receiver.SetNackMode(kNoNack, -1, -1); 531 _receiver.SetNackMode(kNoNack, -1, -1);
522 break; 532 break;
523 #endif 533 #endif
524 } 534 }
525 _receiver.SetDecodeErrorMode(decode_error_mode); 535 _receiver.SetDecodeErrorMode(decode_error_mode);
526 return VCM_OK; 536 return VCM_OK;
527 } 537 }
528 538
529 void VideoReceiver::SetDecodeErrorMode(VCMDecodeErrorMode decode_error_mode) { 539 void VideoReceiver::SetDecodeErrorMode(VCMDecodeErrorMode decode_error_mode) {
530 CriticalSectionScoped cs(_receiveCritSect); 540 rtc::CritScope cs(&receive_lock_);
531 _receiver.SetDecodeErrorMode(decode_error_mode); 541 _receiver.SetDecodeErrorMode(decode_error_mode);
532 } 542 }
533 543
534 void VideoReceiver::SetNackSettings(size_t max_nack_list_size, 544 void VideoReceiver::SetNackSettings(size_t max_nack_list_size,
535 int max_packet_age_to_nack, 545 int max_packet_age_to_nack,
536 int max_incomplete_time_ms) { 546 int max_incomplete_time_ms) {
537 if (max_nack_list_size != 0) { 547 if (max_nack_list_size != 0) {
538 CriticalSectionScoped process_cs(process_crit_sect_.get()); 548 rtc::CritScope cs(&process_lock_);
539 max_nack_list_size_ = max_nack_list_size; 549 max_nack_list_size_ = max_nack_list_size;
540 } 550 }
541 _receiver.SetNackSettings(max_nack_list_size, max_packet_age_to_nack, 551 _receiver.SetNackSettings(max_nack_list_size, max_packet_age_to_nack,
542 max_incomplete_time_ms); 552 max_incomplete_time_ms);
543 } 553 }
544 554
545 int VideoReceiver::SetMinReceiverDelay(int desired_delay_ms) { 555 int VideoReceiver::SetMinReceiverDelay(int desired_delay_ms) {
546 return _receiver.SetMinReceiverDelay(desired_delay_ms); 556 return _receiver.SetMinReceiverDelay(desired_delay_ms);
547 } 557 }
548 558
549 void VideoReceiver::RegisterPreDecodeImageCallback( 559 void VideoReceiver::RegisterPreDecodeImageCallback(
550 EncodedImageCallback* observer) { 560 EncodedImageCallback* observer) {
551 CriticalSectionScoped cs(_receiveCritSect); 561 rtc::CritScope cs(&receive_lock_);
552 pre_decode_image_callback_ = observer; 562 pre_decode_image_callback_ = observer;
pbos-webrtc 2016/04/12 11:22:33 Actually, can we require this to be set before rec
sprang_webrtc 2016/04/12 14:06:17 Done.
553 } 563 }
554 564
555 } // namespace vcm 565 } // namespace vcm
556 } // namespace webrtc 566 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698