@ -1,10 +1,10 @@
/*
*
* $ Id : k3bffmpegwrapper . cpp 641819 2007 - 03 - 12 17 : 29 : 23 Z trueg $
* Copyright ( C ) 2004 - 200 7 Sebastian Trueg < trueg @ k3b . org >
*
* Copyright ( C ) 2004 - 200 8 Sebastian Trueg < trueg @ k3b . org >
*
* This file is part of the K3b project .
* Copyright ( C ) 1998 - 200 7 Sebastian Trueg < trueg @ k3b . org >
* Copyright ( C ) 1998 - 200 8 Sebastian Trueg < trueg @ k3b . org >
*
* 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
@ -16,316 +16,274 @@
# include <config.h>
# include "k3bffmpegwrapper.h"
# include <tdelocale.h>
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 <libavformat/avformat.h>
}
# include <math.h>
# include <string.h>
# include <tdelocale.h>
# define FFMPEG_CODEC(s) (s->codec)
# if LIBAVFORMAT_BUILD < 4629
# define FFMPEG_BUILD_PRE_4629
# if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 2, 0)
// this works because the parameters/options are not used
# 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
# if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52, 64, 0)
# define AVMEDIA_TYPE_AUDIO CODEC_TYPE_AUDIO
# define AVMEDIA_TYPE_VIDEO CODEC_TYPE_VIDEO
# define AVMEDIA_TYPE_SUBTITLE CODEC_TYPE_SUBTITLE
# endif
// From libavcodec version 54.25, CodecID have been renamed to AVCodecID and all CODEC_ID_* to AV_CODEC_ID_*.
// This code can be simplified once all supported distros have updated to libavcodec version >=54.25
// From libavcodec version 54.25, CodecID have been renamed to AVCodecID and all
// CODEC_ID_* to AV_CODEC_ID_*. This code can be simplified once all supported
// distros have updated to libavcodec version >=54.25
# if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54, 25, 0)
# define K3B_CODEC_ID_WMAV1 CODEC_ID_WMAV1
# define K3B_CODEC_ID_WMAV2 CODEC_ID_WMAV2
# define K3B_CODEC_ID_MP3 CODEC_ID_MP3
# define K3B_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
# define AV_CODEC_ID_WMAV1 CODEC_ID_WMAV1
# define AV_CODEC_ID_WMAV2 CODEC_ID_WMAV2
# define AV_CODEC_ID_MP3 CODEC_ID_MP3
# define AV_CODEC_ID_AAC CODEC_ID_AAC
# 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 :
AVFormatContext * formatContext ;
AVCodec * codec ;
TQ_UINT8 * packetData ;
K3b : : Msf length ;
// for decoding
char outputBuffer [ 192000 ] ;
char * outputBufferPos ;
: : AVFormatContext * formatContext ;
: : AVCodec * codec ;
: : AVStream * audio_stream ;
: : AVSampleFormat sampleFormat ;
: : AVFrame * frame ;
: : AVPacket packet ;
char * outputBufferPos = nullptr ;
int outputBufferSize ;
AVPacket packet ;
TQ_UINT8 * packetData ;
int packetSize ;
bool isSpacious ;
} ;
K3bFFMpegFile : : K3bFFMpegFile ( const TQString & filename )
: m_filename ( filename )
{
K3bFFMpegFile : : K3bFFMpegFile ( const TQString & filename ) : m_filename ( filename ) {
d = new Private ;
d - > formatContext = 0 ;
d - > codec = 0 ;
d - > formatContext = nullptr ;
d - > codec = nullptr ;
d - > audio_stream = nullptr ;
d - > frame = av_frame_alloc ( ) ;
}
K3bFFMpegFile : : ~ K3bFFMpegFile ( )
{
K3bFFMpegFile : : ~ K3bFFMpegFile ( ) {
close ( ) ;
av_frame_free ( & d - > frame ) ;
delete d ;
}
bool K3bFFMpegFile : : open ( )
{
bool K3bFFMpegFile : : open ( ) {
close ( ) ;
// open the file
# if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53, 2, 0)
int err = avformat_open_input ( & d - > formatContext , m_filename . local8Bit ( ) , 0 , 0 ) ;
# else
int err = av_open_input_file ( & d - > formatContext , m_filename . local8Bit ( ) , 0 , 0 , 0 ) ;
# endif
if ( err < 0 ) {
kdDebug ( ) < < " (K3bFFMpegFile) unable to open " < < m_filename < < " with error " < < err < < endl ;
int err = : : avformat_open_input ( & d - > formatContext , m_filename . local8Bit ( ) ,
nullptr , nullptr ) ;
if ( err < 0 ) {
kdDebug ( ) < < " (K3bFFMpegFile) unable to open " < < m_filename
< < " with error " < < err ;
return false ;
}
// analyze the streams
# if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53, 6, 0)
avformat_find_stream_info ( d - > formatContext , NULL ) ;
# else
av_find_stream_info ( d - > formatContext ) ;
# endif
: : avformat_find_stream_info ( d - > formatContext , nullptr ) ;
// we only handle files containing one audio stream
if ( d - > formatContext - > nb_streams ! = 1 ) {
kdDebug ( ) < < " (K3bFFMpegFile) more than one stream in " < < m_filename < < endl ;
return false ;
for ( uint i = 0 ; i < d - > formatContext - > nb_streams ; + + i ) {
if ( d - > formatContext - > streams [ i ] - > codecpar - > codec_type = =
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
# ifdef FFMPEG_BUILD_PRE_4629
AVCodecContext * codecContext = & d - > formatContext - > streams [ 0 ] - > codec ;
# else
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 ;
: : AVCodecContext * codecContext = FFMPEG_CODEC ( d - > audio_stream ) ;
if ( codecContext - > codec_type ! = AVMEDIA_TYPE_AUDIO ) {
kdDebug ( ) < < " (K3bFFMpegFile) not a simple audio stream: " < < m_filename ;
return false ;
}
// get the codec
d - > codec = avcodec_find_decoder ( codecContext - > codec_id ) ;
if ( ! d - > codec ) {
kdDebug ( ) < < " (K3bFFMpegFile) no codec found for " < < m_filename < < endl ;
d - > codec = : : avcodec_find_decoder ( codecContext - > codec_id ) ;
if ( ! d - > codec ) {
kdDebug ( ) < < " (K3bFFMpegFile) no codec found for " < < m_filename ;
return false ;
}
// open the codec on our context
kdDebug ( ) < < " (K3bFFMpegFile) found codec for " < < m_filename < < endl ;
if (
# if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53, 8, 0)
avcodec_open2 ( codecContext , d - > codec , NULL ) < 0
# else
avcodec_open ( codecContext , d - > codec ) < 0
# endif
) {
kdDebug ( ) < < " (K3bFFMpegDecoderFactory) could not open codec. " < < endl ;
kdDebug ( ) < < " (K3bFFMpegFile) found codec for " < < m_filename ;
if ( : : avcodec_open2 ( codecContext , d - > codec , nullptr ) < 0 ) {
kdDebug ( ) < < " (K3bFFMpegDecoderFactory) could not open codec. " ;
return false ;
}
// 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 ) {
kdDebug ( ) < < " (K3bFFMpegDecoderFactory) invalid length. " < < endl ;
if ( d - > length = = 0 ) {
kdDebug ( ) < < " (K3bFFMpegDecoderFactory) invalid length. " ;
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
# if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(52, 101, 0)
av_dump_format ( d - > formatContext , 0 , m_filename . local8Bit ( ) , 0 ) ;
# else
dump_format ( d - > formatContext , 0 , m_filename . local8Bit ( ) , 0 ) ;
# endif
: : av_dump_format ( d - > formatContext , 0 , m_filename . local8Bit ( ) , 0 ) ;
return true ;
}
void K3bFFMpegFile : : close ( )
{
void K3bFFMpegFile : : close ( ) {
d - > outputBufferSize = 0 ;
d - > packetSize = 0 ;
d - > packetData = 0 ;
d - > packetData = nullptr ;
if ( d - > codec ) {
# ifdef FFMPEG_BUILD_PRE_4629
avcodec_close ( & d - > formatContext - > streams [ 0 ] - > codec ) ;
# else
avcodec_close ( d - > formatContext - > streams [ 0 ] - > codec ) ;
# endif
d - > codec = 0 ;
if ( d - > codec ) {
: : avcodec_close ( FFMPEG_CODEC ( d - > audio_stream ) ) ;
d - > codec = nullptr ;
}
if ( d - > formatContext ) {
# if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53, 17, 0)
avformat_close_input ( & d - > formatContext ) ;
# else
av_close_input_file ( d - > formatContext ) ;
# endif
d - > formatContext = 0 ;
if ( d - > formatContext ) {
: : avformat_close_input ( & d - > formatContext ) ;
d - > formatContext = nullptr ;
}
}
K3b : : Msf K3bFFMpegFile : : length ( ) const
{
return d - > length ;
d - > audio_stream = nullptr ;
}
K3b : : Msf K3bFFMpegFile : : length ( ) const { return d - > length ; }
int K3bFFMpegFile : : sampleRate ( ) const
{
# 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 : : sampleRate ( ) const {
return d - > audio_stream - > codecpar - > sample_rate ;
}
int K3bFFMpegFile : : type ( ) const
{
# 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 : : channels ( ) const {
return d - > audio_stream - > codecpar - > channels ;
}
int K3bFFMpegFile : : type ( ) const { return d - > audio_stream - > codecpar - > codec_id ; }
TQString K3bFFMpegFile : : typeComment ( ) const
{
switch ( type ( ) ) {
case K3B_CODEC_ID_WMAV1 :
TQString K3bFFMpegFile : : typeComment ( ) const {
switch ( type ( ) ) {
case AV_CODEC_ID_WMAV1 :
return i18n ( " Windows Media v1 " ) ;
case K3B _CODEC_ID_WMAV2:
case AV_CODEC_ID_WMAV2 :
return i18n ( " Windows Media v2 " ) ;
case K3B_CODEC_ID_MP3 :
return i18n ( " MPEG 1 Layer III " ) ;
case K3B_CODEC_ID_AAC :
case AV_CODEC_ID_WAVPACK :
return i18n ( " WavPack " ) ;
case AV_CODEC_ID_APE :
return i18n ( " Monkey's Audio (APE) " ) ;
case AV_CODEC_ID_AAC :
return i18n ( " Advanced Audio Coding (AAC) " ) ;
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??
# if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 2, 0)
if ( d - > formatContext - > title [ 0 ] ! = ' \0 ' )
return TQString : : fromLocal8Bit ( d - > formatContext - > title ) ;
# else
AVDictionaryEntry * entry = av_dict_get ( d - > formatContext - > metadata , " title " , NULL , 0 ) ;
if ( entry - > value [ 0 ] ! = ' \0 ' )
return TQString : : fromLocal8Bit ( entry - > value ) ;
# endif
else
return TQString ( ) ;
AVDictionaryEntry * ade =
av_dict_get ( d - > formatContext - > metadata , " TITLE " , nullptr , 0 ) ;
return ade & & ade - > value & & ade - > value [ 0 ] ! = ' \0 '
? TQString : : fromLocal8Bit ( ade - > value )
: TQString ( ) ;
}
TQString K3bFFMpegFile : : author ( ) const
{
TQString K3bFFMpegFile : : author ( ) const {
// FIXME: is this UTF8 or something??
# if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 2, 0)
if ( d - > formatContext - > author [ 0 ] ! = ' \0 ' )
return TQString : : fromLocal8Bit ( d - > formatContext - > author ) ;
# else
AVDictionaryEntry * entry = av_dict_get ( d - > formatContext - > metadata , " author " , NULL , 0 ) ;
if ( entry - > value [ 0 ] ! = ' \0 ' )
return TQString : : fromLocal8Bit ( entry - > value ) ;
# endif
else
return TQString ( ) ;
AVDictionaryEntry * ade =
av_dict_get ( d - > formatContext - > metadata , " ARTIST " , nullptr , 0 ) ;
return ade & & ade - > value & & ade - > value [ 0 ] ! = ' \0 '
? TQString : : fromLocal8Bit ( ade - > value )
: TQString ( ) ;
}
TQString K3bFFMpegFile : : comment ( ) const
{
TQString K3bFFMpegFile : : comment ( ) const {
// FIXME: is this UTF8 or something??
# if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 2, 0)
if ( d - > formatContext - > comment [ 0 ] ! = ' \0 ' )
return TQString : : fromLocal8Bit ( d - > formatContext - > comment ) ;
# else
AVDictionaryEntry * entry = av_dict_get ( d - > formatContext - > metadata , " comment " , NULL , 0 ) ;
if ( entry - > value [ 0 ] ! = ' \0 ' )
return TQString : : fromLocal8Bit ( entry - > value ) ;
# endif
else
return TQString ( ) ;
AVDictionaryEntry * ade =
av_dict_get ( d - > formatContext - > metadata , " COMMENT " , nullptr , 0 ) ;
return ade & & ade - > value & & ade - > value [ 0 ] ! = ' \0 '
? TQString : : fromLocal8Bit ( ade - > value )
: TQString ( ) ;
}
int K3bFFMpegFile : : read ( char * buf , int bufLen ) {
int K3bFFMpegFile : : read ( char * buf , int bufLen )
{
if ( fillOutputBuffer ( ) > 0 ) {
int len = TQMIN ( bufLen , d - > outputBufferSize ) ;
: : memcpy ( buf , d - > outputBufferPos , len ) ;
int ret = fillOutputBuffer ( ) ;
if ( ret < = 0 ) {
return ret ;
}
// TODO: only swap if needed
for ( int i = 0 ; i < len - 1 ; i + = 2 ) {
char a = buf [ i ] ;
buf [ i ] = buf [ i + 1 ] ;
buf [ i + 1 ] = a ;
}
int len = TQMIN ( bufLen , d - > outputBufferSize ) ;
: : memcpy ( buf , d - > outputBufferPos , len ) ;
if ( d - > isSpacious & & bufLen > d - > outputBufferSize )
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 - > outputBufferSize - = len ;
return len ;
}
else
return 0 ;
return len ;
}
// fill d->packetData with data to decode
int K3bFFMpegFile : : readPacket ( )
{
if ( d - > packetSize < = 0 ) {
av_init_packet ( & d - > packet ) ;
int K3bFFMpegFile : : readPacket ( ) {
if ( d - > packetSize < = 0 ) {
: : 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 ;
}
d - > packetSize = d - > packet . size ;
d - > packetData = d - > packet . data ;
}
@ -333,119 +291,107 @@ int K3bFFMpegFile::readPacket()
return d - > packetSize ;
}
// decode data in d->packetData and fill d->outputBuffer
int K3bFFMpegFile : : fillOutputBuffer ( )
{
int K3bFFMpegFile : : fillOutputBuffer ( ) {
// decode if the output buffer is empty
if( d - > outputBufferSize < = 0 ) {
while ( d - > outputBufferSize < = 0 ) {
// make sure we have data to decode
if ( readPacket ( ) = = 0 ) {
if ( readPacket ( ) = = 0 ) {
return 0 ;
}
d - > outputBufferPos = d - > outputBuffer ;
# if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52, 64, 0)
AVPacket avp ;
av_init_packet ( & avp ) ;
avp . data = d - > packetData ;
avp . size = d - > packetSize ;
# if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53, 25, 0)
int len = avcodec_decode_audio4 ( d - > formatContext - > streams [ 0 ] - > codec ,
( 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
int gotFrame = 0 ;
int len = : : avcodec_decode_audio4 ( FFMPEG_CODEC ( d - > audio_stream ) , d - > frame ,
& gotFrame , & d - > packet ) ;
if ( d - > packetSize < = 0 | | len < 0 )
: : av_packet_unref ( & d - > packet ) ;
if ( len < 0 ) {
kdDebug ( ) < < " (K3bFFMpegFile) decoding failed for " < < m_filename ;
return - 1 ;
}
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 - > packetData + = len ;
if ( d - > packetSize < = 0 )
av_free_packet ( & d - > packet ) ;
}
// if it is still empty try again
if ( d - > outputBufferSize < = 0 )
return fillOutputBuffer ( ) ;
else
return d - > outputBufferSize ;
return d - > outputBufferSize ;
}
bool K3bFFMpegFile : : seek ( const K3b : : Msf & msf )
{
bool K3bFFMpegFile : : seek ( const K3b : : Msf & msf ) {
d - > outputBufferSize = 0 ;
d - > packetSize = 0 ;
double seconds = ( double ) msf . totalFrames ( ) / 75.0 ;
TQ_UINT64 timestamp = ( TQ_UINT64 ) ( seconds * ( double ) AV_TIME_BASE ) ;
double seconds = double ( msf . totalFrames ( ) ) / 75.0 ;
int64_t timestamp = static_cast < int64_t > ( seconds * double ( AV_TIME_BASE ) ) ;
// FIXME: do we really need the start_time and why?
# if LIBAVFORMAT_BUILD >= 4619
return ( av_seek_frame ( d - > formatContext , - 1 , timestamp + d - > formatContext - > start_time , 0 ) > = 0 ) ;
# else
return ( av_seek_frame ( d - > formatContext , - 1 , timestamp + d - > formatContext - > start_time ) > = 0 ) ;
# endif
return ( : : av_seek_frame ( d - > formatContext , - 1 ,
timestamp + d - > formatContext - > start_time , 0 ) > = 0 ) ;
}
//
// av_register_all is deprecated since ffmpeg 4.0, can be dropped
K3bFFMpegWrapper : : K3bFFMpegWrapper ( ) { : : av_register_all ( ) ; }
K3bFFMpegWrapper : : ~ K3bFFMpegWrapper ( ) { s_instance = nullptr ; }
K3bFFMpegWrapper : : K3bFFMpegWrapper ( )
{
av_register_all ( ) ;
}
K3bFFMpegWrapper : : ~ K3bFFMpegWrapper ( )
{
s_instance = 0 ;
}
K3bFFMpegWrapper * K3bFFMpegWrapper : : instance ( )
{
if ( ! s_instance ) {
K3bFFMpegWrapper * K3bFFMpegWrapper : : instance ( ) {
if ( ! s_instance ) {
s_instance = new K3bFFMpegWrapper ( ) ;
}
return s_instance ;
}
K3bFFMpegFile * K3bFFMpegWrapper : : open ( const TQString & filename ) const
{
K3bFFMpegFile * file = new K3bFFMpegFile ( filename ) ;
if ( file - > open ( ) ) {
K3bFFMpegFile * K3bFFMpegWrapper : : open ( const TQString & filename ) const {
K3bFFMpegFile * file = new K3bFFMpegFile ( filename ) ;
if ( file - > open ( ) ) {
# ifndef K3B_FFMPEG_ALL_CODECS
//
// only allow tested formats. ffmpeg seems not to be too reliable with every format.
// mp3 being one of them sadly. Most importantly: allow the libsndfile decoder to do
// its thing.
// only allow tested formats. ffmpeg seems not to be too reliable with every
// format. mp3 being one of them sadly. Most importantly: allow the
// libsndfile decoder to do its thing.
//
if ( file - > type ( ) = = K3B _CODEC_ID_WMAV1 | |
file - > type ( ) = = K3B_CODEC_ID_WMAV2 | |
file - > type ( ) = = K3B_CODEC_ID_AAC )
if ( file - > type ( ) = = AV_CODEC_ID_WMAV1 | |
file - > type ( ) = = AV_CODEC_ID_WMAV2 | | file - > type ( ) = = AV_CODEC_ID_AAC | |
file - > type ( ) = = AV_CODEC_ID_APE | | file - > type ( ) = = AV_CODEC_ID_WAVPACK )
# endif
return file ;
}
delete file ;
return 0 ;
return nullptr ;
}