| 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 |