+++ /dev/null
-// 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
+++ /dev/null
-// 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