mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-18 12:43:44 -04:00
i was working on openAL and found one bug which would cause infinite
loop when if avcodec_decode_audio (ffmpeg function) returned 0 in the loop its in and when fixed in the loop above it. see post http://panda3d.org/phpbb2/viewtopic.php?p=30331#30331 most changes are to ffmpegAudioCursor.cxx and movieAudio.h It basically changes to proper error handling with 0 as DONE - if (len < 0) { + if (len <= 0) { and create a give up counter + // give up after 100 tries to fetch data + int give_up_after = 100; + + while (desired && give_up_after > 0) { + give_up_after --; and some helpful debug messages for the next poor coder to step into this code.
This commit is contained in:
parent
889ccb9860
commit
83803724e6
@ -44,12 +44,12 @@ FfmpegAudioCursor(FfmpegAudio *src) :
|
||||
cleanup();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (av_find_stream_info(_format_ctx)<0) {
|
||||
cleanup();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Find the audio stream
|
||||
for(int i=0; i<_format_ctx->nb_streams; i++) {
|
||||
if(_format_ctx->streams[i]->codec->codec_type==CODEC_TYPE_AUDIO) {
|
||||
@ -60,12 +60,12 @@ FfmpegAudioCursor(FfmpegAudio *src) :
|
||||
_audio_channels = _audio_ctx->channels;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (_audio_ctx == 0) {
|
||||
cleanup();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
AVCodec *pAudioCodec=avcodec_find_decoder(_audio_ctx->codec_id);
|
||||
if(pAudioCodec == 0) {
|
||||
cleanup();
|
||||
@ -88,14 +88,14 @@ FfmpegAudioCursor(FfmpegAudio *src) :
|
||||
return;
|
||||
}
|
||||
memset(_packet, 0, sizeof(AVPacket));
|
||||
|
||||
|
||||
// Align the buffer to a 16-byte boundary
|
||||
// The ffmpeg codec likes this, because it uses SSE/SSE2.
|
||||
_buffer = _buffer_alloc;
|
||||
while (((size_t)_buffer) & 15) {
|
||||
_buffer += 1;
|
||||
}
|
||||
|
||||
|
||||
fetch_packet();
|
||||
_initial_dts = _packet->dts;
|
||||
_last_seek = 0;
|
||||
@ -148,7 +148,7 @@ cleanup() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FfmpegAudioCursor::fetch_packet
|
||||
// Access: Protected
|
||||
// Description: Fetches an audio packet and stores it in the
|
||||
// Description: Fetches an audio packet and stores it in the
|
||||
// packet buffer. Also sets packet_size and packet_data.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void FfmpegAudioCursor::
|
||||
@ -179,6 +179,8 @@ fetch_packet() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void FfmpegAudioCursor::
|
||||
reload_buffer() {
|
||||
|
||||
|
||||
while (_buffer_head == _buffer_tail) {
|
||||
// If we're out of packets, generate silence.
|
||||
if (_packet->data == 0) {
|
||||
@ -188,9 +190,10 @@ reload_buffer() {
|
||||
return;
|
||||
} else if (_packet_size > 0) {
|
||||
int bufsize = _buffer_size * 2;
|
||||
int len = avcodec_decode_audio(_audio_ctx, _buffer, &bufsize,
|
||||
int len = avcodec_decode_audio(_audio_ctx, _buffer, &bufsize,
|
||||
_packet_data, _packet_size);
|
||||
if (len < 0) {
|
||||
movies_debug("avcodec_decode_audio returned " << len);
|
||||
if (len <= 0) {
|
||||
break;
|
||||
}
|
||||
_packet_data += len;
|
||||
@ -210,7 +213,7 @@ reload_buffer() {
|
||||
// Function: FfmpegAudioCursor::seek
|
||||
// Access: Protected
|
||||
// Description: Seeks to a target location. Afterward, the
|
||||
// packet_time is guaranteed to be less than or
|
||||
// packet_time is guaranteed to be less than or
|
||||
// equal to the specified time.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void FfmpegAudioCursor::
|
||||
@ -252,15 +255,25 @@ seek(double t) {
|
||||
// Access: Public, Virtual
|
||||
// Description: Read audio samples from the stream. N is the
|
||||
// number of samples you wish to read. Your buffer
|
||||
// must be equal in size to N * channels.
|
||||
// Multiple-channel audio will be interleaved.
|
||||
// must be equal in size to N * channels.
|
||||
// Multiple-channel audio will be interleaved.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void FfmpegAudioCursor::
|
||||
read_samples(int n, PN_int16 *data) {
|
||||
|
||||
//movies_debug("here!!! FfmpegAudioCursor n="<<n);
|
||||
|
||||
int desired = n * _audio_channels;
|
||||
while (desired) {
|
||||
|
||||
// give up after 100 tries to fetch data
|
||||
int give_up_after = 100;
|
||||
|
||||
while (desired && give_up_after > 0) {
|
||||
|
||||
if (_buffer_head == _buffer_tail) {
|
||||
reload_buffer();
|
||||
give_up_after --;
|
||||
movies_debug("reload_buffer will give up in "<<give_up_after);
|
||||
}
|
||||
int available = _buffer_tail - _buffer_head;
|
||||
int ncopy = (desired > available) ? available : desired;
|
||||
@ -272,6 +285,7 @@ read_samples(int n, PN_int16 *data) {
|
||||
desired -= ncopy;
|
||||
_buffer_head += ncopy;
|
||||
}
|
||||
|
||||
}
|
||||
_samples_read += n;
|
||||
}
|
||||
|
@ -21,6 +21,19 @@
|
||||
#include "typedWritableReferenceCount.h"
|
||||
class MovieAudioCursor;
|
||||
|
||||
|
||||
#ifdef NOTIFY_DEBUG //[
|
||||
// Non-release build:
|
||||
#define movies_debug(msg) \
|
||||
if (movies_cat.is_debug()) { \
|
||||
movies_cat->debug() << msg << endl; \
|
||||
} else {}
|
||||
#else //][
|
||||
// Release build:
|
||||
#define movies_debug(msg) ((void)0);
|
||||
#endif //]
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : MovieAudio
|
||||
// Description : A MovieAudio is actually any source that provides
|
||||
|
Loading…
x
Reference in New Issue
Block a user