diff --git a/panda/src/movies/vorbisAudioCursor.cxx b/panda/src/movies/vorbisAudioCursor.cxx index b6a8d2d6a6..2f206cbc39 100644 --- a/panda/src/movies/vorbisAudioCursor.cxx +++ b/panda/src/movies/vorbisAudioCursor.cxx @@ -33,6 +33,7 @@ VorbisAudioCursor(VorbisAudio *src, istream *stream) : _bitstream(0) { nassertv(stream != NULL); + nassertv(stream->good()); // Set up the callbacks to read via the VFS. ov_callbacks callbacks; @@ -52,7 +53,10 @@ VorbisAudioCursor(VorbisAudio *src, istream *stream) : return; } - _length = ov_time_total(&_ov, -1); + double time_total = ov_time_total(&_ov, -1); + if (time_total != OV_EINVAL) { + _length = time_total; + } vorbis_info *vi = ov_info(&_ov, -1); _audio_channels = vi->channels; @@ -175,6 +179,12 @@ cb_read_func(void *ptr, size_t size, size_t nmemb, void *datasource) { nassertr(stream != NULL, -1); stream->read((char *)ptr, size * nmemb); + + if (stream->eof()) { + // Gracefully handle EOF. + stream->clear(); + } + return stream->gcount(); } @@ -213,6 +223,26 @@ cb_seek_func(void *datasource, ogg_int64_t offset, int whence) { } if (stream->fail()) { + // This is a fatal error and usually leads to + // a libvorbis crash. + movies_cat.error() + << "Failure to seek to byte " << offset; + + switch (whence) { + case SEEK_CUR: + movies_cat.error(false) + << " from current location!\n"; + break; + + case SEEK_END: + movies_cat.error(false) + << " from end of file!\n"; + break; + + default: + movies_cat.error(false) << "!\n"; + } + return -1; }