cast_sender_impl.cc 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  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
  3. // found in the LICENSE file.
  4. #include "media/cast/cast_sender_impl.h"
  5. #include <utility>
  6. #include "base/bind.h"
  7. #include "base/callback.h"
  8. #include "base/callback_helpers.h"
  9. #include "base/logging.h"
  10. #include "media/base/video_frame.h"
  11. #include "media/cast/common/video_frame_factory.h"
  12. namespace media {
  13. namespace cast {
  14. // The LocalVideoFrameInput class posts all incoming video frames to the main
  15. // cast thread for processing.
  16. class LocalVideoFrameInput final : public VideoFrameInput {
  17. public:
  18. LocalVideoFrameInput(scoped_refptr<CastEnvironment> cast_environment,
  19. base::WeakPtr<VideoSender> video_sender)
  20. : cast_environment_(cast_environment),
  21. video_sender_(video_sender),
  22. video_frame_factory_(
  23. video_sender.get() ?
  24. video_sender->CreateVideoFrameFactory().release() : nullptr) {}
  25. LocalVideoFrameInput(const LocalVideoFrameInput&) = delete;
  26. LocalVideoFrameInput& operator=(const LocalVideoFrameInput&) = delete;
  27. void InsertRawVideoFrame(scoped_refptr<media::VideoFrame> video_frame,
  28. base::TimeTicks capture_time) final {
  29. cast_environment_->PostTask(
  30. CastEnvironment::MAIN, FROM_HERE,
  31. base::BindOnce(&VideoSender::InsertRawVideoFrame, video_sender_,
  32. std::move(video_frame), capture_time));
  33. }
  34. scoped_refptr<VideoFrame> MaybeCreateOptimizedFrame(
  35. const gfx::Size& frame_size,
  36. base::TimeDelta timestamp) final {
  37. return video_frame_factory_ ?
  38. video_frame_factory_->MaybeCreateFrame(frame_size, timestamp) : nullptr;
  39. }
  40. bool CanCreateOptimizedFrames() const final {
  41. return video_frame_factory_.get() != nullptr;
  42. }
  43. protected:
  44. ~LocalVideoFrameInput() final = default;
  45. private:
  46. friend class base::RefCountedThreadSafe<LocalVideoFrameInput>;
  47. const scoped_refptr<CastEnvironment> cast_environment_;
  48. const base::WeakPtr<VideoSender> video_sender_;
  49. const std::unique_ptr<VideoFrameFactory> video_frame_factory_;
  50. };
  51. // The LocalAudioFrameInput class posts all incoming audio frames to the main
  52. // cast thread for processing. Therefore frames can be inserted from any thread.
  53. class LocalAudioFrameInput final : public AudioFrameInput {
  54. public:
  55. LocalAudioFrameInput(scoped_refptr<CastEnvironment> cast_environment,
  56. base::WeakPtr<AudioSender> audio_sender)
  57. : cast_environment_(cast_environment), audio_sender_(audio_sender) {}
  58. LocalAudioFrameInput(const LocalAudioFrameInput&) = delete;
  59. LocalAudioFrameInput& operator=(const LocalAudioFrameInput&) = delete;
  60. void InsertAudio(std::unique_ptr<AudioBus> audio_bus,
  61. const base::TimeTicks& recorded_time) final {
  62. cast_environment_->PostTask(
  63. CastEnvironment::MAIN, FROM_HERE,
  64. base::BindOnce(&AudioSender::InsertAudio, audio_sender_,
  65. std::move(audio_bus), recorded_time));
  66. }
  67. protected:
  68. ~LocalAudioFrameInput() final = default;
  69. private:
  70. friend class base::RefCountedThreadSafe<LocalAudioFrameInput>;
  71. scoped_refptr<CastEnvironment> cast_environment_;
  72. base::WeakPtr<AudioSender> audio_sender_;
  73. };
  74. std::unique_ptr<CastSender> CastSender::Create(
  75. scoped_refptr<CastEnvironment> cast_environment,
  76. CastTransport* const transport_sender) {
  77. CHECK(cast_environment.get());
  78. return std::unique_ptr<CastSender>(
  79. new CastSenderImpl(cast_environment, transport_sender));
  80. }
  81. CastSenderImpl::CastSenderImpl(scoped_refptr<CastEnvironment> cast_environment,
  82. CastTransport* const transport_sender)
  83. : cast_environment_(cast_environment), transport_sender_(transport_sender) {
  84. CHECK(cast_environment.get());
  85. }
  86. void CastSenderImpl::InitializeAudio(
  87. const FrameSenderConfig& audio_config,
  88. StatusChangeOnceCallback status_change_cb) {
  89. DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
  90. CHECK(audio_config.use_external_encoder ||
  91. cast_environment_->HasAudioThread());
  92. VLOG(1) << "CastSenderImpl@" << this << "::InitializeAudio()";
  93. audio_sender_ = std::make_unique<AudioSender>(
  94. cast_environment_, audio_config,
  95. base::BindOnce(&CastSenderImpl::OnAudioStatusChange,
  96. weak_factory_.GetWeakPtr(), std::move(status_change_cb)),
  97. transport_sender_);
  98. if (video_sender_) {
  99. DCHECK(audio_sender_->GetTargetPlayoutDelay() ==
  100. video_sender_->GetTargetPlayoutDelay());
  101. }
  102. }
  103. void CastSenderImpl::InitializeVideo(
  104. const FrameSenderConfig& video_config,
  105. const StatusChangeCallback& status_change_cb,
  106. const CreateVideoEncodeAcceleratorCallback& create_vea_cb) {
  107. DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
  108. VLOG(1) << "CastSenderImpl@" << this << "::InitializeVideo()";
  109. // No feedback callback, since it's ignored for CastSender.
  110. video_sender_ = std::make_unique<VideoSender>(
  111. cast_environment_, video_config,
  112. base::BindRepeating(&CastSenderImpl::OnVideoStatusChange,
  113. weak_factory_.GetWeakPtr(), status_change_cb),
  114. create_vea_cb, transport_sender_,
  115. base::BindRepeating(&CastSenderImpl::SetTargetPlayoutDelay,
  116. weak_factory_.GetWeakPtr()),
  117. media::VideoCaptureFeedbackCB());
  118. if (audio_sender_) {
  119. DCHECK(audio_sender_->GetTargetPlayoutDelay() ==
  120. video_sender_->GetTargetPlayoutDelay());
  121. }
  122. }
  123. CastSenderImpl::~CastSenderImpl() {
  124. VLOG(1) << "CastSenderImpl@" << this << "::~CastSenderImpl()";
  125. }
  126. scoped_refptr<AudioFrameInput> CastSenderImpl::audio_frame_input() {
  127. return audio_frame_input_;
  128. }
  129. scoped_refptr<VideoFrameInput> CastSenderImpl::video_frame_input() {
  130. return video_frame_input_;
  131. }
  132. void CastSenderImpl::SetTargetPlayoutDelay(
  133. base::TimeDelta new_target_playout_delay) {
  134. VLOG(1) << "CastSenderImpl@" << this << "::SetTargetPlayoutDelay("
  135. << new_target_playout_delay.InMilliseconds() << " ms)";
  136. if (audio_sender_) {
  137. audio_sender_->SetTargetPlayoutDelay(new_target_playout_delay);
  138. }
  139. if (video_sender_) {
  140. video_sender_->SetTargetPlayoutDelay(new_target_playout_delay);
  141. }
  142. }
  143. void CastSenderImpl::OnAudioStatusChange(
  144. StatusChangeOnceCallback status_change_cb,
  145. OperationalStatus status) {
  146. DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
  147. if (status == STATUS_INITIALIZED && !audio_frame_input_) {
  148. audio_frame_input_ =
  149. new LocalAudioFrameInput(cast_environment_, audio_sender_->AsWeakPtr());
  150. }
  151. std::move(status_change_cb).Run(status);
  152. }
  153. void CastSenderImpl::OnVideoStatusChange(
  154. const StatusChangeCallback& status_change_cb,
  155. OperationalStatus status) {
  156. DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
  157. if (status == STATUS_INITIALIZED && !video_frame_input_) {
  158. video_frame_input_ =
  159. new LocalVideoFrameInput(cast_environment_, video_sender_->AsWeakPtr());
  160. }
  161. status_change_cb.Run(status);
  162. }
  163. } // namespace cast
  164. } // namespace media