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

Side by Side Diff: content/renderer/media/rtc_video_encoder.cc

Issue 1996453003: RTC Video Encoder: Use capturer timestamp (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 6 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 | « no previous file | content/renderer/media/video_track_recorder.cc » ('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 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
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
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.
475 // TODO(hshi): obtain timestamp from the capturer, see crbug.com/350106.
476 const int64_t capture_time_us = rtc::TimeMicros();
477
478 // Derive the capture time (in ms) and RTP timestamp (in 90KHz ticks). 476 // Derive the capture time (in ms) and RTP timestamp (in 90KHz ticks).
479 const int64_t capture_time_ms = capture_time_us / 1000; 477 // This is based on how input timestamps are calculated in
478 // webrtc/video/video_capture_input.cc.
480 const uint32_t rtp_timestamp = 479 const uint32_t rtp_timestamp =
481 static_cast<uint32_t>(capture_time_us * 90 / 1000); 480 static_cast<uint32_t>(timestamp.InMilliseconds()) * 90;
482 481
483 webrtc::EncodedImage image( 482 webrtc::EncodedImage image(
484 reinterpret_cast<uint8_t*>(output_buffer->memory()), payload_size, 483 reinterpret_cast<uint8_t*>(output_buffer->memory()), payload_size,
485 output_buffer->mapped_size()); 484 output_buffer->mapped_size());
486 image._encodedWidth = input_visible_size_.width(); 485 image._encodedWidth = input_visible_size_.width();
487 image._encodedHeight = input_visible_size_.height(); 486 image._encodedHeight = input_visible_size_.height();
488 image._timeStamp = rtp_timestamp; 487 image._timeStamp = rtp_timestamp;
489 image.capture_time_ms_ = capture_time_ms; 488 image.capture_time_ms_ = timestamp.InMilliseconds();
490 image._frameType = 489 image._frameType =
491 (key_frame ? webrtc::kVideoFrameKey : webrtc::kVideoFrameDelta); 490 (key_frame ? webrtc::kVideoFrameKey : webrtc::kVideoFrameDelta);
492 image._completeFrame = true; 491 image._completeFrame = true;
493 492
494 ReturnEncodedImage(image, bitstream_buffer_id, picture_id_); 493 ReturnEncodedImage(image, bitstream_buffer_id, picture_id_);
495 // Picture ID must wrap after reaching the maximum. 494 // Picture ID must wrap after reaching the maximum.
496 picture_id_ = (picture_id_ + 1) & 0x7FFF; 495 picture_id_ = (picture_id_ + 1) & 0x7FFF;
497 } 496 }
498 497
499 void RTCVideoEncoder::Impl::NotifyError( 498 void RTCVideoEncoder::Impl::NotifyError(
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
561 requires_copy = true; 560 requires_copy = true;
562 } 561 }
563 562
564 if (requires_copy) { 563 if (requires_copy) {
565 base::SharedMemory* input_buffer = input_buffers_[index]; 564 base::SharedMemory* input_buffer = input_buffers_[index];
566 frame = media::VideoFrame::WrapExternalSharedMemory( 565 frame = media::VideoFrame::WrapExternalSharedMemory(
567 media::PIXEL_FORMAT_I420, input_frame_coded_size_, 566 media::PIXEL_FORMAT_I420, input_frame_coded_size_,
568 gfx::Rect(input_visible_size_), input_visible_size_, 567 gfx::Rect(input_visible_size_), input_visible_size_,
569 reinterpret_cast<uint8_t*>(input_buffer->memory()), 568 reinterpret_cast<uint8_t*>(input_buffer->memory()),
570 input_buffer->mapped_size(), input_buffer->handle(), 0, 569 input_buffer->mapped_size(), input_buffer->handle(), 0,
571 base::TimeDelta()); 570 base::TimeDelta::FromMilliseconds(next_frame->ntp_time_ms()));
572 if (!frame.get()) { 571 if (!frame.get()) {
573 LogAndNotifyError(FROM_HERE, "failed to create frame", 572 LogAndNotifyError(FROM_HERE, "failed to create frame",
574 media::VideoEncodeAccelerator::kPlatformFailureError); 573 media::VideoEncodeAccelerator::kPlatformFailureError);
575 return; 574 return;
576 } 575 }
577 // Do a strided copy of the input frame to match the input requirements for 576 // Do a strided copy of the input frame to match the input requirements for
578 // the encoder. 577 // the encoder.
579 // TODO(sheu): support zero-copy from WebRTC. http://crbug.com/269312 578 // TODO(sheu): support zero-copy from WebRTC. http://crbug.com/269312
580 if (libyuv::I420Copy(next_frame->video_frame_buffer()->DataY(), 579 if (libyuv::I420Copy(next_frame->video_frame_buffer()->DataY(),
581 next_frame->video_frame_buffer()->StrideY(), 580 next_frame->video_frame_buffer()->StrideY(),
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
855 UMA_HISTOGRAM_BOOLEAN("Media.RTCVideoEncoderInitEncodeSuccess", 854 UMA_HISTOGRAM_BOOLEAN("Media.RTCVideoEncoderInitEncodeSuccess",
856 init_retval == WEBRTC_VIDEO_CODEC_OK); 855 init_retval == WEBRTC_VIDEO_CODEC_OK);
857 if (init_retval == WEBRTC_VIDEO_CODEC_OK) { 856 if (init_retval == WEBRTC_VIDEO_CODEC_OK) {
858 UMA_HISTOGRAM_ENUMERATION("Media.RTCVideoEncoderProfile", 857 UMA_HISTOGRAM_ENUMERATION("Media.RTCVideoEncoderProfile",
859 profile, 858 profile,
860 media::VIDEO_CODEC_PROFILE_MAX + 1); 859 media::VIDEO_CODEC_PROFILE_MAX + 1);
861 } 860 }
862 } 861 }
863 862
864 } // namespace content 863 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | content/renderer/media/video_track_recorder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698