00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <iostream>
00019 #include <string>
00020 #include <qobject.h>
00021 #include <qiodevice.h>
00022 #include <qfile.h>
00023
00024 using namespace std;
00025
00026 #include "avfdecoder.h"
00027 #include "constants.h"
00028 #include <mythtv/audiooutput.h>
00029 #include "metadata.h"
00030 #include "metaioavfcomment.h"
00031
00032 #include <mythtv/mythcontext.h>
00033
00034 avfDecoder::avfDecoder(const QString &file, DecoderFactory *d, QIODevice *i,
00035 AudioOutput *o)
00036 : Decoder(d, i, o)
00037 {
00038 filename = file;
00039 inited = FALSE;
00040 user_stop = FALSE;
00041 stat = 0;
00042 bks = 0;
00043 done = FALSE;
00044 finish = FALSE;
00045 len = 0;
00046 freq = 0;
00047 bitrate = 0;
00048 seekTime = -1.0;
00049 totalTime = 0.0;
00050 chan = 0;
00051 output_buf = 0;
00052 output_bytes = 0;
00053 output_at = 0;
00054
00055 ic = NULL;
00056 oc = NULL;
00057 ifmt = NULL;
00058 ap = ¶ms;
00059 pkt = &pkt1;
00060 }
00061
00062 avfDecoder::~avfDecoder(void)
00063 {
00064 if (inited)
00065 deinit();
00066
00067 if (output_buf)
00068 {
00069 delete [] output_buf;
00070 output_buf = NULL;
00071 }
00072 }
00073
00074 void avfDecoder::stop()
00075 {
00076 user_stop = TRUE;
00077 }
00078
00079 void avfDecoder::flush(bool final)
00080 {
00081 ulong min = final ? 0 : bks;
00082
00083 while ((!done && !finish && seekTime <= 0) && output_bytes > min)
00084 {
00085 if (user_stop || finish)
00086 {
00087 inited = FALSE;
00088 done = TRUE;
00089 }
00090 else
00091 {
00092 ulong sz = output_bytes < bks ? output_bytes : bks;
00093
00094 int samples = (sz*8)/(chan*16);
00095 if (output()->AddSamples(output_buf, samples, -1))
00096 {
00097 output_bytes -= sz;
00098 memmove(output_buf, output_buf + sz, output_bytes);
00099 output_at = output_bytes;
00100 } else {
00101 unlock();
00102 usleep(500);
00103 lock();
00104 done = user_stop;
00105 }
00106 }
00107 }
00108 }
00109
00110 bool avfDecoder::initialize()
00111 {
00112 bks = blockSize();
00113
00114 inited = user_stop = done = finish = FALSE;
00115 len = freq = bitrate = 0;
00116 stat = chan = 0;
00117 seekTime = -1.0;
00118 totalTime = 0.0;
00119
00120 filename = ((QFile *)input())->name();
00121
00122 if (!output_buf)
00123 output_buf = new char[globalBufferSize];
00124 output_at = 0;
00125 output_bytes = 0;
00126
00127
00128
00129 av_register_all();
00130
00131
00132
00133 if (av_open_input_file(&ic, filename, ifmt, 0, ap) < 0)
00134 return FALSE;
00135
00136
00137
00138 if (av_find_stream_info(ic) < 0)
00139 return FALSE;
00140
00141
00142 audio_dec = ic->streams[0]->codec;
00143
00144
00145 ifmt = ic->iformat;
00146
00147
00148
00149
00150 fmt = guess_format("oss", NULL, NULL);
00151 if (!fmt)
00152 {
00153 VERBOSE(VB_IMPORTANT, "avfDecoder.o - failed to get output format");
00154 return FALSE;
00155 }
00156
00157
00158
00159
00160 oc = (AVFormatContext *)av_mallocz(sizeof(AVFormatContext));
00161 oc->oformat = fmt;
00162
00163 dec_st = av_new_stream(oc,0);
00164 dec_st->codec->codec_type = CODEC_TYPE_AUDIO;
00165 dec_st->codec->codec_id = oc->oformat->audio_codec;
00166 dec_st->codec->sample_rate = audio_dec->sample_rate;
00167 dec_st->codec->channels = audio_dec->channels;
00168 dec_st->codec->bit_rate = audio_dec->bit_rate;
00169 av_set_parameters(oc, NULL);
00170
00171
00172
00173
00174
00175 codec = avcodec_find_decoder(audio_dec->codec_id);
00176 if (!codec)
00177 return FALSE;
00178 if (avcodec_open(audio_dec,codec) < 0)
00179 return FALSE;
00180 totalTime = (ic->duration / AV_TIME_BASE) * 1000;
00181
00182 freq = audio_dec->sample_rate;
00183 chan = audio_dec->channels;
00184
00185 if (output())
00186 {
00187 output()->Reconfigure(16, audio_dec->channels, audio_dec->sample_rate,
00188 false );
00189 output()->SetSourceBitrate(audio_dec->bit_rate);
00190 }
00191
00192 inited = TRUE;
00193 return TRUE;
00194 }
00195
00196 void avfDecoder::seek(double pos)
00197 {
00198 seekTime = pos;
00199 }
00200
00201 void avfDecoder::deinit()
00202 {
00203 inited = user_stop = done = finish = FALSE;
00204 len = freq = bitrate = 0;
00205 stat = chan = 0;
00206 setInput(0);
00207 setOutput(0);
00208
00209
00210 if(ic)
00211 {
00212 av_close_input_file(ic);
00213 ic = NULL;
00214 }
00215 if(oc)
00216 {
00217 av_free(oc);
00218 oc = NULL;
00219 }
00220 }
00221
00222 void avfDecoder::run()
00223 {
00224 int mem_len;
00225 char *s;
00226
00227 lock();
00228
00229 if (!inited)
00230 {
00231 unlock();
00232 return;
00233 }
00234
00235 stat = DecoderEvent::Decoding;
00236
00237 unlock();
00238
00239 {
00240 DecoderEvent e((DecoderEvent::Type) stat);
00241 dispatch(e);
00242 }
00243
00244 av_read_play(ic);
00245 while (!done && !finish && !user_stop)
00246 {
00247 lock();
00248
00249
00250 if (seekTime >= 0.0)
00251 {
00252 VERBOSE(VB_GENERAL, QString("avfdecoder.o: seek time %1")
00253 .arg(seekTime));
00254 if (av_seek_frame(ic, -1, (int64_t)(seekTime * AV_TIME_BASE), 0)
00255 < 0)
00256 {
00257 VERBOSE(VB_IMPORTANT, "Error seeking");
00258 }
00259
00260 seekTime = -1.0;
00261 }
00262
00263
00264
00265 if (av_read_frame(ic, pkt) < 0)
00266 {
00267 VERBOSE(VB_IMPORTANT, "Read frame failed");
00268 unlock();
00269 finish = TRUE;
00270 break;
00271 }
00272
00273
00274 ptr = pkt->data;
00275 len = pkt->size;
00276 unlock();
00277
00278 while (len > 0 && !done && !finish && !user_stop && seekTime <= 0.0)
00279 {
00280 lock();
00281
00282
00283
00284
00285
00286 dec_len = avcodec_decode_audio(audio_dec, samples, &data_size,
00287 ptr, len);
00288 if (dec_len < 0)
00289 {
00290 unlock();
00291 break;
00292 }
00293
00294 s = (char *)samples;
00295 unlock();
00296
00297 while (data_size > 0 && !done && !finish && !user_stop &&
00298 seekTime <= 0.0)
00299 {
00300 lock();
00301
00302
00303
00304
00305 mem_len = data_size;
00306 if ((output_at + data_size) > globalBufferSize)
00307 {
00308
00309 mem_len = globalBufferSize - output_at;
00310 }
00311
00312
00313 memcpy((char *)(output_buf + output_at), s, mem_len);
00314
00315
00316 output_at += mem_len;
00317 output_bytes += mem_len;
00318
00319
00320
00321 data_size -= mem_len;
00322 s += mem_len;
00323
00324 if (output())
00325 flush();
00326
00327 unlock();
00328 }
00329
00330 lock();
00331 flush();
00332 ptr += dec_len;
00333 len -= dec_len;
00334 unlock();
00335 }
00336 av_free_packet(pkt);
00337 }
00338
00339 flush(TRUE);
00340 if (output())
00341 output()->Drain();
00342
00343 if (finish)
00344 stat = DecoderEvent::Finished;
00345 else if (user_stop)
00346 stat = DecoderEvent::Stopped;
00347
00348
00349
00350 {
00351 DecoderEvent e((DecoderEvent::Type) stat);
00352 dispatch(e);
00353 }
00354
00355 deinit();
00356 }
00357
00358 MetaIO* avfDecoder::doCreateTagger(void)
00359 {
00360 return new MetaIOAVFComment();
00361 }
00362
00363 bool avfDecoderFactory::supports(const QString &source) const
00364 {
00365 QStringList list = QStringList::split("|", extension());
00366 for (QStringList::Iterator it = list.begin(); it != list.end(); ++it)
00367 {
00368 if (*it == source.right((*it).length()).lower())
00369 return true;
00370 }
00371
00372 return false;
00373 }
00374
00375 const QString &avfDecoderFactory::extension() const
00376 {
00377 static QString ext(".wma|.wav");
00378 return ext;
00379 }
00380
00381 const QString &avfDecoderFactory::description() const
00382 {
00383 static QString desc(QObject::tr("Windows Media Audio"));
00384 return desc;
00385 }
00386
00387 Decoder *avfDecoderFactory::create(const QString &file, QIODevice *input,
00388 AudioOutput *output, bool deletable)
00389 {
00390 if (deletable)
00391 return new avfDecoder(file, this, input, output);
00392
00393 static avfDecoder *decoder = 0;
00394 if (!decoder)
00395 {
00396 decoder = new avfDecoder(file, this, input, output);
00397 }
00398 else
00399 {
00400 decoder->setInput(input);
00401 decoder->setOutput(output);
00402 }
00403
00404 return decoder;
00405 }
00406