This source file includes following definitions.
- m_annexB
- takeContents
- serialize
- serializeSubstreams
#include "common.h"
#include "bitstream.h"
#include "nal.h"
using namespace X265_NS;
NALList::NALList()
: m_numNal(0)
, m_buffer(NULL)
, m_occupancy(0)
, m_allocSize(0)
, m_extraBuffer(NULL)
, m_extraOccupancy(0)
, m_extraAllocSize(0)
, m_annexB(true)
{}
void NALList::takeContents(NALList& other)
{
X265_FREE(m_buffer);
m_buffer = other.m_buffer;
m_allocSize = other.m_allocSize;
m_occupancy = other.m_occupancy;
m_numNal = other.m_numNal;
memcpy(m_nal, other.m_nal, sizeof(x265_nal) * m_numNal);
other.m_numNal = 0;
other.m_occupancy = 0;
other.m_buffer = X265_MALLOC(uint8_t, m_allocSize);
}
void NALList::serialize(NalUnitType nalUnitType, const Bitstream& bs)
{
static const char startCodePrefix[] = { 0, 0, 0, 1 };
uint32_t payloadSize = bs.getNumberOfWrittenBytes();
const uint8_t* bpayload = bs.getFIFO();
if (!bpayload)
return;
uint32_t nextSize = m_occupancy + sizeof(startCodePrefix) + 2 + payloadSize + (payloadSize >> 1) + m_extraOccupancy;
if (nextSize > m_allocSize)
{
uint8_t *temp = X265_MALLOC(uint8_t, nextSize);
if (temp)
{
memcpy(temp, m_buffer, m_occupancy);
for (uint32_t i = 0; i < m_numNal; i++)
m_nal[i].payload = temp + (m_nal[i].payload - m_buffer);
X265_FREE(m_buffer);
m_buffer = temp;
m_allocSize = nextSize;
}
else
{
x265_log(NULL, X265_LOG_ERROR, "Unable to realloc access unit buffer\n");
return;
}
}
uint8_t *out = m_buffer + m_occupancy;
uint32_t bytes = 0;
if (!m_annexB)
{
bytes += 4;
}
else if (!m_numNal || nalUnitType == NAL_UNIT_VPS || nalUnitType == NAL_UNIT_SPS || nalUnitType == NAL_UNIT_PPS)
{
memcpy(out, startCodePrefix, 4);
bytes += 4;
}
else
{
memcpy(out, startCodePrefix + 1, 3);
bytes += 3;
}
out[bytes++] = (uint8_t)nalUnitType << 1;
out[bytes++] = 1 + (nalUnitType == NAL_UNIT_CODED_SLICE_TSA_N);
for (uint32_t i = 0; i < payloadSize; i++)
{
if (i > 2 && !out[bytes - 2] && !out[bytes - 3] && out[bytes - 1] <= 0x03)
{
out[bytes] = out[bytes - 1];
out[bytes - 1] = 0x03;
bytes++;
}
out[bytes++] = bpayload[i];
}
X265_CHECK(bytes <= 4 + 2 + payloadSize + (payloadSize >> 1), "NAL buffer overflow\n");
if (m_extraOccupancy)
{
memcpy(out + bytes, m_extraBuffer, m_extraOccupancy);
bytes += m_extraOccupancy;
m_extraOccupancy = 0;
}
if (!out[bytes - 1])
out[bytes++] = 0x03;
if (!m_annexB)
{
uint32_t dataSize = bytes - 4;
out[0] = (uint8_t)(dataSize >> 24);
out[1] = (uint8_t)(dataSize >> 16);
out[2] = (uint8_t)(dataSize >> 8);
out[3] = (uint8_t)dataSize;
}
m_occupancy += bytes;
X265_CHECK(m_numNal < (uint32_t)MAX_NAL_UNITS, "NAL count overflow\n");
x265_nal& nal = m_nal[m_numNal++];
nal.type = nalUnitType;
nal.sizeBytes = bytes;
nal.payload = out;
}
uint32_t NALList::serializeSubstreams(uint32_t* streamSizeBytes, uint32_t streamCount, const Bitstream* streams)
{
uint32_t maxStreamSize = 0;
uint32_t estSize = 0;
for (uint32_t s = 0; s < streamCount; s++)
estSize += streams[s].getNumberOfWrittenBytes();
estSize += estSize >> 1;
if (estSize > m_extraAllocSize)
{
uint8_t *temp = X265_MALLOC(uint8_t, estSize);
if (temp)
{
X265_FREE(m_extraBuffer);
m_extraBuffer = temp;
m_extraAllocSize = estSize;
}
else
{
x265_log(NULL, X265_LOG_ERROR, "Unable to realloc WPP substream concatenation buffer\n");
return 0;
}
}
uint32_t bytes = 0;
uint8_t *out = m_extraBuffer;
for (uint32_t s = 0; s < streamCount; s++)
{
const Bitstream& stream = streams[s];
uint32_t inSize = stream.getNumberOfWrittenBytes();
const uint8_t *inBytes = stream.getFIFO();
uint32_t prevBufSize = bytes;
if (inBytes)
{
for (uint32_t i = 0; i < inSize; i++)
{
if (bytes >= 2 && !out[bytes - 2] && !out[bytes - 1] && inBytes[i] <= 0x03)
{
out[bytes++] = 3;
}
out[bytes++] = inBytes[i];
}
}
if (s < streamCount - 1)
{
streamSizeBytes[s] = bytes - prevBufSize;
if (streamSizeBytes[s] > maxStreamSize)
maxStreamSize = streamSizeBytes[s];
}
}
m_extraOccupancy = bytes;
return maxStreamSize;
}