Fix metainfo processing, AAC decoding, some domestic code clearance

Initially code entirely taken and adopted from k3b upstream
1e09c7d77f
with subsequent fix of the read() function and reducing of the
compiler warnings.

Signed-off-by: Mashiro <m.t.0x73@gmail.com>
pull/8/head
Mashiro 4 years ago committed by Michele Calgaro
parent da0ee3a001
commit 095c3186b1
Signed by: MicheleC
GPG Key ID: 2A75B7CA8ADED5CF

@ -1,10 +1,10 @@
/* /*
* *
* $Id: k3bffmpegwrapper.cpp 641819 2007-03-12 17:29:23Z trueg $ *
* Copyright (C) 2004-2007 Sebastian Trueg <trueg@k3b.org> * Copyright (C) 2004-2008 Sebastian Trueg <trueg@k3b.org>
* *
* This file is part of the K3b project. * This file is part of the K3b project.
* Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org> * Copyright (C) 1998-2008 Sebastian Trueg <trueg@k3b.org>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -16,316 +16,274 @@
#include <config.h> #include <config.h>
#include "k3bffmpegwrapper.h" #include "k3bffmpegwrapper.h"
#include <tdelocale.h>
extern "C" { extern "C" {
/*
Recent versions of FFmpeg uses C99 constant macros which are not present in C++
standard. The macro __STDC_CONSTANT_MACROS allow C++ to use these macros.
Although it's not defined by C++ standard it's supported by many
implementations. See bug 236036 and discussion:
https://lists.ffmpeg.org/pipermail/ffmpeg-devel/2010-May/095488.html
*/
#define __STDC_CONSTANT_MACROS
#include <libavcodec/avcodec.h> #include <libavcodec/avcodec.h>
#include <libavformat/avformat.h> #include <libavformat/avformat.h>
} }
#include <math.h>
#include <string.h> #include <string.h>
#include <tdelocale.h> #define FFMPEG_CODEC(s) (s->codec)
#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 2, 0)
#if LIBAVFORMAT_BUILD < 4629 // this works because the parameters/options are not used
#define FFMPEG_BUILD_PRE_4629 #define avformat_open_input(c, s, f, o) av_open_input_file(c, s, f, 0, o)
#endif
#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(52, 101, 0)
#define av_dump_format(c, x, f, y) dump_format(c, x, f, y)
#endif
#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 6, 0)
#define avformat_find_stream_info(c, o) av_find_stream_info(c)
#endif
#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 17, 0)
#define avformat_close_input(c) av_close_input_file(*c)
#endif
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53, 8, 0)
#define avcodec_open2(a, c, o) avcodec_open(a, c)
#endif #endif
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52, 64, 0) #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52, 64, 0)
#define AVMEDIA_TYPE_AUDIO CODEC_TYPE_AUDIO #define AVMEDIA_TYPE_AUDIO CODEC_TYPE_AUDIO
#define AVMEDIA_TYPE_VIDEO CODEC_TYPE_VIDEO #define AVMEDIA_TYPE_VIDEO CODEC_TYPE_VIDEO
#define AVMEDIA_TYPE_SUBTITLE CODEC_TYPE_SUBTITLE #define AVMEDIA_TYPE_SUBTITLE CODEC_TYPE_SUBTITLE
#endif #endif
// From libavcodec version 54.25, CodecID have been renamed to AVCodecID and all
// From libavcodec version 54.25, CodecID have been renamed to AVCodecID and all CODEC_ID_* to AV_CODEC_ID_*. // CODEC_ID_* to AV_CODEC_ID_*. This code can be simplified once all supported
// This code can be simplified once all supported distros have updated to libavcodec version >=54.25 // distros have updated to libavcodec version >=54.25
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54, 25, 0) #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54, 25, 0)
#define K3B_CODEC_ID_WMAV1 CODEC_ID_WMAV1 #define AV_CODEC_ID_WMAV1 CODEC_ID_WMAV1
#define K3B_CODEC_ID_WMAV2 CODEC_ID_WMAV2 #define AV_CODEC_ID_WMAV2 CODEC_ID_WMAV2
#define K3B_CODEC_ID_MP3 CODEC_ID_MP3 #define AV_CODEC_ID_MP3 CODEC_ID_MP3
#define K3B_CODEC_ID_AAC CODEC_ID_AAC #define AV_CODEC_ID_AAC CODEC_ID_AAC
#else
#define K3B_CODEC_ID_WMAV1 AV_CODEC_ID_WMAV1
#define K3B_CODEC_ID_WMAV2 AV_CODEC_ID_WMAV2
#define K3B_CODEC_ID_MP3 AV_CODEC_ID_MP3
#define K3B_CODEC_ID_AAC AV_CODEC_ID_AAC
#endif #endif
// TODO: most of the used av_functions there are deprecated and there
// are troubles with improper frame/packet processing that
// leads to aborting of decode process
//
// [wmav2 @ 0xxxxx] Multiple frames in a packet.
// [wmav2 @ 0xxxxx] Got unexpected packet size after a partial decode
K3bFFMpegWrapper* K3bFFMpegWrapper::s_instance = 0; K3bFFMpegWrapper *K3bFFMpegWrapper::s_instance = nullptr;
class K3bFFMpegFile::Private class K3bFFMpegFile::Private {
{
public: public:
AVFormatContext* formatContext; TQ_UINT8 *packetData;
AVCodec* codec;
K3b::Msf length; K3b::Msf length;
// for decoding ::AVFormatContext *formatContext;
char outputBuffer[192000]; ::AVCodec *codec;
char* outputBufferPos; ::AVStream *audio_stream;
::AVSampleFormat sampleFormat;
::AVFrame *frame;
::AVPacket packet;
char *outputBufferPos = nullptr;
int outputBufferSize; int outputBufferSize;
AVPacket packet;
TQ_UINT8* packetData;
int packetSize; int packetSize;
bool isSpacious;
}; };
K3bFFMpegFile::K3bFFMpegFile(const TQString &filename) : m_filename(filename) {
K3bFFMpegFile::K3bFFMpegFile( const TQString& filename )
: m_filename(filename)
{
d = new Private; d = new Private;
d->formatContext = 0; d->formatContext = nullptr;
d->codec = 0; d->codec = nullptr;
d->audio_stream = nullptr;
d->frame = av_frame_alloc();
} }
K3bFFMpegFile::~K3bFFMpegFile() {
K3bFFMpegFile::~K3bFFMpegFile()
{
close(); close();
av_frame_free(&d->frame);
delete d; delete d;
} }
bool K3bFFMpegFile::open() {
bool K3bFFMpegFile::open()
{
close(); close();
// open the file // open the file
# if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53, 2, 0) int err = ::avformat_open_input(&d->formatContext, m_filename.local8Bit(),
int err = avformat_open_input( &d->formatContext, m_filename.local8Bit(), 0, 0); nullptr, nullptr);
# else if (err < 0) {
int err = av_open_input_file( &d->formatContext, m_filename.local8Bit(), 0, 0, 0); kdDebug() << "(K3bFFMpegFile) unable to open " << m_filename
# endif << " with error " << err;
if( err < 0 ) {
kdDebug() << "(K3bFFMpegFile) unable to open " << m_filename << " with error " << err << endl;
return false; return false;
} }
// analyze the streams // analyze the streams
# if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53, 6, 0) ::avformat_find_stream_info(d->formatContext, nullptr);
avformat_find_stream_info( d->formatContext, NULL );
# else
av_find_stream_info( d->formatContext );
# endif
// we only handle files containing one audio stream // we only handle files containing one audio stream
if( d->formatContext->nb_streams != 1 ) { for (uint i = 0; i < d->formatContext->nb_streams; ++i) {
kdDebug() << "(K3bFFMpegFile) more than one stream in " << m_filename << endl; if (d->formatContext->streams[i]->codecpar->codec_type ==
return false; AVMEDIA_TYPE_AUDIO) {
if (!d->audio_stream) {
d->audio_stream = d->formatContext->streams[i];
} else {
d->audio_stream = nullptr;
kdDebug() << "(K3bFFMpegFile) more than one audio stream in "
<< m_filename;
return false;
}
}
} }
// urgh... ugly // urgh... ugly
#ifdef FFMPEG_BUILD_PRE_4629 ::AVCodecContext *codecContext = FFMPEG_CODEC(d->audio_stream);
AVCodecContext* codecContext = &d->formatContext->streams[0]->codec; if (codecContext->codec_type != AVMEDIA_TYPE_AUDIO) {
#else kdDebug() << "(K3bFFMpegFile) not a simple audio stream: " << m_filename;
AVCodecContext* codecContext = d->formatContext->streams[0]->codec;
#endif
if( codecContext->codec_type != AVMEDIA_TYPE_AUDIO ) {
kdDebug() << "(K3bFFMpegFile) not a simple audio stream: " << m_filename << endl;
return false; return false;
} }
// get the codec // get the codec
d->codec = avcodec_find_decoder(codecContext->codec_id); d->codec = ::avcodec_find_decoder(codecContext->codec_id);
if( !d->codec ) { if (!d->codec) {
kdDebug() << "(K3bFFMpegFile) no codec found for " << m_filename << endl; kdDebug() << "(K3bFFMpegFile) no codec found for " << m_filename;
return false; return false;
} }
// open the codec on our context // open the codec on our context
kdDebug() << "(K3bFFMpegFile) found codec for " << m_filename << endl; kdDebug() << "(K3bFFMpegFile) found codec for " << m_filename;
if( if (::avcodec_open2(codecContext, d->codec, nullptr) < 0) {
# if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53, 8, 0) kdDebug() << "(K3bFFMpegDecoderFactory) could not open codec.";
avcodec_open2( codecContext, d->codec, NULL ) < 0
# else
avcodec_open( codecContext, d->codec ) < 0
# endif
) {
kdDebug() << "(K3bFFMpegDecoderFactory) could not open codec." << endl;
return false; return false;
} }
// determine the length of the stream // determine the length of the stream
d->length = K3b::Msf::fromSeconds( (double)d->formatContext->duration / (double)AV_TIME_BASE ); d->length = K3b::Msf::fromSeconds(double(d->formatContext->duration) /
double(AV_TIME_BASE));
if( d->length == 0 ) { if (d->length == 0) {
kdDebug() << "(K3bFFMpegDecoderFactory) invalid length." << endl; kdDebug() << "(K3bFFMpegDecoderFactory) invalid length.";
return false; return false;
} }
d->sampleFormat =
static_cast<::AVSampleFormat>(d->audio_stream->codecpar->format);
d->isSpacious = ::av_sample_fmt_is_planar(d->sampleFormat) &&
d->audio_stream->codecpar->channels > 1;
// dump some debugging info // dump some debugging info
# if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(52, 101, 0) ::av_dump_format(d->formatContext, 0, m_filename.local8Bit(), 0);
av_dump_format( d->formatContext, 0, m_filename.local8Bit(), 0 );
# else
dump_format( d->formatContext, 0, m_filename.local8Bit(), 0 );
# endif
return true; return true;
} }
void K3bFFMpegFile::close() {
void K3bFFMpegFile::close()
{
d->outputBufferSize = 0; d->outputBufferSize = 0;
d->packetSize = 0; d->packetSize = 0;
d->packetData = 0; d->packetData = nullptr;
if( d->codec ) { if (d->codec) {
#ifdef FFMPEG_BUILD_PRE_4629 ::avcodec_close(FFMPEG_CODEC(d->audio_stream));
avcodec_close( &d->formatContext->streams[0]->codec ); d->codec = nullptr;
#else
avcodec_close( d->formatContext->streams[0]->codec );
#endif
d->codec = 0;
} }
if( d->formatContext ) { if (d->formatContext) {
# if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53, 17, 0) ::avformat_close_input(&d->formatContext);
avformat_close_input( &d->formatContext ); d->formatContext = nullptr;
# else
av_close_input_file( d->formatContext );
# endif
d->formatContext = 0;
} }
}
K3b::Msf K3bFFMpegFile::length() const d->audio_stream = nullptr;
{
return d->length;
} }
K3b::Msf K3bFFMpegFile::length() const { return d->length; }
int K3bFFMpegFile::sampleRate() const int K3bFFMpegFile::sampleRate() const {
{ return d->audio_stream->codecpar->sample_rate;
#ifdef FFMPEG_BUILD_PRE_4629
return d->formatContext->streams[0]->codec.sample_rate;
#else
return d->formatContext->streams[0]->codec->sample_rate;
#endif
}
int K3bFFMpegFile::channels() const
{
#ifdef FFMPEG_BUILD_PRE_4629
return d->formatContext->streams[0]->codec.channels;
#else
return d->formatContext->streams[0]->codec->channels;
#endif
} }
int K3bFFMpegFile::channels() const {
int K3bFFMpegFile::type() const return d->audio_stream->codecpar->channels;
{
#ifdef FFMPEG_BUILD_PRE_4629
return d->formatContext->streams[0]->codec.codec_id;
#else
return d->formatContext->streams[0]->codec->codec_id;
#endif
} }
int K3bFFMpegFile::type() const { return d->audio_stream->codecpar->codec_id; }
TQString K3bFFMpegFile::typeComment() const TQString K3bFFMpegFile::typeComment() const {
{ switch (type()) {
switch( type() ) { case AV_CODEC_ID_WMAV1:
case K3B_CODEC_ID_WMAV1:
return i18n("Windows Media v1"); return i18n("Windows Media v1");
case K3B_CODEC_ID_WMAV2: case AV_CODEC_ID_WMAV2:
return i18n("Windows Media v2"); return i18n("Windows Media v2");
case K3B_CODEC_ID_MP3: case AV_CODEC_ID_WAVPACK:
return i18n("MPEG 1 Layer III"); return i18n("WavPack");
case K3B_CODEC_ID_AAC: case AV_CODEC_ID_APE:
return i18n("Monkey's Audio (APE)");
case AV_CODEC_ID_AAC:
return i18n("Advanced Audio Coding (AAC)"); return i18n("Advanced Audio Coding (AAC)");
default: default:
return TQString::fromLocal8Bit( d->codec->name ); return TQString::fromLocal8Bit(d->codec->name);
} }
} }
TQString K3bFFMpegFile::title() const {
TQString K3bFFMpegFile::title() const
{
// FIXME: is this UTF8 or something?? // FIXME: is this UTF8 or something??
#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 2, 0) AVDictionaryEntry *ade =
if( d->formatContext->title[0] != '\0' ) av_dict_get(d->formatContext->metadata, "TITLE", nullptr, 0);
return TQString::fromLocal8Bit( d->formatContext->title ); return ade && ade->value && ade->value[0] != '\0'
#else ? TQString::fromLocal8Bit(ade->value)
AVDictionaryEntry *entry = av_dict_get(d->formatContext->metadata, "title", NULL, 0); : TQString();
if( entry->value[0] != '\0' )
return TQString::fromLocal8Bit( entry->value );
#endif
else
return TQString();
} }
TQString K3bFFMpegFile::author() const {
TQString K3bFFMpegFile::author() const
{
// FIXME: is this UTF8 or something?? // FIXME: is this UTF8 or something??
#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 2, 0) AVDictionaryEntry *ade =
if( d->formatContext->author[0] != '\0' ) av_dict_get(d->formatContext->metadata, "ARTIST", nullptr, 0);
return TQString::fromLocal8Bit( d->formatContext->author ); return ade && ade->value && ade->value[0] != '\0'
#else ? TQString::fromLocal8Bit(ade->value)
AVDictionaryEntry *entry = av_dict_get(d->formatContext->metadata, "author", NULL, 0); : TQString();
if( entry->value[0] != '\0' )
return TQString::fromLocal8Bit( entry->value );
#endif
else
return TQString();
} }
TQString K3bFFMpegFile::comment() const {
TQString K3bFFMpegFile::comment() const
{
// FIXME: is this UTF8 or something?? // FIXME: is this UTF8 or something??
#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 2, 0) AVDictionaryEntry *ade =
if( d->formatContext->comment[0] != '\0' ) av_dict_get(d->formatContext->metadata, "COMMENT", nullptr, 0);
return TQString::fromLocal8Bit( d->formatContext->comment ); return ade && ade->value && ade->value[0] != '\0'
#else ? TQString::fromLocal8Bit(ade->value)
AVDictionaryEntry *entry = av_dict_get(d->formatContext->metadata, "comment", NULL, 0); : TQString();
if( entry->value[0] != '\0' )
return TQString::fromLocal8Bit( entry->value );
#endif
else
return TQString();
} }
int K3bFFMpegFile::read(char *buf, int bufLen) {
int K3bFFMpegFile::read( char* buf, int bufLen ) int ret = fillOutputBuffer();
{ if (ret <= 0) {
if( fillOutputBuffer() > 0 ) { return ret;
int len = TQMIN(bufLen, d->outputBufferSize); }
::memcpy( buf, d->outputBufferPos, len );
// TODO: only swap if needed int len = TQMIN(bufLen, d->outputBufferSize);
for( int i = 0; i < len-1; i+=2 ) { ::memcpy(buf, d->outputBufferPos, len);
char a = buf[i];
buf[i] = buf[i+1]; if (d->isSpacious && bufLen > d->outputBufferSize)
buf[i+1] = a; delete[] d->outputBufferPos; // clean up allocated space
}
// TODO: only swap if needed
for (int i = 0; i < len - 1; i += 2)
tqSwap(buf[i], buf[i + 1]); // BE -> LE
d->outputBufferSize -= len;
if (d->outputBufferSize > 0)
d->outputBufferPos += len; d->outputBufferPos += len;
d->outputBufferSize -= len; return len;
return len;
}
else
return 0;
} }
// fill d->packetData with data to decode // fill d->packetData with data to decode
int K3bFFMpegFile::readPacket() int K3bFFMpegFile::readPacket() {
{ if (d->packetSize <= 0) {
if( d->packetSize <= 0 ) { ::av_init_packet(&d->packet);
av_init_packet( &d->packet );
if( av_read_frame( d->formatContext, &d->packet ) < 0 ) { if (::av_read_frame(d->formatContext, &d->packet) < 0) {
return 0; return 0;
} }
d->packetSize = d->packet.size; d->packetSize = d->packet.size;
d->packetData = d->packet.data; d->packetData = d->packet.data;
} }
@ -333,119 +291,107 @@ int K3bFFMpegFile::readPacket()
return d->packetSize; return d->packetSize;
} }
// decode data in d->packetData and fill d->outputBuffer // decode data in d->packetData and fill d->outputBuffer
int K3bFFMpegFile::fillOutputBuffer() int K3bFFMpegFile::fillOutputBuffer() {
{
// decode if the output buffer is empty // decode if the output buffer is empty
if( d->outputBufferSize <= 0 ) { while (d->outputBufferSize <= 0) {
// make sure we have data to decode // make sure we have data to decode
if( readPacket() == 0 ) { if (readPacket() == 0) {
return 0; return 0;
} }
d->outputBufferPos = d->outputBuffer; int gotFrame = 0;
int len = ::avcodec_decode_audio4(FFMPEG_CODEC(d->audio_stream), d->frame,
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52, 64, 0) &gotFrame, &d->packet);
AVPacket avp;
av_init_packet( &avp ); if (d->packetSize <= 0 || len < 0)
avp.data = d->packetData; ::av_packet_unref(&d->packet);
avp.size = d->packetSize; if (len < 0) {
# if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53, 25, 0) kdDebug() << "(K3bFFMpegFile) decoding failed for " << m_filename;
int len = avcodec_decode_audio4( d->formatContext->streams[0]->codec, return -1;
(AVFrame*)d->outputBuffer, &d->outputBufferSize, }
&avp );
# else
int len = avcodec_decode_audio3( d->formatContext->streams[0]->codec,
(short*)d->outputBuffer, &d->outputBufferSize,
&avp );
# endif
#else
#ifdef FFMPEG_BUILD_PRE_4629
int len = avcodec_decode_audio2( &d->formatContext->streams[0]->codec,
#else
int len = avcodec_decode_audio2( d->formatContext->streams[0]->codec,
#endif
(short*)d->outputBuffer, &d->outputBufferSize,
d->packetData, d->packetSize );
#endif
if (gotFrame) {
int nb_s = d->frame->nb_samples;
int nb_ch = 2; // copy only two channels even if there're more
d->outputBufferSize = nb_s * nb_ch * 2; // 2 means 2 bytes (16bit)
d->outputBufferPos = reinterpret_cast<char *>(d->frame->extended_data[0]);
if (d->isSpacious) {
d->outputBufferPos = new char[d->outputBufferSize];
if (d->sampleFormat == AV_SAMPLE_FMT_FLTP) {
int width = sizeof(float); // sample width of float audio
for (int sample = 0; sample < nb_s; sample++) {
for (int ch = 0; ch < nb_ch; ch++) {
double val = *(reinterpret_cast<float *>(
d->frame->extended_data[ch] + sample * width));
val = ::abs(val) > 1 ? ::copysign(1.0, val) : val;
int16_t result =
static_cast<int16_t>(val * 32767.0 + 32768.5) - 32768;
::memcpy(d->outputBufferPos + (sample * nb_ch + ch) * 2, &result,
2); // 2 is sample width of 16 bit audio
}
}
} else {
for (int sample = 0; sample < nb_s; sample++) {
for (int ch = 0; ch < nb_ch; ch++) {
::memcpy(d->outputBufferPos + (sample * nb_ch + ch) * 2,
d->frame->extended_data[ch] + sample * 2,
2); // 16 bit here as well
}
}
}
}
}
d->packetSize -= len; d->packetSize -= len;
d->packetData += len; d->packetData += len;
if( d->packetSize <= 0 )
av_free_packet( &d->packet );
} }
// if it is still empty try again return d->outputBufferSize;
if( d->outputBufferSize <= 0 )
return fillOutputBuffer();
else
return d->outputBufferSize;
} }
bool K3bFFMpegFile::seek(const K3b::Msf &msf) {
bool K3bFFMpegFile::seek( const K3b::Msf& msf )
{
d->outputBufferSize = 0; d->outputBufferSize = 0;
d->packetSize = 0; d->packetSize = 0;
double seconds = (double)msf.totalFrames()/75.0; double seconds = double(msf.totalFrames()) / 75.0;
TQ_UINT64 timestamp = (TQ_UINT64)(seconds * (double)AV_TIME_BASE); int64_t timestamp = static_cast<int64_t>(seconds * double(AV_TIME_BASE));
// FIXME: do we really need the start_time and why? // FIXME: do we really need the start_time and why?
#if LIBAVFORMAT_BUILD >= 4619 return (::av_seek_frame(d->formatContext, -1,
return ( av_seek_frame( d->formatContext, -1, timestamp + d->formatContext->start_time, 0 ) >= 0 ); timestamp + d->formatContext->start_time, 0) >= 0);
#else
return ( av_seek_frame( d->formatContext, -1, timestamp + d->formatContext->start_time ) >= 0 );
#endif
} }
//
// av_register_all is deprecated since ffmpeg 4.0, can be dropped
K3bFFMpegWrapper::K3bFFMpegWrapper() { ::av_register_all(); }
K3bFFMpegWrapper::~K3bFFMpegWrapper() { s_instance = nullptr; }
K3bFFMpegWrapper *K3bFFMpegWrapper::instance() {
if (!s_instance) {
K3bFFMpegWrapper::K3bFFMpegWrapper()
{
av_register_all();
}
K3bFFMpegWrapper::~K3bFFMpegWrapper()
{
s_instance = 0;
}
K3bFFMpegWrapper* K3bFFMpegWrapper::instance()
{
if( !s_instance ) {
s_instance = new K3bFFMpegWrapper(); s_instance = new K3bFFMpegWrapper();
} }
return s_instance; return s_instance;
} }
K3bFFMpegFile *K3bFFMpegWrapper::open(const TQString &filename) const {
K3bFFMpegFile* K3bFFMpegWrapper::open( const TQString& filename ) const K3bFFMpegFile *file = new K3bFFMpegFile(filename);
{ if (file->open()) {
K3bFFMpegFile* file = new K3bFFMpegFile( filename );
if( file->open() ) {
#ifndef K3B_FFMPEG_ALL_CODECS #ifndef K3B_FFMPEG_ALL_CODECS
// //
// only allow tested formats. ffmpeg seems not to be too reliable with every format. // only allow tested formats. ffmpeg seems not to be too reliable with every
// mp3 being one of them sadly. Most importantly: allow the libsndfile decoder to do // format. mp3 being one of them sadly. Most importantly: allow the
// its thing. // libsndfile decoder to do its thing.
// //
if( file->type() == K3B_CODEC_ID_WMAV1 || if (file->type() == AV_CODEC_ID_WMAV1 ||
file->type() == K3B_CODEC_ID_WMAV2 || file->type() == AV_CODEC_ID_WMAV2 || file->type() == AV_CODEC_ID_AAC ||
file->type() == K3B_CODEC_ID_AAC ) file->type() == AV_CODEC_ID_APE || file->type() == AV_CODEC_ID_WAVPACK)
#endif #endif
return file; return file;
} }
delete file; delete file;
return 0; return nullptr;
} }

Loading…
Cancel
Save