OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "remoting/codec/video_encoder_vpx.h" | 5 #include "remoting/codec/video_encoder_vpx.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/sys_info.h" | 9 #include "base/sys_info.h" |
10 #include "remoting/base/util.h" | 10 #include "remoting/base/util.h" |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 | 263 |
264 scoped_ptr<VideoPacket> VideoEncoderVpx::Encode( | 264 scoped_ptr<VideoPacket> VideoEncoderVpx::Encode( |
265 const webrtc::DesktopFrame& frame) { | 265 const webrtc::DesktopFrame& frame) { |
266 DCHECK_LE(32, frame.size().width()); | 266 DCHECK_LE(32, frame.size().width()); |
267 DCHECK_LE(32, frame.size().height()); | 267 DCHECK_LE(32, frame.size().height()); |
268 | 268 |
269 // If there is nothing to encode, and nothing to top-off, then return nothing. | 269 // If there is nothing to encode, and nothing to top-off, then return nothing. |
270 if (frame.updated_region().is_empty() && !encode_unchanged_frame_) | 270 if (frame.updated_region().is_empty() && !encode_unchanged_frame_) |
271 return nullptr; | 271 return nullptr; |
272 | 272 |
273 base::TimeTicks encode_start_time = base::TimeTicks::Now(); | |
274 | |
275 // Create or reconfigure the codec to match the size of |frame|. | 273 // Create or reconfigure the codec to match the size of |frame|. |
276 if (!codec_ || | 274 if (!codec_ || |
277 (image_ && | 275 (image_ && |
278 !frame.size().equals(webrtc::DesktopSize(image_->w, image_->h)))) { | 276 !frame.size().equals(webrtc::DesktopSize(image_->w, image_->h)))) { |
279 Configure(frame.size()); | 277 Configure(frame.size()); |
280 } | 278 } |
281 | 279 |
282 // Convert the updated capture data ready for encode. | 280 // Convert the updated capture data ready for encode. |
283 webrtc::DesktopRegion updated_region; | 281 webrtc::DesktopRegion updated_region; |
284 PrepareImage(frame, &updated_region); | 282 PrepareImage(frame, &updated_region); |
285 | 283 |
286 // Update active map based on updated region. | 284 // Update active map based on updated region. |
287 SetActiveMapFromRegion(updated_region); | 285 SetActiveMapFromRegion(updated_region); |
288 | 286 |
289 // Apply active map to the encoder. | 287 // Apply active map to the encoder. |
290 vpx_active_map_t act_map; | 288 vpx_active_map_t act_map; |
291 act_map.rows = active_map_size_.height(); | 289 act_map.rows = active_map_size_.height(); |
292 act_map.cols = active_map_size_.width(); | 290 act_map.cols = active_map_size_.width(); |
293 act_map.active_map = active_map_.get(); | 291 act_map.active_map = active_map_.get(); |
294 if (vpx_codec_control(codec_.get(), VP8E_SET_ACTIVEMAP, &act_map)) { | 292 if (vpx_codec_control(codec_.get(), VP8E_SET_ACTIVEMAP, &act_map)) { |
295 LOG(ERROR) << "Unable to apply active map"; | 293 LOG(ERROR) << "Unable to apply active map"; |
296 } | 294 } |
297 | 295 |
298 // Do the actual encoding. | 296 // Do the actual encoding. |
299 int timestamp = (encode_start_time - timestamp_base_).InMilliseconds(); | 297 int timestamp = (base::TimeTicks::Now() - timestamp_base_).InMilliseconds(); |
300 vpx_codec_err_t ret = vpx_codec_encode( | 298 vpx_codec_err_t ret = vpx_codec_encode( |
301 codec_.get(), image_.get(), timestamp, 1, 0, VPX_DL_REALTIME); | 299 codec_.get(), image_.get(), timestamp, 1, 0, VPX_DL_REALTIME); |
302 DCHECK_EQ(ret, VPX_CODEC_OK) | 300 DCHECK_EQ(ret, VPX_CODEC_OK) |
303 << "Encoding error: " << vpx_codec_err_to_string(ret) << "\n" | 301 << "Encoding error: " << vpx_codec_err_to_string(ret) << "\n" |
304 << "Details: " << vpx_codec_error(codec_.get()) << "\n" | 302 << "Details: " << vpx_codec_error(codec_.get()) << "\n" |
305 << vpx_codec_error_detail(codec_.get()); | 303 << vpx_codec_error_detail(codec_.get()); |
306 | 304 |
307 if (use_vp9_ && !lossless_encode_) { | 305 if (use_vp9_ && !lossless_encode_) { |
308 ret = vpx_codec_control(codec_.get(), VP9E_GET_ACTIVEMAP, &act_map); | 306 ret = vpx_codec_control(codec_.get(), VP9E_GET_ACTIVEMAP, &act_map); |
309 DCHECK_EQ(ret, VPX_CODEC_OK) | 307 DCHECK_EQ(ret, VPX_CODEC_OK) |
(...skipping 24 matching lines...) Expand all Loading... |
334 switch (vpx_packet->kind) { | 332 switch (vpx_packet->kind) { |
335 case VPX_CODEC_CX_FRAME_PKT: | 333 case VPX_CODEC_CX_FRAME_PKT: |
336 got_data = true; | 334 got_data = true; |
337 packet->set_data(vpx_packet->data.frame.buf, vpx_packet->data.frame.sz); | 335 packet->set_data(vpx_packet->data.frame.buf, vpx_packet->data.frame.sz); |
338 break; | 336 break; |
339 default: | 337 default: |
340 break; | 338 break; |
341 } | 339 } |
342 } | 340 } |
343 | 341 |
344 // Note the time taken to encode the pixel data. | |
345 packet->set_encode_time_ms( | |
346 (base::TimeTicks::Now() - encode_start_time).InMillisecondsRoundedUp()); | |
347 | |
348 return packet.Pass(); | 342 return packet.Pass(); |
349 } | 343 } |
350 | 344 |
351 VideoEncoderVpx::VideoEncoderVpx(bool use_vp9) | 345 VideoEncoderVpx::VideoEncoderVpx(bool use_vp9) |
352 : use_vp9_(use_vp9), encode_unchanged_frame_(false) { | 346 : use_vp9_(use_vp9), encode_unchanged_frame_(false) { |
353 } | 347 } |
354 | 348 |
355 void VideoEncoderVpx::Configure(const webrtc::DesktopSize& size) { | 349 void VideoEncoderVpx::Configure(const webrtc::DesktopSize& size) { |
356 DCHECK(use_vp9_ || !lossless_color_); | 350 DCHECK(use_vp9_ || !lossless_color_); |
357 DCHECK(use_vp9_ || !lossless_encode_); | 351 DCHECK(use_vp9_ || !lossless_encode_); |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
540 kMacroBlockSize * (y + 1))); | 534 kMacroBlockSize * (y + 1))); |
541 } | 535 } |
542 x0 = x1 + 1; | 536 x0 = x1 + 1; |
543 } | 537 } |
544 } | 538 } |
545 updated_region->IntersectWith( | 539 updated_region->IntersectWith( |
546 webrtc::DesktopRect::MakeWH(image_->w, image_->h)); | 540 webrtc::DesktopRect::MakeWH(image_->w, image_->h)); |
547 } | 541 } |
548 | 542 |
549 } // namespace remoting | 543 } // namespace remoting |
OLD | NEW |