Skip to content

Commit

Permalink
Support for HDMV descriptors is now selectable at runtime (#282)
Browse files Browse the repository at this point in the history
Fixes #273.
  • Loading branch information
jcdr428 committed Apr 25, 2020
1 parent 4bb16e0 commit 330bb47
Show file tree
Hide file tree
Showing 27 changed files with 133 additions and 118 deletions.
2 changes: 1 addition & 1 deletion tsMuxer/aacStreamReader.h
Expand Up @@ -10,7 +10,7 @@ class AACStreamReader : public SimplePacketizerReader, public AACCodec
public:
public:
AACStreamReader() : SimplePacketizerReader(){};
int getTSDescriptor(uint8_t* dstBuff, bool blurayMode) override { return 0; }
int getTSDescriptor(uint8_t* dstBuff, bool blurayMode, bool hdmvDescriptors) override { return 0; }
int getFreq() override { return m_sample_rate; }
int getChannels() override { return m_channels; }

Expand Down
2 changes: 1 addition & 1 deletion tsMuxer/abstractStreamReader.h
Expand Up @@ -55,7 +55,7 @@ class AbstractStreamReader : public BaseAbstractStreamReader
virtual int getTmpBufferSize() { return MAX_AV_PACKET_SIZE; }
virtual int readPacket(AVPacket& avPacket) = 0;
virtual int flushPacket(AVPacket& avPacket) = 0;
virtual int getTSDescriptor(uint8_t* dstBuff, bool blurayMode) { return 0; }
virtual int getTSDescriptor(uint8_t* dstBuff, bool blurayMode, bool hdmvDescriptors) { return 0; }
virtual int getStreamHDR() const { return 0; }
virtual void writePESExtension(PESPacket* pesPacket, const AVPacket& avPacket) {}
virtual void setStreamIndex(int index) { m_streamIndex = index; }
Expand Down
2 changes: 1 addition & 1 deletion tsMuxer/ac3StreamReader.cpp
Expand Up @@ -54,7 +54,7 @@ void AC3StreamReader::writePESExtension(PESPacket* pesPacket, const AVPacket& av
}
}

int AC3StreamReader::getTSDescriptor(uint8_t* dstBuff, bool blurayMode)
int AC3StreamReader::getTSDescriptor(uint8_t* dstBuff, bool blurayMode, bool hdmvDescriptors)
{
AC3Codec::setTestMode(true);
uint8_t* frame = findFrame(m_buffer, m_bufEnd);
Expand Down
2 changes: 1 addition & 1 deletion tsMuxer/ac3StreamReader.h
Expand Up @@ -24,7 +24,7 @@ class AC3StreamReader : public SimplePacketizerReader, public AC3Codec
m_nextAc3Time = 0;
m_thdFrameOffset = 0;
};
int getTSDescriptor(uint8_t* dstBuff, bool blurayMode) override;
int getTSDescriptor(uint8_t* dstBuff, bool blurayMode, bool hdmvDescriptors) override;
void setNewStyleAudioPES(bool value) { m_useNewStyleAudioPES = value; }
void setTestMode(bool value) override { AC3Codec::setTestMode(value); }
int getFreq() override { return AC3Codec::m_sample_rate; }
Expand Down
2 changes: 1 addition & 1 deletion tsMuxer/dtsStreamReader.cpp
Expand Up @@ -66,7 +66,7 @@ const static int AOUT_CHAN_REVERSESTEREO = 0x40000;

using namespace std;

int DTSStreamReader::getTSDescriptor(uint8_t* dstBuff, bool blurayMode)
int DTSStreamReader::getTSDescriptor(uint8_t* dstBuff, bool blurayMode, bool hdmvDescriptors)
{
uint8_t* frame = findFrame(m_buffer, m_bufEnd);
if (frame == 0)
Expand Down
2 changes: 1 addition & 1 deletion tsMuxer/dtsStreamReader.h
Expand Up @@ -45,7 +45,7 @@ class DTSStreamReader : public SimplePacketizerReader
m_dtsEsChannels = 0;
m_testMode = false;
};
int getTSDescriptor(uint8_t* dstBuff, bool blurayMode) override;
int getTSDescriptor(uint8_t* dstBuff, bool blurayMode, bool hdmvDescriptors) override;
void setDownconvertToDTS(bool value) { m_downconvertToDTS = value; }
bool getDownconvertToDTS() { return m_downconvertToDTS; }
DTSHD_SUBTYPE getDTSHDMode() { return m_hdType; }
Expand Down
2 changes: 1 addition & 1 deletion tsMuxer/dvbSubStreamReader.cpp
Expand Up @@ -5,7 +5,7 @@
const static uint64_t TS_FREQ_TO_INT_FREQ_COEFF = INTERNAL_PTS_FREQ / PCR_FREQUENCY;
static const int BAD_FRAME = -1;

