[TTVD] Notify if video decoder can allocate next frame 37/325337/1
authorJakub Gajownik <j.gajownik2@samsung.com>
Fri, 6 Jun 2025 10:54:45 +0000 (12:54 +0200)
committerj.gajownik2 <j.gajownik2@samsung.com>
Mon, 9 Jun 2025 08:49:05 +0000 (08:49 +0000)
When video renderer decides whether buffering is enough,
it checks if video decoder can return another frame without
stalling. It's possible that it won't wait for more frames
and start playback. However, rendering first frame to
overlay might take a while. This leads to subtle issue that
some frames are dropped from rendering and is visible to
user as jump.

This change introduces proper notification whether decoder
can allocate new video frame for decoding.

Bug: https://jira-eu.sec.samsung.net/browse/VDGAME-680
Change-Id: Ia5c70da08deea59176444bbfb7fb861cd07e6dce
Signed-off-by: Jakub Gajownik <j.gajownik2@samsung.com>
media/filters/tizen/ttvd_video_decoder.cc
media/filters/tizen/ttvd_video_decoder.h
media/filters/tizen/ttvd_video_decoder_impl.cc
media/filters/tizen/ttvd_video_decoder_impl.h
media/mojo/mojom/ttvd_media_provider.mojom

index f38f05e2086841ba0875e68a3c62a87f2c344846..d7d13bfd284b6da63f67718415022f89ffab13ca 100644 (file)
@@ -92,8 +92,10 @@ void TTvdVideoDecoder::Reset(base::OnceClosure closure) {
 
 void TTvdVideoDecoder::OnVideoFrameDecoded(
     const scoped_refptr<VideoFrame>& frame,
+    bool can_read_without_stalling,
     const base::UnguessableToken& release_token) {
   TIZEN_MEDIA_LOG(VERBOSE) << "Frame decoded: " << frame->timestamp();
+  can_read_without_stalling_ = can_read_without_stalling;
   frame->SetReleaseMailboxCB(base::BindPostTaskToCurrentDefault(base::BindOnce(
       &TTvdVideoDecoder::ReleaseVideoFrame, weak_this_, release_token)));
   output_cb_.Run(frame);
@@ -131,6 +133,7 @@ void TTvdVideoDecoder::ReleaseVideoFrame(
 }
 
 void TTvdVideoDecoder::OnResetDone() {
+  can_read_without_stalling_ = true;
   std::move(reset_cb_).Run();
 }
 
index b3c8cf5fbe5c48bed6e82a67c610d0175e6f3da1..57d681d3f11de24ff2dd324e103555c2ad799894 100644 (file)
@@ -43,7 +43,9 @@ class MEDIA_EXPORT TTvdVideoDecoder : public VideoDecoder,
   void Decode(scoped_refptr<DecoderBuffer> buffer, DecodeCB decode_cb) override;
   void Reset(base::OnceClosure closure) override;
   bool NeedsBitstreamConversion() const override { return false; }
-  bool CanReadWithoutStalling() const override { return false; }
+  bool CanReadWithoutStalling() const override {
+    return can_read_without_stalling_;
+  }
   int GetMaxDecodeRequests() const override { return 4; }
   VideoDecoderType GetDecoderType() const override {
     return VideoDecoderType::kUnknown;
@@ -52,6 +54,7 @@ class MEDIA_EXPORT TTvdVideoDecoder : public VideoDecoder,
   // mojom::TTvdVideoDecoderClient implementation.
   void OnVideoFrameDecoded(
       const scoped_refptr<VideoFrame>& frame,
+      bool can_read_without_stalling,
       const base::UnguessableToken& release_token) override;
   void OnTotalMemoryUsageReport(int64_t total_video_memory) override;
   void OnWaiting(WaitingReason reason) override;
@@ -98,6 +101,7 @@ class MEDIA_EXPORT TTvdVideoDecoder : public VideoDecoder,
   uint64_t decode_counter_ = 0;
   base::flat_map<uint64_t, DecodeCB> pending_decodes_;
   base::OnceClosure reset_cb_;
+  bool can_read_without_stalling_ = true;
 
   int64_t last_reported_memory_usage_ = 0;
   TotalMemoryUsageCB total_memory_usage_cb_;
index 5a7f2e8f3df7cce925b54f04dd84965a1e8affdd..29ad7ff1eb4e4c0232f3908e4ad98eeadb23041a 100644 (file)
@@ -949,7 +949,7 @@ void TTvdVideoDecoderImpl::TriggerLazyFrames() {
 
     base::UnguessableToken release_token = base::UnguessableToken::Create();
     video_frames_[release_token] = video_frame;
-    client_->OnVideoFrameDecoded(std::move(video_frame),
+    client_->OnVideoFrameDecoded(std::move(video_frame), CanAllocateNewFrame(),
                                  std::move(release_token));
   }
 
@@ -1070,7 +1070,8 @@ void TTvdVideoDecoderImpl::ReturnVideoFrame(
 
   base::UnguessableToken release_token = base::UnguessableToken::Create();
   video_frames_[release_token] = video_frame;
-  client_->OnVideoFrameDecoded(std::move(video_frame), release_token);
+  client_->OnVideoFrameDecoded(std::move(video_frame), CanAllocateNewFrame(),
+                               release_token);
 }
 
 bool TTvdVideoDecoderImpl::CleanFacade() {
@@ -2590,6 +2591,11 @@ void TTvdVideoDecoderImpl::TriggerEos() {
   std::move(eos_cb_).Run(DecoderStatus::Codes::kOk);
 }
 
+bool TTvdVideoDecoderImpl::CanAllocateNewFrame() const {
+  return ttvd_decoded_frame_pool_.size() + decoding_results_.size() <
+         kMaxUsedDecodedFrames;
+}
+
 void TTvdVideoDecoderImpl::OnMemoryUsageChange(int64_t memory_delta) {
   TIZEN_MEDIA_LOG(VERBOSE) << "Video memory delta: " << memory_delta;
   total_memory_usage_ += memory_delta;
index c6eeef10dc7e12f53177fe34dc1cd4c2abf178ad..335ed9cac45b80798ba2490a1f8b94d5074fa69d 100644 (file)
@@ -320,6 +320,10 @@ class MEDIA_EXPORT TTvdVideoDecoderImpl
   // in |decoding_requests_|.
   void TriggerEos();
 
+  // Helper to checked whether new frame can be created without exceeding the
+  // limits.
+  bool CanAllocateNewFrame() const;
+
   // Updates amount of memory usage by decoded frames currently hold by decoder.
   void OnMemoryUsageChange(int64_t memory_delta);
 
index 73476d9852f259681884562c520bdeaf00cc1dfd..19d5dc168215eb42fa5a46a60c12193f9861539f 100644 (file)
@@ -40,6 +40,7 @@ interface TTvdVideoDecoder {
 
 interface TTvdVideoDecoderClient {
   OnVideoFrameDecoded(VideoFrame frame,
+                      bool can_read_without_stalling,
                       mojo_base.mojom.UnguessableToken release_token);
 
   // Provides information what is total memory used by decoder to hold video