UnityVideoEncoderFactory.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. #include "pch.h"
  2. #include <media/engine/internal_encoder_factory.h>
  3. #include <modules/video_coding/include/video_error_codes.h>
  4. #include <tuple>
  5. #include "Codec/CreateVideoCodecFactory.h"
  6. #include "GraphicsDevice/GraphicsUtility.h"
  7. #include "ProfilerMarkerFactory.h"
  8. #include "ScopedProfiler.h"
  9. #include "UnityVideoEncoderFactory.h"
  10. namespace unity
  11. {
  12. namespace webrtc
  13. {
  14. class UnityVideoEncoder : public VideoEncoder
  15. {
  16. public:
  17. UnityVideoEncoder(std::unique_ptr<VideoEncoder> encoder, ProfilerMarkerFactory* profiler)
  18. : encoder_(std::move(encoder))
  19. , profiler_(profiler)
  20. , marker_(nullptr)
  21. , profilerThread_(nullptr)
  22. {
  23. if (profiler)
  24. marker_ = profiler->CreateMarker(
  25. "UnityVideoEncoder.Encode", kUnityProfilerCategoryOther, kUnityProfilerMarkerFlagDefault, 0);
  26. }
  27. ~UnityVideoEncoder() override { }
  28. void SetFecControllerOverride(FecControllerOverride* fec_controller_override) override
  29. {
  30. encoder_->SetFecControllerOverride(fec_controller_override);
  31. }
  32. int32_t InitEncode(const VideoCodec* codec_settings, int32_t number_of_cores, size_t max_payload_size) override
  33. {
  34. int32_t result = encoder_->InitEncode(codec_settings, number_of_cores, max_payload_size);
  35. if (result >= WEBRTC_VIDEO_CODEC_OK && !profilerThread_)
  36. {
  37. std::stringstream ss;
  38. ss << "Encoder ";
  39. ss
  40. << (encoder_->GetEncoderInfo().implementation_name.empty()
  41. ? "VideoEncoder"
  42. : encoder_->GetEncoderInfo().implementation_name);
  43. ss << "(" << CodecTypeToPayloadString(codec_settings->codecType) << ")";
  44. profilerThread_ = profiler_->CreateScopedProfilerThread("WebRTC", ss.str().c_str());
  45. }
  46. return result;
  47. }
  48. int InitEncode(const VideoCodec* codec_settings, const VideoEncoder::Settings& settings) override
  49. {
  50. int result = encoder_->InitEncode(codec_settings, settings);
  51. if (result >= WEBRTC_VIDEO_CODEC_OK && !profilerThread_)
  52. {
  53. std::stringstream ss;
  54. ss << "Encoder ";
  55. ss
  56. << (encoder_->GetEncoderInfo().implementation_name.empty()
  57. ? "VideoEncoder"
  58. : encoder_->GetEncoderInfo().implementation_name);
  59. ss << "(" << CodecTypeToPayloadString(codec_settings->codecType) << ")";
  60. profilerThread_ = profiler_->CreateScopedProfilerThread("WebRTC", ss.str().c_str());
  61. }
  62. return result;
  63. }
  64. int32_t RegisterEncodeCompleteCallback(EncodedImageCallback* callback) override
  65. {
  66. return encoder_->RegisterEncodeCompleteCallback(callback);
  67. }
  68. int32_t Release() override { return encoder_->Release(); }
  69. int32_t Encode(const VideoFrame& frame, const std::vector<VideoFrameType>* frame_types) override
  70. {
  71. int32_t result;
  72. {
  73. std::unique_ptr<const ScopedProfiler> profiler;
  74. if (profiler_)
  75. profiler = profiler_->CreateScopedProfiler(*marker_);
  76. result = encoder_->Encode(frame, frame_types);
  77. }
  78. return result;
  79. }
  80. void SetRates(const RateControlParameters& parameters) override { encoder_->SetRates(parameters); }
  81. void OnPacketLossRateUpdate(float packet_loss_rate) override
  82. {
  83. encoder_->OnPacketLossRateUpdate(packet_loss_rate);
  84. }
  85. void OnRttUpdate(int64_t rtt_ms) override { encoder_->OnRttUpdate(rtt_ms); }
  86. void OnLossNotification(const LossNotification& loss_notification) override
  87. {
  88. encoder_->OnLossNotification(loss_notification);
  89. }
  90. EncoderInfo GetEncoderInfo() const override { return encoder_->GetEncoderInfo(); }
  91. private:
  92. std::unique_ptr<VideoEncoder> encoder_;
  93. ProfilerMarkerFactory* profiler_;
  94. const UnityProfilerMarkerDesc* marker_;
  95. std::unique_ptr<const ScopedProfilerThread> profilerThread_;
  96. };
  97. UnityVideoEncoderFactory::UnityVideoEncoderFactory(IGraphicsDevice* gfxDevice, ProfilerMarkerFactory* profiler)
  98. : profiler_(profiler)
  99. , factories_()
  100. {
  101. const std::vector<std::string> arrayImpl = {
  102. kInternalImpl, kNvCodecImpl, kAndroidMediaCodecImpl, kVideoToolboxImpl
  103. };
  104. for (auto impl : arrayImpl)
  105. {
  106. auto factory = CreateVideoEncoderFactory(impl, gfxDevice, profiler);
  107. if (factory)
  108. factories_.emplace(impl, factory);
  109. }
  110. }
  111. UnityVideoEncoderFactory::~UnityVideoEncoderFactory() = default;
  112. std::vector<webrtc::SdpVideoFormat> UnityVideoEncoderFactory::GetSupportedFormats() const
  113. {
  114. std::vector<SdpVideoFormat> supported_codecs = GetSupportedFormatsInFactories(factories_);
  115. // Set video codec order: default video codec is VP8
  116. auto findIndex = [&](webrtc::SdpVideoFormat& format) -> long
  117. {
  118. const std::string sortOrder[4] = { "VP8", "VP9", "H264", "AV1X" };
  119. auto it = std::find(std::begin(sortOrder), std::end(sortOrder), format.name);
  120. if (it == std::end(sortOrder))
  121. return LONG_MAX;
  122. return static_cast<long>(std::distance(std::begin(sortOrder), it));
  123. };
  124. std::sort(
  125. supported_codecs.begin(),
  126. supported_codecs.end(),
  127. [&](webrtc::SdpVideoFormat& x, webrtc::SdpVideoFormat& y) -> int { return (findIndex(x) < findIndex(y)); });
  128. return supported_codecs;
  129. }
  130. webrtc::VideoEncoderFactory::CodecInfo
  131. UnityVideoEncoderFactory::QueryVideoEncoder(const webrtc::SdpVideoFormat& format) const
  132. {
  133. VideoEncoderFactory* factory = FindCodecFactory(factories_, format);
  134. RTC_DCHECK(format.IsCodecInList(factory->GetSupportedFormats()));
  135. return factory->QueryVideoEncoder(format);
  136. }
  137. std::unique_ptr<webrtc::VideoEncoder>
  138. UnityVideoEncoderFactory::CreateVideoEncoder(const webrtc::SdpVideoFormat& format)
  139. {
  140. VideoEncoderFactory* factory = FindCodecFactory(factories_, format);
  141. auto encoder = factory->CreateVideoEncoder(format);
  142. if (!profiler_)
  143. return encoder;
  144. // Use Unity Profiler for measuring encoding process.
  145. return std::make_unique<UnityVideoEncoder>(std::move(encoder), profiler_);
  146. }
  147. }
  148. }