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

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

Issue 1939683002: Test X11 header pollution (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 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') | media/media.gyp » ('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 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 "content/common/gpu/media/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/thread_task_runner_handle.h" 9 #include "base/thread_task_runner_handle.h"
10 #include "media/base/mac/coremedia_glue.h" 10 #include "media/base/mac/coremedia_glue.h"
11 #include "media/base/mac/corevideo_glue.h" 11 #include "media/base/mac/corevideo_glue.h"
12 #include "media/base/mac/video_frame_mac.h" 12 #include "media/base/mac/video_frame_mac.h"
13 13
14 namespace content { 14 namespace media {
15 15
16 namespace { 16 namespace {
17 17
18 // TODO(emircan): Check if we can find the actual system capabilities via 18 // TODO(emircan): Check if we can find the actual system capabilities via
19 // creating VTCompressionSessions with varying requirements. 19 // creating VTCompressionSessions with varying requirements.
20 // See crbug.com/584784. 20 // See crbug.com/584784.
21 const size_t kBitsPerByte = 8; 21 const size_t kBitsPerByte = 8;
22 const size_t kDefaultResolutionWidth = 640; 22 const size_t kDefaultResolutionWidth = 640;
23 const size_t kDefaultResolutionHeight = 480; 23 const size_t kDefaultResolutionHeight = 480;
24 const size_t kMaxFrameRateNumerator = 30; 24 const size_t kMaxFrameRateNumerator = 30;
25 const size_t kMaxFrameRateDenominator = 1; 25 const size_t kMaxFrameRateDenominator = 1;
26 const size_t kMaxResolutionWidth = 4096; 26 const size_t kMaxResolutionWidth = 4096;
27 const size_t kMaxResolutionHeight = 2160; 27 const size_t kMaxResolutionHeight = 2160;
28 const size_t kNumInputBuffers = 3; 28 const size_t kNumInputBuffers = 3;
29 29
30 } // namespace 30 } // namespace
31 31
32 struct VTVideoEncodeAccelerator::InProgressFrameEncode { 32 struct VTVideoEncodeAccelerator::InProgressFrameEncode {
33 InProgressFrameEncode(base::TimeDelta rtp_timestamp, 33 InProgressFrameEncode(base::TimeDelta rtp_timestamp, base::TimeTicks ref_time)
34 base::TimeTicks ref_time)
35 : timestamp(rtp_timestamp), reference_time(ref_time) {} 34 : timestamp(rtp_timestamp), reference_time(ref_time) {}
36 const base::TimeDelta timestamp; 35 const base::TimeDelta timestamp;
37 const base::TimeTicks reference_time; 36 const base::TimeTicks reference_time;
38 37
39 private: 38 private:
40 DISALLOW_IMPLICIT_CONSTRUCTORS(InProgressFrameEncode); 39 DISALLOW_IMPLICIT_CONSTRUCTORS(InProgressFrameEncode);
41 }; 40 };
42 41
43 struct VTVideoEncodeAccelerator::EncodeOutput { 42 struct VTVideoEncodeAccelerator::EncodeOutput {
44 EncodeOutput(VTEncodeInfoFlags info_flags, CMSampleBufferRef sbuf) 43 EncodeOutput(VTEncodeInfoFlags info_flags, CMSampleBufferRef sbuf)
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 << ", initial_bitrate=" << initial_bitrate; 122 << ", initial_bitrate=" << initial_bitrate;
124 DCHECK(thread_checker_.CalledOnValidThread()); 123 DCHECK(thread_checker_.CalledOnValidThread());
125 DCHECK(client); 124 DCHECK(client);
126 125
127 if (media::PIXEL_FORMAT_I420 != format) { 126 if (media::PIXEL_FORMAT_I420 != format) {
128 DLOG(ERROR) << "Input format not supported= " 127 DLOG(ERROR) << "Input format not supported= "
129 << media::VideoPixelFormatToString(format); 128 << media::VideoPixelFormatToString(format);
130 return false; 129 return false;
131 } 130 }
132 if (media::H264PROFILE_BASELINE != output_profile) { 131 if (media::H264PROFILE_BASELINE != output_profile) {
133 DLOG(ERROR) << "Output profile not supported= " 132 DLOG(ERROR) << "Output profile not supported= " << output_profile;
134 << output_profile;
135 return false; 133 return false;
136 } 134 }
137 135
138 videotoolbox_glue_ = VideoToolboxGlue::Get(); 136 videotoolbox_glue_ = VideoToolboxGlue::Get();
139 if (!videotoolbox_glue_) { 137 if (!videotoolbox_glue_) {
140 DLOG(ERROR) << "Failed creating VideoToolbox glue."; 138 DLOG(ERROR) << "Failed creating VideoToolbox glue.";
141 return false; 139 return false;
142 } 140 }
143 141
144 client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client)); 142 client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client));
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 219
222 void VTVideoEncodeAccelerator::Destroy() { 220 void VTVideoEncodeAccelerator::Destroy() {
223 DVLOG(3) << __FUNCTION__; 221 DVLOG(3) << __FUNCTION__;
224 DCHECK(thread_checker_.CalledOnValidThread()); 222 DCHECK(thread_checker_.CalledOnValidThread());
225 223
226 // Cancel all callbacks. 224 // Cancel all callbacks.
227 client_ptr_factory_.reset(); 225 client_ptr_factory_.reset();
228 226
229 if (encoder_thread_.IsRunning()) { 227 if (encoder_thread_.IsRunning()) {
230 encoder_thread_task_runner_->PostTask( 228 encoder_thread_task_runner_->PostTask(
231 FROM_HERE, 229 FROM_HERE, base::Bind(&VTVideoEncodeAccelerator::DestroyTask,
232 base::Bind(&VTVideoEncodeAccelerator::DestroyTask, 230 base::Unretained(this)));
233 base::Unretained(this)));
234 encoder_thread_.Stop(); 231 encoder_thread_.Stop();
235 } else { 232 } else {
236 DestroyTask(); 233 DestroyTask();
237 } 234 }
238 } 235 }
239 236
240 void VTVideoEncodeAccelerator::EncodeTask( 237 void VTVideoEncodeAccelerator::EncodeTask(
241 const scoped_refptr<media::VideoFrame>& frame, 238 const scoped_refptr<media::VideoFrame>& frame,
242 bool force_keyframe) { 239 bool force_keyframe) {
243 DCHECK(encoder_thread_task_runner_->BelongsToCurrentThread()); 240 DCHECK(encoder_thread_task_runner_->BelongsToCurrentThread());
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 client_task_runner_->PostTask( 406 client_task_runner_->PostTask(
410 FROM_HERE, base::Bind(&Client::BitstreamBufferReady, client_, 407 FROM_HERE, base::Bind(&Client::BitstreamBufferReady, client_,
411 buffer_ref->id, 0, false)); 408 buffer_ref->id, 0, false));
412 return; 409 return;
413 } 410 }
414 411
415 auto sample_attachments = static_cast<CFDictionaryRef>(CFArrayGetValueAtIndex( 412 auto sample_attachments = static_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(
416 CoreMediaGlue::CMSampleBufferGetSampleAttachmentsArray( 413 CoreMediaGlue::CMSampleBufferGetSampleAttachmentsArray(
417 encode_output->sample_buffer.get(), true), 414 encode_output->sample_buffer.get(), true),
418 0)); 415 0));
419 const bool keyframe = 416 const bool keyframe = !CFDictionaryContainsKey(
420 !CFDictionaryContainsKey(sample_attachments, 417 sample_attachments, CoreMediaGlue::kCMSampleAttachmentKey_NotSync());
421 CoreMediaGlue::kCMSampleAttachmentKey_NotSync());
422 418
423 size_t used_buffer_size = 0; 419 size_t used_buffer_size = 0;
424 const bool copy_rv = media::video_toolbox::CopySampleBufferToAnnexBBuffer( 420 const bool copy_rv = media::video_toolbox::CopySampleBufferToAnnexBBuffer(
425 encode_output->sample_buffer.get(), keyframe, buffer_ref->size, 421 encode_output->sample_buffer.get(), keyframe, buffer_ref->size,
426 reinterpret_cast<char*>(buffer_ref->shm->memory()), &used_buffer_size); 422 reinterpret_cast<char*>(buffer_ref->shm->memory()), &used_buffer_size);
427 if (!copy_rv) { 423 if (!copy_rv) {
428 DLOG(ERROR) << "Cannot copy output from SampleBuffer to AnnexBBuffer."; 424 DLOG(ERROR) << "Cannot copy output from SampleBuffer to AnnexBBuffer.";
429 used_buffer_size = 0; 425 used_buffer_size = 0;
430 } 426 }
431 427
432 client_task_runner_->PostTask( 428 client_task_runner_->PostTask(
433 FROM_HERE, base::Bind(&Client::BitstreamBufferReady, client_, 429 FROM_HERE, base::Bind(&Client::BitstreamBufferReady, client_,
434 buffer_ref->id, used_buffer_size, keyframe)); 430 buffer_ref->id, used_buffer_size, keyframe));
435 } 431 }
436 432
437 bool VTVideoEncodeAccelerator::ResetCompressionSession() { 433 bool VTVideoEncodeAccelerator::ResetCompressionSession() {
438 DCHECK(thread_checker_.CalledOnValidThread()); 434 DCHECK(thread_checker_.CalledOnValidThread());
439 435
440 DestroyCompressionSession(); 436 DestroyCompressionSession();
441 437
442 CFTypeRef attributes_keys[] = { 438 CFTypeRef attributes_keys[] = {kCVPixelBufferOpenGLCompatibilityKey,
443 kCVPixelBufferOpenGLCompatibilityKey, 439 kCVPixelBufferIOSurfacePropertiesKey,
444 kCVPixelBufferIOSurfacePropertiesKey, 440 kCVPixelBufferPixelFormatTypeKey};
445 kCVPixelBufferPixelFormatTypeKey
446 };
447 const int format[] = { 441 const int format[] = {
448 CoreVideoGlue::kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange}; 442 CoreVideoGlue::kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange};
449 CFTypeRef attributes_values[] = { 443 CFTypeRef attributes_values[] = {
450 kCFBooleanTrue, 444 kCFBooleanTrue,
451 media::video_toolbox::DictionaryWithKeysAndValues(nullptr, nullptr, 0) 445 media::video_toolbox::DictionaryWithKeysAndValues(nullptr, nullptr, 0)
452 .release(), 446 .release(),
453 media::video_toolbox::ArrayWithIntegers(format, arraysize(format)) 447 media::video_toolbox::ArrayWithIntegers(format, arraysize(format))
454 .release()}; 448 .release()};
455 const base::ScopedCFTypeRef<CFDictionaryRef> attributes = 449 const base::ScopedCFTypeRef<CFDictionaryRef> attributes =
456 media::video_toolbox::DictionaryWithKeysAndValues( 450 media::video_toolbox::DictionaryWithKeysAndValues(
(...skipping 16 matching lines...) Expand all
473 467
474 bool VTVideoEncodeAccelerator::CreateCompressionSession( 468 bool VTVideoEncodeAccelerator::CreateCompressionSession(
475 base::ScopedCFTypeRef<CFDictionaryRef> attributes, 469 base::ScopedCFTypeRef<CFDictionaryRef> attributes,
476 const gfx::Size& input_size, 470 const gfx::Size& input_size,
477 bool require_hw_encoding) { 471 bool require_hw_encoding) {
478 DCHECK(thread_checker_.CalledOnValidThread()); 472 DCHECK(thread_checker_.CalledOnValidThread());
479 473
480 std::vector<CFTypeRef> encoder_keys; 474 std::vector<CFTypeRef> encoder_keys;
481 std::vector<CFTypeRef> encoder_values; 475 std::vector<CFTypeRef> encoder_values;
482 if (require_hw_encoding) { 476 if (require_hw_encoding) {
483 encoder_keys.push_back(videotoolbox_glue_ 477 encoder_keys.push_back(
484 ->kVTVideoEncoderSpecification_RequireHardwareAcceleratedVideoEncoder()); 478 videotoolbox_glue_
479 ->kVTVideoEncoderSpecification_RequireHardwareAcceleratedVideoEncode r());
485 encoder_values.push_back(kCFBooleanTrue); 480 encoder_values.push_back(kCFBooleanTrue);
486 } else { 481 } else {
487 encoder_keys.push_back(videotoolbox_glue_ 482 encoder_keys.push_back(
488 ->kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder()); 483 videotoolbox_glue_
484 ->kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder ());
489 encoder_values.push_back(kCFBooleanTrue); 485 encoder_values.push_back(kCFBooleanTrue);
490 } 486 }
491 base::ScopedCFTypeRef<CFDictionaryRef> encoder_spec = 487 base::ScopedCFTypeRef<CFDictionaryRef> encoder_spec =
492 media::video_toolbox::DictionaryWithKeysAndValues( 488 media::video_toolbox::DictionaryWithKeysAndValues(
493 encoder_keys.data(), encoder_values.data(), encoder_keys.size()); 489 encoder_keys.data(), encoder_values.data(), encoder_keys.size());
494 490
495 // Create the compression session. 491 // Create the compression session.
496 // Note that the encoder object is given to the compression session as the 492 // Note that the encoder object is given to the compression session as the
497 // callback context using a raw pointer. The C API does not allow us to use a 493 // callback context using a raw pointer. The C API does not allow us to use a
498 // smart pointer, nor is this encoder ref counted. However, this is still 494 // smart pointer, nor is this encoder ref counted. However, this is still
499 // safe, because we 1) we own the compression session and 2) we tear it down 495 // safe, because we 1) we own the compression session and 2) we tear it down
500 // safely. When destructing the encoder, the compression session is flushed 496 // safely. When destructing the encoder, the compression session is flushed
501 // and invalidated. Internally, VideoToolbox will join all of its threads 497 // and invalidated. Internally, VideoToolbox will join all of its threads
502 // before returning to the client. Therefore, when control returns to us, we 498 // before returning to the client. Therefore, when control returns to us, we
503 // are guaranteed that the output callback will not execute again. 499 // are guaranteed that the output callback will not execute again.
504 OSStatus status = videotoolbox_glue_->VTCompressionSessionCreate( 500 OSStatus status = videotoolbox_glue_->VTCompressionSessionCreate(
505 kCFAllocatorDefault, 501 kCFAllocatorDefault, input_size.width(), input_size.height(),
506 input_size.width(), 502 CoreMediaGlue::kCMVideoCodecType_H264, encoder_spec, attributes,
507 input_size.height(),
508 CoreMediaGlue::kCMVideoCodecType_H264,
509 encoder_spec,
510 attributes,
511 nullptr /* compressedDataAllocator */, 503 nullptr /* compressedDataAllocator */,
512 &VTVideoEncodeAccelerator::CompressionCallback, 504 &VTVideoEncodeAccelerator::CompressionCallback,
513 reinterpret_cast<void*>(this), 505 reinterpret_cast<void*>(this), compression_session_.InitializeInto());
514 compression_session_.InitializeInto());
515 if (status != noErr) { 506 if (status != noErr) {
516 DLOG(ERROR) << " VTCompressionSessionCreate failed: " << status; 507 DLOG(ERROR) << " VTCompressionSessionCreate failed: " << status;
517 return false; 508 return false;
518 } 509 }
519 DVLOG(3) << " VTCompressionSession created with HW encode: " 510 DVLOG(3) << " VTCompressionSession created with HW encode: "
520 << require_hw_encoding << ", input size=" << input_size.ToString(); 511 << require_hw_encoding << ", input size=" << input_size.ToString();
521 return true; 512 return true;
522 } 513 }
523 514
524 bool VTVideoEncodeAccelerator::ConfigureCompressionSession() { 515 bool VTVideoEncodeAccelerator::ConfigureCompressionSession() {
(...skipping 19 matching lines...) Expand all
544 DCHECK(thread_checker_.CalledOnValidThread() || 535 DCHECK(thread_checker_.CalledOnValidThread() ||
545 (encoder_thread_.IsRunning() && 536 (encoder_thread_.IsRunning() &&
546 encoder_thread_task_runner_->BelongsToCurrentThread())); 537 encoder_thread_task_runner_->BelongsToCurrentThread()));
547 538
548 if (compression_session_) { 539 if (compression_session_) {
549 videotoolbox_glue_->VTCompressionSessionInvalidate(compression_session_); 540 videotoolbox_glue_->VTCompressionSessionInvalidate(compression_session_);
550 compression_session_.reset(); 541 compression_session_.reset();
551 } 542 }
552 } 543 }
553 544
554 } // namespace content 545 } // namespace media
OLDNEW
« no previous file with comments | « media/gpu/vt_video_encode_accelerator_mac.h ('k') | media/media.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698