int DVBSubStreamReader::getTSDescriptor(uint8_t* dstBuff, bool blurayMode) { return 0; }
int DVBSubStreamReader::getTSDescriptor(uint8_t* dstBuff, bool blurayMode, bool hdmvDescriptors) { return 0; }

uint8_t* DVBSubStreamReader::findFrame(uint8_t* buff, uint8_t* end)
{
Expand Down
2 changes: 1 addition & 1 deletion tsMuxer/dvbSubStreamReader.h
Expand Up @@ -9,7 +9,7 @@ class DVBSubStreamReader : public SimplePacketizerReader
{
public:
DVBSubStreamReader() : SimplePacketizerReader(), m_big_offsets(0), m_frameDuration(0), m_firstFrame(true) {}
int getTSDescriptor(uint8_t* dstBuff, bool blurayMode) override;
int getTSDescriptor(uint8_t* dstBuff, bool blurayMode, bool hdmvDescriptors) override;

protected:
unsigned getHeaderLen() override { return 10; }
Expand Down
30 changes: 16 additions & 14 deletions tsMuxer/h264StreamReader.cpp
Expand Up @@ -437,7 +437,7 @@ int H264StreamReader::writeAdditionData(uint8_t* dstBuffer, uint8_t* dstEnd, AVP
return curPos - dstBuffer;
}

int H264StreamReader::getTSDescriptor(uint8_t* dstBuff, bool blurayMode)
int H264StreamReader::getTSDescriptor(uint8_t* dstBuff, bool blurayMode, bool hdmvDescriptors)
{
SliceUnit slice;
if (m_firstDecodeNal)
Expand All @@ -446,23 +446,25 @@ int H264StreamReader::getTSDescriptor(uint8_t* dstBuff, bool blurayMode)
m_firstDecodeNal = false;
}

// put 'HDMV' registration descriptor
*dstBuff++ = 0x05; // registration descriptor tag
*dstBuff++ = 8; // descriptor length
memcpy(dstBuff, "HDMV\xff", 5);
dstBuff += 5;
if (hdmvDescriptors)
{
// put 'HDMV' registration descriptor
*dstBuff++ = 0x05; // registration descriptor tag
*dstBuff++ = 8; // descriptor length
memcpy(dstBuff, "HDMV\xff", 5);
dstBuff += 5;

int video_format, frame_rate_index, aspect_ratio_index;
M2TSStreamInfo::blurayStreamParams(getFPS(), getInterlaced(), getStreamWidth(), getStreamHeight(), getStreamAR(),
&video_format, &frame_rate_index, &aspect_ratio_index);
int video_format, frame_rate_index, aspect_ratio_index;
M2TSStreamInfo::blurayStreamParams(getFPS(), getInterlaced(), getStreamWidth(), getStreamHeight(),
getStreamAR(), &video_format, &frame_rate_index, &aspect_ratio_index);

*dstBuff++ = !m_mvcSubStream ? 0x1b : 0x20;
*dstBuff++ = (video_format << 4) + frame_rate_index;
*dstBuff++ = (aspect_ratio_index << 4) + 0xf;
*dstBuff++ = !m_mvcSubStream ? 0x1b : 0x20;
*dstBuff++ = (video_format << 4) + frame_rate_index;
*dstBuff++ = (aspect_ratio_index << 4) + 0xf;

return 10;
return 10;
}

// For future use: ATSC desciptor
for (uint8_t* nal = NALUnit::findNextNAL(m_buffer, m_bufEnd); nal < m_bufEnd - 4;
nal = NALUnit::findNextNAL(nal, m_bufEnd))
{
Expand Down
2 changes: 1 addition & 1 deletion tsMuxer/h264StreamReader.h
Expand Up @@ -23,7 +23,7 @@ class H264StreamReader : public MPEGStreamReader
H264StreamReader();
~H264StreamReader() override;
void setForceLevel(uint8_t value) { m_forcedLevel = value; }
int getTSDescriptor(uint8_t* dstBuff, bool blurayMode) override;
int getTSDescriptor(uint8_t* dstBuff, bool blurayMode, bool hdmvDescriptors) override;
virtual CheckStreamRez checkStream(uint8_t* buffer, int len);
void setH264SPSCont(bool val) { m_h264SPSCont = val; }

Expand Down
143 changes: 71 additions & 72 deletions tsMuxer/hevcStreamReader.cpp
Expand Up @@ -136,13 +136,39 @@ CheckStreamRez HEVCStreamReader::checkStream(uint8_t* buffer, int len)
return rez;
}

int HEVCStreamReader::getTSDescriptor(uint8_t* dstBuff, bool blurayMode)
int HEVCStreamReader::getTSDescriptor(uint8_t* dstBuff, bool blurayMode, bool hdmvDescriptors)
{
if (m_firstFrame)
CheckStreamRez rez = checkStream(m_buffer, m_bufEnd - m_buffer);

/* non-HDMV descriptor, for future use
if (!blurayMode && (V3_flags & DV))
int lenDoviDesc = 0;
if (!blurayMode && m_hdr->isDVRPU)
{
// 'DOVI' registration descriptor
memcpy(dstBuff, "\x05\x04\x44\x4f\x56\x49", 6);
dstBuff += 6;
lenDoviDesc += 6;
}

if (hdmvDescriptors)
{
// 'HDMV' registration descriptor
*dstBuff++ = 0x05;
*dstBuff++ = 8;
memcpy(dstBuff, "HDMV\xff\x24", 6);
dstBuff += 6;

int video_format, frame_rate_index, aspect_ratio_index;
M2TSStreamInfo::blurayStreamParams(getFPS(), getInterlaced(), getStreamWidth(), getStreamHeight(),
getStreamAR(), &video_format, &frame_rate_index, &aspect_ratio_index);

*dstBuff++ = (video_format << 4) + frame_rate_index;
*dstBuff++ = (aspect_ratio_index << 4) + 0xf;
}
else
{
uint8_t tmpBuffer[512];

for (uint8_t* nal = NALUnit::findNextNAL(m_buffer, m_bufEnd); nal < m_bufEnd - 4;
nal = NALUnit::findNextNAL(nal, m_bufEnd))
{
Expand All @@ -151,75 +177,53 @@ int HEVCStreamReader::getTSDescriptor(uint8_t* dstBuff, bool blurayMode)

if (nalType == NAL_SPS)
{
uint8_t tmpBuffer[512];
int toDecode = FFMIN(sizeof(tmpBuffer) - 8, nextNal - nal);
int decodedLen = NALUnit::decodeNAL(nal, nal + toDecode, tmpBuffer, sizeof(tmpBuffer));
int lenDoviDesc = 0;
if (m_hdr->isDVEL || m_hdr->isDVRPU)
{
lenDoviDesc = setDoViDescriptor(dstBuff);
dstBuff += lenDoviDesc;
}
*dstBuff++ = HEVC_DESCRIPTOR_TAG;
*dstBuff++ = 13; // descriptor length
memcpy(dstBuff, tmpBuffer + 3, 12);
dstBuff += 12;
// temporal_layer_subset, HEVC_still_present, HEVC_24hr_picture_present, HDR_WCG unspecified
*dstBuff = 0x0f;
if (!m_sps->sub_pic_hrd_params_present_flag)
*dstBuff |= 0x10;
dstBuff++;
// HEVC_timing_and_HRD_descriptor
memcpy(dstBuff, "\x3f\x0f\x03\x7f\x7f", 5);
dstBuff += 5;
uint32_t N = 1001 * getFPS();
uint32_t K = 27000000;
uint32_t num_units_in_tick = 1001;
if (N % 1000)
{
N = 1000 * getFPS();
num_units_in_tick = 1000;
}
N = my_htonl(N);
K = my_htonl(K);
num_units_in_tick = my_htonl(num_units_in_tick);
memcpy(dstBuff, &N, 4);
dstBuff += 4;
memcpy(dstBuff, &K, 4);
dstBuff += 4;
memcpy(dstBuff, &num_units_in_tick, 4);
dstBuff += 4;
return 32 + lenDoviDesc;
break;
}
} */

// 'HDMV' registration descriptor
*dstBuff++ = 0x05;
*dstBuff++ = 8;
memcpy(dstBuff, "HDMV\xff\x24", 6);
dstBuff += 6;

int video_format, frame_rate_index, aspect_ratio_index;
M2TSStreamInfo::blurayStreamParams(getFPS(), getInterlaced(), getStreamWidth(), getStreamHeight(), getStreamAR(),
&video_format, &frame_rate_index, &aspect_ratio_index);

*dstBuff++ = (video_format << 4) + frame_rate_index;
*dstBuff++ = (aspect_ratio_index << 4) + 0xf;
}

int lenDoviDesc = 0;
if (!blurayMode && (m_hdr->isDVEL || m_hdr->isDVRPU))
{
lenDoviDesc = setDoViDescriptor(dstBuff);
dstBuff += lenDoviDesc;
*dstBuff++ = HEVC_DESCRIPTOR_TAG;
*dstBuff++ = 13; // descriptor length
memcpy(dstBuff, tmpBuffer + 3, 12);
dstBuff += 12;
// flags temporal_layer_subset, HEVC_still_present,
// HEVC_24hr_picture_present, HDR_WCG unspecified
*dstBuff = 0x0f;

if (!m_sps->sub_pic_hrd_params_present_flag)
*dstBuff |= 0x10;
dstBuff++;

/* HEVC_timing_and_HRD_descriptor
// mandatory for interlaced video only
memcpy(dstBuff, "\x3f\x0f\x03\x7f\x7f", 5);
dstBuff += 5;
uint32_t N = 1001 * getFPS();
uint32_t K = 27000000;
uint32_t num_units_in_tick = 1001;
if (N % 1000)
{
N = 1000 * getFPS();
num_units_in_tick = 1000;
}
N = my_htonl(N);
K = my_htonl(K);
num_units_in_tick = my_htonl(num_units_in_tick);
memcpy(dstBuff, &N, 4);
dstBuff += 4;
memcpy(dstBuff, &K, 4);
dstBuff += 4;
memcpy(dstBuff, &num_units_in_tick, 4);
dstBuff += 4;
*/
}

return 10 + lenDoviDesc;
if (!blurayMode && m_hdr->isDVRPU)
lenDoviDesc += setDoViDescriptor(dstBuff);

return (hdmvDescriptors ? 10 : 15) + lenDoviDesc;
}

int HEVCStreamReader::setDoViDescriptor(uint8_t* dstBuff)
Expand Down Expand Up @@ -318,11 +322,6 @@ int HEVCStreamReader::setDoViDescriptor(uint8_t* dstBuff)
BitStreamWriter bitWriter;
bitWriter.setBuffer(dstBuff, dstBuff + 128);

// 'DOVI' registration descriptor
bitWriter.putBits(8, 5);
bitWriter.putBits(8, 4);
bitWriter.putBits(32, 0x444f5649);

bitWriter.putBits(8, 0xb0); // DoVi descriptor tag
bitWriter.putBits(8, isDVBL ? 5 : 7); // descriptor length
bitWriter.putBits(8, 1); // dv version major
Expand All @@ -341,7 +340,7 @@ int HEVCStreamReader::setDoViDescriptor(uint8_t* dstBuff)
bitWriter.putBits(4, 15); // reserved

bitWriter.flushBits();
return 8 + (isDVBL ? 5 : 7);
return 2 + (isDVBL ? 5 : 7);
}

