File indexing completed on 2024-07-21 07:22:33

0001 /*
0002     SPDX-FileCopyrightText: 1998-2008 Sebastian Trueg <trueg@k3b.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "k3bffmpegdecoder.h"
0008 #include "k3bffmpegwrapper.h"
0009 
0010 #include <config-k3b.h>
0011 
0012 #include <QDebug>
0013 
0014 extern "C" {
0015 /*
0016  Recent versions of FFmpeg uses C99 constant macros which are not present in C++ standard.
0017  The macro __STDC_CONSTANT_MACROS allow C++ to use these macros. Although it's not defined by C++ standard
0018  it's supported by many implementations.
0019  See bug 236036 and discussion: https://lists.ffmpeg.org/pipermail/ffmpeg-devel/2010-May/095488.html
0020  */
0021 #define __STDC_CONSTANT_MACROS
0022 #ifdef NEWFFMPEGAVCODECPATH
0023 #include <libavcodec/avcodec.h>
0024 #else
0025 #include <ffmpeg/avcodec.h>
0026 #endif
0027 }
0028 
0029 #include <math.h>
0030 
0031 K_PLUGIN_CLASS_WITH_JSON(K3bFFMpegDecoderFactory, "k3bffmpegdecoder.json")
0032 
0033 K3bFFMpegDecoderFactory::K3bFFMpegDecoderFactory( QObject* parent, const QVariantList& )
0034     : K3b::AudioDecoderFactory( parent )
0035 {
0036 }
0037 
0038 
0039 K3bFFMpegDecoderFactory::~K3bFFMpegDecoderFactory()
0040 {
0041 }
0042 
0043 
0044 K3b::AudioDecoder* K3bFFMpegDecoderFactory::createDecoder( QObject* parent ) const
0045 {
0046     return new K3bFFMpegDecoder( parent);
0047 }
0048 
0049 
0050 bool K3bFFMpegDecoderFactory::canDecode( const QUrl& url )
0051 {
0052     K3bFFMpegFile* file = K3bFFMpegWrapper::instance()->open( url.toLocalFile() );
0053     if( file ) {
0054         delete file;
0055         return true;
0056     }
0057     else {
0058         return false;
0059     }
0060 }
0061 
0062 
0063 
0064 
0065 
0066 
0067 K3bFFMpegDecoder::K3bFFMpegDecoder( QObject* parent  )
0068     : K3b::AudioDecoder( parent ),
0069       m_file(0)
0070 {
0071 }
0072 
0073 
0074 K3bFFMpegDecoder::~K3bFFMpegDecoder()
0075 {
0076 }
0077 
0078 
0079 QString K3bFFMpegDecoder::fileType() const
0080 {
0081     return m_type;
0082 }
0083 
0084 
0085 bool K3bFFMpegDecoder::analyseFileInternal( K3b::Msf& frames, int& samplerate, int& ch )
0086 {
0087     m_file = K3bFFMpegWrapper::instance()->open( filename() );
0088     if( m_file ) {
0089 
0090         // TODO: call addTechnicalInfo
0091 
0092         addMetaInfo( META_TITLE, m_file->title() );
0093         addMetaInfo( META_ARTIST, m_file->author() );
0094         addMetaInfo( META_COMMENT, m_file->comment() );
0095 
0096         samplerate = m_file->sampleRate();
0097         ch = m_file->channels();
0098         m_type = m_file->typeComment();
0099         frames = m_file->length();
0100 
0101         // ffmpeg's length information is not reliable at all
0102         // so we have to decode the whole file in order to get the correct length
0103 //     char buffer[10*2048];
0104 //     int len = 0;
0105 //     unsigned long long bytes = 0;
0106 //     while( ( len = m_file->read( buffer, 10*2048 ) ) > 0 )
0107 //       bytes += len;
0108 
0109 //     frames = (unsigned long)ceil((double)bytes/2048.0);
0110 
0111         // cleanup;
0112         delete m_file;
0113         m_file = 0;
0114 
0115         return true;
0116     }
0117     else
0118         return false;
0119 }
0120 
0121 
0122 bool K3bFFMpegDecoder::initDecoderInternal()
0123 {
0124     if( !m_file )
0125         m_file = K3bFFMpegWrapper::instance()->open( filename() );
0126 
0127     return (m_file != 0);
0128 }
0129 
0130 
0131 void K3bFFMpegDecoder::cleanup()
0132 {
0133     delete m_file;
0134     m_file = 0;
0135 }
0136 
0137 
0138 bool K3bFFMpegDecoder::seekInternal( const K3b::Msf& msf )
0139 {
0140     if( msf == 0 )
0141         return initDecoderInternal();
0142     else
0143         return m_file->seek( msf );
0144 }
0145 
0146 
0147 int K3bFFMpegDecoder::decodeInternal( char* _data, int maxLen )
0148 {
0149     return m_file->read( _data, maxLen );
0150 }
0151 
0152 
0153 #include "k3bffmpegdecoder.moc"
0154 
0155 #include "moc_k3bffmpegdecoder.cpp"