Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(50)

Side by Side Diff: media/cast/sender/h264_vt_encoder.cc

Issue 1094403002: Add power monitoring to the Cast VideoToolbox encoder. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase on latest version of 1094403002. Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/cast/sender/h264_vt_encoder.h ('k') | media/cast/sender/h264_vt_encoder_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "media/cast/sender/h264_vt_encoder.h" 5 #include "media/cast/sender/h264_vt_encoder.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/big_endian.h" 10 #include "base/big_endian.h"
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/bind_helpers.h" 12 #include "base/bind_helpers.h"
13 #include "base/location.h" 13 #include "base/location.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/macros.h" 15 #include "base/macros.h"
16 #include "base/power_monitor/power_monitor.h"
16 #include "base/synchronization/lock.h" 17 #include "base/synchronization/lock.h"
17 #include "media/base/mac/corevideo_glue.h" 18 #include "media/base/mac/corevideo_glue.h"
18 #include "media/base/mac/video_frame_mac.h" 19 #include "media/base/mac/video_frame_mac.h"
19 #include "media/cast/sender/video_frame_factory.h" 20 #include "media/cast/sender/video_frame_factory.h"
20 21
21 namespace media { 22 namespace media {
22 namespace cast { 23 namespace cast {
23 24
24 namespace { 25 namespace {
25 26
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 H264VideoToolboxEncoder::H264VideoToolboxEncoder( 315 H264VideoToolboxEncoder::H264VideoToolboxEncoder(
315 const scoped_refptr<CastEnvironment>& cast_environment, 316 const scoped_refptr<CastEnvironment>& cast_environment,
316 const VideoSenderConfig& video_config, 317 const VideoSenderConfig& video_config,
317 const StatusChangeCallback& status_change_cb) 318 const StatusChangeCallback& status_change_cb)
318 : cast_environment_(cast_environment), 319 : cast_environment_(cast_environment),
319 videotoolbox_glue_(VideoToolboxGlue::Get()), 320 videotoolbox_glue_(VideoToolboxGlue::Get()),
320 video_config_(video_config), 321 video_config_(video_config),
321 status_change_cb_(status_change_cb), 322 status_change_cb_(status_change_cb),
322 last_frame_id_(kStartFrameId), 323 last_frame_id_(kStartFrameId),
323 encode_next_frame_as_keyframe_(false), 324 encode_next_frame_as_keyframe_(false),
325 power_suspended_(false),
324 weak_factory_(this) { 326 weak_factory_(this) {
325 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 327 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
326 DCHECK(!status_change_cb_.is_null()); 328 DCHECK(!status_change_cb_.is_null());
327 329
328 OperationalStatus operational_status = 330 OperationalStatus operational_status =
329 H264VideoToolboxEncoder::IsSupported(video_config) 331 H264VideoToolboxEncoder::IsSupported(video_config)
330 ? STATUS_INITIALIZED 332 ? STATUS_INITIALIZED
331 : STATUS_UNSUPPORTED_CODEC; 333 : STATUS_UNSUPPORTED_CODEC;
332 cast_environment_->PostTask( 334 cast_environment_->PostTask(
333 CastEnvironment::MAIN, FROM_HERE, 335 CastEnvironment::MAIN, FROM_HERE,
334 base::Bind(status_change_cb_, operational_status)); 336 base::Bind(status_change_cb_, operational_status));
335 337
336 if (operational_status == STATUS_INITIALIZED) { 338 if (operational_status == STATUS_INITIALIZED) {
339 // Create the shared video frame factory. It persists for the combined
340 // lifetime of the encoder and all video frame factory proxies created by
341 // |CreateVideoFrameFactory| that reference it.
337 video_frame_factory_ = 342 video_frame_factory_ =
338 scoped_refptr<VideoFrameFactoryImpl>(new VideoFrameFactoryImpl( 343 scoped_refptr<VideoFrameFactoryImpl>(new VideoFrameFactoryImpl(
339 weak_factory_.GetWeakPtr(), cast_environment_)); 344 weak_factory_.GetWeakPtr(), cast_environment_));
345
346 // Register for power state changes.
347 auto power_monitor = base::PowerMonitor::Get();
348 if (power_monitor) {
349 power_monitor->AddObserver(this);
350 VLOG(1) << "Registered for power state changes.";
351 } else {
352 DLOG(WARNING) << "No power monitor. Process suspension will invalidate "
353 "the encoder.";
354 }
340 } 355 }
341 } 356 }
342 357
343 H264VideoToolboxEncoder::~H264VideoToolboxEncoder() { 358 H264VideoToolboxEncoder::~H264VideoToolboxEncoder() {
344 DestroyCompressionSession(); 359 DestroyCompressionSession();
360
361 // If video_frame_factory_ is not null, the encoder registered for power state
362 // changes in the ctor and it must now unregister.
363 if (video_frame_factory_) {
364 auto power_monitor = base::PowerMonitor::Get();
365 if (power_monitor)
366 power_monitor->RemoveObserver(this);
367 }
345 } 368 }
346 369
347 void H264VideoToolboxEncoder::ResetCompressionSession() { 370 void H264VideoToolboxEncoder::ResetCompressionSession() {
348 DCHECK(thread_checker_.CalledOnValidThread()); 371 DCHECK(thread_checker_.CalledOnValidThread());
349 372
373 // Ignore reset requests while power suspended.
374 if (power_suspended_)
375 return;
376
350 // Notify that we're resetting the encoder. 377 // Notify that we're resetting the encoder.
351 cast_environment_->PostTask( 378 cast_environment_->PostTask(
352 CastEnvironment::MAIN, FROM_HERE, 379 CastEnvironment::MAIN, FROM_HERE,
353 base::Bind(status_change_cb_, STATUS_CODEC_REINIT_PENDING)); 380 base::Bind(status_change_cb_, STATUS_CODEC_REINIT_PENDING));
354 381
355 // Destroy the current session, if any. 382 // Destroy the current session, if any.
356 DestroyCompressionSession(); 383 DestroyCompressionSession();
357 384
358 // On OS X, allow the hardware encoder. Don't require it, it does not support 385 // On OS X, allow the hardware encoder. Don't require it, it does not support
359 // all configurations (some of which are used for testing). 386 // all configurations (some of which are used for testing).
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 if (!compression_session_) 645 if (!compression_session_)
619 return; 646 return;
620 647
621 OSStatus status = videotoolbox_glue_->VTCompressionSessionCompleteFrames( 648 OSStatus status = videotoolbox_glue_->VTCompressionSessionCompleteFrames(
622 compression_session_, CoreMediaGlue::CMTime{0, 0, 0, 0}); 649 compression_session_, CoreMediaGlue::CMTime{0, 0, 0, 0});
623 if (status != noErr) { 650 if (status != noErr) {
624 DLOG(ERROR) << " VTCompressionSessionCompleteFrames failed: " << status; 651 DLOG(ERROR) << " VTCompressionSessionCompleteFrames failed: " << status;
625 } 652 }
626 } 653 }
627 654
655 void H264VideoToolboxEncoder::OnSuspend() {
656 VLOG(1)
657 << "OnSuspend: Emitting all frames and destroying compression session.";
658 EmitFrames();
659 DestroyCompressionSession();
660 power_suspended_ = true;
661 }
662
663 void H264VideoToolboxEncoder::OnResume() {
664 power_suspended_ = false;
665
666 // Reset the compression session only if the frame size is not zero (which
667 // will obviously fail). It is possible for the frame size to be zero if no
668 // frame was submitted for encoding or requested from the video frame factory
669 // before suspension.
670 if (!frame_size_.IsEmpty()) {
671 VLOG(1) << "OnResume: Resetting compression session.";
672 ResetCompressionSession();
673 }
674 }
675
628 bool H264VideoToolboxEncoder::SetSessionProperty(CFStringRef key, 676 bool H264VideoToolboxEncoder::SetSessionProperty(CFStringRef key,
629 int32_t value) { 677 int32_t value) {
630 base::ScopedCFTypeRef<CFNumberRef> cfvalue( 678 base::ScopedCFTypeRef<CFNumberRef> cfvalue(
631 CFNumberCreate(nullptr, kCFNumberSInt32Type, &value)); 679 CFNumberCreate(nullptr, kCFNumberSInt32Type, &value));
632 return videotoolbox_glue_->VTSessionSetProperty(compression_session_, key, 680 return videotoolbox_glue_->VTSessionSetProperty(compression_session_, key,
633 cfvalue) == noErr; 681 cfvalue) == noErr;
634 } 682 }
635 683
636 bool H264VideoToolboxEncoder::SetSessionProperty(CFStringRef key, bool value) { 684 bool H264VideoToolboxEncoder::SetSessionProperty(CFStringRef key, bool value) {
637 CFBooleanRef cfvalue = (value) ? kCFBooleanTrue : kCFBooleanFalse; 685 CFBooleanRef cfvalue = (value) ? kCFBooleanTrue : kCFBooleanFalse;
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
707 CopySampleBufferToAnnexBBuffer(sbuf, &encoded_frame->data, keyframe); 755 CopySampleBufferToAnnexBBuffer(sbuf, &encoded_frame->data, keyframe);
708 756
709 encoder->cast_environment_->PostTask( 757 encoder->cast_environment_->PostTask(
710 CastEnvironment::MAIN, FROM_HERE, 758 CastEnvironment::MAIN, FROM_HERE,
711 base::Bind(request->frame_encoded_callback, 759 base::Bind(request->frame_encoded_callback,
712 base::Passed(&encoded_frame))); 760 base::Passed(&encoded_frame)));
713 } 761 }
714 762
715 } // namespace cast 763 } // namespace cast
716 } // namespace media 764 } // namespace media
OLDNEW
« no previous file with comments | « media/cast/sender/h264_vt_encoder.h ('k') | media/cast/sender/h264_vt_encoder_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698