movies: allow seeking compressed Opus file to beginning

Same change as 2c55663472f50f5e50ea0a605a9f15bf90822fb0 but for Opus files.
This commit is contained in:
rdb 2019-04-29 12:39:44 +02:00
parent 8af3e37bd2
commit d92168cd74
2 changed files with 34 additions and 12 deletions

View File

@ -117,16 +117,7 @@ opus_int64 cb_tell(void *stream) {
return in->tellg();
}
int cb_close(void *stream) {
istream *in = (istream *)stream;
nassertr(in != nullptr, EOF);
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
vfs->close_read_file(in);
return 0;
}
static const OpusFileCallbacks callbacks = {cb_read, cb_seek, cb_tell, cb_close};
static const OpusFileCallbacks callbacks = {cb_read, cb_seek, cb_tell, nullptr};
TypeHandle OpusAudioCursor::_type_handle;
@ -138,6 +129,7 @@ OpusAudioCursor::
OpusAudioCursor(OpusAudio *src, istream *stream) :
MovieAudioCursor(src),
_is_valid(false),
_stream(stream),
_link(0)
{
nassertv(stream != nullptr);
@ -175,6 +167,11 @@ OpusAudioCursor::
op_free(_op);
_op = nullptr;
}
if (_stream != nullptr) {
VirtualFileSystem::close_read_file(_stream);
_stream = nullptr;
}
}
/**
@ -190,7 +187,32 @@ seek(double t) {
t = std::max(t, 0.0);
// Use op_time_seek_lap if cross-lapping is enabled.
int error = op_pcm_seek(_op, (ogg_int64_t)(t * 48000.0));
ogg_int64_t sample = (ogg_int64_t)(t * 48000.0);
int error = op_pcm_seek(_op, sample);
// Special case for seeking to the beginning; if normal seek fails, we may
// be able to explicitly seek to the beginning of the file and call op_open
// again. This allows looping compressed .opus files.
if (error == OP_ENOSEEK && sample == 0) {
if (_stream->rdbuf()->pubseekpos(0, std::ios::in) == 0) {
OggOpusFile *op = op_open_callbacks((void *)_stream, &callbacks, nullptr, 0, nullptr);
if (op != nullptr) {
op_free(_op);
_op = op;
} else {
movies_cat.error()
<< "Failed to reopen Opus file to seek to beginning.\n";
return;
}
// Reset this field for good measure, just in case this changed.
_audio_channels = op_channel_count(_op, -1);
_last_seek = 0.0;
_samples_read = 0;
return;
}
}
if (error != 0) {
movies_cat.error()
<< "Seek failed (error " << error << "). Opus stream may not be seekable.\n";

View File

@ -45,7 +45,7 @@ public:
protected:
OggOpusFile *_op;
std::istream *_stream;
int _link;
public: