summaryrefslogtreecommitdiff
path: root/vdr_decoder_ogg.c
diff options
context:
space:
mode:
Diffstat (limited to 'vdr_decoder_ogg.c')
-rw-r--r--vdr_decoder_ogg.c638
1 files changed, 284 insertions, 354 deletions
diff --git a/vdr_decoder_ogg.c b/vdr_decoder_ogg.c
index 91c9a70..b24c301 100644
--- a/vdr_decoder_ogg.c
+++ b/vdr_decoder_ogg.c
@@ -19,440 +19,370 @@
#include <stdlib.h>
#include <stdio.h>
-
// --- mgOggFile ----------------------------------------------------------------
-class mgOggFile // : public mgFileInfo
+class mgOggFile // : public mgFileInfo
{
- private:
+ private:
- bool m_opened, m_canSeek;
+ bool m_opened, m_canSeek;
- OggVorbis_File vf;
+ OggVorbis_File vf;
- void error (const char *action, const int err);
+ void error (const char *action, const int err);
- std::string m_filename;
+ std::string m_filename;
- public:
+ public:
- mgOggFile (std::string filename);
- ~mgOggFile ();
+ mgOggFile (std::string filename);
+ ~mgOggFile ();
- bool open (bool log = true);
+ bool open (bool log = true);
- void close (void);
+ void close (void);
- long long seek (long long posMs = 0, bool relativ = false);
+ long long seek (long long posMs = 0, bool relativ = false);
- int stream (short *buffer, int samples);
+ int stream (short *buffer, int samples);
- bool canSeek ()
- {
- return m_canSeek;
- }
+ bool canSeek () {
+ return m_canSeek;
+ }
- long long indexMs (void);
+ long long indexMs (void);
};
mgOggFile::mgOggFile (std::string filename):
-m_filename (filename)
-{
- m_canSeek = false;
- m_opened = false;
+m_filename (filename) {
+ m_canSeek = false;
+ m_opened = false;
}
-
-mgOggFile::~mgOggFile ()
-{
- close ();
+mgOggFile::~mgOggFile () {
+ close ();
}
-
-bool mgOggFile::open (bool log)
-{
- if (m_opened)
- {
- if (m_canSeek)
- {
- return (seek () >= 0);
- }
- return true;
- }
-
- FILE *
- f = fopen (m_filename.c_str (), "r");
- if (f)
- {
- int
- r = ov_open (f, &vf, 0, 0);
- if (!r)
- {
- m_canSeek = (ov_seekable (&vf) != 0);
- m_opened = true;
- }
- else
- {
- fclose (f);
- if (log)
- {
- error ("open", r);
- }
- }
- }
- else
- {
- if (log)
- {
-// esyslog("ERROR: failed to open file %s: %s", m_filename.c_str(), strerror(errno) );
- }
- }
- return m_opened;
+bool mgOggFile::open (bool log) {
+ if (m_opened) {
+ if (m_canSeek) {
+ return (seek () >= 0);
+ }
+ return true;
+ }
+
+ FILE *
+ f = fopen (m_filename.c_str (), "r");
+ if (f) {
+ int
+ r = ov_open (f, &vf, 0, 0);
+ if (!r) {
+ m_canSeek = (ov_seekable (&vf) != 0);
+ m_opened = true;
+ }
+ else {
+ fclose (f);
+ if (log) {
+ error ("open", r);
+ }
+ }
+ }
+ else {
+ if (log) {
+ // esyslog("ERROR: failed to open file %s: %s", m_filename.c_str(), strerror(errno) );
+ }
+ }
+ return m_opened;
}
-
void
-mgOggFile::close ()
-{
- if (m_opened)
- {
- ov_clear (&vf);
- m_opened = false;
- }
+mgOggFile::close () {
+ if (m_opened) {
+ ov_clear (&vf);
+ m_opened = false;
+ }
}
-
void
-mgOggFile::error (const char *action, const int err)
-{
- char *errstr;
- switch (err)
- {
- case OV_FALSE:
- errstr = "false/no data available";
- break;
- case OV_EOF:
- errstr = "EOF";
- break;
- case OV_HOLE:
- errstr = "missing or corrupted data";
- break;
- case OV_EREAD:
- errstr = "read error";
- break;
- case OV_EFAULT:
- errstr = "internal error";
- break;
- case OV_EIMPL:
- errstr = "unimplemented feature";
- break;
- case OV_EINVAL:
- errstr = "invalid argument";
- break;
- case OV_ENOTVORBIS:
- errstr = "no Ogg Vorbis stream";
- break;
- case OV_EBADHEADER:
- errstr = "corrupted Ogg Vorbis stream";
- break;
- case OV_EVERSION:
- errstr = "unsupported bitstream version";
- break;
- case OV_ENOTAUDIO:
- errstr = "ENOTAUDIO";
- break;
- case OV_EBADPACKET:
- errstr = "EBADPACKET";
- break;
- case OV_EBADLINK:
- errstr = "corrupted link";
- break;
- case OV_ENOSEEK:
- errstr = "stream not seekable";
- break;
- default:
- errstr = "unspecified error";
- break;
- }
-// esyslog( "ERROR: vorbisfile %s failed on %s: %s", action, m_filename.c_str(), errstr );
+mgOggFile::error (const char *action, const int err) {
+ char *errstr;
+ switch (err) {
+ case OV_FALSE:
+ errstr = "false/no data available";
+ break;
+ case OV_EOF:
+ errstr = "EOF";
+ break;
+ case OV_HOLE:
+ errstr = "missing or corrupted data";
+ break;
+ case OV_EREAD:
+ errstr = "read error";
+ break;
+ case OV_EFAULT:
+ errstr = "internal error";
+ break;
+ case OV_EIMPL:
+ errstr = "unimplemented feature";
+ break;
+ case OV_EINVAL:
+ errstr = "invalid argument";
+ break;
+ case OV_ENOTVORBIS:
+ errstr = "no Ogg Vorbis stream";
+ break;
+ case OV_EBADHEADER:
+ errstr = "corrupted Ogg Vorbis stream";
+ break;
+ case OV_EVERSION:
+ errstr = "unsupported bitstream version";
+ break;
+ case OV_ENOTAUDIO:
+ errstr = "ENOTAUDIO";
+ break;
+ case OV_EBADPACKET:
+ errstr = "EBADPACKET";
+ break;
+ case OV_EBADLINK:
+ errstr = "corrupted link";
+ break;
+ case OV_ENOSEEK:
+ errstr = "stream not seekable";
+ break;
+ default:
+ errstr = "unspecified error";
+ break;
+ }
+ // esyslog( "ERROR: vorbisfile %s failed on %s: %s", action, m_filename.c_str(), errstr );
}
-
long long
-mgOggFile::indexMs (void)
-{
- double p = ov_time_tell (&vf);
- if (p < 0.0)
- {
- p = 0.0;
- }
+mgOggFile::indexMs (void) {
+ double p = ov_time_tell (&vf);
+ if (p < 0.0) {
+ p = 0.0;
+ }
- return (long long) (p * 1000.0);
+ return (long long) (p * 1000.0);
}
-
long long
-mgOggFile::seek (long long posMs, bool relativ)
-{
- if (relativ)
- {
- posMs += indexMs ();
- }
+mgOggFile::seek (long long posMs, bool relativ) {
+ if (relativ) {
+ posMs += indexMs ();
+ }
- int r = ov_time_seek (&vf, (double) posMs / 1000.0);
+ int r = ov_time_seek (&vf, (double) posMs / 1000.0);
- if (r)
- {
- error ("seek", r);
- return -1;
- }
+ if (r) {
+ error ("seek", r);
+ return -1;
+ }
- posMs = indexMs ();
- return posMs;
+ posMs = indexMs ();
+ return posMs;
}
-
int
-mgOggFile::stream (short *buffer, int samples)
-{
- int n;
- do
- {
- int stream;
- n = ov_read (&vf, (char *) buffer, samples * 2, 0, 2, 1, &stream);
- }
- while (n == OV_HOLE);
-
- if (n < 0)
- {
- error ("read", n);
- }
-
- return (n / 2);
+mgOggFile::stream (short *buffer, int samples) {
+ int n;
+ do {
+ int stream;
+ n = ov_read (&vf, (char *) buffer, samples * 2, 0, 2, 1, &stream);
+ }
+ while (n == OV_HOLE);
+
+ if (n < 0) {
+ error ("read", n);
+ }
+
+ return (n / 2);
}
-
// --- mgOggDecoder -------------------------------------------------------------
-mgOggDecoder::mgOggDecoder (mgItemGd * item):mgDecoder (item)
-{
- m_filename = item->getSourceFile ();
- m_file = new mgOggFile (m_filename);
- m_pcm = 0;
- init ();
+mgOggDecoder::mgOggDecoder (mgItemGd * item):mgDecoder (item) {
+ m_filename = item->getSourceFile ();
+ m_file = new mgOggFile (m_filename);
+ m_pcm = 0;
+ init ();
}
-
-mgOggDecoder::~mgOggDecoder ()
-{
- clean ();
- delete m_file;
+mgOggDecoder::~mgOggDecoder () {
+ clean ();
+ delete m_file;
}
-
-bool mgOggDecoder::valid ()
-{
- bool
- res = false;
- if (tryLock ())
- {
- if (m_file->open (false))
- {
- res = true;
- }
- unlock ();
- }
- return res;
+bool mgOggDecoder::valid () {
+ bool
+ res = false;
+ if (tryLock ()) {
+ if (m_file->open (false)) {
+ res = true;
+ }
+ unlock ();
+ }
+ return res;
}
-
mgPlayInfo *
-mgOggDecoder::playInfo (void)
-{
- if (m_playing)
- {
-// m_playinfo.m_index = index/1000;
-// m_playinfo.m_total = info.Total;
+mgOggDecoder::playInfo (void) {
+ if (m_playing) {
+ // m_playinfo.m_index = index/1000;
+ // m_playinfo.m_total = info.Total;
- return &m_playinfo;
- }
+ return &m_playinfo;
+ }
- return 0;
+ return 0;
}
-
void
-mgOggDecoder::init ()
-{
- clean ();
- m_pcm = new struct mad_pcm;
- m_index = 0;
+mgOggDecoder::init () {
+ clean ();
+ m_pcm = new struct mad_pcm;
+ m_index = 0;
}
+bool mgOggDecoder::clean () {
+ m_playing = false;
-bool mgOggDecoder::clean ()
-{
- m_playing = false;
+ delete
+ m_pcm;
+ m_pcm = 0;
- delete
- m_pcm;
- m_pcm = 0;
-
- m_file->close ();
- return false;
+ m_file->close ();
+ return false;
}
-
#define SF_SAMPLES (sizeof(m_pcm->samples[0])/sizeof(mad_fixed_t))
-bool mgOggDecoder::start ()
-{
- lock (true);
- init ();
- m_playing = true;
-
- if (m_file->open () /*&& info.DoScan(true) */ )
- {
-// obtain from database: rate, channels
-/* d(printf("ogg: open rate=%d channels=%d seek=%d\n",
- info.SampleFreq,info.Channels,file.CanSeek()))
- */
- if (m_item->getChannels () <= 2)
- {
- unlock ();
- return true;
- }
- else
- {
-// esyslog( "ERROR: cannot play ogg file %s: more than 2 channels", m_filename.c_str() );
- }
- }
-
- clean ();
- unlock ();
-
- return false;
+bool mgOggDecoder::start () {
+ lock (true);
+ init ();
+ m_playing = true;
+
+ if (m_file->open () /*&& info.DoScan(true) */ ) {
+ // obtain from database: rate, channels
+ /* d(printf("ogg: open rate=%d channels=%d seek=%d\n",
+ info.SampleFreq,info.Channels,file.CanSeek()))
+ */
+ if (m_item->getChannels () <= 2) {
+ unlock ();
+ return true;
+ }
+ else {
+ // esyslog( "ERROR: cannot play ogg file %s: more than 2 channels", m_filename.c_str() );
+ }
+ }
+
+ clean ();
+ unlock ();
+
+ return false;
}
+bool mgOggDecoder::stop (void) {
+ lock ();
-bool mgOggDecoder::stop (void)
-{
- lock ();
+ if (m_playing) {
+ clean ();
+ }
+ unlock ();
- if (m_playing)
- {
- clean ();
- }
- unlock ();
-
- return true;
+ return true;
}
-
struct mgDecode *
-mgOggDecoder::done (eDecodeStatus status)
-{
- m_ds.status = status;
- m_ds.index = m_index;
- m_ds.pcm = m_pcm;
+mgOggDecoder::done (eDecodeStatus status) {
+ m_ds.status = status;
+ m_ds.index = m_index;
+ m_ds.pcm = m_pcm;
- unlock (); // release the lock from decode()
+ unlock (); // release the lock from decode()
- return &m_ds;
+ return &m_ds;
}
-
struct mgDecode *
-mgOggDecoder::decode (void)
-{
- lock (); // this is released in Done()
-
- if (m_playing)
- {
- short framebuff[2 * SF_SAMPLES];
- int n = m_file->stream (framebuff, SF_SAMPLES);
-
- if (n < 0)
- {
- return done (dsError);
- }
-
- if (n == 0)
- {
- return done (dsEof);
- }
-
-// should be done during initialization
- // from database
- m_pcm->samplerate = m_item->getSampleRate ();
- m_pcm->channels = m_item->getChannels (); // from database
-
- n /= m_pcm->channels;
- m_pcm->length = n;
- m_index = m_file->indexMs ();
-
- short *data = framebuff;
- mad_fixed_t *sam0 = m_pcm->samples[0], *sam1 = m_pcm->samples[1];
-
- // shift value for mad_fixed conversion
- const int s = MAD_F_FRACBITS + 1 - (sizeof (short) * 8);
-
- if (m_pcm->channels > 1)
- {
- for (; n > 0; n--)
- {
- *sam0++ = (*data++) << s;
- *sam1++ = (*data++) << s;
- }
- }
- else
- {
- for (; n > 0; n--)
- {
- *sam0++ = (*data++) << s;
- }
- }
- return done (dsPlay);
- }
- return done (dsError);
+mgOggDecoder::decode (void) {
+ lock (); // this is released in Done()
+
+ if (m_playing) {
+ short framebuff[2 * SF_SAMPLES];
+ int n = m_file->stream (framebuff, SF_SAMPLES);
+
+ if (n < 0) {
+ return done (dsError);
+ }
+
+ if (n == 0) {
+ return done (dsEof);
+ }
+
+ // should be done during initialization
+ // from database
+ m_pcm->samplerate = m_item->getSampleRate ();
+ // from database
+ m_pcm->channels = m_item->getChannels ();
+
+ n /= m_pcm->channels;
+ m_pcm->length = n;
+ m_index = m_file->indexMs ();
+
+ short *data = framebuff;
+ mad_fixed_t *sam0 = m_pcm->samples[0], *sam1 = m_pcm->samples[1];
+
+ // shift value for mad_fixed conversion
+ const int s = MAD_F_FRACBITS + 1 - (sizeof (short) * 8);
+
+ if (m_pcm->channels > 1) {
+ for (; n > 0; n--) {
+ *sam0++ = (*data++) << s;
+ *sam1++ = (*data++) << s;
+ }
+ }
+ else {
+ for (; n > 0; n--) {
+ *sam0++ = (*data++) << s;
+ }
+ }
+ return done (dsPlay);
+ }
+ return done (dsError);
}
+bool mgOggDecoder::skip (int Seconds, int Avail, int Rate) {
+ lock ();
+ bool
+ res = false;
-bool mgOggDecoder::skip (int Seconds, int Avail, int Rate)
-{
- lock ();
- bool
- res = false;
-
- if (m_playing && m_file->canSeek ())
- {
- float
- fsecs =
- (float) Seconds - ((float) Avail / (float) (Rate * (16 / 8 * 2)));
-// Byte/s = samplerate * 16 bit * 2 chan
-
- long long
- newpos = m_file->indexMs () + (long long) (fsecs * 1000.0);
-
- if (newpos < 0)
- {
- newpos = 0;
- }
-
- newpos = m_file->seek (newpos, false);
-
- if (newpos >= 0)
- {
- m_index = m_file->indexMs ();
+ if (m_playing && m_file->canSeek ()) {
+ float
+ fsecs =
+ (float) Seconds - ((float) Avail / (float) (Rate * (16 / 8 * 2)));
+ // Byte/s = samplerate * 16 bit * 2 chan
+
+ long long
+ newpos = m_file->indexMs () + (long long) (fsecs * 1000.0);
+
+ if (newpos < 0) {
+ newpos = 0;
+ }
+
+ newpos = m_file->seek (newpos, false);
+
+ if (newpos >= 0) {
+ m_index = m_file->indexMs ();
#ifdef xDEBUG
- int
- i = index / 1000;
- printf ("ogg: skipping to %02d:%02d\n", i / 60, i % 60);
+ int
+ i = index / 1000;
+ printf ("ogg: skipping to %02d:%02d\n", i / 60, i % 60);
#endif
- res = true;
- }
- }
- unlock ();
- return res;
+ res = true;
+ }
+ }
+ unlock ();
+ return res;
}
-#endif //HAVE_VORBISFILE
+#endif //HAVE_VORBISFILE