mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-21 00:38:56 +00:00
LibMedia: Separate file duration from track duration in Demuxer
Most users will only care about the total file duration, and shouldn't be required to determine the file duration from multiple track durations. To facilitate that, add a total_duration() function that returns the demuxer's duration not associated to any particular track.
This commit is contained in:
parent
6653b747ff
commit
ae7f82591b
Notes:
github-actions[bot]
2025-09-12 09:25:06 +00:00
Author: https://github.com/Zaggy1024
Commit: ae7f82591b
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6165
Reviewed-by: https://github.com/gmta ✅
6 changed files with 25 additions and 16 deletions
|
@ -4,7 +4,9 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/Assertions.h>
|
||||
#include <AK/Debug.h>
|
||||
#include <LibMedia/DecoderError.h>
|
||||
|
||||
#include "MatroskaDemuxer.h"
|
||||
|
||||
|
@ -192,10 +194,15 @@ DecoderErrorOr<Sample> MatroskaDemuxer::get_next_sample_for_track(Track track)
|
|||
return Sample(status.block->timestamp(), move(sample_data), VideoSampleData(cicp));
|
||||
}
|
||||
|
||||
DecoderErrorOr<AK::Duration> MatroskaDemuxer::duration(Track)
|
||||
DecoderErrorOr<AK::Duration> MatroskaDemuxer::total_duration()
|
||||
{
|
||||
auto duration = TRY(m_reader.segment_information()).duration();
|
||||
return duration.value_or(AK::Duration::zero());
|
||||
}
|
||||
|
||||
DecoderErrorOr<AK::Duration> MatroskaDemuxer::duration_of_track(Track const&)
|
||||
{
|
||||
return total_duration();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,7 +32,8 @@ public:
|
|||
|
||||
DecoderErrorOr<Optional<AK::Duration>> seek_to_most_recent_keyframe(Track track, AK::Duration timestamp, Optional<AK::Duration> earliest_available_sample = OptionalNone()) override;
|
||||
|
||||
DecoderErrorOr<AK::Duration> duration(Track track) override;
|
||||
DecoderErrorOr<AK::Duration> duration_of_track(Track const& track) override;
|
||||
DecoderErrorOr<AK::Duration> total_duration() override;
|
||||
|
||||
DecoderErrorOr<CodecID> get_codec_id_for_track(Track track) override;
|
||||
|
||||
|
|
|
@ -36,7 +36,8 @@ public:
|
|||
// in the case that the timestamp is closer to the current time than the nearest keyframe.
|
||||
virtual DecoderErrorOr<Optional<AK::Duration>> seek_to_most_recent_keyframe(Track track, AK::Duration timestamp, Optional<AK::Duration> earliest_available_sample = OptionalNone()) = 0;
|
||||
|
||||
virtual DecoderErrorOr<AK::Duration> duration(Track track) = 0;
|
||||
virtual DecoderErrorOr<AK::Duration> duration_of_track(Track const&) = 0;
|
||||
virtual DecoderErrorOr<AK::Duration> total_duration() = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -68,6 +68,15 @@ static inline AK::Duration time_units_to_duration(i64 time_units, AVRational con
|
|||
return time_units_to_duration(time_units, time_base.num, time_base.den);
|
||||
}
|
||||
|
||||
DecoderErrorOr<AK::Duration> FFmpegDemuxer::total_duration()
|
||||
{
|
||||
if (m_format_context->duration < 0) {
|
||||
return DecoderError::format(DecoderErrorCategory::Unknown, "Negative stream duration");
|
||||
}
|
||||
|
||||
return time_units_to_duration(m_format_context->duration, 1, AV_TIME_BASE);
|
||||
}
|
||||
|
||||
DecoderErrorOr<AK::Duration> FFmpegDemuxer::duration_of_track(Track const& track)
|
||||
{
|
||||
VERIFY(track.identifier() < m_format_context->nb_streams);
|
||||
|
@ -78,11 +87,7 @@ DecoderErrorOr<AK::Duration> FFmpegDemuxer::duration_of_track(Track const& track
|
|||
}
|
||||
|
||||
// If the stream doesn't specify the duration, fallback to what the container says the duration is.
|
||||
// If the container doesn't know the duration, then we're out of luck. Return an error.
|
||||
if (m_format_context->duration < 0)
|
||||
return DecoderError::format(DecoderErrorCategory::Unknown, "Negative stream duration");
|
||||
|
||||
return time_units_to_duration(m_format_context->duration, 1, AV_TIME_BASE);
|
||||
return total_duration();
|
||||
}
|
||||
|
||||
DecoderErrorOr<Track> FFmpegDemuxer::get_track_for_stream_index(u32 stream_index)
|
||||
|
@ -144,11 +149,6 @@ DecoderErrorOr<Optional<AK::Duration>> FFmpegDemuxer::seek_to_most_recent_keyfra
|
|||
return timestamp;
|
||||
}
|
||||
|
||||
DecoderErrorOr<AK::Duration> FFmpegDemuxer::duration(Track track)
|
||||
{
|
||||
return duration_of_track(track);
|
||||
}
|
||||
|
||||
DecoderErrorOr<CodecID> FFmpegDemuxer::get_codec_id_for_track(Track track)
|
||||
{
|
||||
VERIFY(track.identifier() < m_format_context->nb_streams);
|
||||
|
|
|
@ -30,7 +30,8 @@ public:
|
|||
|
||||
virtual DecoderErrorOr<Optional<AK::Duration>> seek_to_most_recent_keyframe(Track track, AK::Duration timestamp, Optional<AK::Duration> earliest_available_sample = OptionalNone()) override;
|
||||
|
||||
virtual DecoderErrorOr<AK::Duration> duration(Track track) override;
|
||||
virtual DecoderErrorOr<AK::Duration> duration_of_track(Track const&) override;
|
||||
virtual DecoderErrorOr<AK::Duration> total_duration() override;
|
||||
|
||||
virtual DecoderErrorOr<CodecID> get_codec_id_for_track(Track track) override;
|
||||
|
||||
|
@ -39,7 +40,6 @@ public:
|
|||
virtual DecoderErrorOr<Sample> get_next_sample_for_track(Track track) override;
|
||||
|
||||
private:
|
||||
DecoderErrorOr<AK::Duration> duration_of_track(Track const& track);
|
||||
DecoderErrorOr<Track> get_track_for_stream_index(u32 stream_index);
|
||||
|
||||
NonnullOwnPtr<SeekableStream> m_stream;
|
||||
|
|
|
@ -90,7 +90,7 @@ AK::Duration PlaybackManager::duration()
|
|||
{
|
||||
auto duration_result = ({
|
||||
auto demuxer_locker = Threading::MutexLocker(m_decoder_mutex);
|
||||
m_demuxer->duration(m_selected_video_track);
|
||||
m_demuxer->duration_of_track(m_selected_video_track);
|
||||
});
|
||||
if (duration_result.is_error()) {
|
||||
dispatch_decoder_error(duration_result.release_error());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue