1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Copyright (c) 2011 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
114d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org#include "webrtc/modules/video_coding/main/test/test_util.h"
124d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org
133f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org#include <assert.h>
143f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org#include <math.h>
153f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org
164d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org#include <iomanip>
174d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org#include <sstream>
184d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org
194d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
204d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org#include "webrtc/modules/video_coding/main/source/internal_defines.h"
214d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org#include "webrtc/test/testsupport/fileutils.h"
22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
234d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.orgCmdArgs::CmdArgs()
244d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    : codecName("VP8"),
254d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      codecType(webrtc::kVideoCodecVP8),
264d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      width(352),
274d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      height(288),
284d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      bitRate(500),
294d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      frameRate(30),
304d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      packetLoss(0),
314d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      rtt(0),
324d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      protectionMode(0),
334d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      camaEnable(0),
344d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      inputFile(webrtc::test::ProjectRootPath() + "/resources/foreman_cif.yuv"),
354d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      outputFile(webrtc::test::OutputPath() +
364d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org          "video_coding_test_output_352x288.yuv"),
374d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      fv_outputfile(webrtc::test::OutputPath() + "features.txt"),
384d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      testNum(0) {
394d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org}
40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Normal Distribution
42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#define PI  3.14159265
434d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.orgdouble NormalDist(double mean, double stdDev)
44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Creating a Normal distribution variable from two independent uniform
46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // variables based on the Box-Muller transform
474d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    double uniform1 = (rand() + 1.0) / (RAND_MAX + 1.0);
484d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    double uniform2 = (rand() + 1.0) / (RAND_MAX + 1.0);
49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return (mean + stdDev * sqrt(-2 * log(uniform1)) * cos(2 * PI * uniform2));
50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
524d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.orgnamespace {
534d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org
544d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.orgvoid SplitFilename(const std::string& filename, std::string* basename,
554d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org                   std::string* extension) {
564d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  assert(basename);
574d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  assert(extension);
584d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org
594d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  std::string::size_type idx;
604d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  idx = filename.rfind('.');
614d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org
624d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  if(idx != std::string::npos) {
634d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    *basename = filename.substr(0, idx);
644d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    *extension = filename.substr(idx + 1);
654d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  } else {
664d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    *basename = filename;
674d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    *extension = "";
684d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  }
694d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org}
704d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org
714d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.orgstd::string AppendWidthHeightCount(const std::string& filename, int width,
724d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org                                   int height, int count) {
734d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  std::string basename;
744d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  std::string extension;
754d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  SplitFilename(filename, &basename, &extension);
764d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  std::stringstream ss;
774d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  ss << basename << "_" << count << "." <<  width << "_" << height << "." <<
784d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      extension;
794d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  return ss.str();
804d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org}
814d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org
824d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org}  // namespace
834d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org
844d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.orgFileOutputFrameReceiver::FileOutputFrameReceiver(
854d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    const std::string& base_out_filename, uint32_t ssrc)
864d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    : out_filename_(),
874d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      out_file_(NULL),
884d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      timing_file_(NULL),
894d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      width_(0),
904d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      height_(0),
914d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      count_(0) {
924d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  std::string basename;
934d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  std::string extension;
944d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  if (base_out_filename == "") {
954d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    basename = webrtc::test::OutputPath() + "rtp_decoded";
964d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    extension = "yuv";
974d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  } else {
984d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    SplitFilename(base_out_filename, &basename, &extension);
994d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  }
1004d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  std::stringstream ss;
1014d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  ss << basename << "_" << std::hex << std::setw(8) << std::setfill('0') <<
1024d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      ssrc << "." << extension;
1034d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  out_filename_ = ss.str();
1044d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org}
1054d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org
1064d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.orgFileOutputFrameReceiver::~FileOutputFrameReceiver() {
1074d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  if (timing_file_ != NULL) {
1084d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    fclose(timing_file_);
1094d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  }
1104d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  if (out_file_ != NULL) {
1114d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    fclose(out_file_);
1124d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  }
1134d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org}
1144d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org
11552b2ee5489898b667e38dbee2d40202597f1fc0cpbos@webrtc.orgint32_t FileOutputFrameReceiver::FrameToRender(
1164d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    webrtc::I420VideoFrame& video_frame) {
1174d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  if (timing_file_ == NULL) {
1184d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    std::string basename;
1194d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    std::string extension;
1204d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    SplitFilename(out_filename_, &basename, &extension);
1214d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    timing_file_ = fopen((basename + "_renderTiming.txt").c_str(), "w");
1224d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    if (timing_file_ == NULL) {
1234d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      return -1;
124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1254d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  }
1264d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  if (out_file_ == NULL || video_frame.width() != width_ ||
1274d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      video_frame.height() != height_) {
1284d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    if (out_file_) {
1294d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      fclose(out_file_);
130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1314d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    printf("New size: %dx%d\n", video_frame.width(), video_frame.height());
1324d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    width_ = video_frame.width();
1334d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    height_ = video_frame.height();
1344d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    std::string filename_with_width_height = AppendWidthHeightCount(
1354d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org        out_filename_, width_, height_, count_);
1364d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    ++count_;
1374d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    out_file_ = fopen(filename_with_width_height.c_str(), "wb");
1384d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    if (out_file_ == NULL) {
1394d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      return -1;
140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1414d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  }
1424d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  fprintf(timing_file_, "%u, %u\n", video_frame.timestamp(),
1434d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      webrtc::MaskWord64ToUWord32(video_frame.render_time_ms()));
1444d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  if (PrintI420VideoFrame(video_frame, out_file_) < 0) {
1454d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    return -1;
1464d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  }
1474d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  return 0;
148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1507fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.orgwebrtc::RtpVideoCodecTypes ConvertCodecType(const char* plname) {
1514d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  if (strncmp(plname,"VP8" , 3) == 0) {
1527fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org    return webrtc::kRtpVideoVp8;
1534d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  } else {
1547fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org    return webrtc::kRtpVideoNone;  // Default value
1554d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  }
1564d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org}
157