diff options
| -rw-r--r-- | src/plugins/Input/mad/decoder_mad.cpp | 28 | ||||
| -rw-r--r-- | src/plugins/Output/alsa/outputalsa.cpp | 5 | ||||
| -rw-r--r-- | src/qmmp/constants.h | 6 | ||||
| -rw-r--r-- | src/qmmp/decoder.cpp | 11 | ||||
| -rw-r--r-- | src/qmmp/output.cpp | 10 | ||||
| -rw-r--r-- | src/qmmp/output.h | 5 | ||||
| -rw-r--r-- | src/qmmp/recycler.cpp | 9 |
7 files changed, 48 insertions, 26 deletions
diff --git a/src/plugins/Input/mad/decoder_mad.cpp b/src/plugins/Input/mad/decoder_mad.cpp index 095d80371..578fc2ab0 100644 --- a/src/plugins/Input/mad/decoder_mad.cpp +++ b/src/plugins/Input/mad/decoder_mad.cpp @@ -18,7 +18,8 @@ #include <math.h> #include <stdio.h> -# define XING_MAGIC (('X' << 24) | ('i' << 16) | ('n' << 8) | 'g') +#define XING_MAGIC (('X' << 24) | ('i' << 16) | ('n' << 8) | 'g') +#define INPUT_BUFFER_SIZE (32*1024) DecoderMAD::DecoderMAD(QObject *parent, DecoderFactory *d, QIODevice *i, Output *o) @@ -95,7 +96,7 @@ bool DecoderMAD::initialize() } if (! input_buf) - input_buf = new char[globalBufferSize]; + input_buf = new char[INPUT_BUFFER_SIZE]; if (! output_buf) output_buf = new char[globalBufferSize]; @@ -247,7 +248,7 @@ bool DecoderMAD::findHeader() memmove (input_buf, stream.next_frame, remaining); } - input_bytes = input()->read(input_buf + remaining, globalBufferSize - remaining); + input_bytes = input()->read(input_buf + remaining, INPUT_BUFFER_SIZE - remaining); if (input_bytes <= 0) break; @@ -358,12 +359,11 @@ void DecoderMAD::stop() void DecoderMAD::flush(bool final) { ulong min = final ? 0 : bks; - - while ((! done && ! m_finish) && output_bytes > min && seekTime == -1.) + while (!done && (output_bytes > min) && seekTime == -1.) { output()->recycler()->mutex()->lock(); - while ((! done && ! m_finish) && output()->recycler()->full()) + while (!done && output()->recycler()->full()) { mutex()->unlock(); output()->recycler()->cond()->wait(output()->recycler()->mutex()); @@ -372,7 +372,7 @@ void DecoderMAD::flush(bool final) done = user_stop; } - if (user_stop || m_finish) + if (user_stop) { inited = FALSE; done = TRUE; @@ -395,7 +395,7 @@ void DecoderMAD::flush(bool final) void DecoderMAD::run() { - int skip_frames = 0; //skip first frame + int skip_frames = 0; mutex()->lock(); if (! inited) @@ -427,7 +427,6 @@ void DecoderMAD::run() eof = false; seekTime = -1; } - m_finish = eof; if (! eof) @@ -438,10 +437,10 @@ void DecoderMAD::run() memmove(input_buf, stream.next_frame, input_bytes); } - if (input_bytes < globalBufferSize) + if (stream.error == MAD_ERROR_BUFLEN) { int len = input()->read((char *) input_buf + input_bytes, - globalBufferSize - input_bytes); + INPUT_BUFFER_SIZE - input_bytes); if (len == 0) { @@ -482,6 +481,9 @@ void DecoderMAD::run() if (stream.error == MAD_ERROR_BUFLEN) break; + if (stream.error == MAD_ERROR_BUFLEN) + continue; + // error in decoding if (!MAD_RECOVERABLE(stream.error)) { @@ -513,7 +515,7 @@ void DecoderMAD::run() mutex()->lock(); - if (! user_stop && eof) + if (!user_stop && eof) { flush(TRUE); @@ -532,7 +534,7 @@ void DecoderMAD::run() } done = TRUE; - if (! user_stop) + if (!user_stop) m_finish = TRUE; } diff --git a/src/plugins/Output/alsa/outputalsa.cpp b/src/plugins/Output/alsa/outputalsa.cpp index 5e9c02938..6ed462e16 100644 --- a/src/plugins/Output/alsa/outputalsa.cpp +++ b/src/plugins/Output/alsa/outputalsa.cpp @@ -271,6 +271,7 @@ void OutputALSA::flush() { snd_pcm_uframes_t l = snd_pcm_bytes_to_frames(pcm_handle, m_prebuf_fill); long m; + l = snd_pcm_bytes_to_frames(pcm_handle, l); while (l > 0) { if ((m = alsa_write(m_prebuf, l)) >= 0) @@ -283,6 +284,9 @@ void OutputALSA::flush() else break; } + snd_pcm_nonblock(pcm_handle, 0); + snd_pcm_drain(pcm_handle); + snd_pcm_nonblock(pcm_handle, 1); } long OutputALSA::alsa_write(unsigned char *data, long size) @@ -340,6 +344,7 @@ long OutputALSA::alsa_write(unsigned char *data, long size) } return 0; } + qDebug ("OutputALSA: error: %s", snd_strerror(m)); return -1; } diff --git a/src/qmmp/constants.h b/src/qmmp/constants.h index fc31b4664..e9d346343 100644 --- a/src/qmmp/constants.h +++ b/src/qmmp/constants.h @@ -1,13 +1,7 @@ #ifndef CONSTANTS_H #define CONSTANTS_H -#ifndef LIB_DIR -#define LIB_DIR "/lib" -#endif - -const unsigned int historySize = 100; const unsigned int globalBlockSize = 2 * 1024; //2*1024 const unsigned int globalBufferSize = globalBlockSize * 128; -const unsigned int groupOpenTimeout = 750; #endif // CONSTANTS_H diff --git a/src/qmmp/decoder.cpp b/src/qmmp/decoder.cpp index 65a34abbf..344154164 100644 --- a/src/qmmp/decoder.cpp +++ b/src/qmmp/decoder.cpp @@ -183,7 +183,16 @@ qint64 Decoder::produceSound(char *data, qint64 size, quint32 brate, int chan) void Decoder::finish() { - //output()->wait(); + if (output()) + { + output()->mutex()->lock (); + output()->finish(); + output()->mutex()->unlock(); + /*output()->recycler()->mutex()->lock (); + output()->recycler()->cond()->wakeAll(); + output()->recycler()->mutex()->unlock(); + output()->wait();*/ + } emit playbackFinished(); } diff --git a/src/qmmp/output.cpp b/src/qmmp/output.cpp index bd8948b97..3ce48699b 100644 --- a/src/qmmp/output.cpp +++ b/src/qmmp/output.cpp @@ -29,6 +29,7 @@ Output::Output (QObject* parent) : QThread (parent), m_recycler (stackSize()) m_bytesPerMillisecond = 0; m_userStop = FALSE; m_pause = FALSE; + m_finish = FALSE; } void Output::configure(quint32 freq, int chan, int prec) @@ -51,6 +52,11 @@ void Output::stop() m_userStop = TRUE; } +void Output::finish() +{ + m_finish = TRUE; +} + qint64 Output::written() { return m_totalWritten; @@ -196,10 +202,10 @@ void Output::run() b = 0; mutex()->unlock(); } - mutex()->lock (); //write remaining data - flush(); + if(m_finish) + flush(); dispatch(Qmmp::Stopped); mutex()->unlock(); } diff --git a/src/qmmp/output.h b/src/qmmp/output.h index 6a81ece8f..ecbd5b740 100644 --- a/src/qmmp/output.h +++ b/src/qmmp/output.h @@ -68,6 +68,10 @@ public: */ void stop(); /*! + * Requests playback to finish. + */ + void finish(); + /*! * Returns the number of bytes that were written. */ qint64 written(); @@ -156,6 +160,7 @@ private: int m_channels, m_precision, m_kbps; qint64 m_bytesPerMillisecond; bool m_userStop, m_pause; + bool m_finish; qint64 m_totalWritten, m_currentMilliseconds; static void checkFactories(); diff --git a/src/qmmp/recycler.cpp b/src/qmmp/recycler.cpp index 15d2234a6..67d4e4f7e 100644 --- a/src/qmmp/recycler.cpp +++ b/src/qmmp/recycler.cpp @@ -13,9 +13,9 @@ Recycler::Recycler ( unsigned int sz ) : add_index ( 0 ), done_index ( 0 ), current_count ( 0 ) { buffer_count = ( sz / Buffer::size() ); - if ( buffer_count < 1 ) + if (buffer_count < 4) { - buffer_count = 1; + buffer_count = 4; } buffers = new Buffer*[buffer_count]; @@ -66,7 +66,7 @@ Buffer *Recycler::get(unsigned long size) { if (full()) return 0; - if(size > Buffer::size() + buffers[add_index]->exceeding) + if (size > Buffer::size() + buffers[add_index]->exceeding) { delete buffers[add_index]->data; buffers[add_index]->data = new unsigned char[size]; @@ -94,7 +94,8 @@ Buffer *Recycler::next() void Recycler::done() { done_index = ++done_index % buffer_count; - current_count--; + if (current_count) + current_count--; } |