void HEVCStreamReader::updateStreamFps(void* nalUnit, uint8_t* buff, uint8_t* nextNal, int)
Expand Down
2 changes: 1 addition & 1 deletion tsMuxer/hevcStreamReader.h
Expand Up @@ -12,7 +12,7 @@ class HEVCStreamReader : public MPEGStreamReader
public:
HEVCStreamReader();
~HEVCStreamReader() override;
int getTSDescriptor(uint8_t* dstBuff, bool blurayMode) override;
int getTSDescriptor(uint8_t* dstBuff, bool blurayMode, bool hdmvDescriptors) override;
int setDoViDescriptor(uint8_t* dstBuff);
virtual CheckStreamRez checkStream(uint8_t* buffer, int len);
bool needSPSForSplit() const override { return false; }
Expand Down
2 changes: 1 addition & 1 deletion tsMuxer/lpcmStreamReader.cpp
Expand Up @@ -19,7 +19,7 @@ static const uint32_t FMT_FOURCC = FOUR_CC('f', 'm', 't', ' ');

using namespace wave_format;

int LPCMStreamReader::getTSDescriptor(uint8_t* dstBuff, bool blurayMode)
int LPCMStreamReader::getTSDescriptor(uint8_t* dstBuff, bool blurayMode, bool hdmvDescriptors)
{
if (m_headerType == htNone)
if (!detectLPCMType(m_buffer, m_bufEnd - m_buffer))
Expand Down
2 changes: 1 addition & 1 deletion tsMuxer/lpcmStreamReader.h
Expand Up @@ -32,7 +32,7 @@ class LPCMStreamReader : public SimplePacketizerReader
m_lastChannelRemapPos = 0;
}
void setNewStyleAudioPES(bool value) { m_useNewStyleAudioPES = value; }
int getTSDescriptor(uint8_t* dstBuff, bool blurayMode) override;
int getTSDescriptor(uint8_t* dstBuff, bool blurayMode, bool hdmvDescriptors) override;
int getFreq() override { return m_freq; }
int getChannels() override { return m_channels; }
// void setDemuxMode(bool value) {m_demuxMode = value;}
Expand Down
2 changes: 2 additions & 0 deletions tsMuxer/main.cpp
Expand Up @@ -489,6 +489,8 @@ All parameters in this group start with two dashes:
video PID.
--new-audio-pes Use bytes 0xfd instead of 0xbd for AC3, True-HD, DTS and
DTS-HD. Activated automatically for BD muxing.
--hdmv-descriptors Use HDMV descriptors instead of ITU-T H.222.0 | ISO/IEC 13818-1
descriptors. Activated automatically for BD muxing.
--vbr Use variable bitrate.
--minbitrate Sets the lower limit of the VBR bitrate. If the stream has
a smaller bitrate, NULL packets will be inserted to
Expand Down
2 changes: 1 addition & 1 deletion tsMuxer/mpeg2StreamReader.cpp
Expand Up @@ -8,7 +8,7 @@
#include "vodCoreException.h"
#include "vod_common.h"

