diff --git a/CMakeLists.txt b/CMakeLists.txt index 9dd9719555f79850d640872fd46731a926eda051..d18f5277536e05faf6f54273891be9b6c263c32b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -187,13 +187,8 @@ if( CMAKE_BUILD_TYPE_TOLOWER MATCHES debug ) add_definitions(-Wall -Wextra) endif() -# this needs to be here because also code in shared/ needs config.h. This is also the -# reason why various checks are above why they belong under if( WITH_PLAYER ) -configure_file( shared/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/shared/config.h ) - add_subdirectory( data ) add_subdirectory( images ) -add_subdirectory( shared ) if( WITH_PLAYER ) find_package(X11) @@ -317,6 +312,12 @@ if( WITH_PLAYER ) endif() +# this needs to be here because also code in shared/ needs config.h. This is also the +# reason why various checks are above why they belong under if( WITH_PLAYER ) +configure_file( shared/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/shared/config.h ) + +add_subdirectory( shared ) + if( WITH_UTILITIES ) add_subdirectory( utilities ) endif() diff --git a/shared/config.h.cmake b/shared/config.h.cmake index 3478edd0d468d6beb182fd7ac0d0978c623cb002..9dde3306862a9662c0fb442a926e27572b6acd50 100644 --- a/shared/config.h.cmake +++ b/shared/config.h.cmake @@ -19,10 +19,16 @@ #cmakedefine QT_QTOPENGL_FOUND 1 /* If liblastfm is found */ -#cmakedefine HAVE_LIBLASTFM 1 +#cmakedefine LIBLASTFM_FOUND 1 +#ifdef LIBLASTFM_FOUND +#define HAVE_LIBLASTFM 1 +#endif /* If libofa is found */ -#cmakedefine HAVE_LIBOFA 1 +#cmakedefine LIBOFA_FOUND 1 +#ifdef LIBOFA_FOUND +#define HAVE_LIBOFA 1 +#endif /* Whether cmake build type is debug */ #cmakedefine DEBUG_BUILD_TYPE diff --git a/src/musicbrainz/MusicDNSAudioDecoder.cpp b/src/musicbrainz/MusicDNSAudioDecoder.cpp index e8e14d540efb55f91a3fd79047d8a6171c4b52bb..5f86b16b35a5041c9e4933fc5f58da88c4565844 100644 --- a/src/musicbrainz/MusicDNSAudioDecoder.cpp +++ b/src/musicbrainz/MusicDNSAudioDecoder.cpp @@ -133,8 +133,10 @@ MusicDNSAudioDecoder::run(ThreadWeaver::JobPointer self, ThreadWeaver::Thread *t Q_UNUSED(thread); DecodedAudioData data; +#if LIBAVCODEC_VERSION_MAJOR < 59 avcodec_register_all(); av_register_all(); +#endif foreach( Meta::TrackPtr track, m_tracks ) { @@ -173,7 +175,130 @@ MusicDNSAudioDecoder::defaultEnd(const ThreadWeaver::JobPointer& self, ThreadWea // Function below has separate implementation for each ffmpeg API version int MusicDNSAudioDecoder::decode( const QString &fileName, DecodedAudioData *data, const int length ) -#if LIBAVCODEC_VERSION_MAJOR >= 54 // ffmpeg 0.11 +#if LIBAVCODEC_VERSION_MAJOR >= 59 // ffmpeg 5.0 +{ + AVFormatContext *pFormatCtx = NULL; + AVCodecContext *pCodecCtx = NULL; + const AVCodec *pCodec = NULL; + AVFrame *decodedFrame = NULL; + AVPacket *packet = NULL, *avpkt = NULL; + AVCodecParameters *codecpar = NULL; + AVRational streamTimeBase = { 1, 1000000 }; + AVRational localTimeBase = { 1, 1000 }; + + int audioStream = 0; + int decoderRet = 0; + int planeSize = 0; + + bool isOk = true; + av_log_set_level(AV_LOG_VERBOSE); + + if( avformat_open_input( &pFormatCtx, fileName.toLocal8Bit(), NULL, NULL ) < 0 ) + { + warning() << QLatin1String( "Unable to open input file: " ) + fileName; + return 0; + } + + if( avformat_find_stream_info( pFormatCtx, NULL ) < 0 ) + { + warning() << QLatin1String( "Unable to find stream info: " ) + fileName; + avformat_close_input( &pFormatCtx ); + return 0; + } + + audioStream = av_find_best_stream(pFormatCtx, AVMEDIA_TYPE_AUDIO, -1, -1, &pCodec, 0); + if( audioStream < 0 ) + { + warning() << QLatin1String( "Unable to find stream: " ) + fileName; + avformat_close_input( &pFormatCtx ); + return 0; + } + + if( !pCodec ) + { + warning() << QLatin1String( "Unable to find decoder: " ) + fileName; + avformat_close_input( &pFormatCtx ); + return 0; + } + + pCodecCtx = avcodec_alloc_context3(pCodec); + + if( avcodec_open2( pCodecCtx, pCodec, NULL ) < 0 ) + { + warning() << QLatin1String( "Unable to open codec " ) + fileName; + avformat_close_input( &pFormatCtx ); + return 0; + } + + streamTimeBase = pFormatCtx->streams[audioStream]->time_base; + codecpar = pFormatCtx->streams[audioStream]->codecpar; + + data->setSampleRate( codecpar->sample_rate ); + data->setChannels( ( codecpar->channels > 1 )? 1 : 0 ); + + avpkt = av_packet_alloc(); + packet = av_packet_alloc(); + while( !av_read_frame( pFormatCtx, packet ) && isOk ) + { + if( packet->stream_index == audioStream ) + { + avpkt->size = packet->size; + avpkt->data = packet->data; + if( !decodedFrame ) + { + decodedFrame = av_frame_alloc(); + if( !decodedFrame ) + { + warning() << "Unable to allocate enough memory to decode file."; + isOk = false; + break; + } + else + av_frame_unref( decodedFrame ); + } + + decoderRet = avcodec_send_packet( pCodecCtx, avpkt ); + if( decoderRet < 0 ) + { + warning() << "Error while sending avcodec packet."; + isOk = false; + break; + } + do { + decoderRet = avcodec_receive_frame( pCodecCtx, decodedFrame ); + if( decoderRet == AVERROR(AVERROR_EOF) || decoderRet == AVERROR(EAGAIN) ) + { + break; + } + else if( decoderRet < 0 ) + { + warning() << "Error while decoding."; + isOk = false; + break; + } + av_samples_get_buffer_size( &planeSize, pCodecCtx->channels, decodedFrame->nb_samples, pCodecCtx->sample_fmt, 1); + for( int i = 0; i < qMin( pCodecCtx->channels, 2 ); i++ ) + data->appendData( const_cast( decodedFrame->extended_data[i] ), planeSize ); + } while( decoderRet == 0 ); + + data->addTime( av_rescale_q( packet->duration, streamTimeBase, localTimeBase ) ); + } + + av_packet_unref( packet ); + + if( data->duration() >= length ) + break; + } + + av_packet_unref( avpkt ); + + avcodec_close( pCodecCtx ); + avformat_close_input( &pFormatCtx ); + av_free( decodedFrame ); + + return data->duration(); +} +#elif LIBAVCODEC_VERSION_MAJOR >= 54 // ffmpeg 0.11 { AVFormatContext *pFormatCtx = NULL; AVCodecContext *pCodecCtx = NULL;