diff options
| -rw-r--r-- | src/plugins/Input/ffmpeg/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/plugins/Input/ffmpeg/decoder_ffmpeg.cpp | 84 | ||||
| -rw-r--r-- | src/plugins/Input/ffmpeg/decoder_ffmpeg.h | 9 | ||||
| -rw-r--r-- | src/plugins/Input/ffmpeg/decoderffmpegfactory.cpp | 4 | ||||
| -rw-r--r-- | src/plugins/Input/ffmpeg/ffmpegmetadatamodel.cpp | 8 | ||||
| -rw-r--r-- | src/plugins/Input/ffmpeg/settingsdialog.cpp | 1 |
6 files changed, 58 insertions, 50 deletions
diff --git a/src/plugins/Input/ffmpeg/CMakeLists.txt b/src/plugins/Input/ffmpeg/CMakeLists.txt index 6090845a6..8ff6a2dfe 100644 --- a/src/plugins/Input/ffmpeg/CMakeLists.txt +++ b/src/plugins/Input/ffmpeg/CMakeLists.txt @@ -28,7 +28,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../) link_directories(${CMAKE_CURRENT_BINARY_DIR}/../../../qmmp) # ffmpeg -pkg_check_modules(FFMPEG libavcodec>=53.7.0 libavformat>=53.4.0 libavutil>=51.9.1) +pkg_check_modules(FFMPEG libavcodec>=53.25.0 libavformat>=53.24.0 libavutil>=51.32.0) include_directories(${FFMPEG_INCLUDE_DIRS}) link_directories(${FFMPEG_LIBRARY_DIRS}) 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) { diff --git a/src/plugins/Input/ffmpeg/decoder_ffmpeg.h b/src/plugins/Input/ffmpeg/decoder_ffmpeg.h index e5ec48a49..4c87fc291 100644 --- a/src/plugins/Input/ffmpeg/decoder_ffmpeg.h +++ b/src/plugins/Input/ffmpeg/decoder_ffmpeg.h @@ -48,26 +48,21 @@ public: private: //helper functions void fillBuffer(); - qint64 ffmpeg_decode(uint8_t *audio); + qint64 ffmpeg_decode(); AVFormatContext *ic; AVCodecContext *c; uint wma_st_buff, wma_idx2; int m_bitrate, wma_idx; QString m_path; - bool m_skip; qint64 m_totalTime; AVPacket m_pkt; AVPacket m_temp_pkt; -#if (LIBAVCODEC_VERSION_INT >= ((52<<16)+(102<<8)+0)) AVIOContext *m_stream; -#else - ByteIOContext *m_stream; -#endif + AVFrame *m_decoded_frame; - uint8_t *m_output_buf; qint64 m_output_at; uchar m_input_buf[INPUT_BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE]; diff --git a/src/plugins/Input/ffmpeg/decoderffmpegfactory.cpp b/src/plugins/Input/ffmpeg/decoderffmpegfactory.cpp index 153de7bdb..2febee48b 100644 --- a/src/plugins/Input/ffmpeg/decoderffmpegfactory.cpp +++ b/src/plugins/Input/ffmpeg/decoderffmpegfactory.cpp @@ -126,8 +126,8 @@ Decoder *DecoderFFmpegFactory::create(const QString &path, QIODevice *input) QList<FileInfo *> DecoderFFmpegFactory::createPlayList(const QString &fileName, bool useMetaData) { QList <FileInfo*> list; - avcodec_init(); avcodec_register_all(); + avformat_network_init(); av_register_all(); AVFormatContext *in = 0; @@ -137,7 +137,7 @@ QList<FileInfo *> DecoderFFmpegFactory::createPlayList(const QString &fileName, return list; } FileInfo *info = new FileInfo(fileName); - av_find_stream_info(in); + avformat_find_stream_info(in, 0); if (useMetaData) { diff --git a/src/plugins/Input/ffmpeg/ffmpegmetadatamodel.cpp b/src/plugins/Input/ffmpeg/ffmpegmetadatamodel.cpp index b8c9ff9eb..03ad49dfb 100644 --- a/src/plugins/Input/ffmpeg/ffmpegmetadatamodel.cpp +++ b/src/plugins/Input/ffmpeg/ffmpegmetadatamodel.cpp @@ -23,12 +23,14 @@ FFmpegMetaDataModel::FFmpegMetaDataModel(const QString &path, QObject *parent) : MetaDataModel(parent) { m_in = 0; - avcodec_init(); avcodec_register_all(); + avformat_network_init(); av_register_all(); + + if (avformat_open_input(&m_in, path.toLocal8Bit().constData(), 0, 0) < 0) return; - av_find_stream_info(m_in); + avformat_find_stream_info(m_in, 0); av_read_play(m_in); } @@ -46,7 +48,7 @@ QHash<QString, QString> FFmpegMetaDataModel::audioProperties() QString text = QString("%1").arg(int(m_in->duration/AV_TIME_BASE)/60); text +=":"+QString("%1").arg(int(m_in->duration/AV_TIME_BASE)%60,2,10,QChar('0')); ap.insert(tr("Length"), text); - ap.insert(tr("File size"), QString("%1 ").arg(m_in->file_size/1024)+" "+tr("KB")); + ap.insert(tr("File size"), QString("%1 ").arg(avio_size(m_in->pb)) + " " + tr("KB")); ap.insert(tr("Bitrate"), QString("%1 "+tr("kbps")).arg(m_in->bit_rate/1000)); AVCodecContext *c = 0; diff --git a/src/plugins/Input/ffmpeg/settingsdialog.cpp b/src/plugins/Input/ffmpeg/settingsdialog.cpp index 14cf5aa3c..4100b8d77 100644 --- a/src/plugins/Input/ffmpeg/settingsdialog.cpp +++ b/src/plugins/Input/ffmpeg/settingsdialog.cpp @@ -40,7 +40,6 @@ SettingsDialog::SettingsDialog(QWidget *parent) filters << "*.wma"; filters << "*.ape"; filters = settings.value("FFMPEG/filters", filters).toStringList(); - avcodec_init(); avcodec_register_all(); av_register_all(); ui.wmaCheckBox->setEnabled(avcodec_find_decoder(CODEC_ID_WMAV1)); |
