OLD | NEW |
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 <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <string> | 9 #include <string> |
10 #include <vector> | 10 #include <vector> |
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
400 DLOG(ERROR) << "WrapVideoFrameInCVPixelBuffer failed."; | 400 DLOG(ERROR) << "WrapVideoFrameInCVPixelBuffer failed."; |
401 return false; | 401 return false; |
402 } | 402 } |
403 | 403 |
404 // Convert the frame timestamp to CMTime. | 404 // Convert the frame timestamp to CMTime. |
405 auto timestamp_cm = CoreMediaGlue::CMTimeMake( | 405 auto timestamp_cm = CoreMediaGlue::CMTimeMake( |
406 video_frame->timestamp().InMicroseconds(), USEC_PER_SEC); | 406 video_frame->timestamp().InMicroseconds(), USEC_PER_SEC); |
407 | 407 |
408 // Wrap information we'll need after the frame is encoded in a heap object. | 408 // Wrap information we'll need after the frame is encoded in a heap object. |
409 // We'll get the pointer back from the VideoToolbox completion callback. | 409 // We'll get the pointer back from the VideoToolbox completion callback. |
410 scoped_ptr<InProgressFrameEncode> request(new InProgressFrameEncode( | 410 std::unique_ptr<InProgressFrameEncode> request(new InProgressFrameEncode( |
411 RtpTimeTicks::FromTimeDelta(video_frame->timestamp(), kVideoFrequency), | 411 RtpTimeTicks::FromTimeDelta(video_frame->timestamp(), kVideoFrequency), |
412 reference_time, frame_encoded_callback)); | 412 reference_time, frame_encoded_callback)); |
413 | 413 |
414 // Build a suitable frame properties dictionary for keyframes. | 414 // Build a suitable frame properties dictionary for keyframes. |
415 base::ScopedCFTypeRef<CFDictionaryRef> frame_props; | 415 base::ScopedCFTypeRef<CFDictionaryRef> frame_props; |
416 if (encode_next_frame_as_keyframe_) { | 416 if (encode_next_frame_as_keyframe_) { |
417 frame_props = video_toolbox::DictionaryWithKeyValue( | 417 frame_props = video_toolbox::DictionaryWithKeyValue( |
418 videotoolbox_glue_->kVTEncodeFrameOptionKey_ForceKeyFrame(), | 418 videotoolbox_glue_->kVTEncodeFrameOptionKey_ForceKeyFrame(), |
419 kCFBooleanTrue); | 419 kCFBooleanTrue); |
420 encode_next_frame_as_keyframe_ = false; | 420 encode_next_frame_as_keyframe_ = false; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
463 void H264VideoToolboxEncoder::SetBitRate(int /*new_bit_rate*/) { | 463 void H264VideoToolboxEncoder::SetBitRate(int /*new_bit_rate*/) { |
464 DCHECK(thread_checker_.CalledOnValidThread()); | 464 DCHECK(thread_checker_.CalledOnValidThread()); |
465 // VideoToolbox does not seem to support bitrate reconfiguration. | 465 // VideoToolbox does not seem to support bitrate reconfiguration. |
466 } | 466 } |
467 | 467 |
468 void H264VideoToolboxEncoder::GenerateKeyFrame() { | 468 void H264VideoToolboxEncoder::GenerateKeyFrame() { |
469 DCHECK(thread_checker_.CalledOnValidThread()); | 469 DCHECK(thread_checker_.CalledOnValidThread()); |
470 encode_next_frame_as_keyframe_ = true; | 470 encode_next_frame_as_keyframe_ = true; |
471 } | 471 } |
472 | 472 |
473 scoped_ptr<VideoFrameFactory> | 473 std::unique_ptr<VideoFrameFactory> |
474 H264VideoToolboxEncoder::CreateVideoFrameFactory() { | 474 H264VideoToolboxEncoder::CreateVideoFrameFactory() { |
475 DCHECK(thread_checker_.CalledOnValidThread()); | 475 DCHECK(thread_checker_.CalledOnValidThread()); |
476 return scoped_ptr<VideoFrameFactory>( | 476 return std::unique_ptr<VideoFrameFactory>( |
477 new VideoFrameFactoryImpl::Proxy(video_frame_factory_)); | 477 new VideoFrameFactoryImpl::Proxy(video_frame_factory_)); |
478 } | 478 } |
479 | 479 |
480 void H264VideoToolboxEncoder::EmitFrames() { | 480 void H264VideoToolboxEncoder::EmitFrames() { |
481 DCHECK(thread_checker_.CalledOnValidThread()); | 481 DCHECK(thread_checker_.CalledOnValidThread()); |
482 if (!compression_session_) | 482 if (!compression_session_) |
483 return; | 483 return; |
484 | 484 |
485 OSStatus status = videotoolbox_glue_->VTCompressionSessionCompleteFrames( | 485 OSStatus status = videotoolbox_glue_->VTCompressionSessionCompleteFrames( |
486 compression_session_, CoreMediaGlue::CMTime{0, 0, 0, 0}); | 486 compression_session_, CoreMediaGlue::CMTime{0, 0, 0, 0}); |
(...skipping 22 matching lines...) Expand all Loading... |
509 ResetCompressionSession(); | 509 ResetCompressionSession(); |
510 } | 510 } |
511 } | 511 } |
512 | 512 |
513 void H264VideoToolboxEncoder::CompressionCallback(void* encoder_opaque, | 513 void H264VideoToolboxEncoder::CompressionCallback(void* encoder_opaque, |
514 void* request_opaque, | 514 void* request_opaque, |
515 OSStatus status, | 515 OSStatus status, |
516 VTEncodeInfoFlags info, | 516 VTEncodeInfoFlags info, |
517 CMSampleBufferRef sbuf) { | 517 CMSampleBufferRef sbuf) { |
518 auto encoder = reinterpret_cast<H264VideoToolboxEncoder*>(encoder_opaque); | 518 auto encoder = reinterpret_cast<H264VideoToolboxEncoder*>(encoder_opaque); |
519 const scoped_ptr<InProgressFrameEncode> request( | 519 const std::unique_ptr<InProgressFrameEncode> request( |
520 reinterpret_cast<InProgressFrameEncode*>(request_opaque)); | 520 reinterpret_cast<InProgressFrameEncode*>(request_opaque)); |
521 bool keyframe = false; | 521 bool keyframe = false; |
522 bool has_frame_data = false; | 522 bool has_frame_data = false; |
523 | 523 |
524 if (status != noErr) { | 524 if (status != noErr) { |
525 DLOG(ERROR) << " encoding failed: " << status; | 525 DLOG(ERROR) << " encoding failed: " << status; |
526 encoder->cast_environment_->PostTask( | 526 encoder->cast_environment_->PostTask( |
527 CastEnvironment::MAIN, FROM_HERE, | 527 CastEnvironment::MAIN, FROM_HERE, |
528 base::Bind(encoder->status_change_cb_, STATUS_CODEC_RUNTIME_ERROR)); | 528 base::Bind(encoder->status_change_cb_, STATUS_CODEC_RUNTIME_ERROR)); |
529 } else if ((info & VideoToolboxGlue::kVTEncodeInfo_FrameDropped)) { | 529 } else if ((info & VideoToolboxGlue::kVTEncodeInfo_FrameDropped)) { |
(...skipping 10 matching lines...) Expand all Loading... |
540 keyframe = !CFDictionaryContainsKey( | 540 keyframe = !CFDictionaryContainsKey( |
541 sample_attachments, | 541 sample_attachments, |
542 CoreMediaGlue::kCMSampleAttachmentKey_NotSync()); | 542 CoreMediaGlue::kCMSampleAttachmentKey_NotSync()); |
543 has_frame_data = true; | 543 has_frame_data = true; |
544 } | 544 } |
545 | 545 |
546 // Increment the encoder-scoped frame id and assign the new value to this | 546 // Increment the encoder-scoped frame id and assign the new value to this |
547 // frame. VideoToolbox calls the output callback serially, so this is safe. | 547 // frame. VideoToolbox calls the output callback serially, so this is safe. |
548 const uint32_t frame_id = ++encoder->last_frame_id_; | 548 const uint32_t frame_id = ++encoder->last_frame_id_; |
549 | 549 |
550 scoped_ptr<SenderEncodedFrame> encoded_frame(new SenderEncodedFrame()); | 550 std::unique_ptr<SenderEncodedFrame> encoded_frame(new SenderEncodedFrame()); |
551 encoded_frame->frame_id = frame_id; | 551 encoded_frame->frame_id = frame_id; |
552 encoded_frame->reference_time = request->reference_time; | 552 encoded_frame->reference_time = request->reference_time; |
553 encoded_frame->rtp_timestamp = request->rtp_timestamp; | 553 encoded_frame->rtp_timestamp = request->rtp_timestamp; |
554 if (keyframe) { | 554 if (keyframe) { |
555 encoded_frame->dependency = EncodedFrame::KEY; | 555 encoded_frame->dependency = EncodedFrame::KEY; |
556 encoded_frame->referenced_frame_id = frame_id; | 556 encoded_frame->referenced_frame_id = frame_id; |
557 } else { | 557 } else { |
558 encoded_frame->dependency = EncodedFrame::DEPENDENT; | 558 encoded_frame->dependency = EncodedFrame::DEPENDENT; |
559 // H.264 supports complex frame reference schemes (multiple reference | 559 // H.264 supports complex frame reference schemes (multiple reference |
560 // frames, slice references, backward and forward references, etc). Cast | 560 // frames, slice references, backward and forward references, etc). Cast |
(...skipping 18 matching lines...) Expand all Loading... |
579 encoded_frame->encode_completion_time = | 579 encoded_frame->encode_completion_time = |
580 encoder->cast_environment_->Clock()->NowTicks(); | 580 encoder->cast_environment_->Clock()->NowTicks(); |
581 encoder->cast_environment_->PostTask( | 581 encoder->cast_environment_->PostTask( |
582 CastEnvironment::MAIN, FROM_HERE, | 582 CastEnvironment::MAIN, FROM_HERE, |
583 base::Bind(request->frame_encoded_callback, | 583 base::Bind(request->frame_encoded_callback, |
584 base::Passed(&encoded_frame))); | 584 base::Passed(&encoded_frame))); |
585 } | 585 } |
586 | 586 |
587 } // namespace cast | 587 } // namespace cast |
588 } // namespace media | 588 } // namespace media |
OLD | NEW |