OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/renderer/media/rtc_video_encoder.h" | 5 #include "content/renderer/media/rtc_video_encoder.h" |
6 | 6 |
7 #include <string.h> | 7 #include <string.h> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/location.h" | 10 #include "base/location.h" |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
142 int32_t GetStatus() const; | 142 int32_t GetStatus() const; |
143 | 143 |
144 webrtc::VideoCodecType video_codec_type() { return video_codec_type_; } | 144 webrtc::VideoCodecType video_codec_type() { return video_codec_type_; } |
145 | 145 |
146 // media::VideoEncodeAccelerator::Client implementation. | 146 // media::VideoEncodeAccelerator::Client implementation. |
147 void RequireBitstreamBuffers(unsigned int input_count, | 147 void RequireBitstreamBuffers(unsigned int input_count, |
148 const gfx::Size& input_coded_size, | 148 const gfx::Size& input_coded_size, |
149 size_t output_buffer_size) override; | 149 size_t output_buffer_size) override; |
150 void BitstreamBufferReady(int32_t bitstream_buffer_id, | 150 void BitstreamBufferReady(int32_t bitstream_buffer_id, |
151 size_t payload_size, | 151 size_t payload_size, |
152 bool key_frame) override; | 152 bool key_frame, |
153 base::TimeDelta timestamp) override; | |
153 void NotifyError(media::VideoEncodeAccelerator::Error error) override; | 154 void NotifyError(media::VideoEncodeAccelerator::Error error) override; |
154 | 155 |
155 private: | 156 private: |
156 friend class base::RefCountedThreadSafe<Impl>; | 157 friend class base::RefCountedThreadSafe<Impl>; |
157 | 158 |
158 enum { | 159 enum { |
159 kInputBufferExtraCount = 1, // The number of input buffers allocated, more | 160 kInputBufferExtraCount = 1, // The number of input buffers allocated, more |
160 // than what is requested by | 161 // than what is requested by |
161 // VEA::RequireBitstreamBuffers(). | 162 // VEA::RequireBitstreamBuffers(). |
162 kOutputBufferCount = 3, | 163 kOutputBufferCount = 3, |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
442 video_encoder_->UseOutputBitstreamBuffer(media::BitstreamBuffer( | 443 video_encoder_->UseOutputBitstreamBuffer(media::BitstreamBuffer( |
443 i, output_buffers_[i]->handle(), output_buffers_[i]->mapped_size())); | 444 i, output_buffers_[i]->handle(), output_buffers_[i]->mapped_size())); |
444 output_buffers_free_count_++; | 445 output_buffers_free_count_++; |
445 } | 446 } |
446 DCHECK_EQ(GetStatus(), WEBRTC_VIDEO_CODEC_UNINITIALIZED); | 447 DCHECK_EQ(GetStatus(), WEBRTC_VIDEO_CODEC_UNINITIALIZED); |
447 SetStatus(WEBRTC_VIDEO_CODEC_OK); | 448 SetStatus(WEBRTC_VIDEO_CODEC_OK); |
448 SignalAsyncWaiter(WEBRTC_VIDEO_CODEC_OK); | 449 SignalAsyncWaiter(WEBRTC_VIDEO_CODEC_OK); |
449 } | 450 } |
450 | 451 |
451 void RTCVideoEncoder::Impl::BitstreamBufferReady(int32_t bitstream_buffer_id, | 452 void RTCVideoEncoder::Impl::BitstreamBufferReady(int32_t bitstream_buffer_id, |
452 size_t payload_size, | 453 size_t payload_size, |
453 bool key_frame) { | 454 bool key_frame, |
455 base::TimeDelta timestamp) { | |
454 DVLOG(3) << "Impl::BitstreamBufferReady(): " | 456 DVLOG(3) << "Impl::BitstreamBufferReady(): " |
455 "bitstream_buffer_id=" << bitstream_buffer_id | 457 "bitstream_buffer_id=" << bitstream_buffer_id |
456 << ", payload_size=" << payload_size | 458 << ", payload_size=" << payload_size |
457 << ", key_frame=" << key_frame; | 459 << ", key_frame=" << key_frame; |
458 DCHECK(thread_checker_.CalledOnValidThread()); | 460 DCHECK(thread_checker_.CalledOnValidThread()); |
459 | 461 |
460 if (bitstream_buffer_id < 0 || | 462 if (bitstream_buffer_id < 0 || |
461 bitstream_buffer_id >= static_cast<int>(output_buffers_.size())) { | 463 bitstream_buffer_id >= static_cast<int>(output_buffers_.size())) { |
462 LogAndNotifyError(FROM_HERE, "invalid bitstream_buffer_id", | 464 LogAndNotifyError(FROM_HERE, "invalid bitstream_buffer_id", |
463 media::VideoEncodeAccelerator::kPlatformFailureError); | 465 media::VideoEncodeAccelerator::kPlatformFailureError); |
464 return; | 466 return; |
465 } | 467 } |
466 base::SharedMemory* output_buffer = output_buffers_[bitstream_buffer_id]; | 468 base::SharedMemory* output_buffer = output_buffers_[bitstream_buffer_id]; |
467 if (payload_size > output_buffer->mapped_size()) { | 469 if (payload_size > output_buffer->mapped_size()) { |
468 LogAndNotifyError(FROM_HERE, "invalid payload_size", | 470 LogAndNotifyError(FROM_HERE, "invalid payload_size", |
469 media::VideoEncodeAccelerator::kPlatformFailureError); | 471 media::VideoEncodeAccelerator::kPlatformFailureError); |
470 return; | 472 return; |
471 } | 473 } |
472 output_buffers_free_count_--; | 474 output_buffers_free_count_--; |
473 | 475 |
474 // Use webrtc timestamps to ensure correct RTP sender behavior. | 476 const int64_t capture_time_us = timestamp.InMicroseconds(); |
Pawel Osciak
2016/05/23 07:15:52
Please remove this line and at l.489:
image.captu
shenghao
2016/05/24 10:50:19
Done.
| |
475 // TODO(hshi): obtain timestamp from the capturer, see crbug.com/350106. | |
476 const int64_t capture_time_us = rtc::TimeMicros(); | |
477 | 477 |
478 // Derive the capture time (in ms) and RTP timestamp (in 90KHz ticks). | 478 // Derive the capture time (in ms) and RTP timestamp (in 90KHz ticks). |
479 const int64_t capture_time_ms = capture_time_us / 1000; | 479 const int64_t capture_time_ms = capture_time_us / 1000; |
Pawel Osciak
2016/05/23 07:15:52
This could also be removed and l.480 modified acco
shenghao
2016/05/24 10:50:19
Done.
| |
480 const uint32_t rtp_timestamp = | 480 const uint32_t rtp_timestamp = |
pbos
2016/05/20 12:15:51
This is the timestamp that should be copied over f
shenghao
2016/05/24 10:50:19
Talked offline. We would calculate rtp_timestamp f
| |
481 static_cast<uint32_t>(capture_time_us * 90 / 1000); | 481 static_cast<uint32_t>(capture_time_us * 90 / 1000); |
482 | 482 |
483 webrtc::EncodedImage image( | 483 webrtc::EncodedImage image( |
484 reinterpret_cast<uint8_t*>(output_buffer->memory()), payload_size, | 484 reinterpret_cast<uint8_t*>(output_buffer->memory()), payload_size, |
485 output_buffer->mapped_size()); | 485 output_buffer->mapped_size()); |
486 image._encodedWidth = input_visible_size_.width(); | 486 image._encodedWidth = input_visible_size_.width(); |
487 image._encodedHeight = input_visible_size_.height(); | 487 image._encodedHeight = input_visible_size_.height(); |
488 image._timeStamp = rtp_timestamp; | 488 image._timeStamp = rtp_timestamp; |
489 image.capture_time_ms_ = capture_time_ms; | 489 image.capture_time_ms_ = capture_time_ms; |
490 image._frameType = | 490 image._frameType = |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
561 requires_copy = true; | 561 requires_copy = true; |
562 } | 562 } |
563 | 563 |
564 if (requires_copy) { | 564 if (requires_copy) { |
565 base::SharedMemory* input_buffer = input_buffers_[index]; | 565 base::SharedMemory* input_buffer = input_buffers_[index]; |
566 frame = media::VideoFrame::WrapExternalSharedMemory( | 566 frame = media::VideoFrame::WrapExternalSharedMemory( |
567 media::PIXEL_FORMAT_I420, input_frame_coded_size_, | 567 media::PIXEL_FORMAT_I420, input_frame_coded_size_, |
568 gfx::Rect(input_visible_size_), input_visible_size_, | 568 gfx::Rect(input_visible_size_), input_visible_size_, |
569 reinterpret_cast<uint8_t*>(input_buffer->memory()), | 569 reinterpret_cast<uint8_t*>(input_buffer->memory()), |
570 input_buffer->mapped_size(), input_buffer->handle(), 0, | 570 input_buffer->mapped_size(), input_buffer->handle(), 0, |
571 base::TimeDelta()); | 571 base::TimeDelta::FromMilliseconds(next_frame->ntp_time_ms())); |
pbos
2016/05/20 12:15:51
This needs to copy over next_frame->timestamp(), n
shenghao
2016/05/24 10:50:19
Talked offline. We agreed to use ntp_time_ms()
| |
572 if (!frame.get()) { | 572 if (!frame.get()) { |
573 LogAndNotifyError(FROM_HERE, "failed to create frame", | 573 LogAndNotifyError(FROM_HERE, "failed to create frame", |
574 media::VideoEncodeAccelerator::kPlatformFailureError); | 574 media::VideoEncodeAccelerator::kPlatformFailureError); |
575 return; | 575 return; |
576 } | 576 } |
577 // Do a strided copy of the input frame to match the input requirements for | 577 // Do a strided copy of the input frame to match the input requirements for |
578 // the encoder. | 578 // the encoder. |
579 // TODO(sheu): support zero-copy from WebRTC. http://crbug.com/269312 | 579 // TODO(sheu): support zero-copy from WebRTC. http://crbug.com/269312 |
580 if (libyuv::I420Copy(next_frame->video_frame_buffer()->DataY(), | 580 if (libyuv::I420Copy(next_frame->video_frame_buffer()->DataY(), |
581 next_frame->video_frame_buffer()->StrideY(), | 581 next_frame->video_frame_buffer()->StrideY(), |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
855 UMA_HISTOGRAM_BOOLEAN("Media.RTCVideoEncoderInitEncodeSuccess", | 855 UMA_HISTOGRAM_BOOLEAN("Media.RTCVideoEncoderInitEncodeSuccess", |
856 init_retval == WEBRTC_VIDEO_CODEC_OK); | 856 init_retval == WEBRTC_VIDEO_CODEC_OK); |
857 if (init_retval == WEBRTC_VIDEO_CODEC_OK) { | 857 if (init_retval == WEBRTC_VIDEO_CODEC_OK) { |
858 UMA_HISTOGRAM_ENUMERATION("Media.RTCVideoEncoderProfile", | 858 UMA_HISTOGRAM_ENUMERATION("Media.RTCVideoEncoderProfile", |
859 profile, | 859 profile, |
860 media::VIDEO_CODEC_PROFILE_MAX + 1); | 860 media::VIDEO_CODEC_PROFILE_MAX + 1); |
861 } | 861 } |
862 } | 862 } |
863 | 863 |
864 } // namespace content | 864 } // namespace content |
OLD | NEW |