1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Use of this source code is governed by a BSD-style license
5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  that can be found in the LICENSE file in the root of the source
6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  tree. An additional intellectual property rights grant can be found
7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  in the file PATENTS.  All contributing project authors may
8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
112637d61b86b68c7082ae21b4cc9bc88cc36d1c13stefan@webrtc.org#include "webrtc/modules/video_coding/main/test/normal_test.h"
12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <assert.h>
14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <iostream>
15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <sstream>
16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <time.h>
17b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
182637d61b86b68c7082ae21b4cc9bc88cc36d1c13stefan@webrtc.org#include "webrtc/common_types.h"
192637d61b86b68c7082ae21b4cc9bc88cc36d1c13stefan@webrtc.org#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
202637d61b86b68c7082ae21b4cc9bc88cc36d1c13stefan@webrtc.org#include "webrtc/modules/video_coding/main/interface/video_coding.h"
212637d61b86b68c7082ae21b4cc9bc88cc36d1c13stefan@webrtc.org#include "webrtc/modules/video_coding/main/test/test_callbacks.h"
222637d61b86b68c7082ae21b4cc9bc88cc36d1c13stefan@webrtc.org#include "webrtc/modules/video_coding/main/test/test_macros.h"
232637d61b86b68c7082ae21b4cc9bc88cc36d1c13stefan@webrtc.org#include "webrtc/modules/video_coding/main/test/test_util.h"
241bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.org#include "webrtc/system_wrappers/interface/clock.h"
252637d61b86b68c7082ae21b4cc9bc88cc36d1c13stefan@webrtc.org#include "webrtc/system_wrappers/interface/trace.h"
264d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org#include "webrtc/test/testsupport/fileutils.h"
274d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org#include "webrtc/test/testsupport/metrics/video_metrics.h"
28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgusing namespace webrtc;
30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
312493070884410357ecde7245f8054968f91de7e3brykt@google.comint NormalTest::RunTest(const CmdArgs& args)
32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
332637d61b86b68c7082ae21b4cc9bc88cc36d1c13stefan@webrtc.org    SimulatedClock sim_clock(0);
341bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.org    SimulatedClock* clock = &sim_clock;
352637d61b86b68c7082ae21b4cc9bc88cc36d1c13stefan@webrtc.org    NullEventFactory event_factory;
36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    Trace::CreateTrace();
37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    Trace::SetTraceFile(
38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        (test::OutputPath() + "VCMNormalTestTrace.txt").c_str());
3906eaa5465d57f416c14bb3a587ba4146290d6a58andrew@webrtc.org    Trace::set_level_filter(webrtc::kTraceAll);
408edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org    VideoCodingModule* vcm = VideoCodingModule::Create(clock, &event_factory);
411bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.org    NormalTest VCMNTest(vcm, clock);
42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    VCMNTest.Perform(args);
43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    VideoCodingModule::Destroy(vcm);
44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    Trace::ReturnTrace();
45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org////////////////
49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Callback Implementation
50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//////////////
51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVCMNTEncodeCompleteCallback::VCMNTEncodeCompleteCallback(FILE* encodedFile,
53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                         NormalTest& test):
54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _encodedFile(encodedFile),
55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _encodedBytes(0),
56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _skipCnt(0),
57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _VCMReceiver(NULL),
58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _seqNo(0),
59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _test(test)
60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //
62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVCMNTEncodeCompleteCallback::~VCMNTEncodeCompleteCallback()
64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
672493070884410357ecde7245f8054968f91de7e3brykt@google.comvoid VCMNTEncodeCompleteCallback::RegisterTransportCallback(
682493070884410357ecde7245f8054968f91de7e3brykt@google.com    VCMPacketizationCallback* transport)
69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
72dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.orgint32_t
73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVCMNTEncodeCompleteCallback::SendData(
74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        const FrameType frameType,
75dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org        const uint8_t  payloadType,
76dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org        const uint32_t timeStamp,
77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        int64_t capture_time_ms,
78dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org        const uint8_t* payloadData,
79dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org        const uint32_t payloadSize,
80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        const RTPFragmentationHeader& /*fragmentationHeader*/,
81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        const webrtc::RTPVideoHeader* videoHdr)
82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
842493070884410357ecde7245f8054968f91de7e3brykt@google.com  // will call the VCMReceiver input packet
852493070884410357ecde7245f8054968f91de7e3brykt@google.com  _frameType = frameType;
862493070884410357ecde7245f8054968f91de7e3brykt@google.com  // writing encodedData into file
872493070884410357ecde7245f8054968f91de7e3brykt@google.com  if (fwrite(payloadData, 1, payloadSize, _encodedFile) !=  payloadSize) {
882493070884410357ecde7245f8054968f91de7e3brykt@google.com    return -1;
892493070884410357ecde7245f8054968f91de7e3brykt@google.com  }
902493070884410357ecde7245f8054968f91de7e3brykt@google.com  WebRtcRTPHeader rtpInfo;
912493070884410357ecde7245f8054968f91de7e3brykt@google.com  rtpInfo.header.markerBit = true;
922493070884410357ecde7245f8054968f91de7e3brykt@google.com  rtpInfo.type.Video.width = 0;
932493070884410357ecde7245f8054968f91de7e3brykt@google.com  rtpInfo.type.Video.height = 0;
942493070884410357ecde7245f8054968f91de7e3brykt@google.com  switch (_test.VideoType())
952493070884410357ecde7245f8054968f91de7e3brykt@google.com  {
962493070884410357ecde7245f8054968f91de7e3brykt@google.com  case kVideoCodecVP8:
977fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org    rtpInfo.type.Video.codec = kRtpVideoVp8;
982493070884410357ecde7245f8054968f91de7e3brykt@google.com    rtpInfo.type.Video.codecHeader.VP8.InitRTPVideoHeaderVP8();
992493070884410357ecde7245f8054968f91de7e3brykt@google.com    rtpInfo.type.Video.codecHeader.VP8.nonReference =
1002493070884410357ecde7245f8054968f91de7e3brykt@google.com        videoHdr->codecHeader.VP8.nonReference;
1012493070884410357ecde7245f8054968f91de7e3brykt@google.com    rtpInfo.type.Video.codecHeader.VP8.pictureId =
1022493070884410357ecde7245f8054968f91de7e3brykt@google.com        videoHdr->codecHeader.VP8.pictureId;
1032493070884410357ecde7245f8054968f91de7e3brykt@google.com    break;
1042493070884410357ecde7245f8054968f91de7e3brykt@google.com  default:
1052493070884410357ecde7245f8054968f91de7e3brykt@google.com    assert(false);
1062493070884410357ecde7245f8054968f91de7e3brykt@google.com    return -1;
1072493070884410357ecde7245f8054968f91de7e3brykt@google.com  }
1082493070884410357ecde7245f8054968f91de7e3brykt@google.com  rtpInfo.header.payloadType = payloadType;
1092493070884410357ecde7245f8054968f91de7e3brykt@google.com  rtpInfo.header.sequenceNumber = _seqNo++;
1102493070884410357ecde7245f8054968f91de7e3brykt@google.com  rtpInfo.header.ssrc = 0;
1112493070884410357ecde7245f8054968f91de7e3brykt@google.com  rtpInfo.header.timestamp = timeStamp;
1122493070884410357ecde7245f8054968f91de7e3brykt@google.com  rtpInfo.frameType = frameType;
1132493070884410357ecde7245f8054968f91de7e3brykt@google.com  rtpInfo.type.Video.isFirstPacket = true;
1142493070884410357ecde7245f8054968f91de7e3brykt@google.com  // Size should also be received from that table, since the payload type
1152493070884410357ecde7245f8054968f91de7e3brykt@google.com  // defines the size.
116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1172493070884410357ecde7245f8054968f91de7e3brykt@google.com  _encodedBytes += payloadSize;
1182493070884410357ecde7245f8054968f91de7e3brykt@google.com  if (payloadSize < 20)
1192493070884410357ecde7245f8054968f91de7e3brykt@google.com  {
1202493070884410357ecde7245f8054968f91de7e3brykt@google.com      _skipCnt++;
1212493070884410357ecde7245f8054968f91de7e3brykt@google.com  }
1222493070884410357ecde7245f8054968f91de7e3brykt@google.com  _VCMReceiver->IncomingPacket(payloadData, payloadSize, rtpInfo);
1232493070884410357ecde7245f8054968f91de7e3brykt@google.com  return 0;
124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid
126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVCMNTEncodeCompleteCallback::RegisterReceiverVCM(VideoCodingModule *vcm)
127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
1282493070884410357ecde7245f8054968f91de7e3brykt@google.com  _VCMReceiver = vcm;
1292493070884410357ecde7245f8054968f91de7e3brykt@google.com  return;
130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
131dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org int32_t
132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVCMNTEncodeCompleteCallback::EncodedBytes()
133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
1342493070884410357ecde7245f8054968f91de7e3brykt@google.com  return _encodedBytes;
135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
137dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.orguint32_t
138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVCMNTEncodeCompleteCallback::SkipCnt()
139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
1402493070884410357ecde7245f8054968f91de7e3brykt@google.com  return _skipCnt;
141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Decoded Frame Callback Implementation
144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVCMNTDecodeCompleCallback::~VCMNTDecodeCompleCallback()
145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (_decodedFile)
1472493070884410357ecde7245f8054968f91de7e3brykt@google.com  fclose(_decodedFile);
148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
149dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org int32_t
1503bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.orgVCMNTDecodeCompleCallback::FrameToRender(webrtc::I420VideoFrame& videoFrame)
151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
1523bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    if (videoFrame.width() != _currentWidth ||
1533bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org        videoFrame.height() != _currentHeight)
154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
1553bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org        _currentWidth = videoFrame.width();
1563bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org        _currentHeight = videoFrame.height();
157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (_decodedFile != NULL)
158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            fclose(_decodedFile);
160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            _decodedFile = NULL;
161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _decodedFile = fopen(_outname.c_str(), "wb");
163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1643bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    if (PrintI420VideoFrame(videoFrame, _decodedFile) < 0) {
165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return -1;
166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1673bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    _decodedBytes+= webrtc::CalcBufferSize(webrtc::kI420,
1683bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                                   videoFrame.width(), videoFrame.height());
169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return VCM_OK;
170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
172dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org int32_t
173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVCMNTDecodeCompleCallback::DecodedBytes()
174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
1752493070884410357ecde7245f8054968f91de7e3brykt@google.com  return _decodedBytes;
176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org //VCM Normal Test Class implementation
179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1801bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.orgNormalTest::NormalTest(VideoCodingModule* vcm, Clock* clock)
181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org:
182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_clock(clock),
183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_vcm(vcm),
184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_sumEncBytes(0),
185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_timeStamp(0),
186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_totalEncodeTime(0),
187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_totalDecodeTime(0),
188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_decodeCompleteTime(0),
189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_encodeCompleteTime(0),
190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_totalEncodePipeTime(0),
191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_totalDecodePipeTime(0),
192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_frameCnt(0),
193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_encFrameCnt(0),
194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_decFrameCnt(0)
195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //
197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgNormalTest::~NormalTest()
200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //
202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid
2042493070884410357ecde7245f8054968f91de7e3brykt@google.comNormalTest::Setup(const CmdArgs& args)
205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
2062493070884410357ecde7245f8054968f91de7e3brykt@google.com  _inname = args.inputFile;
2072493070884410357ecde7245f8054968f91de7e3brykt@google.com  _encodedName = test::OutputPath() + "encoded_normaltest.yuv";
2082493070884410357ecde7245f8054968f91de7e3brykt@google.com  _width = args.width;
2092493070884410357ecde7245f8054968f91de7e3brykt@google.com  _height = args.height;
2102493070884410357ecde7245f8054968f91de7e3brykt@google.com  _frameRate = args.frameRate;
2112493070884410357ecde7245f8054968f91de7e3brykt@google.com  _bitRate = args.bitRate;
2122493070884410357ecde7245f8054968f91de7e3brykt@google.com  if (args.outputFile == "")
2132493070884410357ecde7245f8054968f91de7e3brykt@google.com  {
2142493070884410357ecde7245f8054968f91de7e3brykt@google.com      std::ostringstream filename;
2152493070884410357ecde7245f8054968f91de7e3brykt@google.com      filename << test::OutputPath() << "NormalTest_" <<
2162493070884410357ecde7245f8054968f91de7e3brykt@google.com          _width << "x" << _height << "_" << _frameRate << "Hz_P420.yuv";
2172493070884410357ecde7245f8054968f91de7e3brykt@google.com      _outname = filename.str();
2182493070884410357ecde7245f8054968f91de7e3brykt@google.com  }
2192493070884410357ecde7245f8054968f91de7e3brykt@google.com  else
2202493070884410357ecde7245f8054968f91de7e3brykt@google.com  {
2212493070884410357ecde7245f8054968f91de7e3brykt@google.com      _outname = args.outputFile;
2222493070884410357ecde7245f8054968f91de7e3brykt@google.com  }
2232493070884410357ecde7245f8054968f91de7e3brykt@google.com  _lengthSourceFrame  = 3*_width*_height/2;
2242493070884410357ecde7245f8054968f91de7e3brykt@google.com  _videoType = args.codecType;
225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
2262493070884410357ecde7245f8054968f91de7e3brykt@google.com  if ((_sourceFile = fopen(_inname.c_str(), "rb")) == NULL)
2272493070884410357ecde7245f8054968f91de7e3brykt@google.com  {
2282493070884410357ecde7245f8054968f91de7e3brykt@google.com      printf("Cannot read file %s.\n", _inname.c_str());
2292493070884410357ecde7245f8054968f91de7e3brykt@google.com      exit(1);
2302493070884410357ecde7245f8054968f91de7e3brykt@google.com  }
2312493070884410357ecde7245f8054968f91de7e3brykt@google.com  if ((_encodedFile = fopen(_encodedName.c_str(), "wb")) == NULL)
2322493070884410357ecde7245f8054968f91de7e3brykt@google.com  {
2332493070884410357ecde7245f8054968f91de7e3brykt@google.com      printf("Cannot write encoded file.\n");
2342493070884410357ecde7245f8054968f91de7e3brykt@google.com      exit(1);
2352493070884410357ecde7245f8054968f91de7e3brykt@google.com  }
236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
2372493070884410357ecde7245f8054968f91de7e3brykt@google.com  _log.open((test::OutputPath() + "TestLog.txt").c_str(),
2382493070884410357ecde7245f8054968f91de7e3brykt@google.com            std::fstream::out | std::fstream::app);
239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
241dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.orgint32_t
2422493070884410357ecde7245f8054968f91de7e3brykt@google.comNormalTest::Perform(const CmdArgs& args)
243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
2442493070884410357ecde7245f8054968f91de7e3brykt@google.com  Setup(args);
2452493070884410357ecde7245f8054968f91de7e3brykt@google.com  EventWrapper* waitEvent = EventWrapper::Create();
2462493070884410357ecde7245f8054968f91de7e3brykt@google.com  VideoCodec _sendCodec;
2472493070884410357ecde7245f8054968f91de7e3brykt@google.com  _vcm->InitializeReceiver();
2482493070884410357ecde7245f8054968f91de7e3brykt@google.com  _vcm->InitializeSender();
2492493070884410357ecde7245f8054968f91de7e3brykt@google.com  TEST(VideoCodingModule::Codec(_videoType, &_sendCodec) == VCM_OK);
2502493070884410357ecde7245f8054968f91de7e3brykt@google.com  // should be later on changed via the API
2512493070884410357ecde7245f8054968f91de7e3brykt@google.com  _sendCodec.startBitrate = (int)_bitRate;
252dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org  _sendCodec.width = static_cast<uint16_t>(_width);
253dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org  _sendCodec.height = static_cast<uint16_t>(_height);
2542493070884410357ecde7245f8054968f91de7e3brykt@google.com  _sendCodec.maxFramerate = _frameRate;
2552493070884410357ecde7245f8054968f91de7e3brykt@google.com  // will also set and init the desired codec
2562493070884410357ecde7245f8054968f91de7e3brykt@google.com  TEST(_vcm->RegisterSendCodec(&_sendCodec, 4, 1400) == VCM_OK);
2572493070884410357ecde7245f8054968f91de7e3brykt@google.com  // register a decoder (same codec for decoder and encoder )
2582493070884410357ecde7245f8054968f91de7e3brykt@google.com  TEST(_vcm->RegisterReceiveCodec(&_sendCodec, 1) == VCM_OK);
2592493070884410357ecde7245f8054968f91de7e3brykt@google.com  /* Callback Settings */
2602493070884410357ecde7245f8054968f91de7e3brykt@google.com  VCMNTDecodeCompleCallback _decodeCallback(_outname);
2612493070884410357ecde7245f8054968f91de7e3brykt@google.com  _vcm->RegisterReceiveCallback(&_decodeCallback);
2622493070884410357ecde7245f8054968f91de7e3brykt@google.com  VCMNTEncodeCompleteCallback _encodeCompleteCallback(_encodedFile, *this);
2632493070884410357ecde7245f8054968f91de7e3brykt@google.com  _vcm->RegisterTransportCallback(&_encodeCompleteCallback);
2642493070884410357ecde7245f8054968f91de7e3brykt@google.com  // encode and decode with the same vcm
2652493070884410357ecde7245f8054968f91de7e3brykt@google.com  _encodeCompleteCallback.RegisterReceiverVCM(_vcm);
2662493070884410357ecde7245f8054968f91de7e3brykt@google.com  ///////////////////////
2672493070884410357ecde7245f8054968f91de7e3brykt@google.com  /// Start Test
2682493070884410357ecde7245f8054968f91de7e3brykt@google.com  ///////////////////////
2692493070884410357ecde7245f8054968f91de7e3brykt@google.com  I420VideoFrame sourceFrame;
2702493070884410357ecde7245f8054968f91de7e3brykt@google.com  int size_y = _width * _height;
2712493070884410357ecde7245f8054968f91de7e3brykt@google.com  int half_width = (_width + 1) / 2;
2722493070884410357ecde7245f8054968f91de7e3brykt@google.com  int half_height = (_height + 1) / 2;
2732493070884410357ecde7245f8054968f91de7e3brykt@google.com  int size_uv = half_width * half_height;
2742493070884410357ecde7245f8054968f91de7e3brykt@google.com  sourceFrame.CreateEmptyFrame(_width, _height,
2752493070884410357ecde7245f8054968f91de7e3brykt@google.com                               _width, half_width, half_width);
276dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org  uint8_t* tmpBuffer = new uint8_t[_lengthSourceFrame];
2772493070884410357ecde7245f8054968f91de7e3brykt@google.com  double startTime = clock()/(double)CLOCKS_PER_SEC;
27872e204a700e985c1f0c65f7a566fe9aaf7713e64stefan@webrtc.org  _vcm->SetChannelParameters(static_cast<uint32_t>(1000 * _bitRate), 0, 0);
279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
2802493070884410357ecde7245f8054968f91de7e3brykt@google.com  SendStatsTest sendStats;
281dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org  sendStats.set_framerate(static_cast<uint32_t>(_frameRate));
28263136921ece04448f1bc71ce6f3e43974f9d385astefan@webrtc.org  sendStats.set_bitrate(1000 * _bitRate);
2832493070884410357ecde7245f8054968f91de7e3brykt@google.com  _vcm->RegisterSendStatisticsCallback(&sendStats);
284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
2852493070884410357ecde7245f8054968f91de7e3brykt@google.com  while (feof(_sourceFile) == 0) {
2862493070884410357ecde7245f8054968f91de7e3brykt@google.com    TEST(fread(tmpBuffer, 1, _lengthSourceFrame, _sourceFile) > 0 ||
2872493070884410357ecde7245f8054968f91de7e3brykt@google.com         feof(_sourceFile));
2882493070884410357ecde7245f8054968f91de7e3brykt@google.com    _frameCnt++;
2892493070884410357ecde7245f8054968f91de7e3brykt@google.com    sourceFrame.CreateFrame(size_y, tmpBuffer,
2902493070884410357ecde7245f8054968f91de7e3brykt@google.com                            size_uv, tmpBuffer + size_y,
2912493070884410357ecde7245f8054968f91de7e3brykt@google.com                            size_uv, tmpBuffer + size_y + size_uv,
2922493070884410357ecde7245f8054968f91de7e3brykt@google.com                            _width, _height,
2932493070884410357ecde7245f8054968f91de7e3brykt@google.com                            _width, half_width, half_width);
2942493070884410357ecde7245f8054968f91de7e3brykt@google.com    _timeStamp +=
295dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org        (uint32_t)(9e4 / static_cast<float>(_sendCodec.maxFramerate));
2962493070884410357ecde7245f8054968f91de7e3brykt@google.com    sourceFrame.set_timestamp(_timeStamp);
2972493070884410357ecde7245f8054968f91de7e3brykt@google.com    _encodeTimes[int(sourceFrame.timestamp())] =
2982493070884410357ecde7245f8054968f91de7e3brykt@google.com        clock()/(double)CLOCKS_PER_SEC;
299dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org    int32_t ret = _vcm->AddVideoFrame(sourceFrame);
3002493070884410357ecde7245f8054968f91de7e3brykt@google.com    double encodeTime = clock()/(double)CLOCKS_PER_SEC -
3012493070884410357ecde7245f8054968f91de7e3brykt@google.com                        _encodeTimes[int(sourceFrame.timestamp())];
3022493070884410357ecde7245f8054968f91de7e3brykt@google.com    _totalEncodeTime += encodeTime;
3032493070884410357ecde7245f8054968f91de7e3brykt@google.com    if (ret < 0)
3042493070884410357ecde7245f8054968f91de7e3brykt@google.com    {
3052493070884410357ecde7245f8054968f91de7e3brykt@google.com        printf("Error in AddFrame: %d\n", ret);
3062493070884410357ecde7245f8054968f91de7e3brykt@google.com        //exit(1);
3072493070884410357ecde7245f8054968f91de7e3brykt@google.com    }
3082493070884410357ecde7245f8054968f91de7e3brykt@google.com    _decodeTimes[int(sourceFrame.timestamp())] =
3092493070884410357ecde7245f8054968f91de7e3brykt@google.com        clock()/(double)CLOCKS_PER_SEC;
3102493070884410357ecde7245f8054968f91de7e3brykt@google.com    ret = _vcm->Decode();
3112493070884410357ecde7245f8054968f91de7e3brykt@google.com    _totalDecodeTime += clock()/(double)CLOCKS_PER_SEC -
3122493070884410357ecde7245f8054968f91de7e3brykt@google.com                        _decodeTimes[int(sourceFrame.timestamp())];
3132493070884410357ecde7245f8054968f91de7e3brykt@google.com    if (ret < 0)
3142493070884410357ecde7245f8054968f91de7e3brykt@google.com    {
3152493070884410357ecde7245f8054968f91de7e3brykt@google.com        printf("Error in Decode: %d\n", ret);
3162493070884410357ecde7245f8054968f91de7e3brykt@google.com        //exit(1);
3172493070884410357ecde7245f8054968f91de7e3brykt@google.com    }
3182493070884410357ecde7245f8054968f91de7e3brykt@google.com    if (_vcm->TimeUntilNextProcess() <= 0)
3192493070884410357ecde7245f8054968f91de7e3brykt@google.com    {
3202493070884410357ecde7245f8054968f91de7e3brykt@google.com        _vcm->Process();
3212493070884410357ecde7245f8054968f91de7e3brykt@google.com    }
322dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org    uint32_t framePeriod =
323dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org        static_cast<uint32_t>(
3242493070884410357ecde7245f8054968f91de7e3brykt@google.com            1000.0f / static_cast<float>(_sendCodec.maxFramerate) + 0.5f);
3251bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.org    static_cast<SimulatedClock*>(_clock)->AdvanceTimeMilliseconds(framePeriod);
3262493070884410357ecde7245f8054968f91de7e3brykt@google.com  }
3272493070884410357ecde7245f8054968f91de7e3brykt@google.com  double endTime = clock()/(double)CLOCKS_PER_SEC;
3282493070884410357ecde7245f8054968f91de7e3brykt@google.com  _testTotalTime = endTime - startTime;
3292493070884410357ecde7245f8054968f91de7e3brykt@google.com  _sumEncBytes = _encodeCompleteCallback.EncodedBytes();
330b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
3312493070884410357ecde7245f8054968f91de7e3brykt@google.com  delete [] tmpBuffer;
3322493070884410357ecde7245f8054968f91de7e3brykt@google.com  delete waitEvent;
3332493070884410357ecde7245f8054968f91de7e3brykt@google.com  Teardown();
3342493070884410357ecde7245f8054968f91de7e3brykt@google.com  Print();
3352493070884410357ecde7245f8054968f91de7e3brykt@google.com  return 0;
336b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
337b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
338b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid
339dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.orgNormalTest::FrameEncoded(uint32_t timeStamp)
340b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
3412493070884410357ecde7245f8054968f91de7e3brykt@google.com  _encodeCompleteTime = clock()/(double)CLOCKS_PER_SEC;
3422493070884410357ecde7245f8054968f91de7e3brykt@google.com  _encFrameCnt++;
3432493070884410357ecde7245f8054968f91de7e3brykt@google.com  _totalEncodePipeTime += _encodeCompleteTime - _encodeTimes[int(timeStamp)];
344b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
345b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
346b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
347b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid
348dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.orgNormalTest::FrameDecoded(uint32_t timeStamp)
349b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
3502493070884410357ecde7245f8054968f91de7e3brykt@google.com  _decodeCompleteTime = clock()/(double)CLOCKS_PER_SEC;
3512493070884410357ecde7245f8054968f91de7e3brykt@google.com  _decFrameCnt++;
3522493070884410357ecde7245f8054968f91de7e3brykt@google.com  _totalDecodePipeTime += _decodeCompleteTime - _decodeTimes[timeStamp];
353b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
354b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid
356b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgNormalTest::Print()
357b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
3582493070884410357ecde7245f8054968f91de7e3brykt@google.com  std::cout << "Normal Test Completed!" << std::endl;
3592493070884410357ecde7245f8054968f91de7e3brykt@google.com  (_log) << "Normal Test Completed!" << std::endl;
3602493070884410357ecde7245f8054968f91de7e3brykt@google.com  (_log) << "Input file: " << _inname << std::endl;
3612493070884410357ecde7245f8054968f91de7e3brykt@google.com  (_log) << "Output file: " << _outname << std::endl;
3622493070884410357ecde7245f8054968f91de7e3brykt@google.com  (_log) << "Total run time: " << _testTotalTime << std::endl;
3632493070884410357ecde7245f8054968f91de7e3brykt@google.com  printf("Total run time: %f s \n", _testTotalTime);
3642493070884410357ecde7245f8054968f91de7e3brykt@google.com  double ActualBitRate =  8.0 *( _sumEncBytes / (_frameCnt / _frameRate));
3652493070884410357ecde7245f8054968f91de7e3brykt@google.com  double actualBitRate = ActualBitRate / 1000.0;
3662493070884410357ecde7245f8054968f91de7e3brykt@google.com  double avgEncTime = _totalEncodeTime / _frameCnt;
3672493070884410357ecde7245f8054968f91de7e3brykt@google.com  double avgDecTime = _totalDecodeTime / _frameCnt;
3682493070884410357ecde7245f8054968f91de7e3brykt@google.com  webrtc::test::QualityMetricsResult psnr, ssim;
3692493070884410357ecde7245f8054968f91de7e3brykt@google.com  I420PSNRFromFiles(_inname.c_str(), _outname.c_str(), _width, _height,
3702493070884410357ecde7245f8054968f91de7e3brykt@google.com                    &psnr);
3712493070884410357ecde7245f8054968f91de7e3brykt@google.com  I420SSIMFromFiles(_inname.c_str(), _outname.c_str(), _width, _height,
3722493070884410357ecde7245f8054968f91de7e3brykt@google.com                    &ssim);
3732493070884410357ecde7245f8054968f91de7e3brykt@google.com  printf("Actual bitrate: %f kbps\n", actualBitRate);
3742493070884410357ecde7245f8054968f91de7e3brykt@google.com  printf("Target bitrate: %f kbps\n", _bitRate);
3752493070884410357ecde7245f8054968f91de7e3brykt@google.com  ( _log) << "Actual bitrate: " << actualBitRate <<
3762493070884410357ecde7245f8054968f91de7e3brykt@google.com      " kbps\tTarget: " << _bitRate << " kbps" << std::endl;
3772493070884410357ecde7245f8054968f91de7e3brykt@google.com  printf("Average encode time: %f s\n", avgEncTime);
3782493070884410357ecde7245f8054968f91de7e3brykt@google.com  ( _log) << "Average encode time: " << avgEncTime << " s" << std::endl;
3792493070884410357ecde7245f8054968f91de7e3brykt@google.com  printf("Average decode time: %f s\n", avgDecTime);
3802493070884410357ecde7245f8054968f91de7e3brykt@google.com  ( _log) << "Average decode time: " << avgDecTime << " s" << std::endl;
3812493070884410357ecde7245f8054968f91de7e3brykt@google.com  printf("PSNR: %f \n", psnr.average);
3822493070884410357ecde7245f8054968f91de7e3brykt@google.com  ( _log) << "PSNR: " << psnr.average << std::endl;
3832493070884410357ecde7245f8054968f91de7e3brykt@google.com  printf("SSIM: %f \n", ssim.average);
3842493070884410357ecde7245f8054968f91de7e3brykt@google.com  ( _log) << "SSIM: " << ssim.average << std::endl;
3852493070884410357ecde7245f8054968f91de7e3brykt@google.com  (_log) << std::endl;
386b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
3872493070884410357ecde7245f8054968f91de7e3brykt@google.com  printf("\nVCM Normal Test: \n\n%i tests completed\n", vcmMacrosTests);
3882493070884410357ecde7245f8054968f91de7e3brykt@google.com  if (vcmMacrosErrors > 0)
3892493070884410357ecde7245f8054968f91de7e3brykt@google.com  {
3902493070884410357ecde7245f8054968f91de7e3brykt@google.com      printf("%i FAILED\n\n", vcmMacrosErrors);
3912493070884410357ecde7245f8054968f91de7e3brykt@google.com  }
3922493070884410357ecde7245f8054968f91de7e3brykt@google.com  else
3932493070884410357ecde7245f8054968f91de7e3brykt@google.com  {
3942493070884410357ecde7245f8054968f91de7e3brykt@google.com      printf("ALL PASSED\n\n");
3952493070884410357ecde7245f8054968f91de7e3brykt@google.com  }
396b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
397b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid
398b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgNormalTest::Teardown()
399b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
4002493070884410357ecde7245f8054968f91de7e3brykt@google.com  //_log.close();
4012493070884410357ecde7245f8054968f91de7e3brykt@google.com  fclose(_sourceFile);
4022493070884410357ecde7245f8054968f91de7e3brykt@google.com  fclose(_encodedFile);
4032493070884410357ecde7245f8054968f91de7e3brykt@google.com  return;
404b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
405