[M120 Migration][WebRTC] Merge dual decoding patches 67/309467/6
authorpeng.yin <peng8.yin@samsung.com>
Wed, 10 Apr 2024 08:26:37 +0000 (16:26 +0800)
committerBot Blink <blinkbot@samsung.com>
Sat, 13 Apr 2024 04:55:27 +0000 (04:55 +0000)
[WebRTC] Add RTCVideoDecoderRemoteTV Implementation
https://review.tizen.org/gerrit/#/c/297392/

[WebRTC] Refactor renderer recreate logic in `RTCVideoDecoderRemoter` class
https://review.tizen.org/gerrit/#/c/300624/

[WebRTC] Add switch for webrtc video stream dual decoding
https://review.tizen.org/gerrit/#/c/298769/

[MM] Enable dual decoding for kantsu2e model
https://review.tizen.org/gerrit/#/c/300377/

Change-Id: Icacf3a332f4a8c43000d1653defc2ea3f72b314a
Signed-off-by: peng.yin <peng8.yin@samsung.com>
media/base/media_switches.h
third_party/blink/renderer/platform/BUILD.gn
third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_factory.cc
third_party/webrtc/api/video/render_resolution.h
tizen_src/chromium_impl/media/filters/media_capabilities.cc
tizen_src/chromium_impl/third_party/blink/renderer/platform/peerconnection/BUILD.gn [new file with mode: 0755]
tizen_src/chromium_impl/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_remote_tv.cc [new file with mode: 0755]
tizen_src/chromium_impl/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_remote_tv.h [new file with mode: 0755]
tizen_src/chromium_impl/third_party/blink/renderer/platform/peerconnection/video_coding_constants.h [new file with mode: 0644]
tizen_src/chromium_impl/third_party/blink/renderer/platform/peerconnection/video_coding_utils.cc [new file with mode: 0644]
tizen_src/chromium_impl/third_party/blink/renderer/platform/peerconnection/video_coding_utils.h [new file with mode: 0644]

index 7950389..7610a8e 100644 (file)
@@ -104,6 +104,7 @@ MEDIA_EXPORT extern const char kEnableUpstreamArchitecture[];
 
 #if BUILDFLAG(IS_TIZEN_TV)
 MEDIA_EXPORT extern const char kEnableFrameRawDataCopy[];
+MEDIA_EXPORT extern const char kDualDecodingWebRTC[];
 #endif
 
 #if BUILDFLAG(IS_CHROMEOS)
index 9da9a5f..dbea595 100644 (file)
@@ -1661,6 +1661,18 @@ component("platform") {
     "//third_party/blink/renderer:non_test_config",
   ]
 
