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

Side by Side Diff: media/gpu/vt_video_encode_accelerator_mac.cc

Issue 2790063003: Merge 58: Enforce MaxFrameDelayCount in VTVideoEncodeAccelerator and cleanups (Closed)
Patch Set: Created 3 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/gpu/vt_video_encode_accelerator_mac.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/gpu/vt_video_encode_accelerator_mac.h" 5 #include "media/gpu/vt_video_encode_accelerator_mac.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "base/threading/thread_task_runner_handle.h" 9 #include "base/threading/thread_task_runner_handle.h"
10 #include "media/base/mac/video_frame_mac.h" 10 #include "media/base/mac/video_frame_mac.h"
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 DCHECK(!encoder_task_weak_factory_.HasWeakPtrs()); 91 DCHECK(!encoder_task_weak_factory_.HasWeakPtrs());
92 } 92 }
93 93
94 VideoEncodeAccelerator::SupportedProfiles 94 VideoEncodeAccelerator::SupportedProfiles
95 VTVideoEncodeAccelerator::GetSupportedProfiles() { 95 VTVideoEncodeAccelerator::GetSupportedProfiles() {
96 DVLOG(3) << __func__; 96 DVLOG(3) << __func__;
97 DCHECK(thread_checker_.CalledOnValidThread()); 97 DCHECK(thread_checker_.CalledOnValidThread());
98 98
99 SupportedProfiles profiles; 99 SupportedProfiles profiles;
100 const bool rv = CreateCompressionSession( 100 const bool rv = CreateCompressionSession(
101 video_toolbox::DictionaryWithKeysAndValues(nullptr, nullptr, 0), 101 gfx::Size(kDefaultResolutionWidth, kDefaultResolutionHeight));
102 gfx::Size(kDefaultResolutionWidth, kDefaultResolutionHeight), true);
103 DestroyCompressionSession(); 102 DestroyCompressionSession();
104 if (!rv) { 103 if (!rv) {
105 VLOG(1) 104 VLOG(1)
106 << "Hardware encode acceleration is not available on this platform."; 105 << "Hardware encode acceleration is not available on this platform.";
107 return profiles; 106 return profiles;
108 } 107 }
109 108
110 SupportedProfile profile; 109 SupportedProfile profile;
111 profile.profile = H264PROFILE_BASELINE; 110 profile.profile = H264PROFILE_BASELINE;
112 profile.max_framerate_numerator = kMaxFrameRateNumerator; 111 profile.max_framerate_numerator = kMaxFrameRateNumerator;
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 FROM_HERE, 444 FROM_HERE,
446 base::Bind(&Client::BitstreamBufferReady, client_, buffer_ref->id, 445 base::Bind(&Client::BitstreamBufferReady, client_, buffer_ref->id,
447 used_buffer_size, keyframe, encode_output->capture_timestamp)); 446 used_buffer_size, keyframe, encode_output->capture_timestamp));
448 } 447 }
449 448
450 bool VTVideoEncodeAccelerator::ResetCompressionSession() { 449 bool VTVideoEncodeAccelerator::ResetCompressionSession() {
451 DCHECK(thread_checker_.CalledOnValidThread()); 450 DCHECK(thread_checker_.CalledOnValidThread());
452 451
453 DestroyCompressionSession(); 452 DestroyCompressionSession();
454 453
455 CFTypeRef attributes_keys[] = {kCVPixelBufferOpenGLCompatibilityKey, 454 bool session_rv = CreateCompressionSession(input_visible_size_);
456 kCVPixelBufferIOSurfacePropertiesKey,
457 kCVPixelBufferPixelFormatTypeKey};
458 const int format[] = {kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange};
459 CFTypeRef attributes_values[] = {
460 kCFBooleanTrue,
461 video_toolbox::DictionaryWithKeysAndValues(nullptr, nullptr, 0).release(),
462 video_toolbox::ArrayWithIntegers(format, arraysize(format)).release()};
463 const base::ScopedCFTypeRef<CFDictionaryRef> attributes =
464 video_toolbox::DictionaryWithKeysAndValues(
465 attributes_keys, attributes_values, arraysize(attributes_keys));
466 for (auto* v : attributes_values)
467 CFRelease(v);
468
469 bool session_rv =
470 CreateCompressionSession(attributes, input_visible_size_, false);
471 if (!session_rv) { 455 if (!session_rv) {
472 DestroyCompressionSession(); 456 DestroyCompressionSession();
473 return false; 457 return false;
474 } 458 }
475 459
476 const bool configure_rv = ConfigureCompressionSession(); 460 const bool configure_rv = ConfigureCompressionSession();
477 if (configure_rv) 461 if (configure_rv)
478 RequestEncodingParametersChange(initial_bitrate_, frame_rate_); 462 RequestEncodingParametersChange(initial_bitrate_, frame_rate_);
479 return configure_rv; 463 return configure_rv;
480 } 464 }
481 465
482 bool VTVideoEncodeAccelerator::CreateCompressionSession( 466 bool VTVideoEncodeAccelerator::CreateCompressionSession(
483 base::ScopedCFTypeRef<CFDictionaryRef> attributes, 467 const gfx::Size& input_size) {
484 const gfx::Size& input_size,
485 bool require_hw_encoding) {
486 DCHECK(thread_checker_.CalledOnValidThread()); 468 DCHECK(thread_checker_.CalledOnValidThread());
487 469
488 std::vector<CFTypeRef> encoder_keys; 470 std::vector<CFTypeRef> encoder_keys(
489 std::vector<CFTypeRef> encoder_values; 471 1, kVTVideoEncoderSpecification_RequireHardwareAcceleratedVideoEncoder);
490 if (require_hw_encoding) { 472 std::vector<CFTypeRef> encoder_values(1, kCFBooleanTrue);
491 encoder_keys.push_back(
492 kVTVideoEncoderSpecification_RequireHardwareAcceleratedVideoEncoder);
493 encoder_values.push_back(kCFBooleanTrue);
494 } else {
495 encoder_keys.push_back(
496 kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder);
497 encoder_values.push_back(kCFBooleanTrue);
498 }
499 base::ScopedCFTypeRef<CFDictionaryRef> encoder_spec = 473 base::ScopedCFTypeRef<CFDictionaryRef> encoder_spec =
500 video_toolbox::DictionaryWithKeysAndValues( 474 video_toolbox::DictionaryWithKeysAndValues(
501 encoder_keys.data(), encoder_values.data(), encoder_keys.size()); 475 encoder_keys.data(), encoder_values.data(), encoder_keys.size());
502 476
503 // Create the compression session. 477 // Create the compression session.
504 // Note that the encoder object is given to the compression session as the 478 // Note that the encoder object is given to the compression session as the
505 // callback context using a raw pointer. The C API does not allow us to use a 479 // callback context using a raw pointer. The C API does not allow us to use a
506 // smart pointer, nor is this encoder ref counted. However, this is still 480 // smart pointer, nor is this encoder ref counted. However, this is still
507 // safe, because we 1) we own the compression session and 2) we tear it down 481 // safe, because we 1) we own the compression session and 2) we tear it down
508 // safely. When destructing the encoder, the compression session is flushed 482 // safely. When destructing the encoder, the compression session is flushed
509 // and invalidated. Internally, VideoToolbox will join all of its threads 483 // and invalidated. Internally, VideoToolbox will join all of its threads
510 // before returning to the client. Therefore, when control returns to us, we 484 // before returning to the client. Therefore, when control returns to us, we
511 // are guaranteed that the output callback will not execute again. 485 // are guaranteed that the output callback will not execute again.
512 OSStatus status = VTCompressionSessionCreate( 486 OSStatus status = VTCompressionSessionCreate(
513 kCFAllocatorDefault, input_size.width(), input_size.height(), 487 kCFAllocatorDefault, input_size.width(), input_size.height(),
514 kCMVideoCodecType_H264, encoder_spec, attributes, 488 kCMVideoCodecType_H264, encoder_spec,
489 nullptr /* sourceImageBufferAttributes */,
515 nullptr /* compressedDataAllocator */, 490 nullptr /* compressedDataAllocator */,
516 &VTVideoEncodeAccelerator::CompressionCallback, 491 &VTVideoEncodeAccelerator::CompressionCallback,
517 reinterpret_cast<void*>(this), compression_session_.InitializeInto()); 492 reinterpret_cast<void*>(this), compression_session_.InitializeInto());
518 if (status != noErr) { 493 if (status != noErr) {
519 DLOG(ERROR) << " VTCompressionSessionCreate failed: " << status; 494 DLOG(ERROR) << " VTCompressionSessionCreate failed: " << status;
520 return false; 495 return false;
521 } 496 }
522 DVLOG(3) << " VTCompressionSession created with HW encode: " 497 DVLOG(3) << " VTCompressionSession created with input size="
523 << require_hw_encoding << ", input size=" << input_size.ToString(); 498 << input_size.ToString();
524 return true; 499 return true;
525 } 500 }
526 501
527 bool VTVideoEncodeAccelerator::ConfigureCompressionSession() { 502 bool VTVideoEncodeAccelerator::ConfigureCompressionSession() {
528 DCHECK(thread_checker_.CalledOnValidThread()); 503 DCHECK(thread_checker_.CalledOnValidThread());
529 DCHECK(compression_session_); 504 DCHECK(compression_session_);
530 505
531 video_toolbox::SessionPropertySetter session_property_setter( 506 video_toolbox::SessionPropertySetter session_property_setter(
532 compression_session_); 507 compression_session_);
533 bool rv = true; 508 bool rv = true;
534 rv &= session_property_setter.Set(kVTCompressionPropertyKey_ProfileLevel, 509 rv &= session_property_setter.Set(kVTCompressionPropertyKey_ProfileLevel,
535 kVTProfileLevel_H264_Baseline_AutoLevel); 510 kVTProfileLevel_H264_Baseline_AutoLevel);
536 rv &= session_property_setter.Set(kVTCompressionPropertyKey_RealTime, true); 511 rv &= session_property_setter.Set(kVTCompressionPropertyKey_RealTime, true);
537 rv &= session_property_setter.Set( 512 rv &= session_property_setter.Set(
538 kVTCompressionPropertyKey_AllowFrameReordering, false); 513 kVTCompressionPropertyKey_AllowFrameReordering, false);
539 // Limit keyframe output to 4 minutes, see crbug.com/658429. 514 // Limit keyframe output to 4 minutes, see crbug.com/658429.
540 rv &= session_property_setter.Set( 515 rv &= session_property_setter.Set(
541 kVTCompressionPropertyKey_MaxKeyFrameInterval, 7200); 516 kVTCompressionPropertyKey_MaxKeyFrameInterval, 7200);
542 rv &= session_property_setter.Set( 517 rv &= session_property_setter.Set(
543 kVTCompressionPropertyKey_MaxKeyFrameIntervalDuration, 240); 518 kVTCompressionPropertyKey_MaxKeyFrameIntervalDuration, 240);
519 rv &=
520 session_property_setter.Set(kVTCompressionPropertyKey_MaxFrameDelayCount,
521 static_cast<int>(kNumInputBuffers));
544 DLOG_IF(ERROR, !rv) << " Setting session property failed."; 522 DLOG_IF(ERROR, !rv) << " Setting session property failed.";
545 return rv; 523 return rv;
546 } 524 }
547 525
548 void VTVideoEncodeAccelerator::DestroyCompressionSession() { 526 void VTVideoEncodeAccelerator::DestroyCompressionSession() {
549 DCHECK(thread_checker_.CalledOnValidThread() || 527 DCHECK(thread_checker_.CalledOnValidThread() ||
550 (encoder_thread_.IsRunning() && 528 (encoder_thread_.IsRunning() &&
551 encoder_thread_task_runner_->BelongsToCurrentThread())); 529 encoder_thread_task_runner_->BelongsToCurrentThread()));
552 530
553 if (compression_session_) { 531 if (compression_session_) {
554 VTCompressionSessionInvalidate(compression_session_); 532 VTCompressionSessionInvalidate(compression_session_);
555 compression_session_.reset(); 533 compression_session_.reset();
556 } 534 }
557 } 535 }
558 536
559 } // namespace media 537 } // namespace media
OLDNEW
« no previous file with comments | « media/gpu/vt_video_encode_accelerator_mac.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698