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 <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
262 // TODO(wez): Switch to ConfigureCodec() path once libvpx supports it. | 262 // TODO(wez): Switch to ConfigureCodec() path once libvpx supports it. |
263 // See https://code.google.com/p/webm/issues/detail?id=913. | 263 // See https://code.google.com/p/webm/issues/detail?id=913. |
264 // if (codec_) | 264 // if (codec_) |
265 // Configure(webrtc::DesktopSize(codec_->config.enc->g_w, | 265 // Configure(webrtc::DesktopSize(codec_->config.enc->g_w, |
266 // codec_->config.enc->g_h)); | 266 // codec_->config.enc->g_h)); |
267 codec_.reset(); | 267 codec_.reset(); |
268 } | 268 } |
269 } | 269 } |
270 | 270 |
271 std::unique_ptr<VideoPacket> VideoEncoderVpx::Encode( | 271 std::unique_ptr<VideoPacket> VideoEncoderVpx::Encode( |
272 const webrtc::DesktopFrame& frame, | 272 const webrtc::DesktopFrame& frame) { |
273 uint32_t flags) { | |
274 DCHECK_LE(32, frame.size().width()); | 273 DCHECK_LE(32, frame.size().width()); |
275 DCHECK_LE(32, frame.size().height()); | 274 DCHECK_LE(32, frame.size().height()); |
276 | 275 |
277 // If there is nothing to encode, and nothing to top-off, then return nothing. | 276 // If there is nothing to encode, and nothing to top-off, then return nothing. |
278 if (frame.updated_region().is_empty() && !encode_unchanged_frame_) | 277 if (frame.updated_region().is_empty() && !encode_unchanged_frame_) |
279 return nullptr; | 278 return nullptr; |
280 | 279 |
281 // Create or reconfigure the codec to match the size of |frame|. | 280 // Create or reconfigure the codec to match the size of |frame|. |
282 if (!codec_ || | 281 if (!codec_ || |
283 (image_ && | 282 (image_ && |
(...skipping 10 matching lines...) Expand all Loading... |
294 | 293 |
295 // Apply active map to the encoder. | 294 // Apply active map to the encoder. |
296 vpx_active_map_t act_map; | 295 vpx_active_map_t act_map; |
297 act_map.rows = active_map_size_.height(); | 296 act_map.rows = active_map_size_.height(); |
298 act_map.cols = active_map_size_.width(); | 297 act_map.cols = active_map_size_.width(); |
299 act_map.active_map = active_map_.get(); | 298 act_map.active_map = active_map_.get(); |
300 if (vpx_codec_control(codec_.get(), VP8E_SET_ACTIVEMAP, &act_map)) { | 299 if (vpx_codec_control(codec_.get(), VP8E_SET_ACTIVEMAP, &act_map)) { |
301 LOG(ERROR) << "Unable to apply active map"; | 300 LOG(ERROR) << "Unable to apply active map"; |
302 } | 301 } |
303 | 302 |
304 if (flags & REQUEST_KEY_FRAME) | |
305 vpx_codec_control(codec_.get(), VP8E_SET_FRAME_FLAGS, VPX_EFLAG_FORCE_KF); | |
306 | |
307 // Do the actual encoding. | 303 // Do the actual encoding. |
308 int timestamp = (clock_->NowTicks() - timestamp_base_).InMilliseconds(); | 304 int timestamp = (clock_->NowTicks() - timestamp_base_).InMilliseconds(); |
309 vpx_codec_err_t ret = vpx_codec_encode( | 305 vpx_codec_err_t ret = vpx_codec_encode( |
310 codec_.get(), image_.get(), timestamp, 1, 0, VPX_DL_REALTIME); | 306 codec_.get(), image_.get(), timestamp, 1, 0, VPX_DL_REALTIME); |
311 DCHECK_EQ(ret, VPX_CODEC_OK) | 307 DCHECK_EQ(ret, VPX_CODEC_OK) |
312 << "Encoding error: " << vpx_codec_err_to_string(ret) << "\n" | 308 << "Encoding error: " << vpx_codec_err_to_string(ret) << "\n" |
313 << "Details: " << vpx_codec_error(codec_.get()) << "\n" | 309 << "Details: " << vpx_codec_error(codec_.get()) << "\n" |
314 << vpx_codec_error_detail(codec_.get()); | 310 << vpx_codec_error_detail(codec_.get()); |
315 | 311 |
316 if (use_vp9_ && !lossless_encode_) { | 312 if (use_vp9_ && !lossless_encode_) { |
(...skipping 20 matching lines...) Expand all Loading... |
337 while (!got_data) { | 333 while (!got_data) { |
338 const vpx_codec_cx_pkt_t* vpx_packet = | 334 const vpx_codec_cx_pkt_t* vpx_packet = |
339 vpx_codec_get_cx_data(codec_.get(), &iter); | 335 vpx_codec_get_cx_data(codec_.get(), &iter); |
340 if (!vpx_packet) | 336 if (!vpx_packet) |
341 continue; | 337 continue; |
342 | 338 |
343 switch (vpx_packet->kind) { | 339 switch (vpx_packet->kind) { |
344 case VPX_CODEC_CX_FRAME_PKT: | 340 case VPX_CODEC_CX_FRAME_PKT: |
345 got_data = true; | 341 got_data = true; |
346 packet->set_data(vpx_packet->data.frame.buf, vpx_packet->data.frame.sz); | 342 packet->set_data(vpx_packet->data.frame.buf, vpx_packet->data.frame.sz); |
347 packet->set_key_frame(vpx_packet->data.frame.flags & VPX_FRAME_IS_KEY); | |
348 break; | 343 break; |
349 default: | 344 default: |
350 break; | 345 break; |
351 } | 346 } |
352 } | 347 } |
353 | 348 |
354 return packet; | 349 return packet; |
355 } | 350 } |
356 | 351 |
357 VideoEncoderVpx::VideoEncoderVpx(bool use_vp9) | 352 VideoEncoderVpx::VideoEncoderVpx(bool use_vp9) |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
547 kMacroBlockSize * (y + 1))); | 542 kMacroBlockSize * (y + 1))); |
548 } | 543 } |
549 x0 = x1 + 1; | 544 x0 = x1 + 1; |
550 } | 545 } |
551 } | 546 } |
552 updated_region->IntersectWith( | 547 updated_region->IntersectWith( |
553 webrtc::DesktopRect::MakeWH(image_->w, image_->h)); | 548 webrtc::DesktopRect::MakeWH(image_->w, image_->h)); |
554 } | 549 } |
555 | 550 |
556 } // namespace remoting | 551 } // namespace remoting |
OLD | NEW |