+  if (tizen_product_tv && tizen_multimedia) {
+    if (tizen_version > 60) {
+      configs += [
+        # Workaround for media/filters/esplusplayer_util.h in //media which fails
+        # to export required configs.
+        "//tizen_src/build:libesplusplayer",
+      ]
+    } else {
+      configs += [ "//tizen_src/build:libplusplayer" ]
+    }
+  }
+
   include_dirs = []
 
   allow_circular_includes_from = [
@@ -1812,6 +1824,13 @@ component("platform") {
     sources += [ "fonts/fuchsia/font_cache_fuchsia.cc" ]
   }
 
+  if (tizen_product_tv) {
+    deps += [
+      "//third_party/blink/renderer/bindings:generate_bindings_all",
+      "//tizen_src/chromium_impl/third_party/blink/renderer/platform/peerconnection:tizen_media_coding",
+    ]
+  }
+
   if (use_minikin_hyphenation) {
     sources += [
       "text/hyphenation/hyphenation_minikin.cc",
index d188602..6ff83eb 100644 (file)
@@ -8,6 +8,7 @@
 #include <memory>
 
 #include "base/check.h"
+#include "base/command_line.h"
 #include "base/feature_list.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "ui/gfx/color_space.h"
 #include "ui/gfx/geometry/size.h"
 
+#if BUILDFLAG(IS_TIZEN_TV) && defined(TIZEN_VIDEO_HOLE)
+#include "media/filters/esplusplayer_util.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_remote_tv.h"
+#endif  // BUILDFLAG(IS_TIZEN_TV) && defined(TIZEN_VIDEO_HOLE)
+
 namespace blink {
 namespace {
 
@@ -58,6 +64,24 @@ constexpr std::array<CodecConfig, 9> kCodecConfigs = {{
     {media::VideoCodec::kAV1, media::AV1PROFILE_PROFILE_MAIN},
 }};
 
+bool DualDecodingSupportedCodec(const media::VideoCodec& codec) {
+#if BUILDFLAG(IS_TIZEN_TV)
+  return codec == media::VideoCodec::kVP8 || codec == media::VideoCodec::kH264;
+#else
+  return false;
+#endif
+}
+
+bool UseDualDecoding() {
+#if BUILDFLAG(IS_TIZEN_TV)
+  return base::CommandLine::ForCurrentProcess() &&
+         base::CommandLine::ForCurrentProcess()->HasSwitch(
+             switches::kDualDecodingWebRTC);
+#else
+  return false;
+#endif
+}
+
 // Translate from media::VideoDecoderConfig to webrtc::SdpVideoFormat, or return
 // nothing if the profile isn't supported.
 absl::optional<webrtc::SdpVideoFormat> VdcToWebRtcFormat(
@@ -211,6 +235,18 @@ RTCVideoDecoderFactory::GetSupportedFormats() const {
         media::VideoColorSpace(), media::kNoTransformation, kDefaultSize,
         gfx::Rect(kDefaultSize), kDefaultSize, media::EmptyExtraData(),
         media::EncryptionScheme::kUnencrypted);
+
+#if BUILDFLAG(IS_TIZEN_TV) && defined(TIZEN_VIDEO_HOLE)
+    if (UseDualDecoding() && DualDecodingSupportedCodec(codec_config.codec)) {
+      // Since it can not be determined which hardware codec will be selected,
+      // limit it to the base codecs by `DualDecodingSupportedCodec`.
+      auto format = VdcToWebRtcFormat(config);
+      if (format) {
+        supported_formats.push_back(*format);
+      }
+      continue;
+    }
+#endif  // BUILDFLAG(IS_TIZEN_TV) && defined(TIZEN_VIDEO_HOLE)
     config.set_is_rtc(true);
     absl::optional<webrtc::SdpVideoFormat> format;
 
@@ -278,6 +314,12 @@ RTCVideoDecoderFactory::QueryCodecSupport(const webrtc::SdpVideoFormat& format,
     }
   }
 
+#if BUILDFLAG(IS_TIZEN_TV) && defined(TIZEN_VIDEO_HOLE)
+  if (UseDualDecoding() && DualDecodingSupportedCodec(codec)) {
+    return {true, true};
+  }
+#endif  // BUILDFLAG(IS_TIZEN_TV) && defined(TIZEN_VIDEO_HOLE)
+
   media::VideoCodecProfile codec_profile =
       WebRtcVideoFormatToMediaVideoCodecProfile(format);
   media::VideoDecoderConfig config(
@@ -322,6 +364,12 @@ RTCVideoDecoderFactory::CreateVideoDecoder(
   DVLOG(2) << __func__;
   CheckAndWaitDecoderSupportStatusIfNeeded();
 
+#if BUILDFLAG(IS_TIZEN_TV) && defined(TIZEN_VIDEO_HOLE)
+  if (UseDualDecoding()) {
+    return RTCVideoDecoderRemoteTV::Create(format);
+  }
+#endif  // BUILDFLAG(IS_TIZEN_TV) && defined(TIZEN_VIDEO_HOLE)
+
   std::unique_ptr<webrtc::VideoDecoder> decoder;
   if (base::FeatureList::IsEnabled(media::kUseDecoderStreamForWebRTC)) {
     decoder = RTCVideoDecoderStreamAdapter::Create(
index fcf4f12..d2e7642 100644 (file)
@@ -31,6 +31,11 @@ class RenderResolution {
     return !(lhs == rhs);
   }
 
+  friend bool operator<(const RenderResolution& lhs,
+                        const RenderResolution& rhs) {
+    return lhs.width_ < rhs.width_ && lhs.height_ < rhs.height_;
+  }
+
   constexpr bool Valid() const { return width_ > 0 && height_ > 0; }
 
   constexpr int Width() const { return width_; }
index 47092d8..bce34c1 100644 (file)
@@ -21,48 +21,39 @@ namespace platform {
 namespace {
 
 #if BUILDFLAG(IS_TIZEN_TV)
-bool IsCameraHardwareEncoderEnabled() {
-#if !defined(EWK_BRINGUP)  // Fixme: Remove after Port Video Encoders Patch is merged
-//  const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
-//  return cmd_line->HasSwitch(switches::kEnableWebRtcHWEncodingForCamera);
-#else
-  return false;
-#endif
-}
-
 bool IsDualDecodingSupported() {
   const auto tv_chipset = GetTVChipset();
   // TODO(b.chechlinsk): Add NikeL 1.5G chipset code
-  if (tv_chipset == "KANTS2" || tv_chipset == "KANTSU2E" ||
-      tv_chipset == "NIKEL_XXX")
+  if (tv_chipset == "KANTS2" || tv_chipset == "NIKEL_XXX")
+    return false;
+
+  if (IsMultiviewMode())
+    return false;
+
+  if (!content::IsHbbTV() && !base::CommandLine::ForCurrentProcess()->HasSwitch(
+                                 switches::kDualDecodingWebRTC))
     return false;
+
   return true;
 }
-#endif
+#endif  // BUILDFLAG(IS_TIZEN_TV)
 
 std::size_t TVMaxCount(MediaType type) {
-// On LFD TV: web app support 3 videos and 1 audio at most.
-// browser support 1 video and 1 audio at most.
-// Reason : browser cannot support mixer mode, scroll function
-// has some issue when browser in mixer mode(video shows issue).
-#if defined(TIZEN_VD_MULTIPLE_MIXERDECODER)
-  if ((MediaType::Video == type) && content::IsTIZENWRT())
-    return 3;
-#elif BUILDFLAG(IS_TIZEN_TV)
-  if (MediaType::Video == type) {
-    if (
-#if !defined(EWK_BRINGUP)  // Fixme: Remove after HDR and codec related patch is merged
-        !IsMultiviewMode() &&
-#endif
-        IsDualDecodingSupported() &&
-        (blink::IsHbbTV() || IsCameraHardwareEncoderEnabled()))
-      return 2;
+  std::size_t count = 1;
+#if BUILDFLAG(IS_TIZEN_TV)
+  if ((GetProductType() == "LFD") && (content::IsTIZENWRT())) {
+    // On LFD TV: web app support 3 videos and 1 audio at most.
+    // browser support 1 video and 1 audio at most.
+    // Reason : browser cannot support mixer mode, scroll function
+    // has some issue when browser in mixer mode(video shows issue).
+    count = 3;
+  } else if (MediaType::Video == type && IsDualDecodingSupported()) {
+    count = 2;
   }
-  if (blink::IsTIZENWRT())
-    return 4;
-#endif
+#endif  // BUILDFLAG(IS_TIZEN_TV)
 
-  return 1;
+  LOG(INFO) << "Return " << count << " as max count.";
+  return count;
 }
 
 }  // namespace
diff --git a/tizen_src/chromium_impl/third_party/blink/renderer/platform/peerconnection/BUILD.gn b/tizen_src/chromium_impl/third_party/blink/renderer/platform/peerconnection/BUILD.gn
new file mode 100755 (executable)
index 0000000..7faea83
--- /dev/null
@@ -0,0 +1,62 @@
+# Copyright (c) 2021 Samsung Electronics. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//tizen_src/build/config/tizen_features.gni")
+
+source_set("tizen_media_coding") {
+  cflags = [
+    "-Werror",
+    "-Wall",
+  ]
+
+  if (tizen_version < 60 && is_clang) {
+    cflags -= [ "-Werror" ]
+  }
+
+  if (!is_clang) {
+    cflags += [
+      "-Wformat=2",
+      "-Wnull-dereference",
+      "-Wimplicit-fallthrough=4",
+      "-Wno-builtin-macro-redefined",
+      "-Wno-deprecated-copy",
+      "-Wno-error=attributes",
+      "-Wno-error=ignored-qualifiers",
+    ]
+  }
+
+  cflags_cc = [
+    # Added to make it possible to extend platform enums with new values,
+    # while still reporting not handled enum cases during compilation
+    "-Wno-error=switch",
+  ]
+
+  deps = [
+    "//media",
+    "//third_party/blink/public:blink_headers",
+    "//third_party/webrtc_overrides:webrtc_component",
+  ]
+
+  # TODO(m.napiorkows): This should be in public_configs
+  # of //media/base
+  configs += [
+    # Needed for including renderer_media_player_manager_efl.h
+    "//tizen_src/build:capi-media-player",
+    "//tizen_src/build:libcapi-media-player",
+  ]
+
+  sources = [
+    "video_coding_constants.h",
+    "video_coding_utils.cc",
+    "video_coding_utils.h",
+  ]
+
+  if (tizen_multimedia && tizen_video_hole) {
+    sources += [
+      "rtc_video_decoder_remote_tv.cc",
+      "rtc_video_decoder_remote_tv.h"
+    ]
+  }
+
+}
diff --git a/tizen_src/chromium_impl/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_remote_tv.cc b/tizen_src/chromium_impl/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_remote_tv.cc
new file mode 100755 (executable)
index 0000000..4cc3641
--- /dev/null
@@ -0,0 +1,173 @@
+// Copyright 2023 Samsung Electronics Inc. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_remote_tv.h"
+
+#include <utility>
+
+#include "media/base/video_frame.h"
+#include "media/blink/renderer/tizen_esplusplayer_renderer.h"
+#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
+#include "third_party/blink/renderer/platform/peerconnection/video_coding_utils.h"
+#include "third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter.h"
+#include "third_party/webrtc/modules/video_coding/include/video_error_codes.h"
+
+namespace blink {
+
+// static
+std::unique_ptr<webrtc::VideoDecoder> RTCVideoDecoderRemoteTV::Create(
+    const webrtc::SdpVideoFormat& format) {
+  return std::unique_ptr<RTCVideoDecoderRemoteTV>(
+      new RTCVideoDecoderRemoteTV(format));
+}
+
+RTCVideoDecoderRemoteTV::RTCVideoDecoderRemoteTV(
+    const webrtc::SdpVideoFormat& format)
+    : format_(format) {}
+
+bool RTCVideoDecoderRemoteTV::NeedRecreate(const Settings& settings) {
+  LOG(INFO) << " max render size:" << settings_.max_render_resolution().Width()
+            << "x" << settings_.max_render_resolution().Height()
+            << " codec type:" << settings.codec_type();
+
+  return !renderer_ ||
+         settings_.max_render_resolution() < settings.max_render_resolution() ||
+         settings_.codec_type() != settings.codec_type();
+}
+
+void RTCVideoDecoderRemoteTV::OnRendererInit(bool result) {
+  sync_with_init_result.Signal();
+}
+
+void RTCVideoDecoderRemoteTV::RecreateRenderer(const Settings& settings) {
+  LOG(INFO) << __func__;
+  renderer_.reset();
+  renderer_ =
+      media::TizenEsPlusPlayerRendererManager::GetInstance()
+          .CreateTizenEsPlusPlayerRenderer(
+              blink::ToMediaVideoCodec(settings.codec_type()),
+              current_size_.value_or(
+                  gfx::Size(settings.max_render_resolution().Width(),
+                            settings.max_render_resolution().Height())),
+              media::HardwareResouceType::kMain, /* Main-scaler */
+              media::HardwareResouceType::kSub,  /* Sub-decoder */
+              media::CanDropFrames::kYes, media::Mode::kVideoHole,
+              base::BindOnce(&RTCVideoDecoderRemoteTV::OnRendererInit,
+                             base::Unretained(this)),
+              base::BindPostTaskToCurrentDefault(base::BindRepeating(
+                  &RTCVideoDecoderRemoteTV::OnVideoFrameReadyFromRenderer,
+                  base::Unretained(this))),
+              true, false);
+  // Wait for initialization to complete, otherwise frames into Decode()
+  // will be lost.
+  sync_with_init_result.Wait();
+  sync_with_init_result.Reset();
+  settings_ = settings;
+  ms_to_tick_.clear();
+}
+
+void RTCVideoDecoderRemoteTV::RecreateRendererIfNeeded(
+    const Settings& settings) {
+  if (NeedRecreate(settings)) {
+    RecreateRenderer(settings);
+  }
+}
+
+void RTCVideoDecoderRemoteTV::OnVideoFrameReadyFromRenderer(
+    scoped_refptr<media::VideoFrame> frame,
+    base::TimeTicks reference_time) {
+  if (!decode_complete_callback_) {
+    LOG(INFO) << "no decoded callback!";
+    return;
+  }
+
+  if (ms_to_tick_.empty()) {
+    LOG(INFO) << "unexpected frame.";
+    return;
+  }
+
+  auto time_ms = frame->timestamp().InMilliseconds();
+  const auto& pair = ms_to_tick_.front();
+  if (pair.first != time_ms) {
+    LOG(INFO) << "unexpected frame.";
+  }
+
+  rtc::scoped_refptr<webrtc::VideoFrameBuffer> frame_buffer(
+      new rtc::RefCountedObject<WebRtcVideoFrameAdapter>(std::move(frame)));
+  auto rtc_frame = webrtc::VideoFrame::Builder{}
+                       .set_video_frame_buffer(frame_buffer)
+                       .set_timestamp_rtp(pair.second)
+                       .set_timestamp_ms(time_ms)
+                       .build();
+  ms_to_tick_.pop_front();
+  decode_complete_callback_->Decoded(rtc_frame, absl::nullopt, absl::nullopt);
+}
+
+bool RTCVideoDecoderRemoteTV::Configure(const Settings& settings) {
+  RecreateRendererIfNeeded(settings);
+  if (!renderer_)
+    return false;
+
+  return true;
+}
+
+int32_t RTCVideoDecoderRemoteTV::Decode(const webrtc::EncodedImage& input_image,
+                                        bool missing_frames,
+                                        int64_t render_time_ms) {
+  if (IsKeyFrame(input_image)) {
+    auto size =
+        gfx::Size(input_image._encodedWidth, input_image._encodedHeight);
+    if (size == gfx::Size(0, 0)) {
+      LOG(ERROR) << "Invalid size.";
+      return WEBRTC_VIDEO_CODEC_ERROR;
+    }
+
+    current_size_ = size;
+    LOG(INFO) << " key frame, size:" << (*current_size_).ToString()
+              << " rtp time:" << input_image.RtpTimestamp();
+  }
+
+  if (!current_size_.has_value()) {
+    LOG(ERROR) << "There is no key frame yet.";
+    return WEBRTC_VIDEO_CODEC_OK_REQUEST_KEYFRAME;
+  }
+
+  base::AutoLock lk(lock_);
+  if (!renderer_) {
+    LOG(ERROR) << "Decoder does not exist!";
+    return WEBRTC_VIDEO_CODEC_ERROR;
+  }
+
+  if (!renderer_->IsReady()) {
+    LOG(ERROR) << "Decoder is not ready!";
+    return WEBRTC_VIDEO_CODEC_OK_REQUEST_KEYFRAME;
+  }
+
+  media::VideoFrameMetadata meta;
+  int64_t ms = input_image.RtpTimestamp() / kTicksPerMillisecond;
+  meta.reference_time = base::TimeTicks::FromInternalValue(
+      ms * base::Time::kMicrosecondsPerMillisecond);
+  meta.rtp_timestamp = input_image.RtpTimestamp();
+  ms_to_tick_.push_back(std::make_pair(ms, input_image.RtpTimestamp()));
+
+  if (renderer_->QueueBuffer(meta, *current_size_, input_image.data(),
+                             input_image.size(), IsKeyFrame(input_image))) {
+    LOG(INFO) << "Request key frame.";
+    return WEBRTC_VIDEO_CODEC_OK_REQUEST_KEYFRAME;
+  }
+  return WEBRTC_VIDEO_CODEC_OK;
+}
+
+int32_t RTCVideoDecoderRemoteTV::RegisterDecodeCompleteCallback(
+    webrtc::DecodedImageCallback* callback) {
+  decode_complete_callback_ = callback;
+  return WEBRTC_VIDEO_CODEC_OK;
+}
+
+int32_t RTCVideoDecoderRemoteTV::Release() {
+  renderer_.reset();
+  return WEBRTC_VIDEO_CODEC_OK;
+}
+
+}  // namespace blink
diff --git a/tizen_src/chromium_impl/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_remote_tv.h b/tizen_src/chromium_impl/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_remote_tv.h
new file mode 100755 (executable)
index 0000000..d753cc5
--- /dev/null
@@ -0,0 +1,70 @@
+// Copyright 2023 Samsung Electronics Inc. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_VIDEO_DECODER_REMOTE_TV_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_VIDEO_DECODER_REMOTE_TV_H_
+
+#include <deque>
+
+#include "api/video_codecs/sdp_video_format.h"
+#include "api/video_codecs/video_decoder.h"
+#include "base/memory/scoped_refptr.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/time/time.h"
+#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
+#include "ui/gfx/geometry/size.h"
+
+namespace media {
+class TizenEsPlusPlayerRenderer;
+class VideoFrame;
+}  // namespace media
+
+namespace blink {
+
+class RTCVideoDecoderRemoteTV : public webrtc::VideoDecoder {
+ public:
+  static constexpr int64_t kTicksPerMillisecond =
+      webrtc::kVideoPayloadTypeFrequency / base::Time::kMillisecondsPerSecond;
+  static std::unique_ptr<webrtc::VideoDecoder> Create(
+      const webrtc::SdpVideoFormat& format);
+
+  // webrtc::VideoDecoder implementation
+  bool Configure(const Settings& settings) override;
+
+  int32_t Decode(const webrtc::EncodedImage& input_image,
+                 bool missing_frames,
+                 int64_t render_time_ms) override;
+  int32_t RegisterDecodeCompleteCallback(
+      webrtc::DecodedImageCallback* callback) override;
+  int32_t Release() override;
+  const char* ImplementationName() const override {
+    return "tizen-tv-espp-decoder";
+  }
+
+ private:
+  RTCVideoDecoderRemoteTV(const webrtc::SdpVideoFormat& format);
+  bool NeedRecreate(const Settings& settings);
+  void RecreateRenderer(const Settings& settings);
+  void RecreateRendererIfNeeded(const Settings& settings);
+  void OnVideoFrameReadyFromRenderer(scoped_refptr<media::VideoFrame> frame,
+                                     base::TimeTicks reference_time);
+  inline bool IsKeyFrame(const webrtc::EncodedImage& img) const {
+    return img._frameType == webrtc::VideoFrameType::kVideoFrameKey;
+  }
+  void OnRendererInit(bool result);
+
+  std::unique_ptr<media::TizenEsPlusPlayerRenderer> renderer_;
+  webrtc::SdpVideoFormat format_;
+  Settings settings_;
+  webrtc::DecodedImageCallback* decode_complete_callback_;
+  absl::optional<gfx::Size> current_size_;
+  std::deque<std::pair<int64_t, uint32_t>> ms_to_tick_;
+  base::Lock lock_{};
+  base::WaitableEvent sync_with_init_result{
+      base::WaitableEvent::ResetPolicy::MANUAL};
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_VIDEO_DECODER_REMOTE_TV_H_
\ No newline at end of file
diff --git a/tizen_src/chromium_impl/third_party/blink/renderer/platform/peerconnection/video_coding_constants.h b/tizen_src/chromium_impl/third_party/blink/renderer/platform/peerconnection/video_coding_constants.h
new file mode 100644 (file)
index 0000000..19ed66d
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2021 Samsung Electronics Inc. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_VIDEO_CODING_CONSTANTS_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_VIDEO_CODING_CONSTANTS_H_
+
+namespace blink {
+// Synced with
+// third_party/webrtc/modules/video_coding/codecs/h264/h264_encoder_impl.cc
+// QP (quantization parameter) values below kLowH264QpThreshold are considered
+// too high quality values above kHighH264QpThreshold are too low quality
+constexpr int kLowH264QpThreshold = 24;
+constexpr int kHighH264QpThreshold = 37;
+
+// Arbitraty values in range 0-63
+// TODO(m.napiorkows): Adjust based on visual quality
+constexpr int kLowVP8QpThreshold = 25;
+constexpr int kHighVP8QpThreshold = 53;
+
+// https://tools.ietf.org/html/rfc6184#section-5.1:
+// "The RTP timestamp is set to the sampling timestamp of the content.
+// A 90 kHz clock rate MUST be used."
+constexpr int kVideoRtpTimestampClockRate = 90;
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_VIDEO_CODING_CONSTANTS_H_
diff --git a/tizen_src/chromium_impl/third_party/blink/renderer/platform/peerconnection/video_coding_utils.cc b/tizen_src/chromium_impl/third_party/blink/renderer/platform/peerconnection/video_coding_utils.cc
new file mode 100644 (file)
index 0000000..ec27919
--- /dev/null
@@ -0,0 +1,83 @@
+// Copyright 2021 Samsung Electronics Inc. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/platform/peerconnection/video_coding_utils.h"
+
+#include "api/video/video_rotation.h"
+#include "media/base/video_transformation.h"
+#include "media/media_buildflags.h"
+#include "rtc_base/time_utils.h"
+#include "third_party/blink/renderer/platform/peerconnection/video_coding_constants.h"
+
+namespace blink {
+bool IsKeyframeRequested(
+    const std::vector<webrtc::VideoFrameType>* const frame_types) {
+  return std::any_of(frame_types->begin(), frame_types->end(),
+                     [](const auto& type) {
+                       return type == webrtc::VideoFrameType::kVideoFrameKey;
+                     });
+}
+
+media::VideoCodec ToMediaVideoCodec(webrtc::VideoCodecType codec) noexcept {
+  switch (codec) {
+    case webrtc::kVideoCodecGeneric:
+    // No support for multiplex for now
+    case webrtc::kVideoCodecMultiplex:
+      return media::VideoCodec::kUnknown;
+    case webrtc::kVideoCodecVP8:
+      return media::VideoCodec::kVP8;
+    case webrtc::kVideoCodecVP9:
+      return media::VideoCodec::kVP9;
+    case webrtc::kVideoCodecAV1:
+      return media::VideoCodec::kAV1;
+    case webrtc::kVideoCodecH264:
+      return media::VideoCodec::kH264;
+#if BUILDFLAG(IS_TIZEN_TV) && BUILDFLAG(ENABLE_PLATFORM_HEVC)
+    case webrtc::kVideoCodecH265:
+      return media::VideoCodec::kHEVC;
+#endif
+  }
+  return media::VideoCodec::kUnknown;
+}
+
+webrtc::VideoRotation ToWebRTCRotation(media::VideoRotation rotation) noexcept {
+  switch (rotation) {
+    case media::VIDEO_ROTATION_0:
+      return webrtc::kVideoRotation_0;
+    case media::VIDEO_ROTATION_90:
+      return webrtc::kVideoRotation_90;
+    case media::VIDEO_ROTATION_180:
+      return webrtc::kVideoRotation_180;
+    case media::VIDEO_ROTATION_270:
+      return webrtc::kVideoRotation_270;
+  }
+  return webrtc::kVideoRotation_0;
+}
+
+void TimestampConverter::OnInputFrame(uint32_t timestamp_rtp,
+                                      int64_t timestamp_us) {
+  if (first_input_frame_wall_clock_.is_zero()) {
+    first_input_frame_wall_clock_ = base::Milliseconds(rtc::TimeMillis());
+    first_input_frame_timestamp_ = base::Microseconds(timestamp_us);
+    first_input_frame_rtp_timestamp_ = timestamp_rtp;
+  }
+}
+
+int64_t TimestampConverter::GetCaptureTime(base::TimeDelta now) const {
+  return (first_input_frame_timestamp_ - first_input_frame_wall_clock_ + now)
+      .InMilliseconds();
+}
+
+uint32_t TimestampConverter::GetRtpTime(base::TimeDelta now) const {
+  return static_cast<uint32_t>(
+      kVideoRtpTimestampClockRate *
+          (now - first_input_frame_wall_clock_).InMilliseconds() +
+      first_input_frame_rtp_timestamp_);
+}
+
+void TimestampConverter::Reset() {
+  first_input_frame_wall_clock_ = {};
+}
+
+}  // namespace blink
diff --git a/tizen_src/chromium_impl/third_party/blink/renderer/platform/peerconnection/video_coding_utils.h b/tizen_src/chromium_impl/third_party/blink/renderer/platform/peerconnection/video_coding_utils.h
new file mode 100644 (file)
index 0000000..107400a
--- /dev/null
@@ -0,0 +1,38 @@
+// Copyright 2021 Samsung Electronics Inc. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_VIDEO_CODING_UTILS_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_VIDEO_CODING_UTILS_H_
+
+#include <vector>
+
+#include "api/video/video_codec_type.h"
+#include "api/video/video_rotation.h"
+#include "base/time/time.h"
+#include "media/base/video_codecs.h"
+#include "media/base/video_transformation.h"
+#include "third_party/webrtc/api/video/video_frame_type.h"
+
+namespace blink {
+bool IsKeyframeRequested(const std::vector<webrtc::VideoFrameType>* const);
+media::VideoCodec ToMediaVideoCodec(webrtc::VideoCodecType codec) noexcept;
+webrtc::VideoRotation ToWebRTCRotation(media::VideoRotation rotation) noexcept;
+
+class TimestampConverter {
+ public:
+  void OnInputFrame(uint32_t timestamp_rtp, int64_t timestamp_us);
+
+  int64_t GetCaptureTime(base::TimeDelta now) const;
+  uint32_t GetRtpTime(base::TimeDelta now) const;
+
+  void Reset();
+
+ private:
+  base::TimeDelta first_input_frame_wall_clock_{};
+  base::TimeDelta first_input_frame_timestamp_{};
+  uint32_t first_input_frame_rtp_timestamp_{};
+};
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_VIDEO_CODING_UTILS_H_
\ No newline at end of file