@@ -162,7 +162,8 @@ std::optional<Size> ParseMaxResolution(
162162
163163class VideoFrameImpl : public VideoFrame {
164164 public:
165- typedef std::function<void ()> VideoFrameReleaseCallback;
165+ typedef std::function<void (int64_t pts_us, int64_t release_at_us)>
166+ VideoFrameReleaseCallback;
166167
167168 VideoFrameImpl (const DequeueOutputResult& dequeue_output_result,
168169 MediaCodecBridge* media_codec_bridge,
@@ -183,7 +184,7 @@ class VideoFrameImpl : public VideoFrame {
183184 media_codec_bridge_->ReleaseOutputBuffer (dequeue_output_result_.index ,
184185 false );
185186 if (!is_end_of_stream ()) {
186- release_callback_ ();
187+ release_callback_ (timestamp (), CurrentMonotonicTime () );
187188 }
188189 }
189190 }
@@ -194,7 +195,7 @@ class VideoFrameImpl : public VideoFrame {
194195 released_ = true ;
195196 media_codec_bridge_->ReleaseOutputBufferAtTimestamp (
196197 dequeue_output_result_.index , release_time_in_nanoseconds);
197- release_callback_ ();
198+ release_callback_ (timestamp (), release_time_in_nanoseconds / 1'000 );
198199 }
199200
200201 private:
@@ -212,7 +213,7 @@ const int kNonInitialPrerollFrameCount = 1;
212213
213214const int kSeekingPrerollPendingWorkSizeInTunnelMode =
214215 16 + kInitialPrerollFrameCount ;
215- const int kMaxPendingInputsSize = 128 ;
216+ const int kDefaultMaxPendingInputsSize = 128 ;
216217
217218const int kFpsGuesstimateRequiredInputBufferCount = 3 ;
218219
@@ -344,7 +345,8 @@ MediaCodecVideoDecoder::Create(JobQueue* job_queue,
344345 void * surface_view,
345346 bool enable_flush_during_seek,
346347 int64_t reset_delay_usec,
347- int64_t flush_delay_usec) {
348+ int64_t flush_delay_usec,
349+ const FlowControlOptions& flow_control_options) {
348350 std::string error_message;
349351 auto video_decoder = std::make_unique<MediaCodecVideoDecoder>(
350352 PassKey<MediaCodecVideoDecoder>(), job_queue, video_stream_info,
@@ -353,7 +355,7 @@ MediaCodecVideoDecoder::Create(JobQueue* job_queue,
353355 force_secure_pipeline_under_tunnel_mode, force_reset_surface,
354356 force_big_endian_hdr_metadata, max_input_size, surface_view,
355357 enable_flush_during_seek, reset_delay_usec, flush_delay_usec,
356- &error_message);
358+ flow_control_options, &error_message);
357359
358360 if (!error_message.empty ()) {
359361 return Failure (error_message);
@@ -387,6 +389,7 @@ MediaCodecVideoDecoder::MediaCodecVideoDecoder(
387389 bool enable_flush_during_seek,
388390 int64_t reset_delay_usec,
389391 int64_t flush_delay_usec,
392+ const FlowControlOptions& flow_control_options,
390393 std::string* error_message)
391394 : JobOwner(job_queue),
392395 video_codec_ (video_stream_info.codec),
@@ -395,6 +398,11 @@ MediaCodecVideoDecoder::MediaCodecVideoDecoder(
395398 decode_target_graphics_context_provider_(
396399 decode_target_graphics_context_provider),
397400 max_video_capabilities_(max_video_capabilities),
401+ initial_max_frames_in_decoder_(
402+ flow_control_options.initial_max_frames_in_decoder),
403+ max_pending_inputs_size_(
404+ flow_control_options.max_pending_input_frames.value_or(
405+ kDefaultMaxPendingInputsSize )),
398406 require_software_codec_(IsSoftwareDecodeRequired(max_video_capabilities)),
399407 force_big_endian_hdr_metadata_(force_big_endian_hdr_metadata),
400408 tunnel_mode_audio_session_id_(tunnel_mode_audio_session_id),
@@ -428,7 +436,7 @@ MediaCodecVideoDecoder::MediaCodecVideoDecoder(
428436
429437 if (is_video_frame_tracker_enabled_) {
430438 video_frame_tracker_ =
431- std::make_unique<VideoFrameTracker>(kMaxPendingInputsSize * 2 );
439+ std::make_unique<VideoFrameTracker>(max_pending_inputs_size_ * 2 );
432440 }
433441
434442 if (require_software_codec_) {
@@ -448,6 +456,7 @@ MediaCodecVideoDecoder::MediaCodecVideoDecoder(
448456 SB_LOG (INFO ) << " Created VideoDecoder for codec "
449457 << GetMediaVideoCodecName (video_codec_) << " , with output mode "
450458 << GetPlayerOutputModeName (output_mode_)
459+ << " , max pending input size " << max_pending_inputs_size_
451460 << " , max video capabilities \" " << max_video_capabilities_
452461 << " \" , and tunnel mode audio session id "
453462 << tunnel_mode_audio_session_id_;
@@ -780,7 +789,7 @@ Result<void> MediaCodecVideoDecoder::InitializeCodec(
780789 std::bind (&MediaCodecVideoDecoder::OnFrameRendered, this , _1),
781790 std::bind (&MediaCodecVideoDecoder::OnFirstTunnelFrameReady, this ),
782791 tunnel_mode_audio_session_id_, force_big_endian_hdr_metadata_,
783- max_video_input_size_, flush_delay_usec_);
792+ max_video_input_size_, flush_delay_usec_, initial_max_frames_in_decoder_ );
784793 if (result) {
785794 media_decoder_ = std::move (result.value ());
786795 if (error_cb_) {
@@ -884,7 +893,7 @@ void MediaCodecVideoDecoder::WriteInputBuffersInternal(
884893 }
885894
886895 media_decoder_->WriteInputBuffers (input_buffers);
887- if (media_decoder_->GetNumberOfPendingInputs () < kMaxPendingInputsSize ) {
896+ if (media_decoder_->GetNumberOfPendingInputs () < max_pending_inputs_size_ ) {
888897 decoder_status_cb_ (kNeedMoreInput , NULL );
889898 } else if (tunnel_mode_audio_session_id_ != -1 ) {
890899 // In tunnel mode playback when need data is not signaled above, it is
@@ -921,8 +930,8 @@ void MediaCodecVideoDecoder::WriteInputBuffersInternal(
921930 max_timestamp >= video_frame_tracker_->seek_to_time ();
922931 }
923932
924- bool cache_full =
925- media_decoder_-> GetNumberOfPendingInputs () >= kMaxPendingInputsSize ;
933+ bool cache_full = media_decoder_-> GetNumberOfPendingInputs () >=
934+ max_pending_inputs_size_ ;
926935 bool prerolled = tunnel_mode_frame_rendered_.load () > 0 ||
927936 enough_buffers_written_to_media_codec || cache_full;
928937
@@ -960,9 +969,10 @@ void MediaCodecVideoDecoder::ProcessOutputBuffer(
960969 }
961970 decoder_status_cb_ (
962971 is_end_of_stream ? kBufferFull : kNeedMoreInput ,
963- new VideoFrameImpl (
964- dequeue_output_result, media_codec_bridge,
965- std::bind (&MediaCodecVideoDecoder::OnVideoFrameRelease, this )));
972+ new VideoFrameImpl (dequeue_output_result, media_codec_bridge,
973+ [this ](int64_t pts_us, int64_t release_at_us) {
974+ OnVideoFrameRelease (pts_us, release_at_us);
975+ }));
966976}
967977
968978void MediaCodecVideoDecoder::RefreshOutputFormat (
@@ -1279,7 +1289,7 @@ void MediaCodecVideoDecoder::OnTunnelModeCheckForNeedMoreInput() {
12791289 return ;
12801290 }
12811291
1282- if (media_decoder_->GetNumberOfPendingInputs () < kMaxPendingInputsSize ) {
1292+ if (media_decoder_->GetNumberOfPendingInputs () < max_pending_inputs_size_ ) {
12831293 decoder_status_cb_ (kNeedMoreInput , NULL );
12841294 return ;
12851295 }
@@ -1289,11 +1299,17 @@ void MediaCodecVideoDecoder::OnTunnelModeCheckForNeedMoreInput() {
12891299 kNeedMoreInputCheckIntervalInTunnelMode );
12901300}
12911301
1292- void MediaCodecVideoDecoder::OnVideoFrameRelease () {
1302+ void MediaCodecVideoDecoder::OnVideoFrameRelease (int64_t pts_us,
1303+ int64_t release_at_us) {
12931304 if (output_format_) {
12941305 --buffered_output_frames_;
12951306 SB_DCHECK_GE (buffered_output_frames_, 0 );
12961307 }
1308+
1309+ if (media_decoder_ && media_decoder_->decoder_state_tracker ()) {
1310+ media_decoder_->decoder_state_tracker ()->MarkFrameReleased (pts_us,
1311+ release_at_us);
1312+ }
12971313}
12981314
12991315void MediaCodecVideoDecoder::OnSurfaceDestroyed () {
0 commit comments