|
From: Lasse Kärkkäi. <tr...@us...> - 2009-07-27 04:28:44
|
Module: performous
Branch: master
Commit: b430fc092ba36020c07338320b0500d22e443e9e
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Jul 27 07:27:56 2009 +0300
Fix two memory leaks in our FFMPEG code.
---
game/ffmpeg.cc | 19 ++++++++++---------
game/ffmpeg.hh | 13 ++++++-------
2 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/game/ffmpeg.cc b/game/ffmpeg.cc
index a9a53b8..df6374e 100644
--- a/game/ffmpeg.cc
+++ b/game/ffmpeg.cc
@@ -154,7 +154,6 @@ void FFmpeg::operator()() {
errors = 0;
} catch (eof_error&) {
m_eof = true;
- audioQueue.push(new AudioFrame()); // EOF marker
videoQueue.push(new VideoFrame()); // EOF marker
boost::thread::sleep(now() + 0.1);
} catch (std::exception& e) {
@@ -164,8 +163,10 @@ void FFmpeg::operator()() {
}
m_running = false;
m_eof = true;
- audioQueue.push(new AudioFrame()); // EOF marker
videoQueue.push(new VideoFrame()); // EOF marker
+#ifdef USE_FFMPEG_CRASH_RECOVERY
+ ffmpeg_ptr.reset(); // Free the memory
+#endif
}
void FFmpeg::seek(double time, bool wait) {
@@ -249,9 +250,10 @@ void FFmpeg::decodeNextFrame() {
sws_scale(img_convert_ctx, videoFrame->data, videoFrame->linesize, 0, h, &data, &linesize);
}
if (packet.time() == packet.time()) m_position = packet.time();
+ // Construct a new video frame and push it to output queue
VideoFrame* tmp = new VideoFrame(m_position, w, h);
tmp->data.swap(buffer);
- videoQueue.push(tmp);
+ videoQueue.push(tmp); // Takes ownership and may block
}
}
} else if (decodeAudio && packet.stream_index==audioStream) {
@@ -272,13 +274,12 @@ void FFmpeg::decodeNextFrame() {
outsize /= sizeof(int16_t) * pAudioCodecCtx->channels;
std::vector<int16_t> resampled(AVCODEC_MAX_AUDIO_FRAME_SIZE);
int frames = audio_resample(pResampleCtx, &resampled[0], audioFrames, outsize);
- // Construct AudioFrame and add it to the queue
- AudioFrame* tmp = new AudioFrame();
- std::copy(resampled.begin(), resampled.begin() + frames * AUDIO_CHANNELS, std::back_inserter(tmp->data));
+ resampled.resize(frames * AUDIO_CHANNELS);
+ // Calculate new positions
if (packet.time() == packet.time()) m_position = packet.time();
- else m_position += double(tmp->data.size())/double(audioQueue.getSamplesPerSecond());
- tmp->timestamp = m_position;
- audioQueue.push(tmp);
+ else m_position += double(resampled.size())/double(audioQueue.getSamplesPerSecond());
+ // Push to output queue (may block)
+ audioQueue.push(resampled, m_position);
}
// Audio frames are always finished
frameFinished = 1;
diff --git a/game/ffmpeg.hh b/game/ffmpeg.hh
index 2056e99..e1f97dd 100644
--- a/game/ffmpeg.hh
+++ b/game/ffmpeg.hh
@@ -130,17 +130,16 @@ class AudioBuffer {
void setSamplesPerSecond(unsigned sps) { m_sps = sps; }
/// get samples per second
unsigned getSamplesPerSecond() { return m_sps; }
- void push(AudioFrame* f) {
- if (f->data.empty()) return;
+ void push(std::vector<int16_t> const& data, double timestamp) {
boost::mutex::scoped_lock l(m_mutex);
while (!condition()) m_cond.wait(l);
if (m_quit) return;
- if (m_pos == 0 && f->timestamp != 0.0) {
- //std::cerr << "Warning: The first audio frame begins at " << f->timestamp << " seconds instead of zero, compensating." << std::endl;
- m_pos = f->timestamp * m_sps;
+ if (m_pos == 0 && timestamp != 0.0) {
+ //std::cerr << "Warning: The first audio frame begins at " << timestamp << " seconds instead of zero, compensating." << std::endl;
+ m_pos = timestamp * m_sps;
}
- m_data.insert(m_data.end(), f->data.begin(), f->data.end());
- m_pos += f->data.size();
+ m_data.insert(m_data.end(), data.begin(), data.end());
+ m_pos += data.size();
}
bool operator()(da::pcm_data data, int64_t& pos) {
boost::mutex::scoped_lock l(m_mutex);
|