diff options
Diffstat (limited to 'src/plugins/Input')
| -rw-r--r-- | src/plugins/Input/CMakeLists.txt | 20 | ||||
| -rw-r--r-- | src/plugins/Input/Input.pro | 18 | ||||
| -rw-r--r-- | src/plugins/Input/mad/decoder_mad.cpp | 432 | ||||
| -rw-r--r-- | src/plugins/Input/mad/decoder_mad.h | 34 | ||||
| -rw-r--r-- | src/plugins/Input/vorbis/decoder_vorbis.cpp | 207 | ||||
| -rw-r--r-- | src/plugins/Input/vorbis/decoder_vorbis.h | 35 |
6 files changed, 201 insertions, 545 deletions
diff --git a/src/plugins/Input/CMakeLists.txt b/src/plugins/Input/CMakeLists.txt index a62066aea..98c733694 100644 --- a/src/plugins/Input/CMakeLists.txt +++ b/src/plugins/Input/CMakeLists.txt @@ -21,7 +21,7 @@ add_subdirectory(mad) ENDIF(USE_MAD AND TAGLIB_FOUND) IF(USE_FLAC AND TAGLIB_FOUND) -add_subdirectory(flac) +#add_subdirectory(flac) ENDIF(USE_FLAC AND TAGLIB_FOUND) IF(USE_VORBIS AND TAGLIB_FOUND) @@ -29,37 +29,37 @@ add_subdirectory(vorbis) ENDIF(USE_VORBIS AND TAGLIB_FOUND) IF(USE_FFMPEG) -add_subdirectory(ffmpeg) +#add_subdirectory(ffmpeg) ENDIF(USE_FFMPEG) IF(USE_MPC AND TAGLIB_FOUND) -add_subdirectory(mpc) +#add_subdirectory(mpc) ENDIF(USE_MPC AND TAGLIB_FOUND) IF(USE_SNDFILE) -add_subdirectory(sndfile) +#add_subdirectory(sndfile) ENDIF(USE_SNDFILE) IF(USE_WAVPACK) -add_subdirectory(wavpack) +#add_subdirectory(wavpack) ENDIF(USE_WAVPACK) IF(USE_MODPLUG) -add_subdirectory(modplug) +#add_subdirectory(modplug) ENDIF(USE_MODPLUG) IF(USE_AAC) -add_subdirectory(aac) +#add_subdirectory(aac) ENDIF(USE_AAC) IF(USE_CUE) -add_subdirectory(cue) +#add_subdirectory(cue) ENDIF(USE_CUE) IF(USE_MPLAYER) -add_subdirectory(mplayer) +#add_subdirectory(mplayer) ENDIF(USE_MPLAYER) IF(USE_CDA) -add_subdirectory(cdaudio) +#add_subdirectory(cdaudio) ENDIF(USE_CDA) diff --git a/src/plugins/Input/Input.pro b/src/plugins/Input/Input.pro index 520d9060b..7b07b7571 100644 --- a/src/plugins/Input/Input.pro +++ b/src/plugins/Input/Input.pro @@ -1,54 +1,54 @@ include(../../../qmmp.pri) -SUBDIRS += mad cue +SUBDIRS += mad #cue TEMPLATE = subdirs unix{ -SUBDIRS += vorbis sndfile wavpack +SUBDIRS += vorbis #sndfile wavpack contains(CONFIG, MODPLUG_PLUGIN){ - SUBDIRS += modplug + #SUBDIRS += modplug message(***************************) message(* Modplug plugin enabled *) message(***************************) } contains(CONFIG, MUSEPACK_PLUGIN){ - SUBDIRS += mpc + #SUBDIRS += mpc message(***************************) message(* Musepack plugin enabled *) message(***************************) } contains(CONFIG, FLAC_PLUGIN){ - SUBDIRS += flac + #SUBDIRS += flac message(***********************) message(* FLAC plugin enabled *) message(***********************) } contains(CONFIG, FFMPEG_PLUGIN){ - SUBDIRS += ffmpeg + #SUBDIRS += ffmpeg message(*************************) message(* FFMPEG plugin enabled *) message(*************************) } contains(CONFIG, AAC_PLUGIN){ - SUBDIRS += aac + #SUBDIRS += aac message(**********************) message(* AAC plugin enabled *) message(**********************) } contains(CONFIG, MPLAYER_PLUGIN){ - SUBDIRS += mplayer + #SUBDIRS += mplayer message(**************************) message(* Mplayer plugin enabled *) message(**************************) } contains(CONFIG, CDAUDIO_PLUGIN){ - SUBDIRS += cdaudio + #SUBDIRS += cdaudio message(***************************) message(* CD Audio plugin enabled *) message(***************************) diff --git a/src/plugins/Input/mad/decoder_mad.cpp b/src/plugins/Input/mad/decoder_mad.cpp index 645c2369d..d2a5f7d3c 100644 --- a/src/plugins/Input/mad/decoder_mad.cpp +++ b/src/plugins/Input/mad/decoder_mad.cpp @@ -11,7 +11,6 @@ #include "decoder_mad.h" #include "tagextractor.h" -#include <qmmp/constants.h> #include <qmmp/buffer.h> #include <qmmp/output.h> @@ -25,85 +24,55 @@ DecoderMAD::DecoderMAD(QObject *parent, DecoderFactory *d, QIODevice *i, Output *o) : Decoder(parent, d, i, o) { - inited = false; - user_stop = false; - done = false; - m_finish = false; - derror = false; - eof = false; - useeq = false; + m_inited = false; m_totalTime = 0.; - seekTime = -1.; - channels = 0; - bks = 0; - bitrate = 0; - freq = 0; - len = 0; - input_buf = 0; - input_bytes = 0; - output_buf = 0; - output_bytes = 0; - output_at = 0; - output_size = 0; + m_channels = 0; + m_bitrate = 0; + m_freq = 0; + m_len = 0; + m_input_buf = 0; + m_input_bytes = 0; + m_output_bytes = 0; + m_output_at = 0; + m_skip_frames = 0; } DecoderMAD::~DecoderMAD() { wait(); deinit(); - mutex()->lock(); - if (input_buf) + if (m_input_buf) { qDebug("DecoderMAD: deleting input_buf"); - delete [] input_buf; - } - input_buf = 0; - - if (output_buf) - { - qDebug("DecoderMAD: deleting output_buf"); - delete [] output_buf; - } - output_buf = 0; - mutex()->unlock(); + delete [] m_input_buf; + m_input_buf = 0; + } } bool DecoderMAD::initialize() { - bks = Buffer::size(); - - inited = false; - user_stop = false; - done = false; - m_finish = false; - derror = false; - eof = false; + m_inited = false; m_totalTime = 0.; - seekTime = -1.; - channels = 0; - bitrate = 0; - freq = 0; - len = 0; - input_bytes = 0; - output_bytes = 0; - output_at = 0; - output_size = 0; - - if (! input()) + m_channels = 0; + m_bitrate = 0; + m_freq = 0; + m_len = 0; + m_input_bytes = 0; + m_output_bytes = 0; + m_output_at = 0; + + if (!input()) { qWarning("DecoderMAD: cannot initialize. No input."); return FALSE; } - if (! input_buf) - input_buf = new char[INPUT_BUFFER_SIZE]; + if (!m_input_buf) + m_input_buf = new char[INPUT_BUFFER_SIZE]; - if (! output_buf) - output_buf = new char[globalBufferSize]; - - if (! input()->isOpen()) + if (!input()->isOpen()) { - if (! input()->open(QIODevice::ReadOnly)) + if (!input()->open(QIODevice::ReadOnly)) { qWarning("DecoderMAD: %s", qPrintable(input()->errorString ())); return FALSE; @@ -121,51 +90,43 @@ bool DecoderMAD::initialize() mad_frame_init(&frame); mad_synth_init(&synth); - if (! findHeader()) + if (!findHeader()) { qDebug("DecoderMAD: Can't find a valid MPEG header."); return FALSE; } - mad_stream_buffer(&stream, (unsigned char *) input_buf, input_bytes); + mad_stream_buffer(&stream, (unsigned char *) m_input_buf, m_input_bytes); stream.error = MAD_ERROR_NONE; stream.error = MAD_ERROR_BUFLEN; mad_frame_mute (&frame); stream.next_frame = NULL; stream.sync = 0; - configure(freq, channels, 16); + configure(m_freq, m_channels, 16); - inited = TRUE; + m_inited = TRUE; return TRUE; } void DecoderMAD::deinit() { - if (!inited) + if (!m_inited) return; mad_synth_finish(&synth); mad_frame_finish(&frame); mad_stream_finish(&stream); - inited = false; - user_stop = false; - done = false; - m_finish = false; - derror = false; - eof = false; - useeq = false; + m_inited = FALSE; m_totalTime = 0.; - seekTime = -1.; - channels = 0; - bks = 0; - bitrate = 0; - freq = 0; - len = 0; - input_bytes = 0; - output_bytes = 0; - output_at = 0; - output_size = 0; + m_channels = 0; + m_bitrate = 0; + m_freq = 0; + m_len = 0; + m_input_bytes = 0; + m_output_bytes = 0; + m_output_at = 0; + m_skip_frames = 0; } bool DecoderMAD::findXingHeader(struct mad_bitptr ptr, unsigned int bitlen) @@ -236,9 +197,9 @@ bool DecoderMAD::findHeader() struct mad_header header; mad_header_init (&header); - while (TRUE) + forever { - input_bytes = 0; + m_input_bytes = 0; if (stream.error == MAD_ERROR_BUFLEN || !stream.buffer) { size_t remaining = 0; @@ -246,15 +207,15 @@ bool DecoderMAD::findHeader() if (!stream.next_frame) { remaining = stream.bufend - stream.next_frame; - memmove (input_buf, stream.next_frame, remaining); + memmove (m_input_buf, stream.next_frame, remaining); } - input_bytes = input()->read(input_buf + remaining, INPUT_BUFFER_SIZE - remaining); + m_input_bytes = input()->read(m_input_buf + remaining, INPUT_BUFFER_SIZE - remaining); - if (input_bytes <= 0) + if (m_input_bytes <= 0) break; - mad_stream_buffer(&stream, (unsigned char *) input_buf + remaining, input_bytes); + mad_stream_buffer(&stream, (unsigned char *) m_input_buf + remaining, m_input_bytes); stream.error = MAD_ERROR_NONE; } @@ -298,13 +259,13 @@ bool DecoderMAD::findHeader() //try to detect VBR if (!is_vbr && !(count > 15)) { - if (bitrate && header.bitrate != bitrate) + if (m_bitrate && header.bitrate != m_bitrate) { qDebug ("DecoderMAD: VBR detected"); is_vbr = TRUE; } else - bitrate = header.bitrate; + m_bitrate = header.bitrate; } else if (!is_vbr) { @@ -331,144 +292,41 @@ bool DecoderMAD::findHeader() m_totalTime = mad_timer_count(duration, MAD_UNITS_MILLISECONDS); qDebug ("DecoderMAD: Total time: %ld", long(m_totalTime)); - freq = header.samplerate; - channels = MAD_NCHANNELS(&header); - bitrate = header.bitrate / 1000; + m_freq = header.samplerate; + m_channels = MAD_NCHANNELS(&header); + m_bitrate = header.bitrate / 1000; mad_header_finish(&header); input()->seek(0); - input_bytes = 0; + m_input_bytes = 0; return TRUE; } qint64 DecoderMAD::totalTime() { - if (! inited) - return 0.; + if (!m_inited) + return 0; return m_totalTime; } -void DecoderMAD::seek(qint64 pos) -{ - seekTime = pos; -} - -void DecoderMAD::stop() +int DecoderMAD::bitrate() { - user_stop = TRUE; -} - -void DecoderMAD::flush(bool final) -{ - ulong min = final ? 0 : bks; - while (!done && (output_bytes > min) && seekTime == -1.) - { - output()->recycler()->mutex()->lock(); - - while (!done && output()->recycler()->full()) - { - mutex()->unlock(); - output()->recycler()->cond()->wait(output()->recycler()->mutex()); - - mutex()->lock(); - done = user_stop; - } - - if (user_stop) - { - inited = FALSE; - done = TRUE; - } - else - { - output_bytes -= produceSound(output_buf, output_bytes, bitrate, channels); - output_size += bks; - output_at = output_bytes; - } - - if (output()->recycler()->full()) - { - output()->recycler()->cond()->wakeOne(); - } - - output()->recycler()->mutex()->unlock(); - } + return int(m_bitrate); } -void DecoderMAD::run() +qint64 DecoderMAD::readAudio(char *data, qint64 size) { - int skip_frames = 0; - mutex()->lock(); - - if (! inited) + forever { - mutex()->unlock(); - return; - } - - mutex()->unlock(); - - while (! done && ! m_finish && ! derror) - { - mutex()->lock(); - - if (seekTime >= 0.0 && m_totalTime > 0) + if(stream.error == MAD_ERROR_BUFLEN || !stream.buffer) { - long seek_pos = long(seekTime * input()->size() / m_totalTime); - input()->seek(seek_pos); - output_size = long(seekTime) * long(freq * channels * 16 / 2); - mad_frame_mute(&frame); - mad_synth_mute(&synth); - stream.error = MAD_ERROR_BUFLEN; - stream.sync = 0; - input_bytes = 0; - output_at = 0; - output_bytes = 0; - stream.next_frame = 0; - skip_frames = 2; - eof = false; - seekTime = -1; + if(!fillBuffer()) + return 0; } - m_finish = eof; - - if (! eof) + if(mad_frame_decode(&frame, &stream) < 0) { - if (stream.next_frame) + switch((int) stream.error) { - input_bytes = &input_buf[input_bytes] - (char *) stream.next_frame; - memmove(input_buf, stream.next_frame, input_bytes); - } - - if (stream.error == MAD_ERROR_BUFLEN) - { - int len = input()->read((char *) input_buf + input_bytes, - INPUT_BUFFER_SIZE - input_bytes); - - if (len == 0) - { - qDebug("DecoderMAD: end of file"); - eof = true; - } - else if (len < 0) - { - qWarning("DecoderMAD: %s", qPrintable(input()->errorString ())); - derror = true; - break; - } - - input_bytes += len; - } - - mad_stream_buffer(&stream, (unsigned char *) input_buf, input_bytes); - } - - mutex()->unlock(); - - // decode - while (!done && !m_finish && !derror && seekTime == -1.) - { - if (mad_frame_decode(&frame, &stream) == -1) - { - if (stream.error == MAD_ERROR_LOSTSYNC) + case MAD_ERROR_LOSTSYNC: { //skip ID3v2 tag uint tagSize = findID3v2((uchar *)stream.this_frame, @@ -480,76 +338,61 @@ void DecoderMAD::run() } continue; } - - if (stream.error == MAD_ERROR_BUFLEN) - break; - - if (stream.error == MAD_ERROR_BUFLEN) + case MAD_ERROR_BUFLEN: continue; - - // error in decoding - if (!MAD_RECOVERABLE(stream.error)) - { - derror = true; - break; - } - continue; + default: + if (!MAD_RECOVERABLE(stream.error)) + return 0; + else + continue; } - - mutex()->lock(); - - if (seekTime >= 0.) - { - mutex()->unlock(); - break; - } - - if (skip_frames) - { - skip_frames-- ; - mutex()->unlock(); - continue; - } - mad_synth_frame(&synth, &frame); - madOutput(); - mutex()->unlock(); } - } - - mutex()->lock(); - - if (!user_stop && eof) - { - flush(TRUE); - - if (output()) + if(m_skip_frames) { - output()->recycler()->mutex()->lock(); - // end of stream - while (! output()->recycler()->empty() && ! user_stop) - { - output()->recycler()->cond()->wakeOne(); - mutex()->unlock(); - output()->recycler()->cond()->wait(output()->recycler()->mutex()); - mutex()->lock(); - } - output()->recycler()->mutex()->unlock(); + m_skip_frames--; + continue; } - - done = TRUE; - if (!user_stop) - m_finish = TRUE; + mad_synth_frame(&synth, &frame); + return madOutput(data, size); } +} +void DecoderMAD::seekAudio(qint64 pos) +{ + if(m_totalTime > 0) + { + qint64 seek_pos = qint64(pos * input()->size() / m_totalTime); + input()->seek(seek_pos); + mad_frame_mute(&frame); + mad_synth_mute(&synth); + stream.error = MAD_ERROR_BUFLEN; + stream.sync = 0; + m_input_bytes = 0; + stream.next_frame = 0; + m_skip_frames = 2; + } +} - if (m_finish) - finish(); - - mutex()->unlock(); - - if (input()) - input()->close(); - deinit(); - +bool DecoderMAD::fillBuffer() +{ + if (stream.next_frame) + { + m_input_bytes = &m_input_buf[m_input_bytes] - (char *) stream.next_frame; + memmove(m_input_buf, stream.next_frame, m_input_bytes); + } + int len = input()->read((char *) m_input_buf + m_input_bytes, INPUT_BUFFER_SIZE - m_input_bytes); + if (!len) + { + qDebug("DecoderMAD: end of file"); + return FALSE; + } + else if(len < 0) + { + qWarning("error"); + return FALSE; + } + m_input_bytes += len; + mad_stream_buffer(&stream, (unsigned char *) m_input_buf, m_input_bytes); + return TRUE; } uint DecoderMAD::findID3v2(uchar *data, ulong size) //retuns ID3v2 tag size @@ -603,7 +446,7 @@ static inline signed long fix_sample(unsigned int bits, mad_fixed_t sample) return quantized >> (MAD_F_FRACBITS + 1 - bits); } -enum mad_flow DecoderMAD::madOutput() +qint64 DecoderMAD::madOutput(char *data, qint64 size) { unsigned int samples, channels; mad_fixed_t const *left, *right; @@ -612,45 +455,32 @@ enum mad_flow DecoderMAD::madOutput() channels = synth.pcm.channels; left = synth.pcm.samples[0]; right = synth.pcm.samples[1]; + m_bitrate = frame.header.bitrate / 1000; + m_output_at = 0; + m_output_bytes = 0; + if(samples * channels * 2 > size) + { + qWarning("DecoderMad: input buffer is too small"); + samples = size / channels / 2; + } - bitrate = frame.header.bitrate / 1000; - done = user_stop; - - while (samples-- && !user_stop) + while (samples--) { signed int sample; - if (output_bytes + 4096 > globalBufferSize) - flush(); - sample = fix_sample(16, *left++); - *(output_buf + output_at++) = ((sample >> 0) & 0xff); - *(output_buf + output_at++) = ((sample >> 8) & 0xff); - output_bytes += 2; + *(data + m_output_at++) = ((sample >> 0) & 0xff); + *(data + m_output_at++) = ((sample >> 8) & 0xff); + m_output_bytes += 2; if (channels == 2) { sample = fix_sample(16, *right++); - *(output_buf + output_at++) = ((sample >> 0) & 0xff); - *(output_buf + output_at++) = ((sample >> 8) & 0xff); - output_bytes += 2; + *(data + m_output_at++) = ((sample >> 0) & 0xff); + *(data + m_output_at++) = ((sample >> 8) & 0xff); + m_output_bytes += 2; } } - - if (done || m_finish) - { - return MAD_FLOW_STOP; - } - - return MAD_FLOW_CONTINUE; -} - -enum mad_flow DecoderMAD::madError(struct mad_stream *stream, - struct mad_frame *) -{ - if (MAD_RECOVERABLE(stream->error)) - return MAD_FLOW_CONTINUE; - qFatal("MADERROR!\n"); - return MAD_FLOW_STOP; + return m_output_bytes; } diff --git a/src/plugins/Input/mad/decoder_mad.h b/src/plugins/Input/mad/decoder_mad.h index 6fb6f2a40..f25ad2b80 100644 --- a/src/plugins/Input/mad/decoder_mad.h +++ b/src/plugins/Input/mad/decoder_mad.h @@ -28,37 +28,29 @@ public: // standard decoder API bool initialize(); qint64 totalTime(); - void seek(qint64); - void stop(); + int bitrate(); private: - // thread run function - void run(); - - enum mad_flow madOutput(); - enum mad_flow madError(struct mad_stream *, struct mad_frame *); + qint64 readAudio(char *data, qint64 size); + void seekAudio(qint64); // helper functions - void flush(bool = FALSE); + qint64 madOutput(char *data, qint64 size); + bool fillBuffer(); void deinit(); bool findHeader(); bool findXingHeader(struct mad_bitptr, unsigned int); uint findID3v2(uchar *data, ulong size); - bool inited, user_stop, done, m_finish, derror, eof, useeq; - qint64 m_totalTime, seekTime; - int channels; - unsigned long bitrate; - long freq, len; - unsigned int bks; - mad_fixed_t eqbands[32]; + bool m_inited; + qint64 m_totalTime; + int m_channels, m_skip_frames; + uint m_bitrate; + long m_freq, m_len; + qint64 m_output_bytes, m_output_at; // file input buffer - char *input_buf; - unsigned long input_bytes; - - // output buffer - char *output_buf; - unsigned long output_bytes, output_at, output_size; + char *m_input_buf; + qint64 m_input_bytes; // MAD decoder struct diff --git a/src/plugins/Input/vorbis/decoder_vorbis.cpp b/src/plugins/Input/vorbis/decoder_vorbis.cpp index 492d256df..fdbfd1432 100644 --- a/src/plugins/Input/vorbis/decoder_vorbis.cpp +++ b/src/plugins/Input/vorbis/decoder_vorbis.cpp @@ -5,7 +5,6 @@ // -#include <qmmp/constants.h> #include <qmmp/buffer.h> #include <qmmp/output.h> #include <qmmp/recycler.h> @@ -78,103 +77,32 @@ DecoderVorbis::DecoderVorbis(QObject *parent, DecoderFactory *d, QIODevice *i, O : Decoder(parent, d, i, o) { inited = FALSE; - user_stop = FALSE; - stat = 0; - output_buf = 0; - output_bytes = 0; - output_at = 0; - bks = 0; - done = FALSE; - m_finish = FALSE; - len = 0; - freq = 0; - bitrate = 0; - seekTime = -1.0; - m_totalTime = 0.0; - chan = 0; - output_size = 0; + m_totalTime = 0; + m_section = 0; + m_last_section = -1; + m_bitrate = 0; } DecoderVorbis::~DecoderVorbis() { deinit(); - - if (output_buf) - delete [] output_buf; - output_buf = 0; -} - - -void DecoderVorbis::stop() -{ - user_stop = TRUE; -} - - -void DecoderVorbis::flush(bool final) -{ - ulong min = final ? 0 : bks; - - while ((!done && !m_finish) && output_bytes > min) - { - output()->recycler()->mutex()->lock (); - while ((! done && ! m_finish) && output()->recycler()->full()) - { - mutex()->unlock(); - output()->recycler()->cond()->wait(output()->recycler()->mutex()); - mutex()->lock (); - done = user_stop; - } - - if (user_stop || m_finish) - { - inited = FALSE; - done = TRUE; - } - else - { - output_bytes -= produceSound(output_buf, output_bytes, bitrate, chan); - output_size += bks; - output_at = output_bytes; - } - - if (output()->recycler()->full()) - { - output()->recycler()->cond()->wakeOne(); - } - - output()->recycler()->mutex()->unlock(); - } } - bool DecoderVorbis::initialize() { qDebug("DecoderVorbis: initialize"); - bks = Buffer::size(); - - inited = user_stop = done = m_finish = FALSE; - len = freq = bitrate = 0; - stat = chan = 0; - output_size = 0; - seekTime = -1.0; - m_totalTime = 0.0; - if (! input()) + inited = FALSE; + m_totalTime = 0; + if (!input()) { qDebug("DecoderVorbis: cannot initialize. No input"); - return FALSE; } - if (! output_buf) - output_buf = new char[globalBufferSize]; - output_at = 0; - output_bytes = 0; - - if (! input()->isOpen()) + if (!input()->isOpen()) { - if (! input()->open(QIODevice::ReadOnly)) + if (!input()->open(QIODevice::ReadOnly)) { qWarning("%s",qPrintable("DecoderVorbis: failed to open input. " + input()->errorString () + ".")); @@ -196,9 +124,9 @@ bool DecoderVorbis::initialize() return FALSE; } - freq = 0; - bitrate = ov_bitrate(&oggfile, -1) / 1000; - chan = 0; + quint32 freq = 0; + m_bitrate = ov_bitrate(&oggfile, -1) / 1000; + int chan = 0; m_totalTime = ov_time_total(&oggfile, -1) * 1000; m_totalTime = qMax(qint64(0), m_totalTime); @@ -219,16 +147,14 @@ bool DecoderVorbis::initialize() qint64 DecoderVorbis::totalTime() { - if (! inited) + if (!inited) return 0; - return m_totalTime; } - -void DecoderVorbis::seek(qint64 pos) +int DecoderVorbis::bitrate() { - seekTime = pos; + return m_bitrate; } @@ -236,10 +162,7 @@ void DecoderVorbis::deinit() { if (inited) ov_clear(&oggfile); - inited = user_stop = done = m_finish = FALSE; - len = freq = bitrate = 0; - stat = chan = 0; - output_size = 0; + len = 0; } void DecoderVorbis::updateTags() @@ -292,92 +215,22 @@ void DecoderVorbis::updateTags() stateHandler()->dispatch(metaData); } -void DecoderVorbis::run() +void DecoderVorbis::seekAudio(qint64 time) { - mutex()->lock (); + ov_time_seek(&oggfile, (double) time/1000); +} - if (!inited) +qint64 DecoderVorbis::readAudio(char *data, qint64 maxSize) +{ + len = -1; + while (len < 0) { - mutex()->unlock(); - return; + len = ov_read(&oggfile, data, maxSize, 0, 2, 1, &m_section); } - - mutex()->unlock(); - - int section = 0; - int last_section = -1; - - while (! done && ! m_finish) - { - mutex()->lock (); - // decode - - if (seekTime >= 0.0) - { - ov_time_seek(&oggfile, (double) seekTime/1000); - seekTime = -1.0; - - output_size = ov_time_tell(&oggfile) * freq * chan * 2; - } - len = -1; - while (len < 0) - { - len = ov_read(&oggfile, (char *) (output_buf + output_at), bks, 0, 2, 1, - §ion); - } - if (section != last_section) - updateTags(); - last_section = section; - - if (len > 0) - { - bitrate = ov_bitrate_instant(&oggfile) / 1000; - - output_at += len; - output_bytes += len; - if (output()) - flush(); - } - else if (len == 0) - { - flush(TRUE); - - if (output()) - { - output()->recycler()->mutex()->lock (); - // end of stream - while (! output()->recycler()->empty() && ! user_stop) - { - output()->recycler()->cond()->wakeOne(); - mutex()->unlock(); - output()->recycler()->cond()->wait(output()->recycler()->mutex()); - mutex()->lock (); - } - output()->recycler()->mutex()->unlock(); - } - - done = TRUE; - if (! user_stop) - { - m_finish = TRUE; - } - } - else - { - // error in read - //error("DecoderVorbis: Error while decoding stream, File appears to be " - // "corrupted"); - - m_finish = TRUE; - } - mutex()->unlock(); - } - - mutex()->lock (); - - if (m_finish) - finish(); - - mutex()->unlock(); - deinit(); + if (m_section != m_last_section) + updateTags(); + m_last_section = m_section; + if(len > 0) + m_bitrate = ov_bitrate_instant(&oggfile) / 1000; + return len; } diff --git a/src/plugins/Input/vorbis/decoder_vorbis.h b/src/plugins/Input/vorbis/decoder_vorbis.h index ec1158f31..b20b26ab7 100644 --- a/src/plugins/Input/vorbis/decoder_vorbis.h +++ b/src/plugins/Input/vorbis/decoder_vorbis.h @@ -21,42 +21,23 @@ public: // Standard Decoder API bool initialize(); qint64 totalTime(); - void seek(qint64); - void stop(); - - // Equalizer - bool isEQSupported() const { return FALSE; } - void setEQEnabled(bool) { ; } - void setEQGain(int) { ; } - void setEQBands(int[10]) { ; } - + int bitrate(); private: - // thread run function - void run(); + virtual qint64 readAudio(char *data, qint64 maxSize); + void seekAudio(qint64 time); // helper functions - void flush(bool = FALSE); void deinit(); - void updateTags(); - bool inited, user_stop; - int stat; - - // output buffer - char *output_buf; - ulong output_bytes, output_at; - // OggVorbis Decoder OggVorbis_File oggfile; - - unsigned int bks; - bool done, m_finish; - long len, freq, bitrate; - int chan; - qint64 output_size; - qint64 m_totalTime, seekTime; + qint64 m_totalTime; + long len; + int m_section, m_last_section; + int m_bitrate; + bool inited; }; |
