mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-18 20:53:50 -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();
|
cleanup();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (av_find_stream_info(_format_ctx)<0) {
|
if (av_find_stream_info(_format_ctx)<0) {
|
||||||
cleanup();
|
cleanup();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the audio stream
|
// Find the audio stream
|
||||||
for(int i=0; i<_format_ctx->nb_streams; i++) {
|
for(int i=0; i<_format_ctx->nb_streams; i++) {
|
||||||
if(_format_ctx->streams[i]->codec->codec_type==CODEC_TYPE_AUDIO) {
|
if(_format_ctx->streams[i]->codec->codec_type==CODEC_TYPE_AUDIO) {
|
||||||
@ -60,12 +60,12 @@ FfmpegAudioCursor(FfmpegAudio *src) :
|
|||||||
_audio_channels = _audio_ctx->channels;
|
_audio_channels = _audio_ctx->channels;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_audio_ctx == 0) {
|
if (_audio_ctx == 0) {
|
||||||
cleanup();
|
cleanup();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AVCodec *pAudioCodec=avcodec_find_decoder(_audio_ctx->codec_id);
|
AVCodec *pAudioCodec=avcodec_find_decoder(_audio_ctx->codec_id);
|
||||||
if(pAudioCodec == 0) {
|
if(pAudioCodec == 0) {
|
||||||
cleanup();
|
cleanup();
|
||||||
@ -88,14 +88,14 @@ FfmpegAudioCursor(FfmpegAudio *src) :
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memset(_packet, 0, sizeof(AVPacket));
|
memset(_packet, 0, sizeof(AVPacket));
|
||||||
|
|
||||||
// Align the buffer to a 16-byte boundary
|
// Align the buffer to a 16-byte boundary
|
||||||
// The ffmpeg codec likes this, because it uses SSE/SSE2.
|
// The ffmpeg codec likes this, because it uses SSE/SSE2.
|
||||||
_buffer = _buffer_alloc;
|
_buffer = _buffer_alloc;
|
||||||
while (((size_t)_buffer) & 15) {
|
while (((size_t)_buffer) & 15) {
|
||||||
_buffer += 1;
|
_buffer += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fetch_packet();
|
fetch_packet();
|
||||||
_initial_dts = _packet->dts;
|
_initial_dts = _packet->dts;
|
||||||
_last_seek = 0;
|
_last_seek = 0;
|
||||||
@ -148,7 +148,7 @@ cleanup() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: FfmpegAudioCursor::fetch_packet
|
// Function: FfmpegAudioCursor::fetch_packet
|
||||||
// Access: Protected
|
// 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.
|
// packet buffer. Also sets packet_size and packet_data.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void FfmpegAudioCursor::
|
void FfmpegAudioCursor::
|
||||||
@ -179,6 +179,8 @@ fetch_packet() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void FfmpegAudioCursor::
|
void FfmpegAudioCursor::
|
||||||
reload_buffer() {
|
reload_buffer() {
|
||||||
|
|
||||||
|
|
||||||
while (_buffer_head == _buffer_tail) {
|
while (_buffer_head == _buffer_tail) {
|
||||||
// If we're out of packets, generate silence.
|
// If we're out of packets, generate silence.
|
||||||
if (_packet->data == 0) {
|
if (_packet->data == 0) {
|
||||||
@ -188,9 +190,10 @@ reload_buffer() {
|
|||||||
return;
|
return;
|
||||||
} else if (_packet_size > 0) {
|
} else if (_packet_size > 0) {
|
||||||
int bufsize = _buffer_size * 2;
|
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);
|
_packet_data, _packet_size);
|
||||||
if (len < 0) {
|
movies_debug("avcodec_decode_audio returned " << len);
|
||||||
|
if (len <= 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
_packet_data += len;
|
_packet_data += len;
|
||||||
@ -210,7 +213,7 @@ reload_buffer() {
|
|||||||
// Function: FfmpegAudioCursor::seek
|
// Function: FfmpegAudioCursor::seek
|
||||||
// Access: Protected
|
// Access: Protected
|
||||||
// Description: Seeks to a target location. Afterward, the
|
// 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.
|
// equal to the specified time.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void FfmpegAudioCursor::
|
void FfmpegAudioCursor::
|
||||||
@ -252,15 +255,25 @@ seek(double t) {
|
|||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
// Description: Read audio samples from the stream. N is the
|
// Description: Read audio samples from the stream. N is the
|
||||||
// number of samples you wish to read. Your buffer
|
// number of samples you wish to read. Your buffer
|
||||||
// must be equal in size to N * channels.
|
// must be equal in size to N * channels.
|
||||||
// Multiple-channel audio will be interleaved.
|
// Multiple-channel audio will be interleaved.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void FfmpegAudioCursor::
|
void FfmpegAudioCursor::
|
||||||
read_samples(int n, PN_int16 *data) {
|
read_samples(int n, PN_int16 *data) {
|
||||||
|
|
||||||
|
//movies_debug("here!!! FfmpegAudioCursor n="<<n);
|
||||||
|
|
||||||
int desired = n * _audio_channels;
|
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) {
|
if (_buffer_head == _buffer_tail) {
|
||||||
reload_buffer();
|
reload_buffer();
|
||||||
|
give_up_after --;
|
||||||
|
movies_debug("reload_buffer will give up in "<<give_up_after);
|
||||||
}
|
}
|
||||||
int available = _buffer_tail - _buffer_head;
|
int available = _buffer_tail - _buffer_head;
|
||||||
int ncopy = (desired > available) ? available : desired;
|
int ncopy = (desired > available) ? available : desired;
|
||||||
@ -272,6 +285,7 @@ read_samples(int n, PN_int16 *data) {
|
|||||||
desired -= ncopy;
|
desired -= ncopy;
|
||||||
_buffer_head += ncopy;
|
_buffer_head += ncopy;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
_samples_read += n;
|
_samples_read += n;
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,19 @@
|
|||||||
#include "typedWritableReferenceCount.h"
|
#include "typedWritableReferenceCount.h"
|
||||||
class MovieAudioCursor;
|
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
|
// Class : MovieAudio
|
||||||
// Description : A MovieAudio is actually any source that provides
|
// Description : A MovieAudio is actually any source that provides
|
||||||
|
Loading…
x
Reference in New Issue
Block a user