int MPEG2StreamReader::getTSDescriptor(uint8_t* dstBuff, bool blurayMode)
int MPEG2StreamReader::getTSDescriptor(uint8_t* dstBuff, bool blurayMode, bool hdmvDescriptors)
{
m_sequence.video_format = 5; // Unspecified video format
try
Expand Down
2 changes: 1 addition & 1 deletion tsMuxer/mpeg2StreamReader.h
Expand Up @@ -21,7 +21,7 @@ class MPEG2StreamReader : public MPEGStreamReader
m_longCodesAllowed = false;
m_prevFrameDelay = 0;
}
int getTSDescriptor(uint8_t* dstBuff, bool blurayMode) override;
int getTSDescriptor(uint8_t* dstBuff, bool blurayMode, bool hdmvDescriptors) override;
virtual CheckStreamRez checkStream(uint8_t* buffer, int len);

int getStreamWidth() const override { return m_sequence.width; }
Expand Down
2 changes: 1 addition & 1 deletion tsMuxer/mpegAudioStreamReader.cpp
Expand Up @@ -3,7 +3,7 @@

#include <sstream>

int MpegAudioStreamReader::getTSDescriptor(uint8_t* dstBuff, bool blurayMode)
int MpegAudioStreamReader::getTSDescriptor(uint8_t* dstBuff, bool blurayMode, bool hdmvDescriptors)
{
uint8_t* frame = findFrame(m_buffer, m_bufEnd);
if (frame == 0)
Expand Down
2 changes: 1 addition & 1 deletion tsMuxer/mpegAudioStreamReader.h
Expand Up @@ -9,7 +9,7 @@ class MpegAudioStreamReader : public SimplePacketizerReader, MP3Codec
public:
const static uint32_t DTS_HD_PREFIX = 0x64582025;
MpegAudioStreamReader() : SimplePacketizerReader() {}
int getTSDescriptor(uint8_t* dstBuff, bool blurayMode) override;
int getTSDescriptor(uint8_t* dstBuff, bool blurayMode, bool hdmvDescriptors) override;
int getLayer() { return m_layer; }
int getFreq() override { return m_sample_rate; }
int getChannels() override { return 2; }
Expand Down
2 changes: 1 addition & 1 deletion tsMuxer/singleFileMuxer.cpp
Expand Up @@ -40,7 +40,7 @@ void SingleFileMuxer::intAddStream(const std::string& streamName, const std::str
{
codecReader->setDemuxMode(true);
uint8_t descrBuffer[188];
int descriptorLen = codecReader->getTSDescriptor(descrBuffer, true);
int descriptorLen = codecReader->getTSDescriptor(descrBuffer, true, true);
string fileExt = "track";
if (codecName == "A_AC3")
fileExt = ".ac3";
Expand Down

0 comments on commit 330bb47

Please sign in to comment.