autom. IPF update

This commit is contained in:
Christian R. Helmrich 2021-03-08 21:00:00 +01:00
parent 2d0fa2f10d
commit 0bde366c7f
3 changed files with 62 additions and 0 deletions

View File

@ -87,6 +87,20 @@ int BasicMP4Writer::addFrameAU (const uint8_t* byteBuf, const uint32_t byteCount
if (((m_frameCount++) % m_rndAccPeriod) == 0) // add RAP to list (stco)
{
m_rndAccOffsets.push_back (m_mediaSize);
#ifndef NO_PREROLL_DATA
if (((m_frameCount - 1u) % (m_rndAccPeriod << 1)) == 0) // every 2nd
{
if ((byteBuf[0] & 0xE0) == 0xC0) // IPF?
{
// byte-offset of UsacConfig() in AU (excl. first 5 config bits!)
m_ipfCfgOffsets.push_back (byteBuf[0] == 0xDF && (byteBuf[1] & 0xE0) == 0xE0 ? 5 : 3);
}
else // 3-bit ID is missing, not an IPF!
{
m_ipfCfgOffsets.push_back (0);
}
}
#endif
}
m_mediaSize += byteCount;
@ -425,6 +439,37 @@ void BasicMP4Writer::reset (const unsigned frameLength /*= 0*/, const unsigned p
m_sampleRate = 0;
m_dynamicHeader.clear ();
m_rndAccOffsets.clear ();
#ifndef NO_PREROLL_DATA
m_ipfCfgOffsets.clear ();
#endif
if (m_fileHandle != -1) _SEEK (m_fileHandle, 0, 0 /*SEEK_SET*/);
}
#ifndef NO_PREROLL_DATA
int BasicMP4Writer::updateIPFs (const uint8_t* ascUcBuf, const uint32_t ascUcLength, const uint32_t ucOffset)
{
const uint8_t bw = uint8_t (ascUcLength - ucOffset);
int bytesWritten = 0, configsWritten = 0;
if ((m_fileHandle == -1) || (ascUcBuf == nullptr) || (ascUcLength == 0) || (ascUcLength <= ucOffset))
{
return 1; // invalid file handle or IPF config parameter
}
// write updated UsacConfig() to AudioPreRoll() extensions
for (uint32_t i = 0; i < (uint32_t) m_ipfCfgOffsets.size (); i++)
{
const uint32_t configOffset = m_ipfCfgOffsets.at (i);
if (configOffset > 0) // this AU is an IPF
{
_SEEK (m_fileHandle, m_rndAccOffsets.at (i << 1) + m_mediaOffset + configOffset, 0 /*SEEK_SET*/);
bytesWritten += _WRITE (m_fileHandle, &ascUcBuf[ucOffset], bw);
configsWritten++;
}
}
return (bytesWritten != configsWritten * bw ? 1 : 0);
}
#endif

View File

@ -43,6 +43,9 @@ private:
uint8_t m_staticHeader[STAT_HEADER_SIZE]; // fixed-size
std::vector <uint8_t> m_dynamicHeader; // variable-sized
std::vector <uint32_t> m_rndAccOffsets; // random access
#ifndef NO_PREROLL_DATA
std::vector <uint8_t> m_ipfCfgOffsets; // IPF UsacConfig
#endif
// helper function
void push32BitValue (const uint32_t value); // to header
@ -52,7 +55,11 @@ public:
// constructor
BasicMP4Writer () { m_fileHandle = -1; reset (); }
// destructor
#ifdef NO_PREROLL_DATA
~BasicMP4Writer() { m_dynamicHeader.clear (); m_rndAccOffsets.clear (); }
#else
~BasicMP4Writer() { m_dynamicHeader.clear (); m_rndAccOffsets.clear (); m_ipfCfgOffsets.clear (); }
#endif
// public functions
int addFrameAU (const uint8_t* byteBuf, const uint32_t byteCount);
int finishFile (const unsigned avgBitrate, const unsigned maxBitrate, const uint32_t audioLength,
@ -64,6 +71,9 @@ public:
const unsigned raPeriod, const uint8_t* ascBuf, const unsigned ascSize,
const uint32_t creatTime = 0, const char vbrQuality = 0);
void reset (const unsigned frameLength = 0, const unsigned pregapLength = 0, const unsigned raPeriod = 0);
#ifndef NO_PREROLL_DATA
int updateIPFs (const uint8_t* ascUcBuf, const uint32_t ascUcLength, const uint32_t ucOffset);
#endif
}; // BasicMP4Writer
#endif // _BASIC_MP4_WRITER_H_

View File

@ -1016,6 +1016,13 @@ int main (const int argc, char* argv[])
bw = EA_LOUD_INIT | (qPeak << 18) | (qLoud << 6) | 11u;
memset (outAuData, 0, 108 * sizeof (uint8_t)); // max allowed ASC + UC size
i = exhaleEnc.initEncoder (outAuData, &bw); // with finished loudnessInfo()
#ifndef NO_PREROLL_DATA
if (i == 0)
{
i = __min (USHRT_MAX, wavReader.getSampleRate ());
i = (uint16_t) mp4Writer.updateIPFs (outAuData, bw, (i == 57600 || i == 38400 || i == 19200 /*BL USAC*/ ? 6 : 3));
}
#endif
}
// mean & max. bit-rate of encoded AUs
br = uint32_t (((actualLength >> 1) + 8 * (byteCount + 4 * (int64_t) mp4Writer.getFrameCount ()) * sampleRate) / actualLength);