2
* Chromaprint -- Audio fingerprinting toolkit
3
* Copyright (C) 2010 Lukas Lalinsky <lalinsky@gmail.com>
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Lesser General Public
7
* License as published by the Free Software Foundation; either
8
* version 2.1 of the License, or (at your option) any later version.
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Lesser General Public License for more details.
15
* You should have received a copy of the GNU Lesser General Public
16
* License along with this library; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
21
#ifndef FPSUBMIT_DECODER_H_
22
#define FPSUBMIT_DECODER_H_
29
#include <libavcodec/avcodec.h>
30
#include <libavformat/avformat.h>
32
#define NEW_AVFRAME_API (LIBAVCODEC_VERSION_MAJOR >= 55)
34
#include <libavutil/frame.h>
37
#ifdef HAVE_AV_AUDIO_CONVERT
38
#include "ffmpeg/audioconvert.h"
39
#include "ffmpeg/samplefmt.h"
42
#include "fingerprintcalculator.h"
47
Decoder(const std::string &fileName);
51
void Decode(FingerprintCalculator *consumer, int maxLength = 0);
55
return m_codec_ctx->channels;
60
return m_codec_ctx->sample_rate;
63
std::string LastError()
68
//static void lock_manager();
69
static void initialize();
73
std::string m_file_name;
75
AVFormatContext *m_format_ctx;
76
AVCodecContext *m_codec_ctx;
79
static QMutex m_mutex;
81
#ifdef HAVE_AV_AUDIO_CONVERT
82
AVAudioConvert *m_convert_ctx;
86
/*inline static void Decoder::lock_manager(void **mutex, enum AVLockOp op)
90
*mutex = new QMutex();
93
delete (QMutex *)(*mutex);
96
((QMutex *)(*mutex))->lock();
99
((QMutex *)(*mutex))->unlock();
105
inline void Decoder::initialize()
108
av_log_set_level(AV_LOG_ERROR);
109
//av_lockmgr_register(&Decoder::lock_manager)
112
inline Decoder::Decoder(const std::string &file_name)
113
: m_file_name(file_name), m_format_ctx(0), m_codec_ctx(0), m_stream(0), m_codec_open(false)
114
#ifdef HAVE_AV_AUDIO_CONVERT
118
#ifdef HAVE_AV_AUDIO_CONVERT
119
m_buffer2 = (uint8_t *)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE * 2 + 16);
123
m_frame = av_frame_alloc();
125
m_frame = avcodec_alloc_frame();
129
inline Decoder::~Decoder()
131
if (m_codec_ctx && m_codec_open) {
132
QMutexLocker locker(&m_mutex);
133
avcodec_close(m_codec_ctx);
136
avformat_close_input(&m_format_ctx);
138
#ifdef HAVE_AV_AUDIO_CONVERT
140
av_audio_convert_free(m_convert_ctx);
146
av_frame_free(&m_frame);
152
inline bool Decoder::Open()
154
QMutexLocker locker(&m_mutex);
156
if (avformat_open_input(&m_format_ctx, m_file_name.c_str(), NULL, NULL) != 0) {
157
m_error = "Couldn't open the file." + m_file_name;
161
if (avformat_find_stream_info(m_format_ctx, NULL) < 0) {
162
m_error = "Couldn't find stream information in the file.";
166
//dump_format(m_format_ctx, 0, m_file_name.c_str(), 0);
168
for (int i = 0; i < m_format_ctx->nb_streams; i++) {
169
AVCodecContext *avctx = m_format_ctx->streams[i]->codec;
170
if (avctx && avctx->codec_type == AVMEDIA_TYPE_AUDIO) {
171
m_stream = m_format_ctx->streams[i];
177
m_error = "Couldn't find any audio stream in the file.";
181
AVCodec *codec = avcodec_find_decoder(m_codec_ctx->codec_id);
183
m_error = "Unknown codec.";
187
if (avcodec_open2(m_codec_ctx, codec, NULL) < 0) {
188
m_error = "Couldn't open the codec.";
193
if (m_codec_ctx->sample_fmt != AV_SAMPLE_FMT_S16) {
194
#ifdef HAVE_AV_AUDIO_CONVERT
195
m_convert_ctx = av_audio_convert_alloc(AV_SAMPLE_FMT_S16, m_codec_ctx->channels,
196
(AVSampleFormat)m_codec_ctx->sample_fmt, m_codec_ctx->channels, NULL, 0);
197
if (!m_convert_ctx) {
198
m_error = "Couldn't create sample format converter.";
202
m_error = "Unsupported sample format.";
207
if (Channels() <= 0) {
208
m_error = "Invalid audio stream (no channels).";
212
if (SampleRate() <= 0) {
213
m_error = "Invalid sample rate.";
222
inline void Decoder::Decode(FingerprintCalculator *consumer, int max_length)
224
AVPacket packet, packet_temp;
226
int remaining = max_length * SampleRate() * Channels();
229
av_init_packet(&packet);
230
av_init_packet(&packet_temp);
232
if (av_read_frame(m_format_ctx, &packet) < 0) {
233
// consumer->Flush();
237
packet_temp.data = packet.data;
238
packet_temp.size = packet.size;
239
while (packet_temp.size > 0) {
241
int consumed = avcodec_decode_audio4(m_codec_ctx, m_frame,
242
&got_output, &packet_temp);
247
packet_temp.data += consumed;
248
packet_temp.size -= consumed;
254
int16_t *audio_buffer;
255
#ifdef HAVE_AV_AUDIO_CONVERT
257
const void *ibuf[6] = { m_frame->data[0] };
258
void *obuf[6] = { m_buffer2 };
259
int istride[6] = { av_get_bytes_per_sample(m_codec_ctx->sample_fmt) };
260
int ostride[6] = { 2 };
261
int len = m_frame->nb_samples;
262
if (av_audio_convert(m_convert_ctx, obuf, ostride, ibuf, istride, len) < 0) {
265
audio_buffer = (int16_t *)m_buffer2;
268
audio_buffer = (int16_t *)m_frame->data[0];
271
audio_buffer = (int16_t *)m_frame->data[0];
274
int length = m_frame->nb_samples;
276
length = std::min(remaining, length);
279
consumer->feed(audio_buffer, length);
283
if (remaining <= 0) {
291
av_free_packet(&packet);