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

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

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