OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 PacketManipulator* packet_manipulator, | 53 PacketManipulator* packet_manipulator, |
54 const TestConfig& config, | 54 const TestConfig& config, |
55 Stats* stats) | 55 Stats* stats) |
56 : encoder_(encoder), | 56 : encoder_(encoder), |
57 decoder_(decoder), | 57 decoder_(decoder), |
58 frame_reader_(frame_reader), | 58 frame_reader_(frame_reader), |
59 frame_writer_(frame_writer), | 59 frame_writer_(frame_writer), |
60 packet_manipulator_(packet_manipulator), | 60 packet_manipulator_(packet_manipulator), |
61 config_(config), | 61 config_(config), |
62 stats_(stats), | 62 stats_(stats), |
63 encode_callback_(nullptr), | |
64 decode_callback_(nullptr), | |
65 last_successful_frame_buffer_(nullptr), | 63 last_successful_frame_buffer_(nullptr), |
66 first_key_frame_has_been_excluded_(false), | 64 first_key_frame_has_been_excluded_(false), |
67 last_frame_missing_(false), | 65 last_frame_missing_(false), |
68 initialized_(false), | 66 initialized_(false), |
69 encoded_frame_size_(0), | 67 encoded_frame_size_(0), |
70 encoded_frame_type_(kVideoFrameKey), | 68 encoded_frame_type_(kVideoFrameKey), |
71 prev_time_stamp_(0), | 69 prev_time_stamp_(0), |
72 num_dropped_frames_(0), | 70 num_dropped_frames_(0), |
73 num_spatial_resizes_(0), | 71 num_spatial_resizes_(0), |
74 last_encoder_frame_width_(0), | 72 last_encoder_frame_width_(0), |
(...skipping 22 matching lines...) Expand all Loading... |
97 | 95 |
98 // Initialize data structures used by the encoder/decoder APIs | 96 // Initialize data structures used by the encoder/decoder APIs |
99 size_t frame_length_in_bytes = frame_reader_->FrameLength(); | 97 size_t frame_length_in_bytes = frame_reader_->FrameLength(); |
100 last_successful_frame_buffer_ = new uint8_t[frame_length_in_bytes]; | 98 last_successful_frame_buffer_ = new uint8_t[frame_length_in_bytes]; |
101 // Set fixed properties common for all frames. | 99 // Set fixed properties common for all frames. |
102 // To keep track of spatial resize actions by encoder. | 100 // To keep track of spatial resize actions by encoder. |
103 last_encoder_frame_width_ = config_.codec_settings->width; | 101 last_encoder_frame_width_ = config_.codec_settings->width; |
104 last_encoder_frame_height_ = config_.codec_settings->height; | 102 last_encoder_frame_height_ = config_.codec_settings->height; |
105 | 103 |
106 // Setup required callbacks for the encoder/decoder: | 104 // Setup required callbacks for the encoder/decoder: |
107 encode_callback_ = new VideoProcessorEncodeCompleteCallback(this); | 105 encode_callback_.reset(new VideoProcessorEncodeCompleteCallback(this)); |
108 decode_callback_ = new VideoProcessorDecodeCompleteCallback(this); | 106 decode_callback_.reset(new VideoProcessorDecodeCompleteCallback(this)); |
109 int32_t register_result = | 107 RTC_CHECK_EQ(encoder_->RegisterEncodeCompleteCallback(encode_callback_.get()), |
110 encoder_->RegisterEncodeCompleteCallback(encode_callback_); | 108 WEBRTC_VIDEO_CODEC_OK) |
111 if (register_result != WEBRTC_VIDEO_CODEC_OK) { | 109 << "Failed to register encode complete callback"; |
112 fprintf(stderr, | 110 RTC_CHECK_EQ(decoder_->RegisterDecodeCompleteCallback(decode_callback_.get()), |
113 "Failed to register encode complete callback, return code: " | 111 WEBRTC_VIDEO_CODEC_OK) |
114 "%d\n", | 112 << "Failed to register decode complete callback"; |
115 register_result); | 113 |
116 return false; | |
117 } | |
118 register_result = decoder_->RegisterDecodeCompleteCallback(decode_callback_); | |
119 if (register_result != WEBRTC_VIDEO_CODEC_OK) { | |
120 fprintf(stderr, | |
121 "Failed to register decode complete callback, return code: " | |
122 "%d\n", | |
123 register_result); | |
124 return false; | |
125 } | |
126 // Init the encoder and decoder | 114 // Init the encoder and decoder |
127 uint32_t nbr_of_cores = 1; | 115 uint32_t nbr_of_cores = 1; |
128 if (!config_.use_single_core) { | 116 if (!config_.use_single_core) { |
129 nbr_of_cores = CpuInfo::DetectNumberOfCores(); | 117 nbr_of_cores = CpuInfo::DetectNumberOfCores(); |
130 } | 118 } |
131 int32_t init_result = | 119 RTC_CHECK_EQ( |
132 encoder_->InitEncode(config_.codec_settings, nbr_of_cores, | 120 encoder_->InitEncode(config_.codec_settings, nbr_of_cores, |
133 config_.networking_config.max_payload_size_in_bytes); | 121 config_.networking_config.max_payload_size_in_bytes), |
134 if (init_result != WEBRTC_VIDEO_CODEC_OK) { | 122 WEBRTC_VIDEO_CODEC_OK) |
135 fprintf(stderr, "Failed to initialize VideoEncoder, return code: %d\n", | 123 << "Failed to initialize VideoEncoder"; |
136 init_result); | 124 |
137 return false; | 125 RTC_CHECK_EQ(decoder_->InitDecode(config_.codec_settings, nbr_of_cores), |
138 } | 126 WEBRTC_VIDEO_CODEC_OK) |
139 init_result = decoder_->InitDecode(config_.codec_settings, nbr_of_cores); | 127 << "Failed to initialize VideoDecoder"; |
140 if (init_result != WEBRTC_VIDEO_CODEC_OK) { | |
141 fprintf(stderr, "Failed to initialize VideoDecoder, return code: %d\n", | |
142 init_result); | |
143 return false; | |
144 } | |
145 | 128 |
146 if (config_.verbose) { | 129 if (config_.verbose) { |
147 printf("Video Processor:\n"); | 130 printf("Video Processor:\n"); |
148 printf(" #CPU cores used : %d\n", nbr_of_cores); | 131 printf(" #CPU cores used : %d\n", nbr_of_cores); |
149 printf(" Total # of frames: %d\n", frame_reader_->NumberOfFrames()); | 132 printf(" Total # of frames: %d\n", frame_reader_->NumberOfFrames()); |
150 printf(" Codec settings:\n"); | 133 printf(" Codec settings:\n"); |
151 printf(" Start bitrate : %d kbps\n", | 134 printf(" Start bitrate : %d kbps\n", |
152 config_.codec_settings->startBitrate); | 135 config_.codec_settings->startBitrate); |
153 printf(" Width : %d\n", config_.codec_settings->width); | 136 printf(" Width : %d\n", config_.codec_settings->width); |
154 printf(" Height : %d\n", config_.codec_settings->height); | 137 printf(" Height : %d\n", config_.codec_settings->height); |
(...skipping 17 matching lines...) Expand all Loading... |
172 printf(" Resilience : %d\n", | 155 printf(" Resilience : %d\n", |
173 config_.codec_settings->VP9()->resilience); | 156 config_.codec_settings->VP9()->resilience); |
174 } | 157 } |
175 } | 158 } |
176 initialized_ = true; | 159 initialized_ = true; |
177 return true; | 160 return true; |
178 } | 161 } |
179 | 162 |
180 VideoProcessorImpl::~VideoProcessorImpl() { | 163 VideoProcessorImpl::~VideoProcessorImpl() { |
181 delete[] last_successful_frame_buffer_; | 164 delete[] last_successful_frame_buffer_; |
182 encoder_->RegisterEncodeCompleteCallback(NULL); | 165 encoder_->RegisterEncodeCompleteCallback(nullptr); |
183 delete encode_callback_; | 166 decoder_->RegisterDecodeCompleteCallback(nullptr); |
184 decoder_->RegisterDecodeCompleteCallback(NULL); | |
185 delete decode_callback_; | |
186 } | 167 } |
187 | 168 |
188 void VideoProcessorImpl::SetRates(int bit_rate, int frame_rate) { | 169 void VideoProcessorImpl::SetRates(int bit_rate, int frame_rate) { |
189 int set_rates_result = encoder_->SetRateAllocation( | 170 int set_rates_result = encoder_->SetRateAllocation( |
190 bitrate_allocator_->GetAllocation(bit_rate * 1000, frame_rate), | 171 bitrate_allocator_->GetAllocation(bit_rate * 1000, frame_rate), |
191 frame_rate); | 172 frame_rate); |
192 RTC_CHECK_GE(set_rates_result, 0); | 173 RTC_CHECK_GE(set_rates_result, 0) << "Failed to update encoder with new rate " |
193 if (set_rates_result < 0) { | 174 << bit_rate; |
194 fprintf(stderr, | |
195 "Failed to update encoder with new rate %d, " | |
196 "return code: %d\n", | |
197 bit_rate, set_rates_result); | |
198 } | |
199 num_dropped_frames_ = 0; | 175 num_dropped_frames_ = 0; |
200 num_spatial_resizes_ = 0; | 176 num_spatial_resizes_ = 0; |
201 } | 177 } |
202 | 178 |
203 size_t VideoProcessorImpl::EncodedFrameSize() { | 179 size_t VideoProcessorImpl::EncodedFrameSize() { |
204 return encoded_frame_size_; | 180 return encoded_frame_size_; |
205 } | 181 } |
206 | 182 |
207 FrameType VideoProcessorImpl::EncodedFrameType() { | 183 FrameType VideoProcessorImpl::EncodedFrameType() { |
208 return encoded_frame_type_; | 184 return encoded_frame_type_; |
209 } | 185 } |
210 | 186 |
211 int VideoProcessorImpl::NumberDroppedFrames() { | 187 int VideoProcessorImpl::NumberDroppedFrames() { |
212 return num_dropped_frames_; | 188 return num_dropped_frames_; |
213 } | 189 } |
214 | 190 |
215 int VideoProcessorImpl::NumberSpatialResizes() { | 191 int VideoProcessorImpl::NumberSpatialResizes() { |
216 return num_spatial_resizes_; | 192 return num_spatial_resizes_; |
217 } | 193 } |
218 | 194 |
219 bool VideoProcessorImpl::ProcessFrame(int frame_number) { | 195 bool VideoProcessorImpl::ProcessFrame(int frame_number) { |
220 RTC_DCHECK_GE(frame_number, 0); | 196 RTC_DCHECK_GE(frame_number, 0); |
221 if (!initialized_) { | 197 RTC_CHECK(initialized_) << "Attempting to use uninitialized VideoProcessor"; |
222 fprintf(stderr, "Attempting to use uninitialized VideoProcessor!\n"); | 198 |
223 return false; | |
224 } | |
225 // |prev_time_stamp_| is used for getting number of dropped frames. | 199 // |prev_time_stamp_| is used for getting number of dropped frames. |
226 if (frame_number == 0) { | 200 if (frame_number == 0) { |
227 prev_time_stamp_ = -1; | 201 prev_time_stamp_ = -1; |
228 } | 202 } |
229 rtc::scoped_refptr<VideoFrameBuffer> buffer(frame_reader_->ReadFrame()); | 203 rtc::scoped_refptr<VideoFrameBuffer> buffer(frame_reader_->ReadFrame()); |
230 if (buffer) { | 204 if (buffer) { |
231 // Use the frame number as "timestamp" to identify frames | 205 // Use the frame number as "timestamp" to identify frames |
232 VideoFrame source_frame(buffer, frame_number, 0, webrtc::kVideoRotation_0); | 206 VideoFrame source_frame(buffer, frame_number, 0, webrtc::kVideoRotation_0); |
233 | 207 |
234 // Ensure we have a new statistics data object we can fill: | 208 // Ensure we have a new statistics data object we can fill: |
235 FrameStatistic& stat = stats_->NewFrame(frame_number); | 209 FrameStatistic& stat = stats_->NewFrame(frame_number); |
236 | 210 |
237 encode_start_ns_ = rtc::TimeNanos(); | 211 encode_start_ns_ = rtc::TimeNanos(); |
238 | 212 |
239 // Decide if we're going to force a keyframe: | 213 // Decide if we're going to force a keyframe: |
240 std::vector<FrameType> frame_types(1, kVideoFrameDelta); | 214 std::vector<FrameType> frame_types(1, kVideoFrameDelta); |
241 if (config_.keyframe_interval > 0 && | 215 if (config_.keyframe_interval > 0 && |
242 frame_number % config_.keyframe_interval == 0) { | 216 frame_number % config_.keyframe_interval == 0) { |
243 frame_types[0] = kVideoFrameKey; | 217 frame_types[0] = kVideoFrameKey; |
244 } | 218 } |
245 | 219 |
246 // For dropped frames, we regard them as zero size encoded frames. | 220 // For dropped frames, we regard them as zero size encoded frames. |
247 encoded_frame_size_ = 0; | 221 encoded_frame_size_ = 0; |
248 encoded_frame_type_ = kVideoFrameDelta; | 222 encoded_frame_type_ = kVideoFrameDelta; |
249 | 223 |
250 int32_t encode_result = encoder_->Encode(source_frame, NULL, &frame_types); | 224 int32_t encode_result = |
| 225 encoder_->Encode(source_frame, nullptr, &frame_types); |
251 | 226 |
252 if (encode_result != WEBRTC_VIDEO_CODEC_OK) { | 227 if (encode_result != WEBRTC_VIDEO_CODEC_OK) { |
253 fprintf(stderr, "Failed to encode frame %d, return code: %d\n", | 228 fprintf(stderr, "Failed to encode frame %d, return code: %d\n", |
254 frame_number, encode_result); | 229 frame_number, encode_result); |
255 } | 230 } |
256 stat.encode_return_code = encode_result; | 231 stat.encode_return_code = encode_result; |
257 return true; | 232 return true; |
258 } else { | 233 } else { |
259 return false; // we've reached the last frame | 234 return false; // we've reached the last frame |
260 } | 235 } |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
330 stat.packets_dropped = | 305 stat.packets_dropped = |
331 packet_manipulator_->ManipulatePackets(&copied_image); | 306 packet_manipulator_->ManipulatePackets(&copied_image); |
332 } | 307 } |
333 | 308 |
334 // Keep track of if frames are lost due to packet loss so we can tell | 309 // Keep track of if frames are lost due to packet loss so we can tell |
335 // this to the encoder (this is handled by the RTP logic in the full stack) | 310 // this to the encoder (this is handled by the RTP logic in the full stack) |
336 decode_start_ns_ = rtc::TimeNanos(); | 311 decode_start_ns_ = rtc::TimeNanos(); |
337 // TODO(kjellander): Pass fragmentation header to the decoder when | 312 // TODO(kjellander): Pass fragmentation header to the decoder when |
338 // CL 172001 has been submitted and PacketManipulator supports this. | 313 // CL 172001 has been submitted and PacketManipulator supports this. |
339 int32_t decode_result = | 314 int32_t decode_result = |
340 decoder_->Decode(copied_image, last_frame_missing_, NULL); | 315 decoder_->Decode(copied_image, last_frame_missing_, nullptr); |
341 stat.decode_return_code = decode_result; | 316 stat.decode_return_code = decode_result; |
342 if (decode_result != WEBRTC_VIDEO_CODEC_OK) { | 317 if (decode_result != WEBRTC_VIDEO_CODEC_OK) { |
343 // Write the last successful frame the output file to avoid getting it out | 318 // Write the last successful frame the output file to avoid getting it out |
344 // of sync with the source file for SSIM and PSNR comparisons: | 319 // of sync with the source file for SSIM and PSNR comparisons: |
345 frame_writer_->WriteFrame(last_successful_frame_buffer_); | 320 frame_writer_->WriteFrame(last_successful_frame_buffer_); |
346 } | 321 } |
347 // save status for losses so we can inform the decoder for the next frame: | 322 // save status for losses so we can inform the decoder for the next frame: |
348 last_frame_missing_ = copied_image._length == 0; | 323 last_frame_missing_ = copied_image._length == 0; |
349 } | 324 } |
350 | 325 |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
440 } | 415 } |
441 int32_t VideoProcessorImpl::VideoProcessorDecodeCompleteCallback::Decoded( | 416 int32_t VideoProcessorImpl::VideoProcessorDecodeCompleteCallback::Decoded( |
442 VideoFrame& image) { | 417 VideoFrame& image) { |
443 // Forward to parent class. | 418 // Forward to parent class. |
444 video_processor_->FrameDecoded(image); | 419 video_processor_->FrameDecoded(image); |
445 return 0; | 420 return 0; |
446 } | 421 } |
447 | 422 |
448 } // namespace test | 423 } // namespace test |
449 } // namespace webrtc | 424 } // namespace webrtc |
OLD | NEW |