00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <iostream>
00004 #include <string>
00005 #include <qobject.h>
00006 #include <qiodevice.h>
00007 using namespace std;
00008
00009 #include "flacdecoder.h"
00010 #include "constants.h"
00011 #include <mythtv/audiooutput.h>
00012 #include "metadata.h"
00013 #include "metaioflacvorbiscomment.h"
00014
00015 #include <mythtv/mythconfig.h>
00016 #include <mythtv/mythcontext.h>
00017
00018 #include <qtimer.h>
00019
00020 static StreamDecoderReadStatus flacread(const StreamDecoder *decoder, FLAC__byte bufferp[], bytesSize *bytes, void *client_data)
00021 {
00022 decoder = decoder;
00023
00024 FlacDecoder *dflac = (FlacDecoder *) client_data;
00025 int len = dflac->input()->readBlock((char *)bufferp, *bytes);
00026
00027 if (len == -1)
00028 {
00029 return STREAM_DECODER_READ_STATUS_ERROR;
00030 }
00031
00032 *bytes = len;
00033 return STREAM_DECODER_READ_STATUS_OK;
00034 }
00035
00036 static StreamDecoderSeekStatus flacseek(const StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
00037 {
00038 decoder = decoder;
00039 FlacDecoder *dflac = (FlacDecoder *)client_data;
00040
00041 if (!dflac->input()->isDirectAccess())
00042 return STREAM_DECODER_SEEK_STATUS_ERROR;
00043
00044 if (dflac->input()->at(absolute_byte_offset))
00045 return STREAM_DECODER_SEEK_STATUS_OK;
00046 return STREAM_DECODER_SEEK_STATUS_ERROR;
00047 }
00048
00049 static StreamDecoderTellStatus flactell(const StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
00050 {
00051 decoder = decoder;
00052 FlacDecoder *dflac = (FlacDecoder *)client_data;
00053
00054 long t = dflac->input()->at();
00055 *absolute_byte_offset = t;
00056
00057 return STREAM_DECODER_TELL_STATUS_OK;
00058 }
00059
00060 static StreamDecoderLengthStatus flaclength(const StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
00061 {
00062 decoder = decoder;
00063
00064 FlacDecoder *dflac = (FlacDecoder *)client_data;
00065
00066 *stream_length = dflac->input()->size();
00067 return STREAM_DECODER_LENGTH_STATUS_OK;
00068 }
00069
00070 static FLAC__bool flaceof(const StreamDecoder *decoder, void *client_data)
00071 {
00072 decoder = decoder;
00073
00074 FlacDecoder *dflac = (FlacDecoder *)client_data;
00075
00076 return dflac->input()->atEnd();
00077 }
00078
00079 static FLAC__StreamDecoderWriteStatus flacwrite(const StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
00080 {
00081 decoder = decoder;
00082
00083 FlacDecoder *dflac = (FlacDecoder *)client_data;
00084
00085 dflac->doWrite(frame, buffer);
00086
00087 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
00088 }
00089
00090 void FlacDecoder::doWrite(const FLAC__Frame *frame,
00091 const FLAC__int32 * const buffer[])
00092 {
00093 unsigned int samples = frame->header.blocksize;
00094
00095 unsigned int cursamp;
00096 int sample;
00097 int channel;
00098
00099 if (bitspersample == 8)
00100 {
00101 for (cursamp = 0; cursamp < samples; cursamp++)
00102 {
00103 for (channel = 0; channel < chan; channel++)
00104 {
00105 sample = (FLAC__int8)buffer[channel][cursamp];
00106 #ifdef WORDS_BIGENDIAN
00107 *(output_buf + output_at++) = ((sample >> 8) & 0xff);
00108 #else
00109 *(output_buf + output_at++) = ((sample >> 0) & 0xff);
00110 #endif
00111 output_bytes += 1;
00112 }
00113 }
00114 }
00115 else if (bitspersample == 16)
00116 {
00117 for (cursamp = 0; cursamp < samples; cursamp++)
00118 {
00119 for (channel = 0; channel < chan; channel++)
00120 {
00121 sample = (FLAC__int16)buffer[channel][cursamp];
00122 #ifdef WORDS_BIGENDIAN
00123 *(output_buf + output_at++) = ((sample >> 8) & 0xff);
00124 *(output_buf + output_at++) = ((sample >> 0) & 0xff);
00125 #else
00126 *(output_buf + output_at++) = ((sample >> 0) & 0xff);
00127 *(output_buf + output_at++) = ((sample >> 8) & 0xff);
00128 #endif
00129 output_bytes += 2;
00130 }
00131 }
00132 }
00133 }
00134
00135 static void flacmetadata(const StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
00136 {
00137 decoder = decoder;
00138
00139 FlacDecoder *dflac = (FlacDecoder *)client_data;
00140
00141 dflac->setFlacMetadata(metadata);
00142 }
00143
00144 void FlacDecoder::setFlacMetadata(const FLAC__StreamMetadata *metadata)
00145 {
00146 bitspersample = metadata->data.stream_info.bits_per_sample;
00147 chan = metadata->data.stream_info.channels;
00148 freq = metadata->data.stream_info.sample_rate;
00149 totalsamples = metadata->data.stream_info.total_samples;
00150
00151 if (output())
00152 {
00153 output()->Reconfigure(bitspersample, chan,
00154 freq, false );
00155 output()->SetSourceBitrate(44100 * 2 * 16);
00156 }
00157 }
00158
00159 static void flacerror(const StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
00160 {
00161 decoder = decoder;
00162
00163 FileDecoder *file_decoder = (FileDecoder *)client_data;
00164
00165 file_decoder = file_decoder;
00166 status = status;
00167 }
00168
00169
00170 FlacDecoder::FlacDecoder(const QString &file, DecoderFactory *d, QIODevice *i,
00171 AudioOutput *o)
00172 : Decoder(d, i, o)
00173 {
00174 filename = file;
00175 inited = FALSE;
00176 user_stop = FALSE;
00177 stat = 0;
00178 output_buf = 0;
00179 output_bytes = 0;
00180 output_at = 0;
00181 bks = 0;
00182 done = FALSE;
00183 finish = FALSE;
00184 len = 0;
00185 freq = 0;
00186 bitrate = 0;
00187 seekTime = -1.0;
00188 totalTime = 0.0;
00189 chan = 0;
00190
00191 decoder = 0;
00192 }
00193
00194 FlacDecoder::~FlacDecoder(void)
00195 {
00196 if (inited)
00197 deinit();
00198
00199 if (output_buf)
00200 delete [] output_buf;
00201 output_buf = 0;
00202 }
00203
00204 void FlacDecoder::stop()
00205 {
00206 user_stop = TRUE;
00207 }
00208
00209 void FlacDecoder::flush(bool final)
00210 {
00211 ulong min = final ? 0 : bks;
00212
00213 while ((! done && ! finish) && output_bytes > min) {
00214 if (user_stop || finish) {
00215 inited = FALSE;
00216 done = TRUE;
00217 } else {
00218 ulong sz = output_bytes < bks ? output_bytes : bks;
00219
00220 int samples = (sz*8)/(chan*bitspersample);
00221 if (output()->AddSamples(output_buf, samples, -1))
00222 {
00223 output_bytes -= sz;
00224 memmove(output_buf, output_buf + sz, output_bytes);
00225 output_at = output_bytes;
00226 } else {
00227 unlock();
00228 usleep(500);
00229 lock();
00230 done = user_stop;
00231 }
00232 }
00233 }
00234 }
00235
00236 bool FlacDecoder::initialize()
00237 {
00238 bks = blockSize();
00239
00240 inited = user_stop = done = finish = FALSE;
00241 len = freq = bitrate = 0;
00242 stat = chan = 0;
00243 seekTime = -1.0;
00244 totalTime = 0.0;
00245
00246 if (! input()) {
00247 error("FlacDecoder: cannot initialize. No input.");
00248
00249 return FALSE;
00250 }
00251
00252 if (! output_buf)
00253 output_buf = new char[globalBufferSize];
00254 output_at = 0;
00255 output_bytes = 0;
00256
00257 if (! input()->isOpen()) {
00258 if (! input()->open(IO_ReadOnly)) {
00259 error("FlacDecoder: Failed to open input. Error " +
00260 QString::number(input()->status()) + ".");
00261 return FALSE;
00262 }
00263 }
00264
00265 decoder = decoder_new();
00266 decoder_set_md5_checking(decoder, false);
00267 decoder_setup(decoder, flacread, flacseek, flactell, flaclength,
00268 flaceof, flacwrite, flacmetadata, flacerror, this);
00269
00270 freq = 0;
00271 bitrate = 0;
00272 chan = 0;
00273
00274 totalTime = 0;
00275 totalTime = totalTime < 0 ? 0 : totalTime;
00276
00277 #if !defined(NEWFLAC)
00278 FLAC__seekable_stream_decoder_init(decoder);
00279 #endif
00280 decoder_process_metadata(decoder);
00281
00282 inited = TRUE;
00283 return TRUE;
00284 }
00285
00286 void FlacDecoder::seek(double pos)
00287 {
00288 seekTime = pos;
00289 }
00290
00291 void FlacDecoder::deinit()
00292 {
00293 decoder_finish(decoder);
00294 decoder_delete(decoder);
00295
00296 if (input()->isOpen())
00297 input()->close();
00298
00299 decoder = 0;
00300
00301 inited = user_stop = done = finish = FALSE;
00302 len = freq = bitrate = 0;
00303 stat = chan = 0;
00304 setInput(0);
00305 setOutput(0);
00306 }
00307
00308 void FlacDecoder::run()
00309 {
00310 lock();
00311
00312 if (! inited) {
00313 unlock();
00314
00315 return;
00316 }
00317
00318 stat = DecoderEvent::Decoding;
00319
00320 unlock();
00321
00322 {
00323 DecoderEvent e((DecoderEvent::Type) stat);
00324 dispatch(e);
00325 }
00326
00327 bool flacok = true;
00328 DecoderState decoderstate;
00329
00330 while (! done && ! finish) {
00331 lock();
00332
00333
00334 if (seekTime >= 0.0) {
00335 FLAC__uint64 sample = (FLAC__uint64)(seekTime * 44100.0);
00336 if (sample > totalsamples - 50)
00337 sample = totalsamples - 50;
00338 decoder_seek_absolute(decoder, sample);
00339 seekTime = -1.0;
00340 }
00341
00342 flacok = decoder_process_single(decoder);
00343 decoderstate = decoder_get_state(decoder);
00344
00345 if (decoderstate == STREAM_DECODER_SEARCH_FOR_METADATA ||
00346 decoderstate == STREAM_DECODER_READ_METADATA ||
00347 decoderstate == STREAM_DECODER_SEARCH_FOR_FRAME_SYNC ||
00348 decoderstate == STREAM_DECODER_READ_FRAME )
00349 {
00350 if (output())
00351 flush();
00352 }
00353 else
00354 {
00355
00356
00357 flush(TRUE);
00358
00359 if (output())
00360 output()->Drain();
00361
00362 done = TRUE;
00363 if (!user_stop)
00364 finish = TRUE;
00365 }
00366
00367 unlock();
00368 }
00369
00370 lock();
00371
00372 if (finish)
00373 stat = DecoderEvent::Finished;
00374 else if (user_stop)
00375 stat = DecoderEvent::Stopped;
00376
00377 unlock();
00378
00379 {
00380 DecoderEvent e((DecoderEvent::Type) stat);
00381 dispatch(e);
00382 }
00383
00384 deinit();
00385 }
00386
00387 typedef struct {
00388 char *field;
00389
00390 char *field_name;
00391
00392
00393 unsigned field_value_length;
00394 char *field_value;
00395 } Argument_VcField;
00396
00397 MetaIO *FlacDecoder::doCreateTagger(void)
00398 {
00399 return new MetaIOFLACVorbisComment();
00400 }
00401
00402 bool FlacDecoderFactory::supports(const QString &source) const
00403 {
00404 return (source.right(extension().length()).lower() == extension());
00405 }
00406
00407
00408 const QString &FlacDecoderFactory::extension() const
00409 {
00410 static QString ext(".flac");
00411 return ext;
00412 }
00413
00414
00415 const QString &FlacDecoderFactory::description() const
00416 {
00417 static QString desc(QObject::tr("FLAC Audio"));
00418 return desc;
00419 }
00420
00421 Decoder *FlacDecoderFactory::create(const QString &file, QIODevice *input,
00422 AudioOutput *output, bool deletable)
00423 {
00424 if (deletable)
00425 return new FlacDecoder(file, this, input, output);
00426
00427 static FlacDecoder *decoder = 0;
00428 if (! decoder) {
00429 decoder = new FlacDecoder(file, this, input, output);
00430 } else {
00431 decoder->setInput(input);
00432 decoder->setFilename(file);
00433 decoder->setOutput(output);
00434 }
00435
00436 return decoder;
00437 }
00438