4
* Copyright (C) 2004-2008 Sebastian Trueg <trueg@k3b.org>
6
* This file is part of the K3b project.
7
* Copyright (C) 1998-2008 Sebastian Trueg <trueg@k3b.org>
9
* This program is free software; you can redistribute it and/or modify
10
* it under the terms of the GNU General Public License as published by
11
* the Free Software Foundation; either version 2 of the License, or
12
* (at your option) any later version.
13
* See the file "COPYING" for the exact licensing terms.
15
#include "k3bffmpegwrapper.h"
17
#include <config-k3b.h>
21
Recent versions of FFmepg uses C99 constant macros which are not presebt in C++ standard.
22
The macro __STDC_CONSTANT_MACROS allow C++ to use these macros. Altough it's not defined by C++ standard
23
it's supported by many implementations.
24
See bug 236036 and discussion: http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/2010-May/088074.html
26
#define __STDC_CONSTANT_MACROS
27
#ifdef NEWFFMPEGAVCODECPATH
28
#include <libavcodec/avcodec.h>
29
#include <libavformat/avformat.h>
31
#include <ffmpeg/avcodec.h>
32
#include <ffmpeg/avformat.h>
41
#if LIBAVFORMAT_BUILD < 4629
42
#define FFMPEG_BUILD_PRE_4629
46
K3bFFMpegWrapper* K3bFFMpegWrapper::s_instance = 0;
49
class K3bFFMpegFile::Private
52
::AVFormatContext* formatContext;
57
// for decoding. ffmpeg requires 16-byte alignment.
58
char outputBuffer[AVCODEC_MAX_AUDIO_FRAME_SIZE + 15];
59
char* alignedOutputBuffer;
60
char* outputBufferPos;
68
K3bFFMpegFile::K3bFFMpegFile( const QString& filename )
69
: m_filename(filename)
74
int offset = 0x10 - (reinterpret_cast<intptr_t>(&d->outputBuffer) & 0xf);
75
d->alignedOutputBuffer = &d->outputBuffer[offset];
79
K3bFFMpegFile::~K3bFFMpegFile()
86
bool K3bFFMpegFile::open()
91
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53,2,0)
92
int err = ::avformat_open_input( &d->formatContext, m_filename.toLocal8Bit(), 0, 0 );
94
int err = ::av_open_input_file( &d->formatContext, m_filename.toLocal8Bit(), 0, 0, 0 );
97
kDebug() << "(K3bFFMpegFile) unable to open " << m_filename << " with error " << err;
101
// analyze the streams
102
::av_find_stream_info( d->formatContext );
104
// we only handle files containing one audio stream
105
if( d->formatContext->nb_streams != 1 ) {
106
kDebug() << "(K3bFFMpegFile) more than one stream in " << m_filename;
111
#ifdef FFMPEG_BUILD_PRE_4629
112
::AVCodecContext* codecContext = &d->formatContext->streams[0]->codec;
114
::AVCodecContext* codecContext = d->formatContext->streams[0]->codec;
116
if( codecContext->codec_type !=
117
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52, 64, 0)
123
kDebug() << "(K3bFFMpegFile) not a simple audio stream: " << m_filename;
128
d->codec = ::avcodec_find_decoder(codecContext->codec_id);
130
kDebug() << "(K3bFFMpegFile) no codec found for " << m_filename;
134
// open the codec on our context
135
kDebug() << "(K3bFFMpegFile) found codec for " << m_filename;
136
if( ::avcodec_open( codecContext, d->codec ) < 0 ) {
137
kDebug() << "(K3bFFMpegDecoderFactory) could not open codec.";
141
// determine the length of the stream
142
d->length = K3b::Msf::fromSeconds( (double)d->formatContext->duration / (double)AV_TIME_BASE );
144
if( d->length == 0 ) {
145
kDebug() << "(K3bFFMpegDecoderFactory) invalid length.";
149
// dump some debugging info
150
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53,2,0)
151
::av_dump_format( d->formatContext, 0, m_filename.toLocal8Bit(), 0 );
153
::dump_format( d->formatContext, 0, m_filename.toLocal8Bit(), 0 );
160
void K3bFFMpegFile::close()
162
d->outputBufferSize = 0;
167
#ifdef FFMPEG_BUILD_PRE_4629
168
::avcodec_close( &d->formatContext->streams[0]->codec );
170
::avcodec_close( d->formatContext->streams[0]->codec );
175
if( d->formatContext ) {
176
::av_close_input_file( d->formatContext );
177
d->formatContext = 0;
182
K3b::Msf K3bFFMpegFile::length() const
188
int K3bFFMpegFile::sampleRate() const
190
#ifdef FFMPEG_BUILD_PRE_4629
191
return d->formatContext->streams[0]->codec.sample_rate;
193
return d->formatContext->streams[0]->codec->sample_rate;
198
int K3bFFMpegFile::channels() const
200
#ifdef FFMPEG_BUILD_PRE_4629
201
return d->formatContext->streams[0]->codec.channels;
203
return d->formatContext->streams[0]->codec->channels;
208
int K3bFFMpegFile::type() const
210
#ifdef FFMPEG_BUILD_PRE_4629
211
return d->formatContext->streams[0]->codec.codec_id;
213
return d->formatContext->streams[0]->codec->codec_id;
218
QString K3bFFMpegFile::typeComment() const
222
return i18n("Windows Media v1");
224
return i18n("Windows Media v2");
225
#if LIBAVCODEC_VERSION_MAJOR < 52
226
case CODEC_ID_MP3LAME:
230
return i18n("MPEG 1 Layer III");
232
return i18n("Advanced Audio Coding (AAC)");
234
return QString::fromLocal8Bit( d->codec->name );
239
QString K3bFFMpegFile::title() const
241
// FIXME: is this UTF8 or something??
242
AVDictionaryEntry *ade = av_dict_get( d->formatContext->metadata, "TITLE", NULL, 0 );
245
if( ade->value != '\0' )
246
return QString::fromLocal8Bit( ade->value );
252
QString K3bFFMpegFile::author() const
254
// FIXME: is this UTF8 or something??
255
AVDictionaryEntry *ade = av_dict_get( d->formatContext->metadata, "ARTIST", NULL, 0 );
258
if( ade->value != '\0' )
259
return QString::fromLocal8Bit( ade->value );
265
QString K3bFFMpegFile::comment() const
267
// FIXME: is this UTF8 or something??
268
AVDictionaryEntry *ade = av_dict_get( d->formatContext->metadata, "COMMENT", NULL, 0 );
271
if( ade->value != '\0' )
272
return QString::fromLocal8Bit( ade->value );
278
int K3bFFMpegFile::read( char* buf, int bufLen )
280
int ret = fillOutputBuffer();
285
int len = qMin(bufLen, d->outputBufferSize);
286
::memcpy( buf, d->outputBufferPos, len );
288
// TODO: only swap if needed
289
for( int i = 0; i < len-1; i+=2 ) {
295
d->outputBufferPos += len;
296
d->outputBufferSize -= len;
301
// fill d->packetData with data to decode
302
int K3bFFMpegFile::readPacket()
304
if( d->packetSize <= 0 ) {
305
::av_init_packet( &d->packet );
307
if( ::av_read_frame( d->formatContext, &d->packet ) < 0 ) {
310
d->packetSize = d->packet.size;
311
d->packetData = d->packet.data;
314
return d->packetSize;
318
// decode data in d->packetData and fill d->outputBuffer
319
int K3bFFMpegFile::fillOutputBuffer()
321
// decode if the output buffer is empty
322
if( d->outputBufferSize <= 0 ) {
324
// make sure we have data to decode
325
if( readPacket() == 0 ) {
329
d->outputBufferPos = d->alignedOutputBuffer;
330
d->outputBufferSize = AVCODEC_MAX_AUDIO_FRAME_SIZE;
332
#if LIBAVCODEC_VERSION_MAJOR < 52
333
int len = ::avcodec_decode_audio(
335
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52, 64, 0)
336
int len = ::avcodec_decode_audio3(
338
int len = ::avcodec_decode_audio2(
342
#ifdef FFMPEG_BUILD_PRE_4629
343
&d->formatContext->streams[0]->codec,
345
d->formatContext->streams[0]->codec,
347
(short*)d->alignedOutputBuffer,
348
&d->outputBufferSize,
349
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52, 64, 0)
352
d->packetData, d->packetSize );
355
if( d->packetSize <= 0 || len < 0 )
356
::av_free_packet( &d->packet );
358
kDebug() << "(K3bFFMpegFile) decoding failed for " << m_filename;
362
d->packetSize -= len;
363
d->packetData += len;
366
// if it is still empty try again
367
if( d->outputBufferSize <= 0 )
368
return fillOutputBuffer();
370
return d->outputBufferSize;
374
bool K3bFFMpegFile::seek( const K3b::Msf& msf )
376
d->outputBufferSize = 0;
379
double seconds = (double)msf.totalFrames()/75.0;
380
quint64 timestamp = (quint64)(seconds * (double)AV_TIME_BASE);
382
// FIXME: do we really need the start_time and why?
383
#if LIBAVFORMAT_BUILD >= 4619
384
return ( ::av_seek_frame( d->formatContext, -1, timestamp + d->formatContext->start_time, 0 ) >= 0 );
386
return ( ::av_seek_frame( d->formatContext, -1, timestamp + d->formatContext->start_time ) >= 0 );
395
K3bFFMpegWrapper::K3bFFMpegWrapper()
401
K3bFFMpegWrapper::~K3bFFMpegWrapper()
407
K3bFFMpegWrapper* K3bFFMpegWrapper::instance()
410
s_instance = new K3bFFMpegWrapper();
417
K3bFFMpegFile* K3bFFMpegWrapper::open( const QString& filename ) const
419
K3bFFMpegFile* file = new K3bFFMpegFile( filename );
421
#ifndef K3B_FFMPEG_ALL_CODECS
423
// only allow tested formats. ffmpeg seems not to be too reliable with every format.
424
// mp3 being one of them sadly. Most importantly: allow the libsndfile decoder to do
427
if( file->type() == CODEC_ID_WMAV1 ||
428
file->type() == CODEC_ID_WMAV2 ||
429
file->type() == CODEC_ID_AAC )