mirror of
https://github.com/cookiengineer/audacity
synced 2025-07-26 09:28:07 +02:00
OD FFmpeg: fix a bug with demand seeking by using a safer seek test
This commit is contained in:
parent
1fb7a1dcee
commit
c4f1a52413
@ -155,6 +155,7 @@ bool ODFFmpegDecoder::SeekingAllowed()
|
|||||||
AVFormatContext* ic = (AVFormatContext*)mFormatContext;
|
AVFormatContext* ic = (AVFormatContext*)mFormatContext;
|
||||||
bool audioStreamExists = false;
|
bool audioStreamExists = false;
|
||||||
AVStream* st;
|
AVStream* st;
|
||||||
|
|
||||||
//test the audio stream(s)
|
//test the audio stream(s)
|
||||||
for (unsigned int i = 0; i < ic->nb_streams; i++)
|
for (unsigned int i = 0; i < ic->nb_streams; i++)
|
||||||
{
|
{
|
||||||
@ -177,14 +178,31 @@ bool ODFFmpegDecoder::SeekingAllowed()
|
|||||||
goto test_failed;
|
goto test_failed;
|
||||||
//TODO: now try a seek and see if dts/pts (decode/presentation timestamp) is updated as we expected it to be.
|
//TODO: now try a seek and see if dts/pts (decode/presentation timestamp) is updated as we expected it to be.
|
||||||
//This should be done using a new AVFormatContext clone so that we don't ruin the file pointer if we fail.
|
//This should be done using a new AVFormatContext clone so that we don't ruin the file pointer if we fail.
|
||||||
// url_fseek(mFormatContext->pb,0,SEEK_SET);
|
// url_fseek(mFormatContext->pb,0,SEEK_SET);
|
||||||
|
|
||||||
if(av_seek_frame(mFormatContext,st->index,0,0) >= 0) {
|
|
||||||
|
|
||||||
|
AVFormatContext* tempContext;
|
||||||
|
int err;
|
||||||
|
err = ufile_fopen_input(&tempContext, mFName);
|
||||||
|
if (err < 0)
|
||||||
|
{
|
||||||
|
goto test_failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = av_find_stream_info(tempContext);
|
||||||
|
if (err < 0)
|
||||||
|
{
|
||||||
|
goto test_failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(av_seek_frame(tempContext, st->index, 0, 0) >= 0) {
|
||||||
mSeekingAllowedStatus = ODFFMPEG_SEEKING_TEST_SUCCESS;
|
mSeekingAllowedStatus = ODFFMPEG_SEEKING_TEST_SUCCESS;
|
||||||
|
if (tempContext) av_close_input_file(tempContext);
|
||||||
return SeekingAllowed();
|
return SeekingAllowed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tempContext) av_close_input_file(tempContext);
|
||||||
|
|
||||||
test_failed:
|
test_failed:
|
||||||
mSeekingAllowedStatus = ODFFMPEG_SEEKING_TEST_FAILED;
|
mSeekingAllowedStatus = ODFFMPEG_SEEKING_TEST_FAILED;
|
||||||
return SeekingAllowed();
|
return SeekingAllowed();
|
||||||
@ -279,7 +297,7 @@ int ODFFmpegDecoder::Decode(samplePtr & data, sampleFormat & format, sampleCount
|
|||||||
|
|
||||||
int nChannels;
|
int nChannels;
|
||||||
|
|
||||||
|
printf("start %llu len %llu\n", start, len);
|
||||||
//TODO update this to work with seek - this only works linearly now.
|
//TODO update this to work with seek - this only works linearly now.
|
||||||
if(mCurrentPos > start && mCurrentPos <= start+len + kDecodeSampleAllowance)
|
if(mCurrentPos > start && mCurrentPos <= start+len + kDecodeSampleAllowance)
|
||||||
{
|
{
|
||||||
@ -302,7 +320,7 @@ int ODFFmpegDecoder::Decode(samplePtr & data, sampleFormat & format, sampleCount
|
|||||||
stindex =i;
|
stindex =i;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(stindex >=0) {
|
if(stindex >=0) {
|
||||||
int numAttempts = 0;
|
int numAttempts = 0;
|
||||||
//reset mCurrentPos to a bogus value
|
//reset mCurrentPos to a bogus value
|
||||||
mCurrentPos = start+len +1;
|
mCurrentPos = start+len +1;
|
||||||
@ -311,6 +329,8 @@ int ODFFmpegDecoder::Decode(samplePtr & data, sampleFormat & format, sampleCount
|
|||||||
targetts = (start-kDecodeSampleAllowance*numAttempts/kMaxSeekRewindAttempts) * ((double)st->time_base.den/(st->time_base.num * st->codec->sample_rate ));
|
targetts = (start-kDecodeSampleAllowance*numAttempts/kMaxSeekRewindAttempts) * ((double)st->time_base.den/(st->time_base.num * st->codec->sample_rate ));
|
||||||
if(targetts<0)
|
if(targetts<0)
|
||||||
targetts=0;
|
targetts=0;
|
||||||
|
|
||||||
|
printf("attempting seek to %llu, attempts %d\n", targetts, numAttempts);
|
||||||
if(av_seek_frame(mFormatContext,stindex,targetts,0) >= 0){
|
if(av_seek_frame(mFormatContext,stindex,targetts,0) >= 0){
|
||||||
//find out the dts we've seekd to.
|
//find out the dts we've seekd to.
|
||||||
sampleCount actualDecodeStart = 0.5 + st->codec->sample_rate * st->cur_dts * ((double)st->time_base.num/st->time_base.den); //this is mostly safe because den is usually 1 or low number but check for high values.
|
sampleCount actualDecodeStart = 0.5 + st->codec->sample_rate * st->cur_dts * ((double)st->time_base.num/st->time_base.den); //this is mostly safe because den is usually 1 or low number but check for high values.
|
||||||
@ -320,8 +340,10 @@ int ODFFmpegDecoder::Decode(samplePtr & data, sampleFormat & format, sampleCount
|
|||||||
|
|
||||||
//if the seek was past our desired position, rewind a bit.
|
//if the seek was past our desired position, rewind a bit.
|
||||||
//printf("seek ok to %llu samps, float: %f\n",actualDecodeStart,actualDecodeStartDouble);
|
//printf("seek ok to %llu samps, float: %f\n",actualDecodeStart,actualDecodeStartDouble);
|
||||||
} else
|
} else {
|
||||||
|
printf("seek failed");
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(mCurrentPos>start){
|
if(mCurrentPos>start){
|
||||||
mSeekingAllowedStatus = ODFFMPEG_SEEKING_TEST_FAILED;
|
mSeekingAllowedStatus = ODFFMPEG_SEEKING_TEST_FAILED;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user