Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / test / fake_encoder.cc
1 /*
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/test/fake_encoder.h"
12
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 #include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h"
16
17 namespace webrtc {
18 namespace test {
19
20 FakeEncoder::FakeEncoder(Clock* clock)
21     : clock_(clock),
22       callback_(NULL),
23       target_bitrate_kbps_(0),
24       max_target_bitrate_kbps_(-1),
25       last_encode_time_ms_(0) {
26   // Generate some arbitrary not-all-zero data
27   for (size_t i = 0; i < sizeof(encoded_buffer_); ++i) {
28     encoded_buffer_[i] = static_cast<uint8_t>(i);
29   }
30 }
31
32 FakeEncoder::~FakeEncoder() {}
33
34 void FakeEncoder::SetMaxBitrate(int max_kbps) {
35   assert(max_kbps >= -1);  // max_kbps == -1 disables it.
36   max_target_bitrate_kbps_ = max_kbps;
37 }
38
39 int32_t FakeEncoder::InitEncode(const VideoCodec* config,
40                                 int32_t number_of_cores,
41                                 uint32_t max_payload_size) {
42   config_ = *config;
43   target_bitrate_kbps_ = config_.startBitrate;
44   return 0;
45 }
46
47 int32_t FakeEncoder::Encode(
48     const I420VideoFrame& input_image,
49     const CodecSpecificInfo* codec_specific_info,
50     const std::vector<VideoFrameType>* frame_types) {
51   assert(config_.maxFramerate > 0);
52   int time_since_last_encode_ms = 1000 / config_.maxFramerate;
53   int64_t time_now_ms = clock_->TimeInMilliseconds();
54   const bool first_encode = last_encode_time_ms_ == 0;
55   if (!first_encode) {
56     // For all frames but the first we can estimate the display time by looking
57     // at the display time of the previous frame.
58     time_since_last_encode_ms = time_now_ms - last_encode_time_ms_;
59   }
60
61   int bits_available = target_bitrate_kbps_ * time_since_last_encode_ms;
62   int min_bits =
63       config_.simulcastStream[0].minBitrate * time_since_last_encode_ms;
64   if (bits_available < min_bits)
65     bits_available = min_bits;
66   int max_bits = max_target_bitrate_kbps_ * time_since_last_encode_ms;
67   if (max_bits > 0 && max_bits < bits_available)
68     bits_available = max_bits;
69   last_encode_time_ms_ = time_now_ms;
70
71   assert(config_.numberOfSimulcastStreams > 0);
72   for (int i = 0; i < config_.numberOfSimulcastStreams; ++i) {
73     CodecSpecificInfo specifics;
74     memset(&specifics, 0, sizeof(specifics));
75     specifics.codecType = kVideoCodecGeneric;
76     specifics.codecSpecific.generic.simulcast_idx = i;
77     int min_stream_bits =
78         config_.simulcastStream[i].minBitrate * time_since_last_encode_ms;
79     int max_stream_bits =
80         config_.simulcastStream[i].maxBitrate * time_since_last_encode_ms;
81     int stream_bits = (bits_available > max_stream_bits) ? max_stream_bits :
82         bits_available;
83     int stream_bytes = (stream_bits + 7) / 8;
84     if (first_encode) {
85       // The first frame is a key frame and should be larger.
86       // TODO(holmer): The FakeEncoder should store the bits_available between
87       // encodes so that it can compensate for oversized frames.
88       stream_bytes *= 10;
89     }
90     if (static_cast<size_t>(stream_bytes) > sizeof(encoded_buffer_))
91       stream_bytes = sizeof(encoded_buffer_);
92
93     EncodedImage encoded(
94         encoded_buffer_, stream_bytes, sizeof(encoded_buffer_));
95     encoded._timeStamp = input_image.timestamp();
96     encoded.capture_time_ms_ = input_image.render_time_ms();
97     encoded._frameType = (*frame_types)[i];
98     // Always encode something on the first frame.
99     if (min_stream_bits > bits_available && i > 0) {
100       encoded._length = 0;
101       encoded._frameType = kSkipFrame;
102     }
103     assert(callback_ != NULL);
104     if (callback_->Encoded(encoded, &specifics, NULL) != 0)
105       return -1;
106     bits_available -= encoded._length * 8;
107   }
108   return 0;
109 }
110
111 int32_t FakeEncoder::RegisterEncodeCompleteCallback(
112     EncodedImageCallback* callback) {
113   callback_ = callback;
114   return 0;
115 }
116
117 int32_t FakeEncoder::Release() { return 0; }
118
119 int32_t FakeEncoder::SetChannelParameters(uint32_t packet_loss, int rtt) {
120   return 0;
121 }
122
123 int32_t FakeEncoder::SetRates(uint32_t new_target_bitrate, uint32_t framerate) {
124   target_bitrate_kbps_ = new_target_bitrate;
125   return 0;
126 }
127
128 FakeH264Encoder::FakeH264Encoder(Clock* clock)
129     : FakeEncoder(clock), callback_(NULL), idr_counter_(0) {
130   FakeEncoder::RegisterEncodeCompleteCallback(this);
131 }
132
133 int32_t FakeH264Encoder::RegisterEncodeCompleteCallback(
134     EncodedImageCallback* callback) {
135   callback_ = callback;
136   return 0;
137 }
138
139 int32_t FakeH264Encoder::Encoded(EncodedImage& encoded_image,
140                                  const CodecSpecificInfo* codec_specific_info,
141                                  const RTPFragmentationHeader* fragments) {
142   const size_t kSpsSize = 8;
143   const size_t kPpsSize = 11;
144   const int kIdrFrequency = 10;
145   RTPFragmentationHeader fragmentation;
146   if (idr_counter_++ % kIdrFrequency == 0 &&
147       encoded_image._length > kSpsSize + kPpsSize + 1) {
148     const size_t kNumSlices = 3;
149     fragmentation.VerifyAndAllocateFragmentationHeader(kNumSlices);
150     fragmentation.fragmentationOffset[0] = 0;
151     fragmentation.fragmentationLength[0] = kSpsSize;
152     fragmentation.fragmentationOffset[1] = kSpsSize;
153     fragmentation.fragmentationLength[1] = kPpsSize;
154     fragmentation.fragmentationOffset[2] = kSpsSize + kPpsSize;
155     fragmentation.fragmentationLength[2] =
156         encoded_image._length - (kSpsSize + kPpsSize);
157     const uint8_t kSpsNalHeader = 0x37;
158     const uint8_t kPpsNalHeader = 0x38;
159     const uint8_t kIdrNalHeader = 0x15;
160     encoded_image._buffer[fragmentation.fragmentationOffset[0]] = kSpsNalHeader;
161     encoded_image._buffer[fragmentation.fragmentationOffset[1]] = kPpsNalHeader;
162     encoded_image._buffer[fragmentation.fragmentationOffset[2]] = kIdrNalHeader;
163   } else {
164     const size_t kNumSlices = 1;
165     fragmentation.VerifyAndAllocateFragmentationHeader(kNumSlices);
166     fragmentation.fragmentationOffset[0] = 0;
167     fragmentation.fragmentationLength[0] = encoded_image._length;
168     const uint8_t kNalHeader = 0x11;
169     encoded_image._buffer[fragmentation.fragmentationOffset[0]] = kNalHeader;
170   }
171   uint8_t value = 0;
172   int fragment_counter = 0;
173   for (size_t i = 0; i < encoded_image._length; ++i) {
174     if (fragment_counter == fragmentation.fragmentationVectorSize ||
175         i != fragmentation.fragmentationOffset[fragment_counter]) {
176       encoded_image._buffer[i] = value++;
177     } else {
178       ++fragment_counter;
179     }
180   }
181   return callback_->Encoded(encoded_image, NULL, &fragmentation);
182 }
183 }  // namespace test
184 }  // namespace webrtc