Use unreliable video duration if open with audio.

This commit is contained in:
John Preston 2022-02-01 15:49:53 +03:00
parent 18bf48bf90
commit 4bef1e9f59
5 changed files with 19 additions and 8 deletions

View file

@ -20,8 +20,10 @@ constexpr auto kMaxQueuedPackets = 1024;
[[nodiscard]] bool UnreliableFormatDuration( [[nodiscard]] bool UnreliableFormatDuration(
not_null<AVFormatContext*> format, not_null<AVFormatContext*> format,
not_null<AVStream*> stream) { not_null<AVStream*> stream,
return stream->codec Mode mode) {
return (mode == Mode::Video || mode == Mode::Inspection)
&& stream->codec
&& (stream->codec->codec_id == AV_CODEC_ID_VP9) && (stream->codec->codec_id == AV_CODEC_ID_VP9)
&& format->iformat && format->iformat
&& format->iformat->name && format->iformat->name
@ -145,7 +147,8 @@ void File::Context::logFatal(
Stream File::Context::initStream( Stream File::Context::initStream(
not_null<AVFormatContext*> format, not_null<AVFormatContext*> format,
AVMediaType type) { AVMediaType type,
Mode mode) {
auto result = Stream(); auto result = Stream();
const auto index = result.index = av_find_best_stream( const auto index = result.index = av_find_best_stream(
format, format,
@ -186,7 +189,7 @@ Stream File::Context::initStream(
result.timeBase = info->time_base; result.timeBase = info->time_base;
result.duration = (info->duration != AV_NOPTS_VALUE) result.duration = (info->duration != AV_NOPTS_VALUE)
? FFmpeg::PtsToTime(info->duration, result.timeBase) ? FFmpeg::PtsToTime(info->duration, result.timeBase)
: UnreliableFormatDuration(format, info) : UnreliableFormatDuration(format, info, mode)
? kTimeUnknown ? kTimeUnknown
: FFmpeg::PtsToTime(format->duration, FFmpeg::kUniversalTimeBase); : FFmpeg::PtsToTime(format->duration, FFmpeg::kUniversalTimeBase);
if (result.duration == kTimeUnknown) { if (result.duration == kTimeUnknown) {
@ -276,12 +279,13 @@ void File::Context::start(crl::time position) {
return logFatal(qstr("avformat_find_stream_info"), error); return logFatal(qstr("avformat_find_stream_info"), error);
} }
auto video = initStream(format.get(), AVMEDIA_TYPE_VIDEO); const auto mode = _delegate->fileOpenMode();
auto video = initStream(format.get(), AVMEDIA_TYPE_VIDEO, mode);
if (unroll()) { if (unroll()) {
return; return;
} }
auto audio = initStream(format.get(), AVMEDIA_TYPE_AUDIO); auto audio = initStream(format.get(), AVMEDIA_TYPE_AUDIO, mode);
if (unroll()) { if (unroll()) {
return; return;
} }

View file

@ -72,9 +72,10 @@ private:
void logFatal(QLatin1String method, FFmpeg::AvErrorWrap error); void logFatal(QLatin1String method, FFmpeg::AvErrorWrap error);
void fail(Error error); void fail(Error error);
Stream initStream( [[nodiscard]] Stream initStream(
not_null<AVFormatContext *> format, not_null<AVFormatContext *> format,
AVMediaType type); AVMediaType type,
Mode mode);
void seekToPosition( void seekToPosition(
not_null<AVFormatContext *> format, not_null<AVFormatContext *> format,
const Stream &stream, const Stream &stream,

View file

@ -19,6 +19,7 @@ enum class Error;
class FileDelegate { class FileDelegate {
public: public:
[[nodiscard]] virtual Mode fileOpenMode() = 0;
[[nodiscard]] virtual bool fileReady( [[nodiscard]] virtual bool fileReady(
int headerSize, int headerSize,
Stream &&video, Stream &&video,

View file

@ -234,6 +234,10 @@ void Player::videoPlayedTill(crl::time position) {
trackPlayedTill(*_video, _information.video.state, position); trackPlayedTill(*_video, _information.video.state, position);
} }
Mode Player::fileOpenMode() {
return _options.mode;
}
bool Player::fileReady(int headerSize, Stream &&video, Stream &&audio) { bool Player::fileReady(int headerSize, Stream &&video, Stream &&audio) {
_waitingForData = false; _waitingForData = false;

View file

@ -97,6 +97,7 @@ private:
not_null<FileDelegate*> delegate(); not_null<FileDelegate*> delegate();
// FileDelegate methods are called only from the File thread. // FileDelegate methods are called only from the File thread.
Mode fileOpenMode() override;
bool fileReady(int headerSize, Stream &&video, Stream &&audio) override; bool fileReady(int headerSize, Stream &&video, Stream &&audio) override;
void fileError(Error error) override; void fileError(Error error) override;
void fileWaitingForData() override; void fileWaitingForData() override;