2015-09-06 19:57:33 +02:00
# include "./mpegaudioframestream.h"
2015-04-22 19:22:01 +02:00
2015-09-06 19:57:33 +02:00
# include "../exceptions.h"
# include "../mediaformat.h"
2015-04-22 19:22:01 +02:00
# include <sstream>
using namespace std ;
using namespace IoUtilities ;
using namespace ConversionUtilities ;
using namespace ChronoUtilities ;
namespace Media {
/*!
* \ class Media : : MpegAudioFrameStream
2015-07-15 00:10:24 +02:00
* \ brief Implementation of Media : : AbstractTrack MPEG audio streams .
2015-04-22 19:22:01 +02:00
*/
2015-06-10 01:28:22 +02:00
/*!
* \ brief Adds the information from the specified \ a frame to the specified \ a track .
*/
void MpegAudioFrameStream : : addInfo ( const MpegAudioFrame & frame , AbstractTrack & track )
{
track . m_version = frame . mpegVersion ( ) ;
track . m_format = MediaFormat ( GeneralMediaFormat : : Mpeg1Audio , frame . layer ( ) ) ;
track . m_channelCount = frame . channelMode ( ) = = MpegChannelMode : : SingleChannel ? 1 : 2 ;
2015-07-31 01:09:41 +02:00
track . m_channelConfig = static_cast < byte > ( frame . channelMode ( ) ) ;
2015-08-13 03:23:28 +02:00
track . m_samplingFrequency = frame . samplingFrequency ( ) ;
2015-06-10 01:28:22 +02:00
}
2015-04-22 19:22:01 +02:00
void MpegAudioFrameStream : : internalParseHeader ( )
{
2015-06-10 01:28:22 +02:00
static const string context ( " parsing MPEG audio frame header " ) ;
2015-04-22 19:22:01 +02:00
if ( ! m_istream ) {
throw NoDataFoundException ( ) ;
}
// get size
m_istream - > seekg ( - 128 , ios_base : : end ) ;
if ( m_reader . readUInt24BE ( ) = = 0x544147 ) {
m_size = static_cast < uint64 > ( m_istream - > tellg ( ) ) - 3u - m_startOffset ;
} else {
m_size = static_cast < uint64 > ( m_istream - > tellg ( ) ) + 125u - m_startOffset ;
}
m_istream - > seekg ( m_startOffset , ios_base : : beg ) ;
// parse frame header
2015-06-10 01:28:22 +02:00
m_frames . emplace_back ( ) ;
MpegAudioFrame & frame = m_frames . back ( ) ;
2015-07-15 00:10:24 +02:00
frame . parseHeader ( m_reader ) ;
2015-06-10 01:28:22 +02:00
addInfo ( frame , * this ) ;
2015-04-22 19:22:01 +02:00
if ( frame . isXingBytesfieldPresent ( ) ) {
uint32 xingSize = frame . xingBytesfield ( ) ;
2015-06-10 01:28:22 +02:00
if ( m_size & & xingSize ! = m_size ) {
2015-08-16 23:39:42 +02:00
addNotification ( NotificationType : : Warning , " Real length of MPEG audio frames is not equal with value provided by Xing header. The Xing header value will be used. " , context ) ;
2015-04-22 19:22:01 +02:00
m_size = xingSize ;
}
}
m_bitrate = frame . isXingFramefieldPresent ( )
2015-07-31 01:09:41 +02:00
? ( ( static_cast < double > ( m_size ) * 8.0 ) / ( static_cast < double > ( frame . xingFrameCount ( ) * frame . sampleCount ( ) ) / static_cast < double > ( frame . samplingFrequency ( ) ) ) / 1024.0 )
2015-04-22 19:22:01 +02:00
: frame . bitrate ( ) ;
2016-01-31 00:02:23 +01:00
m_duration = TimeSpan : : fromSeconds ( static_cast < double > ( m_size ) / ( m_bytesPerSecond = m_bitrate * 125 ) ) ;
2015-04-22 19:22:01 +02:00
}
}