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

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: Rebase 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,
28 EncodedImageCallback* pre_decode_image_callback,
30 NackSender* nack_sender, 29 NackSender* nack_sender,
31 KeyFrameRequestSender* keyframe_request_sender) 30 KeyFrameRequestSender* keyframe_request_sender)
32 : clock_(clock), 31 : clock_(clock),
33 process_crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
34 _receiveCritSect(CriticalSectionWrapper::CreateCriticalSection()),
35 _timing(clock_), 32 _timing(clock_),
36 _receiver(&_timing, 33 _receiver(&_timing,
37 clock_, 34 clock_,
38 event_factory, 35 event_factory,
39 nack_sender, 36 nack_sender,
40 keyframe_request_sender), 37 keyframe_request_sender),
41 _decodedFrameCallback(&_timing, clock_), 38 _decodedFrameCallback(&_timing, clock_),
42 _frameTypeCallback(NULL), 39 _frameTypeCallback(nullptr),
43 _receiveStatsCallback(NULL), 40 _receiveStatsCallback(nullptr),
44 _decoderTimingCallback(NULL), 41 _decoderTimingCallback(nullptr),
45 _packetRequestCallback(NULL), 42 _packetRequestCallback(nullptr),
46 render_buffer_callback_(NULL), 43 render_buffer_callback_(nullptr),
47 _decoder(NULL), 44 _decoder(nullptr),
48 #ifdef DEBUG_DECODER_BIT_STREAM
49 _bitStreamBeforeDecoder(NULL),
50 #endif
51 _frameFromFile(), 45 _frameFromFile(),
52 _scheduleKeyRequest(false), 46 _scheduleKeyRequest(false),
53 drop_frames_until_keyframe_(false), 47 drop_frames_until_keyframe_(false),
54 max_nack_list_size_(0), 48 max_nack_list_size_(0),
55 _codecDataBase(nullptr, nullptr), 49 _codecDataBase(nullptr, nullptr),
56 pre_decode_image_callback_(NULL), 50 pre_decode_image_callback_(pre_decode_image_callback),
57 _receiveStatsTimer(1000, clock_), 51 _receiveStatsTimer(1000, clock_),
58 _retransmissionTimer(10, clock_), 52 _retransmissionTimer(10, clock_),
59 _keyRequestTimer(500, clock_) { 53 _keyRequestTimer(500, clock_) {}
60 assert(clock_);
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_crit_);
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_crit_);
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_crit_);
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_crit_);
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_crit_);
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_crit_);
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_crit_);
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_crit_);
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_crit_);
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_crit_);
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_crit_);
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_crit_);
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_crit_);
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_crit_);
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_crit_);
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
303 // If this frame was too late, we should adjust the delay accordingly
304 _timing.UpdateCurrentDelay(frame->RenderTimeMs(),
305 clock_->TimeInMilliseconds());
306 285
307 if (pre_decode_image_callback_) { 286 if (pre_decode_image_callback_) {
308 EncodedImage encoded_image(frame->EncodedImage()); 287 EncodedImage encoded_image(frame->EncodedImage());
309 int qp = -1; 288 int qp = -1;
310 if (qp_parser_.GetQp(*frame, &qp)) { 289 if (qp_parser_.GetQp(*frame, &qp)) {
311 encoded_image.qp_ = qp; 290 encoded_image.qp_ = qp;
312 } 291 }
313 pre_decode_image_callback_->Encoded(encoded_image, frame->CodecSpecific(), 292 pre_decode_image_callback_->Encoded(encoded_image, frame->CodecSpecific(),
314 NULL); 293 nullptr);
315 } 294 }
316 295
317 #ifdef DEBUG_DECODER_BIT_STREAM 296 rtc::CritScope cs(&receive_crit_);
318 if (_bitStreamBeforeDecoder != NULL) { 297 // If this frame was too late, we should adjust the delay accordingly
319 // Write bit stream to file for debugging purposes 298 _timing.UpdateCurrentDelay(frame->RenderTimeMs(),
320 if (fwrite(frame->Buffer(), 1, frame->Length(), _bitStreamBeforeDecoder) != 299 clock_->TimeInMilliseconds());
321 frame->Length()) {
322 return -1;
323 }
324 }
325 #endif
326 300
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_crit_);
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_crit_);
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) {
371 TRACE_EVENT_ASYNC_STEP1("webrtc", "Video", frame.TimeStamp(), "Decode", 345 TRACE_EVENT_ASYNC_STEP1("webrtc", "Video", frame.TimeStamp(), "Decode",
372 "type", frame.FrameType()); 346 "type", frame.FrameType());
373 // Change decoder if payload type has changed 347 // Change decoder if payload type has changed
374 _decoder = _codecDataBase.GetDecoder(frame, &_decodedFrameCallback); 348 _decoder = _codecDataBase.GetDecoder(frame, &_decodedFrameCallback);
375 if (_decoder == NULL) { 349 if (_decoder == nullptr) {
376 return VCM_NO_CODEC_REGISTERED; 350 return VCM_NO_CODEC_REGISTERED;
377 } 351 }
378 // Decode a frame 352 // Decode a frame
379 int32_t ret = _decoder->Decode(frame, clock_->TimeInMilliseconds()); 353 int32_t ret = _decoder->Decode(frame, clock_->TimeInMilliseconds());
380 354
381 // Check for failed decoding, run frame type request callback if needed. 355 // Check for failed decoding, run frame type request callback if needed.
382 bool request_key_frame = false; 356 bool request_key_frame = false;
383 if (ret < 0) { 357 if (ret < 0) {
384 if (ret == VCM_ERROR_REQUEST_SLI) { 358 if (ret == VCM_ERROR_REQUEST_SLI) {
385 return RequestSliceLossIndication( 359 return RequestSliceLossIndication(
386 _decodedFrameCallback.LastReceivedPictureID() + 1); 360 _decodedFrameCallback.LastReceivedPictureID() + 1);
387 } else { 361 } else {
388 request_key_frame = true; 362 request_key_frame = true;
389 } 363 }
390 } else if (ret == VCM_REQUEST_SLI) { 364 } else if (ret == VCM_REQUEST_SLI) {
391 ret = RequestSliceLossIndication( 365 ret = RequestSliceLossIndication(
392 _decodedFrameCallback.LastReceivedPictureID() + 1); 366 _decodedFrameCallback.LastReceivedPictureID() + 1);
393 } 367 }
394 if (!frame.Complete() || frame.MissingFrame()) { 368 if (!frame.Complete() || frame.MissingFrame()) {
395 request_key_frame = true; 369 request_key_frame = true;
396 ret = VCM_OK; 370 ret = VCM_OK;
397 } 371 }
398 if (request_key_frame) { 372 if (request_key_frame) {
399 CriticalSectionScoped cs(process_crit_sect_.get()); 373 rtc::CritScope cs(&process_crit_);
400 _scheduleKeyRequest = true; 374 _scheduleKeyRequest = true;
401 } 375 }
402 TRACE_EVENT_ASYNC_END0("webrtc", "Video", frame.TimeStamp()); 376 TRACE_EVENT_ASYNC_END0("webrtc", "Video", frame.TimeStamp());
403 return ret; 377 return ret;
404 } 378 }
405 379
406 // Register possible receive codecs, can be called multiple times 380 // Register possible receive codecs, can be called multiple times
407 int32_t VideoReceiver::RegisterReceiveCodec(const VideoCodec* receiveCodec, 381 int32_t VideoReceiver::RegisterReceiveCodec(const VideoCodec* receiveCodec,
408 int32_t numberOfCores, 382 int32_t numberOfCores,
409 bool requireKeyFrame) { 383 bool requireKeyFrame) {
410 CriticalSectionScoped cs(_receiveCritSect); 384 rtc::CritScope cs(&receive_crit_);
411 if (receiveCodec == NULL) { 385 if (receiveCodec == nullptr) {
412 return VCM_PARAMETER_ERROR; 386 return VCM_PARAMETER_ERROR;
413 } 387 }
414 if (!_codecDataBase.RegisterReceiveCodec(receiveCodec, numberOfCores, 388 if (!_codecDataBase.RegisterReceiveCodec(receiveCodec, numberOfCores,
415 requireKeyFrame)) { 389 requireKeyFrame)) {
416 return -1; 390 return -1;
417 } 391 }
418 return 0; 392 return 0;
419 } 393 }
420 394
421 // Get current received codec 395 // Get current received codec
422 int32_t VideoReceiver::ReceiveCodec(VideoCodec* currentReceiveCodec) const { 396 int32_t VideoReceiver::ReceiveCodec(VideoCodec* currentReceiveCodec) const {
423 CriticalSectionScoped cs(_receiveCritSect); 397 rtc::CritScope cs(&receive_crit_);
424 if (currentReceiveCodec == NULL) { 398 if (currentReceiveCodec == nullptr) {
425 return VCM_PARAMETER_ERROR; 399 return VCM_PARAMETER_ERROR;
426 } 400 }
427 return _codecDataBase.ReceiveCodec(currentReceiveCodec) ? 0 : -1; 401 return _codecDataBase.ReceiveCodec(currentReceiveCodec) ? 0 : -1;
428 } 402 }
429 403
430 // Get current received codec 404 // Get current received codec
431 VideoCodecType VideoReceiver::ReceiveCodec() const { 405 VideoCodecType VideoReceiver::ReceiveCodec() const {
432 CriticalSectionScoped cs(_receiveCritSect); 406 rtc::CritScope cs(&receive_crit_);
433 return _codecDataBase.ReceiveCodec(); 407 return _codecDataBase.ReceiveCodec();
434 } 408 }
435 409
436 // Incoming packet from network parsed and ready for decode, non blocking. 410 // Incoming packet from network parsed and ready for decode, non blocking.
437 int32_t VideoReceiver::IncomingPacket(const uint8_t* incomingPayload, 411 int32_t VideoReceiver::IncomingPacket(const uint8_t* incomingPayload,
438 size_t payloadLength, 412 size_t payloadLength,
439 const WebRtcRTPHeader& rtpInfo) { 413 const WebRtcRTPHeader& rtpInfo) {
440 if (rtpInfo.frameType == kVideoFrameKey) { 414 if (rtpInfo.frameType == kVideoFrameKey) {
441 TRACE_EVENT1("webrtc", "VCM::PacketKeyFrame", "seqnum", 415 TRACE_EVENT1("webrtc", "VCM::PacketKeyFrame", "seqnum",
442 rtpInfo.header.sequenceNumber); 416 rtpInfo.header.sequenceNumber);
443 } 417 }
444 if (incomingPayload == NULL) { 418 if (incomingPayload == nullptr) {
445 // The jitter buffer doesn't handle non-zero payload lengths for packets 419 // The jitter buffer doesn't handle non-zero payload lengths for packets
446 // without payload. 420 // without payload.
447 // TODO(holmer): We should fix this in the jitter buffer. 421 // TODO(holmer): We should fix this in the jitter buffer.
448 payloadLength = 0; 422 payloadLength = 0;
449 } 423 }
450 const VCMPacket packet(incomingPayload, payloadLength, rtpInfo); 424 const VCMPacket packet(incomingPayload, payloadLength, rtpInfo);
451 int32_t ret = _receiver.InsertPacket(packet, rtpInfo.type.Video.width, 425 int32_t ret = _receiver.InsertPacket(packet, rtpInfo.type.Video.width,
452 rtpInfo.type.Video.height); 426 rtpInfo.type.Video.height);
427
453 // TODO(holmer): Investigate if this somehow should use the key frame 428 // TODO(holmer): Investigate if this somehow should use the key frame
454 // request scheduling to throttle the requests. 429 // request scheduling to throttle the requests.
455 if (ret == VCM_FLUSH_INDICATOR) { 430 if (ret == VCM_FLUSH_INDICATOR) {
456 { 431 {
457 CriticalSectionScoped process_cs(process_crit_sect_.get()); 432 rtc::CritScope cs(&process_crit_);
458 drop_frames_until_keyframe_ = true; 433 drop_frames_until_keyframe_ = true;
459 } 434 }
460 RequestKeyFrame(); 435 RequestKeyFrame();
461 } else if (ret < 0) { 436 } else if (ret < 0) {
462 return ret; 437 return ret;
463 } 438 }
464 return VCM_OK; 439 return VCM_OK;
465 } 440 }
466 441
467 // Minimum playout delay (used for lip-sync). This is the minimum delay required 442 // Minimum playout delay (used for lip-sync). This is the minimum delay required
(...skipping 16 matching lines...) Expand all
484 return _timing.TargetVideoDelay(); 459 return _timing.TargetVideoDelay();
485 } 460 }
486 461
487 uint32_t VideoReceiver::DiscardedPackets() const { 462 uint32_t VideoReceiver::DiscardedPackets() const {
488 return _receiver.DiscardedPackets(); 463 return _receiver.DiscardedPackets();
489 } 464 }
490 465
491 int VideoReceiver::SetReceiverRobustnessMode( 466 int VideoReceiver::SetReceiverRobustnessMode(
492 ReceiverRobustness robustnessMode, 467 ReceiverRobustness robustnessMode,
493 VCMDecodeErrorMode decode_error_mode) { 468 VCMDecodeErrorMode decode_error_mode) {
494 CriticalSectionScoped cs(_receiveCritSect); 469 rtc::CritScope cs(&receive_crit_);
495 switch (robustnessMode) { 470 switch (robustnessMode) {
496 case VideoCodingModule::kNone: 471 case VideoCodingModule::kNone:
497 _receiver.SetNackMode(kNoNack, -1, -1); 472 _receiver.SetNackMode(kNoNack, -1, -1);
498 break; 473 break;
499 case VideoCodingModule::kHardNack: 474 case VideoCodingModule::kHardNack:
500 // Always wait for retransmissions (except when decoding with errors). 475 // Always wait for retransmissions (except when decoding with errors).
501 _receiver.SetNackMode(kNack, -1, -1); 476 _receiver.SetNackMode(kNack, -1, -1);
502 break; 477 break;
503 case VideoCodingModule::kSoftNack: 478 case VideoCodingModule::kSoftNack:
504 #if 1 479 #if 1
(...skipping 15 matching lines...) Expand all
520 } 495 }
521 _receiver.SetNackMode(kNoNack, -1, -1); 496 _receiver.SetNackMode(kNoNack, -1, -1);
522 break; 497 break;
523 #endif 498 #endif
524 } 499 }
525 _receiver.SetDecodeErrorMode(decode_error_mode); 500 _receiver.SetDecodeErrorMode(decode_error_mode);
526 return VCM_OK; 501 return VCM_OK;
527 } 502 }
528 503
529 void VideoReceiver::SetDecodeErrorMode(VCMDecodeErrorMode decode_error_mode) { 504 void VideoReceiver::SetDecodeErrorMode(VCMDecodeErrorMode decode_error_mode) {
530 CriticalSectionScoped cs(_receiveCritSect); 505 rtc::CritScope cs(&receive_crit_);
531 _receiver.SetDecodeErrorMode(decode_error_mode); 506 _receiver.SetDecodeErrorMode(decode_error_mode);
532 } 507 }
533 508
534 void VideoReceiver::SetNackSettings(size_t max_nack_list_size, 509 void VideoReceiver::SetNackSettings(size_t max_nack_list_size,
535 int max_packet_age_to_nack, 510 int max_packet_age_to_nack,
536 int max_incomplete_time_ms) { 511 int max_incomplete_time_ms) {
537 if (max_nack_list_size != 0) { 512 if (max_nack_list_size != 0) {
538 CriticalSectionScoped process_cs(process_crit_sect_.get()); 513 rtc::CritScope cs(&process_crit_);
539 max_nack_list_size_ = max_nack_list_size; 514 max_nack_list_size_ = max_nack_list_size;
540 } 515 }
541 _receiver.SetNackSettings(max_nack_list_size, max_packet_age_to_nack, 516 _receiver.SetNackSettings(max_nack_list_size, max_packet_age_to_nack,
542 max_incomplete_time_ms); 517 max_incomplete_time_ms);
543 } 518 }
544 519
545 int VideoReceiver::SetMinReceiverDelay(int desired_delay_ms) { 520 int VideoReceiver::SetMinReceiverDelay(int desired_delay_ms) {
546 return _receiver.SetMinReceiverDelay(desired_delay_ms); 521 return _receiver.SetMinReceiverDelay(desired_delay_ms);
547 } 522 }
548 523
549 void VideoReceiver::RegisterPreDecodeImageCallback(
550 EncodedImageCallback* observer) {
551 CriticalSectionScoped cs(_receiveCritSect);
552 pre_decode_image_callback_ = observer;
553 }
554
555 } // namespace vcm 524 } // namespace vcm
556 } // namespace webrtc 525 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/video_coding/video_coding_impl.cc ('k') | webrtc/modules/video_coding/video_receiver_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698