decoder: fixed longstanding audio sync issue
Wow this has probably been a bug for 3 years straight
This commit is contained in:
@@ -217,14 +217,11 @@ DecoderPtr Decoder::CreateFromID(const QString &id)
|
||||
|
||||
int64_t Decoder::GetTimeInTimebaseUnits(const rational &time, const rational &timebase, int64_t start_time)
|
||||
{
|
||||
int64_t t = Timecode::time_to_timestamp(time, timebase);
|
||||
t += start_time;
|
||||
return t;
|
||||
return Timecode::time_to_timestamp(time, timebase);
|
||||
}
|
||||
|
||||
rational Decoder::GetTimestampInTimeUnits(int64_t time, const rational &timebase, int64_t start_time)
|
||||
{
|
||||
time -= start_time;
|
||||
return Timecode::timestamp_to_time(time, timebase);
|
||||
}
|
||||
|
||||
@@ -294,10 +291,13 @@ bool Decoder::ConformAudioInternal(const QVector<QString> &filenames, const Audi
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Decoder::RetrieveAudioFromConform(SampleBuffer &sample_buffer, const QVector<QString> &conform_filenames, const TimeRange& range, LoopMode loop_mode, const AudioParams &input_params)
|
||||
bool Decoder::RetrieveAudioFromConform(SampleBuffer &sample_buffer, const QVector<QString> &conform_filenames, TimeRange range, LoopMode loop_mode, const AudioParams &input_params)
|
||||
{
|
||||
PlanarFileDevice input;
|
||||
if (input.open(conform_filenames, QFile::ReadOnly)) {
|
||||
// Offset range by audio start offset
|
||||
range -= GetAudioStartOffset();
|
||||
|
||||
qint64 read_index = input_params.time_to_bytes(range.in()) / input_params.channel_count();
|
||||
qint64 write_index = 0;
|
||||
|
||||
|
||||
+3
-1
@@ -297,6 +297,8 @@ protected:
|
||||
static int64_t GetTimeInTimebaseUnits(const rational& time, const rational& timebase, int64_t start_time);
|
||||
static rational GetTimestampInTimeUnits(int64_t time, const rational& timebase, int64_t start_time);
|
||||
|
||||
virtual rational GetAudioStartOffset() const { return 0; }
|
||||
|
||||
signals:
|
||||
/**
|
||||
* @brief While indexing, this signal will provide progress as a percentage (0-100 inclusive) if
|
||||
@@ -307,7 +309,7 @@ signals:
|
||||
private:
|
||||
void UpdateLastAccessed();
|
||||
|
||||
bool RetrieveAudioFromConform(SampleBuffer &sample_buffer, const QVector<QString> &conform_filenames, const TimeRange &range, LoopMode loop_mode, const AudioParams ¶ms);
|
||||
bool RetrieveAudioFromConform(SampleBuffer &sample_buffer, const QVector<QString> &conform_filenames, TimeRange range, LoopMode loop_mode, const AudioParams ¶ms);
|
||||
|
||||
CodecStream stream_;
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ bool FFmpegDecoder::OpenInternal()
|
||||
|
||||
TexturePtr FFmpegDecoder::RetrieveVideoInternal(const RetrieveVideoParams &p)
|
||||
{
|
||||
if (AVFramePtr f = RetrieveFrame(p.time, p.cancelled)) {
|
||||
if (AVFramePtr f = RetrieveFrame(p.time, p.src_interlacing, p.cancelled)) {
|
||||
if (p.cancelled && p.cancelled->IsCancelled()) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -311,6 +311,16 @@ void FFmpegDecoder::CloseInternal()
|
||||
native_output_pix_fmt_ = VideoParams::kFormatInvalid;
|
||||
}
|
||||
|
||||
rational FFmpegDecoder::GetAudioStartOffset() const
|
||||
{
|
||||
AVStream *s = this->instance_.avstream();
|
||||
if (s) {
|
||||
return rational(s->start_time * s->time_base.num, s->time_base.den);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
QString FFmpegDecoder::id() const
|
||||
{
|
||||
return QStringLiteral("ffmpeg");
|
||||
@@ -787,10 +797,14 @@ void FFmpegDecoder::ClearFrameCache()
|
||||
}
|
||||
}
|
||||
|
||||
AVFramePtr FFmpegDecoder::RetrieveFrame(const rational& time, CancelAtom *cancelled)
|
||||
AVFramePtr FFmpegDecoder::RetrieveFrame(const rational& time, VideoParams::Interlacing interlacing, CancelAtom *cancelled)
|
||||
{
|
||||
int64_t target_ts = GetTimeInTimebaseUnits(time, instance_.avstream()->time_base, instance_.avstream()->start_time);
|
||||
|
||||
if (interlacing != VideoParams::kInterlaceNone) {
|
||||
target_ts *= 2;
|
||||
}
|
||||
|
||||
const int64_t min_seek = -instance_.avstream()->start_time;
|
||||
int64_t seek_ts = std::max(min_seek, target_ts - MaximumQueueSize());
|
||||
bool still_seeking = false;
|
||||
|
||||
@@ -67,6 +67,8 @@ protected:
|
||||
virtual bool ConformAudioInternal(const QVector<QString>& filenames, const AudioParams ¶ms, CancelAtom *cancelled) override;
|
||||
virtual void CloseInternal() override;
|
||||
|
||||
virtual rational GetAudioStartOffset() const override;
|
||||
|
||||
private:
|
||||
class Instance
|
||||
{
|
||||
@@ -148,7 +150,7 @@ private:
|
||||
|
||||
void ClearFrameCache();
|
||||
|
||||
AVFramePtr RetrieveFrame(const rational &time, CancelAtom *cancelled);
|
||||
AVFramePtr RetrieveFrame(const rational &time, VideoParams::Interlacing interlacing, CancelAtom *cancelled);
|
||||
|
||||
void RemoveFirstFrame();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user