blob: c5e58f53b4364c02a975b751c2291ac06c1a0907 [file] [log] [blame]
stefan@webrtc.org360e3762013-08-22 09:29:56 +00001/*
2 * Copyright (c) 2013 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/video_engine/test/common/fake_encoder.h"
12
13#include "testing/gtest/include/gtest/gtest.h"
14
15namespace webrtc {
pbos@webrtc.orgcb5118c2013-09-03 09:10:37 +000016namespace test {
stefan@webrtc.org360e3762013-08-22 09:29:56 +000017
18FakeEncoder::FakeEncoder(Clock* clock)
19 : clock_(clock),
20 callback_(NULL),
21 target_bitrate_kbps_(0),
22 last_encode_time_ms_(0) {
23 memset(encoded_buffer_, 0, sizeof(encoded_buffer_));
24}
25
26FakeEncoder::~FakeEncoder() {}
27
pbos@webrtc.org0181b5f2013-09-09 08:26:30 +000028void FakeEncoder::SetCodecSettings(VideoCodec* codec,
pbos@webrtc.orgcb5118c2013-09-03 09:10:37 +000029 size_t num_streams) {
30 assert(num_streams > 0);
31 assert(num_streams <= kMaxSimulcastStreams);
32
33 static const SimulcastStream stream_settings[] = {
34 {320, 180, 0, 150, 150, 50, codec->qpMax},
35 {640, 360, 0, 500, 500, 150, codec->qpMax},
36 {1280, 720, 0, 1200, 1200, 600, codec->qpMax}};
37 // Add more streams to the settings above with reasonable values if required.
38 assert(num_streams <= sizeof(stream_settings) / sizeof(stream_settings[0]));
39
40 codec->numberOfSimulcastStreams = static_cast<unsigned char>(num_streams);
41
42 unsigned int sum_of_max_bitrates = 0;
43 for (size_t i = 0; i < num_streams; ++i) {
44 codec->simulcastStream[i] = stream_settings[i];
45 sum_of_max_bitrates += stream_settings[i].maxBitrate;
46 }
47
48 size_t last_stream = num_streams - 1;
49 codec->width = stream_settings[last_stream].width;
50 codec->height = stream_settings[last_stream].height;
51 // Start with the average for the middle stream's max/min settings.
52 codec->startBitrate = (stream_settings[last_stream / 2].maxBitrate +
53 stream_settings[last_stream / 2].minBitrate) /
54 2;
55 codec->minBitrate = stream_settings[0].minBitrate;
56 codec->maxBitrate = sum_of_max_bitrates;
pbos@webrtc.org0181b5f2013-09-09 08:26:30 +000057
58 codec->codecType = kVideoCodecGeneric;
59 strcpy(codec->plName, "FAKE");
60 codec->plType = 125;
pbos@webrtc.orgcb5118c2013-09-03 09:10:37 +000061}
62
stefan@webrtc.org360e3762013-08-22 09:29:56 +000063int32_t FakeEncoder::InitEncode(const VideoCodec* config,
64 int32_t number_of_cores,
65 uint32_t max_payload_size) {
66 config_ = *config;
67 target_bitrate_kbps_ = config_.startBitrate;
68 return 0;
69}
70
71int32_t FakeEncoder::Encode(
72 const I420VideoFrame& input_image,
73 const CodecSpecificInfo* codec_specific_info,
74 const std::vector<VideoFrameType>* frame_types) {
75 assert(config_.maxFramerate > 0);
76 int delta_since_last_encode = 1000 / config_.maxFramerate;
77 int64_t time_now_ms = clock_->TimeInMilliseconds();
78 if (last_encode_time_ms_ > 0) {
79 // For all frames but the first we can estimate the display time by looking
80 // at the display time of the previous frame.
81 delta_since_last_encode = time_now_ms - last_encode_time_ms_;
82 }
83
84 int bits_available = target_bitrate_kbps_ * delta_since_last_encode;
pbos@webrtc.org0181b5f2013-09-09 08:26:30 +000085 int min_bits =
86 config_.simulcastStream[0].minBitrate * delta_since_last_encode;
87 if (bits_available < min_bits)
88 bits_available = min_bits;
stefan@webrtc.org360e3762013-08-22 09:29:56 +000089 last_encode_time_ms_ = time_now_ms;
90
91 for (int i = 0; i < config_.numberOfSimulcastStreams; ++i) {
92 CodecSpecificInfo specifics;
93 memset(&specifics, 0, sizeof(specifics));
pbos@webrtc.org0181b5f2013-09-09 08:26:30 +000094 specifics.codecType = kVideoCodecGeneric;
95 specifics.codecSpecific.generic.simulcast_idx = i;
stefan@webrtc.org360e3762013-08-22 09:29:56 +000096 int min_stream_bits = config_.simulcastStream[i].minBitrate *
97 delta_since_last_encode;
98 int max_stream_bits = config_.simulcastStream[i].maxBitrate *
99 delta_since_last_encode;
100 int stream_bits = (bits_available > max_stream_bits) ? max_stream_bits :
101 bits_available;
102 int stream_bytes = (stream_bits + 7) / 8;
pbos@webrtc.orgc095f512013-08-22 12:34:58 +0000103 EXPECT_LT(static_cast<size_t>(stream_bytes), sizeof(encoded_buffer_));
104 if (static_cast<size_t>(stream_bytes) > sizeof(encoded_buffer_))
stefan@webrtc.org360e3762013-08-22 09:29:56 +0000105 return -1;
106
pbos@webrtc.orgc095f512013-08-22 12:34:58 +0000107 EncodedImage encoded(
108 encoded_buffer_, stream_bytes, sizeof(encoded_buffer_));
stefan@webrtc.org360e3762013-08-22 09:29:56 +0000109 encoded._timeStamp = input_image.timestamp();
110 encoded.capture_time_ms_ = input_image.render_time_ms();
pbos@webrtc.org0181b5f2013-09-09 08:26:30 +0000111 encoded._frameType = (*frame_types)[i];
stefan@webrtc.org360e3762013-08-22 09:29:56 +0000112 if (min_stream_bits > bits_available) {
113 encoded._length = 0;
114 encoded._frameType = kSkipFrame;
115 }
116 if (callback_->Encoded(encoded, &specifics, NULL) != 0)
117 return -1;
118
119 bits_available -= encoded._length * 8;
120 }
121 return 0;
122}
123
124int32_t FakeEncoder::RegisterEncodeCompleteCallback(
125 EncodedImageCallback* callback) {
126 callback_ = callback;
127 return 0;
128}
129
130int32_t FakeEncoder::Release() { return 0; }
131
132int32_t FakeEncoder::SetChannelParameters(uint32_t packet_loss, int rtt) {
133 return 0;
134}
135
136int32_t FakeEncoder::SetRates(uint32_t new_target_bitrate, uint32_t framerate) {
137 target_bitrate_kbps_ = new_target_bitrate;
138 return 0;
139}
pbos@webrtc.orgcb5118c2013-09-03 09:10:37 +0000140} // namespace test
stefan@webrtc.org360e3762013-08-22 09:29:56 +0000141} // namespace webrtc