Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / video_coding / main / test / test_callbacks.cc
1 /*
2  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3  *
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
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10
11 #include "webrtc/modules/video_coding/main/test/test_callbacks.h"
12
13 #include <math.h>
14
15 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
16 #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
17 #include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
18 #include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
19 #include "webrtc/modules/utility/interface/rtp_dump.h"
20 #include "webrtc/modules/video_coding/main/test/test_macros.h"
21 #include "webrtc/system_wrappers/interface/clock.h"
22
23 namespace webrtc {
24
25 /******************************
26  *  VCMEncodeCompleteCallback
27  *****************************/
28 // Basic callback implementation
29 // passes the encoded frame directly to the encoder
30 // Packetization callback implementation
31 VCMEncodeCompleteCallback::VCMEncodeCompleteCallback(FILE* encodedFile):
32     _encodedFile(encodedFile),
33     _encodedBytes(0),
34     _VCMReceiver(NULL),
35     _seqNo(0),
36     _encodeComplete(false),
37     _width(0),
38     _height(0),
39     _codecType(kRtpVideoNone)
40 {
41     //
42 }
43 VCMEncodeCompleteCallback::~VCMEncodeCompleteCallback()
44 {
45 }
46
47 void
48 VCMEncodeCompleteCallback::RegisterTransportCallback(
49                                             VCMPacketizationCallback* transport)
50 {
51 }
52
53 int32_t
54 VCMEncodeCompleteCallback::SendData(
55         const FrameType frameType,
56         const uint8_t  payloadType,
57         const uint32_t timeStamp,
58         int64_t capture_time_ms,
59         const uint8_t* payloadData,
60         const uint32_t payloadSize,
61         const RTPFragmentationHeader& fragmentationHeader,
62         const RTPVideoHeader* videoHdr)
63 {
64     // will call the VCMReceiver input packet
65     _frameType = frameType;
66     // writing encodedData into file
67     if (fwrite(payloadData, 1, payloadSize, _encodedFile) !=  payloadSize) {
68       return -1;
69     }
70     WebRtcRTPHeader rtpInfo;
71     rtpInfo.header.markerBit = true; // end of frame
72     rtpInfo.type.Video.isFirstPacket = true;
73     rtpInfo.type.Video.codec = _codecType;
74     rtpInfo.type.Video.height = (uint16_t)_height;
75     rtpInfo.type.Video.width = (uint16_t)_width;
76     switch (_codecType)
77     {
78     case webrtc::kRtpVideoVp8:
79         rtpInfo.type.Video.codecHeader.VP8.InitRTPVideoHeaderVP8();
80         rtpInfo.type.Video.codecHeader.VP8.nonReference =
81             videoHdr->codecHeader.VP8.nonReference;
82         rtpInfo.type.Video.codecHeader.VP8.pictureId =
83             videoHdr->codecHeader.VP8.pictureId;
84         break;
85     case webrtc::kRtpVideoGeneric:
86       // Leave for now, until we add kRtpVideoVp9 to RTP.
87       break;
88     default:
89         assert(false);
90         return -1;
91     }
92
93     rtpInfo.header.payloadType = payloadType;
94     rtpInfo.header.sequenceNumber = _seqNo++;
95     rtpInfo.header.ssrc = 0;
96     rtpInfo.header.timestamp = timeStamp;
97     rtpInfo.frameType = frameType;
98     // Size should also be received from that table, since the payload type
99     // defines the size.
100
101     _encodedBytes += payloadSize;
102     // directly to receiver
103     int ret = _VCMReceiver->IncomingPacket(payloadData, payloadSize, rtpInfo);
104     _encodeComplete = true;
105
106     return ret;
107 }
108
109 float
110 VCMEncodeCompleteCallback::EncodedBytes()
111 {
112     return _encodedBytes;
113 }
114
115 bool
116 VCMEncodeCompleteCallback::EncodeComplete()
117 {
118     if (_encodeComplete)
119     {
120         _encodeComplete = false;
121         return true;
122     }
123     return false;
124 }
125
126 void
127 VCMEncodeCompleteCallback::Initialize()
128 {
129     _encodeComplete = false;
130     _encodedBytes = 0;
131     _seqNo = 0;
132     return;
133 }
134
135 void
136 VCMEncodeCompleteCallback::ResetByteCount()
137 {
138     _encodedBytes = 0;
139 }
140
141 /***********************************/
142 /*   VCMRTPEncodeCompleteCallback  */
143 /***********************************/
144 // Encode Complete callback implementation
145 // passes the encoded frame via the RTP module to the decoder
146 // Packetization callback implementation
147
148 int32_t
149 VCMRTPEncodeCompleteCallback::SendData(
150         const FrameType frameType,
151         const uint8_t  payloadType,
152         const uint32_t timeStamp,
153         int64_t capture_time_ms,
154         const uint8_t* payloadData,
155         const uint32_t payloadSize,
156         const RTPFragmentationHeader& fragmentationHeader,
157         const RTPVideoHeader* videoHdr)
158 {
159     _frameType = frameType;
160     _encodedBytes+= payloadSize;
161     _encodeComplete = true;
162     return _RTPModule->SendOutgoingData(frameType,
163                                         payloadType,
164                                         timeStamp,
165                                         capture_time_ms,
166                                         payloadData,
167                                         payloadSize,
168                                         &fragmentationHeader,
169                                         videoHdr);
170 }
171
172 float
173 VCMRTPEncodeCompleteCallback::EncodedBytes()
174 {
175     // only good for one call  - after which will reset value;
176     float tmp = _encodedBytes;
177     _encodedBytes = 0;
178     return tmp;
179  }
180
181 bool
182 VCMRTPEncodeCompleteCallback::EncodeComplete()
183 {
184     if (_encodeComplete)
185     {
186         _encodeComplete = false;
187         return true;
188     }
189     return false;
190 }
191
192 // Decoded Frame Callback Implementation
193
194 int32_t
195 VCMDecodeCompleteCallback::FrameToRender(I420VideoFrame& videoFrame)
196 {
197   if (PrintI420VideoFrame(videoFrame, _decodedFile) < 0) {
198     return -1;
199   }
200   _decodedBytes+= CalcBufferSize(kI420, videoFrame.width(),
201                                  videoFrame.height());
202   return VCM_OK;
203  }
204
205 int32_t
206 VCMDecodeCompleteCallback::DecodedBytes()
207 {
208     return _decodedBytes;
209 }
210
211 RTPSendCompleteCallback::RTPSendCompleteCallback(Clock* clock,
212                                                  const char* filename):
213     _clock(clock),
214     _sendCount(0),
215     rtp_payload_registry_(NULL),
216     rtp_receiver_(NULL),
217     _rtp(NULL),
218     _lossPct(0),
219     _burstLength(0),
220     _networkDelayMs(0),
221     _jitterVar(0),
222     _prevLossState(0),
223     _totalSentLength(0),
224     _rtpPackets(),
225     _rtpDump(NULL)
226 {
227     if (filename != NULL)
228     {
229         _rtpDump = RtpDump::CreateRtpDump();
230         _rtpDump->Start(filename);
231     }
232 }
233
234 RTPSendCompleteCallback::~RTPSendCompleteCallback()
235 {
236     if (_rtpDump != NULL)
237     {
238         _rtpDump->Stop();
239         RtpDump::DestroyRtpDump(_rtpDump);
240     }
241     // Delete remaining packets
242     while (!_rtpPackets.empty())
243     {
244         // Take first packet in list
245         delete _rtpPackets.front();
246         _rtpPackets.pop_front();
247     }
248 }
249
250 int
251 RTPSendCompleteCallback::SendPacket(int channel, const void *data, int len)
252 {
253     _sendCount++;
254     _totalSentLength += len;
255
256     if (_rtpDump != NULL)
257     {
258         if (_rtpDump->DumpPacket((const uint8_t*)data, len) != 0)
259         {
260             return -1;
261         }
262     }
263
264     bool transmitPacket = true;
265     transmitPacket = PacketLoss();
266
267     int64_t now = _clock->TimeInMilliseconds();
268     // Insert outgoing packet into list
269     if (transmitPacket)
270     {
271         RtpPacket* newPacket = new RtpPacket();
272         memcpy(newPacket->data, data, len);
273         newPacket->length = len;
274         // Simulate receive time = network delay + packet jitter
275         // simulated as a Normal distribution random variable with
276         // mean = networkDelay and variance = jitterVar
277         int32_t
278         simulatedDelay = (int32_t)NormalDist(_networkDelayMs,
279                                                    sqrt(_jitterVar));
280         newPacket->receiveTime = now + simulatedDelay;
281         _rtpPackets.push_back(newPacket);
282     }
283
284     // Are we ready to send packets to the receiver?
285     RtpPacket* packet = NULL;
286
287     while (!_rtpPackets.empty())
288     {
289         // Take first packet in list
290         packet = _rtpPackets.front();
291         int64_t timeToReceive = packet->receiveTime - now;
292         if (timeToReceive > 0)
293         {
294             // No available packets to send
295             break;
296         }
297
298         _rtpPackets.pop_front();
299         assert(_rtp);  // We must have a configured RTP module for this test.
300         // Send to receive side
301         RTPHeader header;
302         scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
303         if (!parser->Parse(packet->data, packet->length, &header)) {
304           delete packet;
305           return -1;
306         }
307         PayloadUnion payload_specific;
308         if (!rtp_payload_registry_->GetPayloadSpecifics(
309             header.payloadType, &payload_specific)) {
310           return -1;
311         }
312         if (!rtp_receiver_->IncomingRtpPacket(header, packet->data,
313                                               packet->length, payload_specific,
314                                               true))
315         {
316             delete packet;
317             return -1;
318         }
319         delete packet;
320         packet = NULL;
321     }
322     return len; // OK
323 }
324
325 int
326 RTPSendCompleteCallback::SendRTCPPacket(int channel, const void *data, int len)
327 {
328     // Incorporate network conditions
329     return SendPacket(channel, data, len);
330 }
331
332 void
333 RTPSendCompleteCallback::SetLossPct(double lossPct)
334 {
335     _lossPct = lossPct;
336     return;
337 }
338
339 void
340 RTPSendCompleteCallback::SetBurstLength(double burstLength)
341 {
342     _burstLength = burstLength;
343     return;
344 }
345
346 bool
347 RTPSendCompleteCallback::PacketLoss()
348 {
349     bool transmitPacket = true;
350     if (_burstLength <= 1.0)
351     {
352         // Random loss: if _burstLength parameter is not set, or <=1
353         if (UnifomLoss(_lossPct))
354         {
355             // drop
356             transmitPacket = false;
357         }
358     }
359     else
360     {
361         // Simulate bursty channel (Gilbert model)
362         // (1st order) Markov chain model with memory of the previous/last
363         // packet state (loss or received)
364
365         // 0 = received state
366         // 1 = loss state
367
368         // probTrans10: if previous packet is lost, prob. to -> received state
369         // probTrans11: if previous packet is lost, prob. to -> loss state
370
371         // probTrans01: if previous packet is received, prob. to -> loss state
372         // probTrans00: if previous packet is received, prob. to -> received
373
374         // Map the two channel parameters (average loss rate and burst length)
375         // to the transition probabilities:
376         double probTrans10 = 100 * (1.0 / _burstLength);
377         double probTrans11 = (100.0 - probTrans10);
378         double probTrans01 = (probTrans10 * ( _lossPct / (100.0 - _lossPct)));
379
380         // Note: Random loss (Bernoulli) model is a special case where:
381         // burstLength = 100.0 / (100.0 - _lossPct) (i.e., p10 + p01 = 100)
382
383         if (_prevLossState == 0 )
384         {
385             // previous packet was received
386             if (UnifomLoss(probTrans01))
387             {
388                 // drop, update previous state to loss
389                 _prevLossState = 1;
390                 transmitPacket = false;
391             }
392         }
393         else if (_prevLossState == 1)
394         {
395             _prevLossState = 0;
396             // previous packet was lost
397             if (UnifomLoss(probTrans11))
398             {
399                 // drop, update previous state to loss
400                 _prevLossState = 1;
401                 transmitPacket = false;
402              }
403         }
404     }
405     return transmitPacket;
406 }
407
408
409 bool
410 RTPSendCompleteCallback::UnifomLoss(double lossPct)
411 {
412     double randVal = (rand() + 1.0) / (RAND_MAX + 1.0);
413     return randVal < lossPct/100;
414 }
415
416 int32_t
417 PacketRequester::ResendPackets(const uint16_t* sequenceNumbers,
418                                uint16_t length)
419 {
420     return _rtp.SendNACK(sequenceNumbers, length);
421 }
422
423 int32_t
424 SendStatsTest::SendStatistics(const uint32_t bitRate,
425                               const uint32_t frameRate)
426 {
427     TEST(frameRate <= _framerate);
428     TEST(bitRate > _bitrate / 2 && bitRate < 3 * _bitrate / 2);
429     printf("VCM 1 sec: Bit rate: %u\tFrame rate: %u\n", bitRate, frameRate);
430     return 0;
431 }
432
433 int32_t KeyFrameReqTest::RequestKeyFrame() {
434   printf("Key frame requested\n");
435   return 0;
436 }
437
438
439 VideoProtectionCallback::VideoProtectionCallback():
440 delta_fec_params_(),
441 key_fec_params_()
442 {
443     memset(&delta_fec_params_, 0, sizeof(delta_fec_params_));
444     memset(&key_fec_params_, 0, sizeof(key_fec_params_));
445 }
446
447 VideoProtectionCallback::~VideoProtectionCallback()
448 {
449     //
450 }
451
452 int32_t
453 VideoProtectionCallback::ProtectionRequest(
454     const FecProtectionParams* delta_fec_params,
455     const FecProtectionParams* key_fec_params,
456     uint32_t* sent_video_rate_bps,
457     uint32_t* sent_nack_rate_bps,
458     uint32_t* sent_fec_rate_bps)
459 {
460     key_fec_params_ = *key_fec_params;
461     delta_fec_params_ = *delta_fec_params;
462
463     // Update RTP
464     if (_rtp->SetFecParameters(&delta_fec_params_,
465                                &key_fec_params_) != 0)
466     {
467         printf("Error in Setting FEC rate\n");
468         return -1;
469
470     }
471     return 0;
472
473 }
474
475 FecProtectionParams VideoProtectionCallback::DeltaFecParameters() const
476 {
477     return delta_fec_params_;
478 }
479
480 FecProtectionParams VideoProtectionCallback::KeyFecParameters() const
481 {
482     return key_fec_params_;
483 }
484 }  // namespace webrtc