aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/Input/ffmpeg/decoder_ffmpeg.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/Input/ffmpeg/decoder_ffmpeg.cpp')
-rw-r--r--src/plugins/Input/ffmpeg/decoder_ffmpeg.cpp256
1 files changed, 57 insertions, 199 deletions
diff --git a/src/plugins/Input/ffmpeg/decoder_ffmpeg.cpp b/src/plugins/Input/ffmpeg/decoder_ffmpeg.cpp
index 678aa3ddb..2a1c1a9d4 100644
--- a/src/plugins/Input/ffmpeg/decoder_ffmpeg.cpp
+++ b/src/plugins/Input/ffmpeg/decoder_ffmpeg.cpp
@@ -21,7 +21,6 @@
#include <QObject>
#include <QFile>
-#include <qmmp/constants.h>
#include <qmmp/buffer.h>
#include <qmmp/output.h>
#include <qmmp/recycler.h>
@@ -33,102 +32,30 @@
DecoderFFmpeg::DecoderFFmpeg(QObject *parent, DecoderFactory *d, Output *o, const QString &path)
: Decoder(parent, d, o)
{
- inited = FALSE;
- user_stop = FALSE;
- output_buf = 0;
- output_bytes = 0;
- output_at = 0;
- bks = 0;
- done = FALSE;
- m_finish = FALSE;
- freq = 0;
- bitrate = 0;
- seekTime = -1.0;
- m_totalTime = 0.0;
- chan = 0;
- output_size = 0;
+ m_bitrate = 0;
+ seekTime = -1;
+ m_totalTime = 0;
ic = 0;
- wma_outbuf = 0;
m_path = path;
+ m_size = 0;
}
DecoderFFmpeg::~DecoderFFmpeg()
{
- deinit();
- if (wma_outbuf)
- {
- delete [] wma_outbuf;
- wma_outbuf = 0;
- }
- if (output_buf)
- delete [] output_buf;
- output_buf = 0;
-
+ m_bitrate = 0;
if (ic)
av_close_input_file(ic);
+ if(m_pkt.data)
+ av_free_packet(&m_pkt);
}
-
-void DecoderFFmpeg::stop()
-{
- user_stop = TRUE;
-}
-
-
-void DecoderFFmpeg::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 DecoderFFmpeg::initialize()
{
- bks = Buffer::size();
- inited = user_stop = done = m_finish = FALSE;
- freq = bitrate = 0;
- chan = 0;
- output_size = 0;
- seekTime = -1.0;
+ m_bitrate = 0;
+ seekTime = -1;
m_totalTime = 0.0;
- if (!output_buf)
- output_buf = new char[globalBufferSize];
- output_at = 0;
- output_bytes = 0;
-
avcodec_init();
avcodec_register_all();
av_register_all();
@@ -143,7 +70,7 @@ bool DecoderFFmpeg::initialize()
av_find_stream_info(ic);
av_read_play(ic);
- for (wma_idx = 0; wma_idx < ic->nb_streams; wma_idx++)
+ for (wma_idx = 0; wma_idx < (int)ic->nb_streams; wma_idx++)
{
c = ic->streams[wma_idx]->codec;
if (c->codec_type == CODEC_TYPE_AUDIO) break;
@@ -166,11 +93,7 @@ bool DecoderFFmpeg::initialize()
m_totalTime = ic->duration * 1000 / AV_TIME_BASE;
configure(c->sample_rate, c->channels, 16);
-
- bitrate = c->bit_rate;
- chan = c->channels;
- wma_outbuf = new uint8_t[AVCODEC_MAX_AUDIO_FRAME_SIZE*sizeof(int16_t) + globalBufferSize];
- inited = TRUE;
+ m_bitrate = c->bit_rate;
qDebug("DecoderFFmpeg: initialize succes");
return TRUE;
}
@@ -178,135 +101,70 @@ bool DecoderFFmpeg::initialize()
qint64 DecoderFFmpeg::totalTime()
{
- if (! inited)
- return 0;
-
return m_totalTime;
}
-void DecoderFFmpeg::seek(qint64 pos)
-{
- seekTime = pos;
-}
-
-
-void DecoderFFmpeg::deinit()
+int DecoderFFmpeg::bitrate()
{
- inited = user_stop = done = m_finish = FALSE;
- freq = bitrate = 0;
- chan = 0;
- output_size = 0;
+ return m_bitrate;
}
-void DecoderFFmpeg::run()
+qint64 DecoderFFmpeg::readAudio(char *audio, qint64 maxSize)
{
- uint8_t *inbuf_ptr;
- int out_size, size;
- AVPacket pkt;
-
- mutex()->lock ();
-
- if (!inited)
+ if(seekTime == 1)
{
- mutex()->unlock();
- return;
+ if(!m_size)
+ fillBuffer();
+ if(!m_size)
+ return 0;
+ while(m_size > 0)
+ ffmpeg_decode(audio, maxSize);
+ seekTime = -1;
}
- mutex()->unlock();
-
- while (!done && !m_finish)
- {
- mutex()->lock ();
- // decode
-
- if (seekTime >= 0.0)
- {
- int64_t timestamp;
- timestamp = int64_t(seekTime)*AV_TIME_BASE/1000;
- if (ic->start_time != AV_NOPTS_VALUE)
- timestamp += ic->start_time;
- av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD);
- avcodec_flush_buffers(c);
- seekTime = -1.0;
- }
-
- int l = 0;
- if (av_read_frame(ic, &pkt) < 0)
- {
- m_finish = TRUE;
- goto end;
- }
- size = pkt.size;
- inbuf_ptr = pkt.data;
- out_size = 0;
-
- while (size > 0 && (pkt.stream_index == wma_idx))
- {
- out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE*sizeof(int16_t);
- l = avcodec_decode_audio2(c, (int16_t *)(wma_outbuf), &out_size, inbuf_ptr, size);
-
- if (l < 0)
- goto end;
- ffmpeg_out(out_size);
- size -= l;
- inbuf_ptr += l;
- if (pkt.data)
- av_free_packet(&pkt);
- }
- bitrate = c->bit_rate/1024;
-end:
- if (m_finish)
- {
- 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;
- }
- }
+ if(!m_size)
+ fillBuffer();
+ if(!m_size)
+ return 0;
+ return ffmpeg_decode(audio, maxSize);
+}
- mutex()->unlock();
+qint64 DecoderFFmpeg::ffmpeg_decode(char *audio, qint64 maxSize)
+{
+ int out_size = maxSize;
+ if((m_pkt.stream_index == wma_idx))
+ {
+ int l = avcodec_decode_audio2(c, (int16_t *)(audio), &out_size, m_inbuf_ptr, m_size);
+ if(l < 0)
+ return 0;
+ m_inbuf_ptr += l;
+ m_size -= l;
}
+ if (!m_size && m_pkt.data)
+ av_free_packet(&m_pkt);
- mutex()->lock ();
- if (m_finish)
- finish();
- mutex()->unlock();
- deinit();
+ return out_size;
+}
+
+void DecoderFFmpeg::seekAudio(qint64 pos)
+{
+ int64_t timestamp = int64_t(pos)*AV_TIME_BASE/1000;
+ if (ic->start_time != AV_NOPTS_VALUE)
+ timestamp += ic->start_time;
+ av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD);
+ avcodec_flush_buffers(c);
+ seekTime = 1;
}
-void DecoderFFmpeg::ffmpeg_out(int size)
+void DecoderFFmpeg::fillBuffer()
{
- if (size == 0)
- return;
- int at = 0;
- int to_copy = 0;
- while ((size > 0) && !user_stop && (seekTime < 0)) //ape fast seeking hack
+ if (av_read_frame(ic, &m_pkt) < 0)
{
- to_copy = qMin(int(globalBufferSize - output_at), int(size) );
- memmove ( (char *) (output_buf + output_at), wma_outbuf + at, to_copy);
- at += to_copy;
- size -= to_copy;
- output_at += to_copy;
- output_bytes += to_copy;
- if (output())
- flush();
+ m_size = 0;
+ m_inbuf_ptr = 0;
}
+ m_size = m_pkt.size;
+ m_inbuf_ptr = m_pkt.data;
}