aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/Input/ffmpeg/decoder_ffmpeg.cpp
diff options
context:
space:
mode:
authortrialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38>2011-12-17 19:29:48 +0000
committertrialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38>2011-12-17 19:29:48 +0000
commitbe4ee17cbe5294e1df0bd1ab787089eb088106e0 (patch)
tree7cc99fcb6ba569c745764610bd4356928ea1d55c /src/plugins/Input/ffmpeg/decoder_ffmpeg.cpp
parent6ae6e25f660991d7597956df1a241e2596cb4d5e (diff)
downloadqmmp-be4ee17cbe5294e1df0bd1ab787089eb088106e0.tar.gz
qmmp-be4ee17cbe5294e1df0bd1ab787089eb088106e0.tar.bz2
qmmp-be4ee17cbe5294e1df0bd1ab787089eb088106e0.zip
ffmpeg plugin: latest api support (Closes issue 512)
git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@2535 90c681e8-e032-0410-971d-27865f9a5e38
Diffstat (limited to 'src/plugins/Input/ffmpeg/decoder_ffmpeg.cpp')
-rw-r--r--src/plugins/Input/ffmpeg/decoder_ffmpeg.cpp84
1 files changed, 48 insertions, 36 deletions
diff --git a/src/plugins/Input/ffmpeg/decoder_ffmpeg.cpp b/src/plugins/Input/ffmpeg/decoder_ffmpeg.cpp
index 31799fef6..9d62be278 100644
--- a/src/plugins/Input/ffmpeg/decoder_ffmpeg.cpp
+++ b/src/plugins/Input/ffmpeg/decoder_ffmpeg.cpp
@@ -65,17 +65,16 @@ DecoderFFmpeg::DecoderFFmpeg(const QString &path, QIODevice *i)
: Decoder(i)
{
m_bitrate = 0;
- m_skip = false;
m_totalTime = 0;
ic = 0;
m_path = path;
m_temp_pkt.size = 0;
m_pkt.size = 0;
m_pkt.data = 0;
- m_output_buf = 0;
m_output_at = 0;
m_skipBytes = 0;
m_stream = 0;
+ m_decoded_frame = 0;
av_init_packet(&m_pkt);
av_init_packet(&m_temp_pkt);
}
@@ -89,20 +88,23 @@ DecoderFFmpeg::~DecoderFFmpeg()
av_close_input_stream(ic);
if(m_pkt.data)
av_free_packet(&m_pkt);
- if(m_output_buf)
- av_free(m_output_buf);
if(m_stream)
av_free(m_stream);
+ if(m_decoded_frame)
+ av_free(m_decoded_frame);
}
bool DecoderFFmpeg::initialize()
{
m_bitrate = 0;
- m_skip = false;
m_totalTime = 0;
m_seekTime = -1;
+
+ avcodec_register_all();
+ avformat_network_init();
av_register_all();
+
AVProbeData pd;
uint8_t buf[PROBE_BUFFER_SIZE + AVPROBE_PADDING_SIZE];
pd.filename = m_path.toLocal8Bit().constData();
@@ -139,7 +141,7 @@ bool DecoderFFmpeg::initialize()
qDebug("DecoderFFmpeg: av_open_input_stream() failed");
return false;
}
- av_find_stream_info(ic);
+ avformat_find_stream_info(ic, 0);
if(ic->pb)
ic->pb->eof_reached = 0;
@@ -208,15 +210,15 @@ bool DecoderFFmpeg::initialize()
return false;
}
- if (avcodec_open(c, codec) < 0)
+ if (avcodec_open2(c, codec, 0) < 0)
{
qWarning("DecoderFFmpeg: error while opening codec for output stream");
return false;
}
- m_totalTime = input()->isSequential() ? 0 : ic->duration * 1000 / AV_TIME_BASE;
- m_output_buf = (uint8_t *)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE*2);
+ m_decoded_frame = avcodec_alloc_frame();
+ m_totalTime = input()->isSequential() ? 0 : ic->duration * 1000 / AV_TIME_BASE;
if(c->codec_id == CODEC_ID_SHORTEN) //ffmpeg bug workaround
m_totalTime = 0;
@@ -266,48 +268,55 @@ int DecoderFFmpeg::bitrate()
qint64 DecoderFFmpeg::read(char *audio, qint64 maxSize)
{
m_skipBytes = 0;
- if (m_skip)
- {
- while(m_temp_pkt.size)
- ffmpeg_decode(m_output_buf);
- m_output_at = 0;
- m_skip = false;
- }
+
if(!m_output_at)
fillBuffer();
if(!m_output_at)
return 0;
qint64 len = qMin(m_output_at, maxSize);
- memcpy(audio, m_output_buf, len);
+
+ memcpy(audio, m_decoded_frame->extended_data[0], len);
+
m_output_at -= len;
- memmove(m_output_buf, m_output_buf + len, m_output_at);
+ memmove(m_decoded_frame->extended_data[0], m_decoded_frame->extended_data[0] + len, m_output_at);
+
+ if(c->sample_fmt == AV_SAMPLE_FMT_FLT)
+ {
+ //convert float to signed 32 bit LE
+ for(int i = 0; i < len >> 2; i++)
+ {
+ int32_t *out = (int32_t *)audio;
+ float *in = (float *) audio;
+ out[i] = qBound(-1.0f, in[i], +1.0f) * (double) 0x7fffffff;
+ }
+ }
return len;
}
-qint64 DecoderFFmpeg::ffmpeg_decode(uint8_t *audio)
+qint64 DecoderFFmpeg::ffmpeg_decode()
{
- int out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE * 2;
+ int out_size = 0;
+ int got_frame = 0;
if((m_pkt.stream_index == wma_idx))
{
- int l = avcodec_decode_audio3(c, (int16_t *)(audio), &out_size, &m_temp_pkt);
+ avcodec_get_frame_defaults(m_decoded_frame);
- if(c->sample_fmt == AV_SAMPLE_FMT_FLT)
- {
- //convert float to signed 32 bit LE
- for(int i = 0; i < out_size >> 2; i++)
- {
- int32_t *out = (int32_t *)audio;
- float *in = (float *) audio;
- out[i] = qBound(-1.0f, in[i], +1.0f) * (double) 0x7fffffff;
- }
- }
+ int l = avcodec_decode_audio4(c, m_decoded_frame, &got_frame, &m_temp_pkt);
+
+ if(got_frame)
+ out_size = av_samples_get_buffer_size(0, c->channels, m_decoded_frame->nb_samples,
+ c->sample_fmt, 1);
+ else
+ out_size = 0;
if(c->bit_rate)
m_bitrate = c->bit_rate/1000;
if(l < 0)
+ {
return l;
+ }
m_temp_pkt.data += l;
m_temp_pkt.size -= l;
}
@@ -324,8 +333,9 @@ void DecoderFFmpeg::seek(qint64 pos)
timestamp += ic->start_time;
m_seekTime = timestamp;
av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD);
- if(m_pkt.size)
- m_skip = true;
+ avcodec_flush_buffers(c);
+ av_free_packet(&m_pkt);
+ m_temp_pkt.size = 0;
}
void DecoderFFmpeg::fillBuffer()
@@ -366,7 +376,7 @@ void DecoderFFmpeg::fillBuffer()
{
while (m_skipBytes > 0)
{
- m_output_at = ffmpeg_decode(m_output_buf);
+ m_output_at = ffmpeg_decode();
if(m_output_at < 0)
break;
m_skipBytes -= m_output_at;
@@ -377,12 +387,14 @@ void DecoderFFmpeg::fillBuffer()
qint64 size = m_output_at;
m_output_at = - m_skipBytes;
m_output_at = m_output_at/4*4;
- memmove(m_output_buf, (m_output_buf + size - m_output_at), m_output_at);
+ memmove(m_decoded_frame->data[0],
+ (m_decoded_frame->data[0] + size - m_output_at),
+ m_output_at);
m_skipBytes = 0;
}
}
else
- m_output_at = ffmpeg_decode(m_output_buf);
+ m_output_at = ffmpeg_decode();
if(m_output_at < 0)
{