1/*
2 *  Copyright (c) 2011 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_util.h"
12
13#include <assert.h>
14#include <math.h>
15
16#include <iomanip>
17#include <sstream>
18
19#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
20#include "webrtc/modules/video_coding/main/source/internal_defines.h"
21#include "webrtc/test/testsupport/fileutils.h"
22
23CmdArgs::CmdArgs()
24    : codecName("VP8"),
25      codecType(webrtc::kVideoCodecVP8),
26      width(352),
27      height(288),
28      bitRate(500),
29      frameRate(30),
30      packetLoss(0),
31      rtt(0),
32      protectionMode(0),
33      camaEnable(0),
34      inputFile(webrtc::test::ProjectRootPath() + "/resources/foreman_cif.yuv"),
35      outputFile(webrtc::test::OutputPath() +
36          "video_coding_test_output_352x288.yuv"),
37      fv_outputfile(webrtc::test::OutputPath() + "features.txt"),
38      testNum(0) {
39}
40
41// Normal Distribution
42#define PI  3.14159265
43double NormalDist(double mean, double stdDev)
44{
45    // Creating a Normal distribution variable from two independent uniform
46    // variables based on the Box-Muller transform
47    double uniform1 = (rand() + 1.0) / (RAND_MAX + 1.0);
48    double uniform2 = (rand() + 1.0) / (RAND_MAX + 1.0);
49    return (mean + stdDev * sqrt(-2 * log(uniform1)) * cos(2 * PI * uniform2));
50}
51
52namespace {
53
54void SplitFilename(const std::string& filename, std::string* basename,
55                   std::string* extension) {
56  assert(basename);
57  assert(extension);
58
59  std::string::size_type idx;
60  idx = filename.rfind('.');
61
62  if(idx != std::string::npos) {
63    *basename = filename.substr(0, idx);
64    *extension = filename.substr(idx + 1);
65  } else {
66    *basename = filename;
67    *extension = "";
68  }
69}
70
71std::string AppendWidthHeightCount(const std::string& filename, int width,
72                                   int height, int count) {
73  std::string basename;
74  std::string extension;
75  SplitFilename(filename, &basename, &extension);
76  std::stringstream ss;
77  ss << basename << "_" << count << "." <<  width << "_" << height << "." <<
78      extension;
79  return ss.str();
80}
81
82}  // namespace
83
84FileOutputFrameReceiver::FileOutputFrameReceiver(
85    const std::string& base_out_filename, uint32_t ssrc)
86    : out_filename_(),
87      out_file_(NULL),
88      timing_file_(NULL),
89      width_(0),
90      height_(0),
91      count_(0) {
92  std::string basename;
93  std::string extension;
94  if (base_out_filename == "") {
95    basename = webrtc::test::OutputPath() + "rtp_decoded";
96    extension = "yuv";
97  } else {
98    SplitFilename(base_out_filename, &basename, &extension);
99  }
100  std::stringstream ss;
101  ss << basename << "_" << std::hex << std::setw(8) << std::setfill('0') <<
102      ssrc << "." << extension;
103  out_filename_ = ss.str();
104}
105
106FileOutputFrameReceiver::~FileOutputFrameReceiver() {
107  if (timing_file_ != NULL) {
108    fclose(timing_file_);
109  }
110  if (out_file_ != NULL) {
111    fclose(out_file_);
112  }
113}
114
115int32_t FileOutputFrameReceiver::FrameToRender(
116    webrtc::I420VideoFrame& video_frame) {
117  if (timing_file_ == NULL) {
118    std::string basename;
119    std::string extension;
120    SplitFilename(out_filename_, &basename, &extension);
121    timing_file_ = fopen((basename + "_renderTiming.txt").c_str(), "w");
122    if (timing_file_ == NULL) {
123      return -1;
124    }
125  }
126  if (out_file_ == NULL || video_frame.width() != width_ ||
127      video_frame.height() != height_) {
128    if (out_file_) {
129      fclose(out_file_);
130    }
131    printf("New size: %dx%d\n", video_frame.width(), video_frame.height());
132    width_ = video_frame.width();
133    height_ = video_frame.height();
134    std::string filename_with_width_height = AppendWidthHeightCount(
135        out_filename_, width_, height_, count_);
136    ++count_;
137    out_file_ = fopen(filename_with_width_height.c_str(), "wb");
138    if (out_file_ == NULL) {
139      return -1;
140    }
141  }
142  fprintf(timing_file_, "%u, %u\n", video_frame.timestamp(),
143      webrtc::MaskWord64ToUWord32(video_frame.render_time_ms()));
144  if (PrintI420VideoFrame(video_frame, out_file_) < 0) {
145    return -1;
146  }
147  return 0;
148}
149
150webrtc::RtpVideoCodecTypes ConvertCodecType(const char* plname) {
151  if (strncmp(plname,"VP8" , 3) == 0) {
152    return webrtc::kRtpVideoVp8;
153  } else {
154    return webrtc::kRtpVideoNone;  // Default value
155  }
156}
157