Skip to content

Commit

Permalink
Convert to std::array and std::string. (libmythtv/mpeg 6)
Browse files Browse the repository at this point in the history
Convert descriptors, etc. from C arrays to C+++ arrays.
  • Loading branch information
linuxdude42 committed Aug 28, 2020
1 parent 2ae8807 commit ff59065
Show file tree
Hide file tree
Showing 10 changed files with 76 additions and 41 deletions.
6 changes: 6 additions & 0 deletions mythtv/libs/libmythtv/mpeg/dvbdescriptors.h
Expand Up @@ -1801,6 +1801,8 @@ class ParentalRatingDescriptor : public MPEGDescriptor
public:
explicit ParentalRatingDescriptor(const unsigned char *data, int len = 300) :
MPEGDescriptor(data, len, DescriptorID::parental_rating) { }
explicit ParentalRatingDescriptor(const std::vector<uint8_t> &data) :
MPEGDescriptor(data, DescriptorID::parental_rating) { }
// Name bits loc expected value
// descriptor_tag 8 0.0 0x55
// descriptor_length 8 1.0
Expand Down Expand Up @@ -1869,6 +1871,8 @@ class PrivateDataSpecifierDescriptor : public MPEGDescriptor
public:
explicit PrivateDataSpecifierDescriptor(const unsigned char *data, int len = 300) :
MPEGDescriptor(data, len, DescriptorID::private_data_specifier) { }
explicit PrivateDataSpecifierDescriptor(const std::vector<uint8_t> &data) :
MPEGDescriptor(data, DescriptorID::private_data_specifier) { }
// Name bits loc expected value
// descriptor_tag 8 0.0 0x5f
// descriptor_length 8 1.0
Expand Down Expand Up @@ -2909,6 +2913,8 @@ class PrivateUPCCablecomEpisodeTitleDescriptor : public MPEGDescriptor
public:
explicit PrivateUPCCablecomEpisodeTitleDescriptor(const unsigned char *data, int len = 300) :
MPEGDescriptor(data, len, PrivateDescriptorID::upc_event_episode_title) { }
explicit PrivateUPCCablecomEpisodeTitleDescriptor(const std::vector<uint8_t> &data) :
MPEGDescriptor(data, PrivateDescriptorID::upc_event_episode_title) { }
// Name bits loc expected value
// descriptor_tag 8 0.0 0xa7
// descriptor_length 8 1.0
Expand Down
14 changes: 14 additions & 0 deletions mythtv/libs/libmythtv/mpeg/mpegdescriptors.h
Expand Up @@ -4,6 +4,7 @@
#define MPEG_DESCRIPTORS_H

// C++ headers
#include <array>
#include <vector>
using namespace std;

Expand Down Expand Up @@ -302,13 +303,26 @@ class MTV_PUBLIC MPEGDescriptor
if ((len < 2) || (int(DescriptorLength()) + 2) > len)
m_data = nullptr;
}
explicit MPEGDescriptor(const std::vector<uint8_t> &data) : m_data(data.data())
{
if ((data.size() < 2) ||
((static_cast<size_t>(DescriptorLength()) + 2) > data.size()))
m_data = nullptr;
}
MPEGDescriptor(const unsigned char *data,
int len, uint tag) : m_data(data)
{
if ((len < 2) || ((int(DescriptorLength()) + 2) > len)
|| (DescriptorTag() != tag))
m_data = nullptr;
}
MPEGDescriptor(const std::vector<uint8_t> &data, uint tag) : m_data(data.data())
{
if ((data.size() < 2) ||
((static_cast<size_t>(DescriptorLength()) + 2) > data.size())
|| (DescriptorTag() != tag))
m_data = nullptr;
}
MPEGDescriptor(const unsigned char *data,
int len, uint tag, uint req_desc_len) : m_data(data)
{
Expand Down
16 changes: 8 additions & 8 deletions mythtv/libs/libmythtv/mpeg/mpegtables.cpp
Expand Up @@ -7,7 +7,7 @@
#include "mythlogging.h"
#include "mpegtables.h"

const unsigned char DEFAULT_PAT_HEADER[8] =
const std::array<const uint8_t,8> DEFAULT_PAT_HEADER
{
0x00, // TableID::PAT
0xb0, // Syntax indicator
Expand All @@ -20,7 +20,7 @@ const unsigned char DEFAULT_PAT_HEADER[8] =
0x00, // Last Section
};

const unsigned char DEFAULT_PMT_HEADER[12] =
const std::array<const uint8_t,12> DEFAULT_PMT_HEADER
{
0x02, // TableID::PMT
0xb0, // Syntax indicator
Expand Down Expand Up @@ -331,14 +331,14 @@ ProgramAssociationTable* ProgramAssociationTable::CreateBlank(bool smallPacket)
{
(void) smallPacket; // currently always a small packet..
TSPacket *tspacket = TSPacket::CreatePayloadOnlyPacket();
memcpy(tspacket->data() + sizeof(TSHeader) + 1/* start of field pointer */,
DEFAULT_PAT_HEADER, sizeof(DEFAULT_PAT_HEADER));
auto *dst = tspacket->data() + sizeof(TSHeader) + 1; /* start of field pointer */
std::copy(DEFAULT_PAT_HEADER.cbegin(), DEFAULT_PAT_HEADER.cend(), dst);
PSIPTable psip = PSIPTable::View(*tspacket);
psip.SetLength(TSPacket::kPayloadSize
- 1 /* for start of field pointer */
- 3 /* for data before data last byte of pes length */);
auto *pat = new ProgramAssociationTable(psip);
pat->SetTotalLength(sizeof(DEFAULT_PAT_HEADER));
pat->SetTotalLength(DEFAULT_PAT_HEADER.size());
delete tspacket;
return pat;
}
Expand Down Expand Up @@ -382,8 +382,8 @@ ProgramMapTable* ProgramMapTable::CreateBlank(bool smallPacket)
{
ProgramMapTable *pmt = nullptr;
TSPacket *tspacket = TSPacket::CreatePayloadOnlyPacket();
memcpy(tspacket->data() + sizeof(TSHeader) + 1/* start of field pointer */,
DEFAULT_PMT_HEADER, sizeof(DEFAULT_PMT_HEADER));
auto *dst = tspacket->data() + sizeof(TSHeader) + 1; /* start of field pointer */
std::copy(DEFAULT_PMT_HEADER.cbegin(), DEFAULT_PMT_HEADER.cend(), dst);

if (smallPacket)
{
Expand All @@ -398,7 +398,7 @@ ProgramMapTable* ProgramMapTable::CreateBlank(bool smallPacket)
pmt = new ProgramMapTable(psip);
}

pmt->SetTotalLength(sizeof(DEFAULT_PMT_HEADER));
pmt->SetTotalLength(DEFAULT_PMT_HEADER.size());
delete tspacket;
return pmt;
}
Expand Down
6 changes: 6 additions & 0 deletions mythtv/libs/libmythtv/mpeg/mpegtables.h
Expand Up @@ -457,6 +457,12 @@ class MTV_PUBLIC PSIPTable : public PESPacket
// fixup wrong assumption about length for sections without CRC
m_pesDataSize = SectionLength();
}
explicit PSIPTable(const std::vector<uint8_t> &pesdata)
: PESPacket(pesdata)
{
// fixup wrong assumption about length for sections without CRC
m_pesDataSize = SectionLength();
}
public:
PSIPTable(const PSIPTable&) = default;
// section_syntax_ind 1 1.0 8 should always be 1
Expand Down
7 changes: 7 additions & 0 deletions mythtv/libs/libmythtv/mpeg/pespacket.h
Expand Up @@ -39,6 +39,13 @@ class MTV_PUBLIC PESPacket
m_badPacket = !VerifyCRC();
m_pesDataSize = max(((int)Length())-1 + (PESPacket::HasCRC() ? 4 : 0), 0);
}
explicit PESPacket(const std::vector<uint8_t> &pesdata)
: m_pesData(const_cast<unsigned char*>(pesdata.data())),
m_fullBuffer(const_cast<unsigned char*>(pesdata.data()))
{
m_badPacket = !VerifyCRC();
m_pesDataSize = max(((int)Length())-1 + (PESPacket::HasCRC() ? 4 : 0), 0);
}

// Deleted functions should be public.
//const PESPacket& operator=(const PESPacket& pkt);
Expand Down
6 changes: 3 additions & 3 deletions mythtv/libs/libmythtv/mpeg/tspacket.cpp
Expand Up @@ -3,15 +3,15 @@
#include <cstdint> // for intptr_t
#include "tspacket.h"

const unsigned char TSHeader::kPayloadOnlyHeader[4] =
const TSHeaderArray TSHeader::kPayloadOnlyHeader
{
SYNC_BYTE,
0x40, // payload start
0x0,
0x10, // adaptation field control == payload only
};

const unsigned char NULL_PACKET_BYTES[188] =
const std::array<unsigned char,188> NULL_PACKET_BYTES
{
SYNC_BYTE, 0x1F, 0xFF, 0x00,
0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, // 36
Expand All @@ -23,7 +23,7 @@ const unsigned char NULL_PACKET_BYTES[188] =
};

const TSPacket *TSPacket::kNullPacket =
reinterpret_cast<const TSPacket*>(NULL_PACKET_BYTES);
reinterpret_cast<const TSPacket*>(NULL_PACKET_BYTES.data());

QString TSPacket::toString() const
{
Expand Down
23 changes: 13 additions & 10 deletions mythtv/libs/libmythtv/mpeg/tspacket.h
Expand Up @@ -3,6 +3,7 @@
#ifndef TS_PACKET_H
#define TS_PACKET_H

#include <algorithm>
#include <chrono>
#include <cstdlib>
#include "mythcontext.h"
Expand All @@ -14,6 +15,8 @@
#define AUDIO_PID(bp) ((bp)+4)
#define SYNC_BYTE 0x0047

using TSHeaderArray = std::array<uint8_t,4>;

/** \class TSHeader
* \brief Used to access header of a TSPacket.
*
Expand Down Expand Up @@ -149,13 +152,13 @@ class MTV_PUBLIC TSHeader
m_tsData[3] = (m_tsData[3] & 0xf0) | (cc & 0xf);
}

const unsigned char* data(void) const { return m_tsData; }
unsigned char* data(void) { return m_tsData; }
const unsigned char* data(void) const { return m_tsData.data(); }
unsigned char* data(void) { return m_tsData.data(); }

static constexpr unsigned int kHeaderSize {4};
static const unsigned char kPayloadOnlyHeader[4];
static const TSHeaderArray kPayloadOnlyHeader;
private:
unsigned char m_tsData[4] {};
TSHeaderArray m_tsData {};
};

/** \class TSPacket
Expand All @@ -174,8 +177,8 @@ class MTV_PUBLIC TSPacket : public TSHeader
static TSPacket* CreatePayloadOnlyPacket(void)
{
auto *pkt = new TSPacket();
pkt->InitHeader(kPayloadOnlyHeader);
memset(pkt->m_tsPayload, 0xFF, kPayloadSize);
pkt->InitHeader(kPayloadOnlyHeader.data());
pkt->m_tsPayload.fill(0xFF);
pkt->SetStartOfFieldPointer(0);
return pkt;
}
Expand All @@ -189,18 +192,18 @@ class MTV_PUBLIC TSPacket : public TSHeader
void InitPayload(const unsigned char *payload)
{
if (payload)
memcpy(m_tsPayload, payload, kPayloadSize);
std::copy(payload, payload+kPayloadSize, m_tsPayload.data());
}

void InitPayload(const unsigned char *payload, uint size)
{
if (payload)
memcpy(m_tsPayload, payload, size);
std::copy(payload, payload+size, m_tsPayload.data());
else
size = 0;

if (size < TSPacket::kPayloadSize)
memset(m_tsPayload + size, 0xff, TSPacket::kPayloadSize - size);
std::fill_n(&m_tsPayload[size], TSPacket::kPayloadSize - size, 0xff);
}

// This points outside the TSHeader data, but is declared here because
Expand All @@ -224,7 +227,7 @@ class MTV_PUBLIC TSPacket : public TSHeader
static constexpr unsigned int k8VSBEmissionSize {208};
static const TSPacket *kNullPacket;
private:
unsigned char m_tsPayload[184] {};
std::array<uint8_t,184> m_tsPayload {};
};

#if 0 /* not used yet */
Expand Down
4 changes: 2 additions & 2 deletions mythtv/libs/libmythtv/test/test_mpegtables/specimen.cpp
Expand Up @@ -16,7 +16,7 @@
* "Role Player" -> "actor"
* "Scriptwriter" -> "writer"
*/
unsigned char eit_data_0000[] = {
std::array<uint8_t,805> eit_data_0000 {
0x4e, 0xf2, 0xc2, 0x2f, 0x46, 0xc7, 0x00, 0x01, 0x00, 0xa1, 0x27, 0x0f, 0x01, 0x4e, 0xbb, 0xe8, /* N../F.....'..N.. */
0xde, 0x91, 0x21, 0x15, 0x00, 0x00, 0x55, 0x00, 0x82, 0xa7, 0x4d, 0xc0, 0x67, 0x65, 0x72, 0x07, /* ..!...U...M.ger. */
0x05, 0x43, 0x61, 0x73, 0x74, 0x6c, 0x65, 0xb4, 0x05, 0x4b, 0x72, 0x69, 0x6d, 0x69, 0x73, 0x65, /* .Castle..Krimise */
Expand Down Expand Up @@ -67,7 +67,7 @@ unsigned char eit_data_0000[] = {
/**
* #12612, trailing NULL character in string
*/
unsigned char tvct_data_0000[] = {
std::array<uint8_t,433> tvct_data_0000 {
0xc8, 0xf1, 0x8e, 0x13, 0x83, 0xc1, 0x00, 0x00, 0x00, 0x06, 0x00, 0x4b, 0x00, 0x59, 0x00, 0x4e, /* ...........K.Y.N */
0x00, 0x4d, 0x00, 0x2d, 0x00, 0x48, 0x00, 0x44, 0xf0, 0x54, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, /* .M.-.H.D.T...... */
0x13, 0x83, 0x00, 0x01, 0x4d, 0xc2, 0x00, 0x01, 0xfc, 0x11, 0xa1, 0x0f, 0xe0, 0x31, 0x02, 0x02, /* ....M........1.. */
Expand Down
31 changes: 15 additions & 16 deletions mythtv/libs/libmythtv/test/test_mpegtables/test_mpegtables.cpp
Expand Up @@ -27,7 +27,7 @@

void TestMPEGTables::pat_test(void)
{
const unsigned char si_data[] = {
const std::vector<uint8_t> si_data {
0x00, 0xb0, 0x31, 0x04, 0x37, 0xdf, 0x00, 0x00, 0x2b, 0x66, 0xf7, 0xd4, 0x6d, 0x66, 0xe0, 0x64, /* ..1.7...+f..mf.d */
0x6d, 0x67, 0xe0, 0xc8, 0x6d, 0x68, 0xe1, 0x2c, 0x6d, 0x6b, 0xe2, 0x58, 0x6d, 0x6c, 0xe2, 0xbc, /* mg..mh.,mk.Xml.. */
0x6d, 0x6d, 0xe3, 0x20, 0x6d, 0x6e, 0xe2, 0x8a, 0x6d, 0x70, 0xe4, 0x4c, 0x6d, 0x71, 0xe1, 0x9b, /* mm. mn..mp.Lmq.. */
Expand Down Expand Up @@ -113,11 +113,10 @@ void TestMPEGTables::pat_test(void)
QVERIFY (pat3->VerifyCRC());

// Create a PAT object
unsigned char si_data4[188];
memset (&si_data4, 0, sizeof(si_data4));
std::vector<uint8_t> si_data4(188,'\0');
si_data4[1] = 1 << 7 & 0 << 6 & 3 << 4 & 0 << 2 & 0;
si_data4[2] = 0x00;
auto* pat4 = new ProgramAssociationTable(PSIPTable((unsigned char*)&si_data4));
auto* pat4 = new ProgramAssociationTable(PSIPTable(si_data4));
QCOMPARE (pat4->CalcCRC(), (uint) 0xFFFFFFFF);
QVERIFY (pat4->VerifyCRC());
delete pat4;
Expand All @@ -135,7 +134,7 @@ void TestMPEGTables::dvbdate(void)

void TestMPEGTables::tdt_test(void)
{
const unsigned char si_data[] = {
const std::vector<uint8_t> si_data {
0x70, 0x70, 0x05, 0xdc, 0xa9, 0x12, 0x33, 0x37 /* pp....37 */
};

Expand Down Expand Up @@ -169,7 +168,7 @@ void TestMPEGTables::tdt_test(void)

void TestMPEGTables::ContentIdentifierDescriptor_test(void)
{
const unsigned char eit_data[] = {
const std::vector<uint8_t> eit_data {
0x4f, 0xf2, 0x17, 0x42, 0xd8, 0xdb, 0x00, 0x01, 0x00, 0xab, 0x27, 0x0f, 0x01, 0x4f, 0x30, 0x17, /* O..B......'..O0. */
0xdc, 0xc9, 0x07, 0x15, 0x00, 0x00, 0x25, 0x00, 0x81, 0xfc, 0x4d, 0xb2, 0x65, 0x6e, 0x67, 0x0d, /* ......%...M.eng. */
0x05, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x62, 0x72, 0x6f, 0x74, 0x68, 0x65, 0x72, 0xa0, 0x05, 0x44, /* .Moneybrother..D */
Expand Down Expand Up @@ -243,7 +242,7 @@ void TestMPEGTables::clone_test(void)
void TestMPEGTables::PrivateDataSpecifierDescriptor_test (void)
{
/* from https://code.mythtv.org/trac/ticket/12091 */
const unsigned char si_data[] = {
const std::vector<uint8_t> si_data {
0x5f, 0x04, 0x00, 0x00, 0x06, 0x00
};
PrivateDataSpecifierDescriptor desc(si_data);
Expand All @@ -252,7 +251,7 @@ void TestMPEGTables::PrivateDataSpecifierDescriptor_test (void)

void TestMPEGTables::PrivateUPCCablecomEpisodetitleDescriptor_test (void)
{
const unsigned char si_data[] = {
const std::vector<uint8_t> si_data {
0xa7, 0x13, 0x67, 0x65, 0x72, 0x05, 0x4b, 0x72, 0x61, 0x6e, 0x6b, 0x20, 0x76, 0x6f, 0x72, 0x20, /* ..ger.Krank vor */
0x4c, 0x69, 0x65, 0x62, 0x65 /* Liebe */
};
Expand Down Expand Up @@ -287,24 +286,24 @@ void TestMPEGTables::ItemList_test (void)

void TestMPEGTables::TestUCS2 (void)
{
unsigned char ucs2_data[] = {
std::array<uint8_t,24> ucs2_data {
0x17, 0x11, 0x80, 0x06, 0x5e, 0xb7, 0x67, 0x03, 0x54, 0x48, 0x73, 0x7b, 0x00, 0x3a, 0x95, 0x8b,
0xc3, 0x80, 0x01, 0x53, 0xcb, 0x8a, 0x18, 0xbf
};

wchar_t wchar_data[] = L"\u8006\u5eb7\u6703\u5448\u737b\u003a\u958b\uc380\u0153\ucb8a\u18bf";
std::array<wchar_t,12> wchar_data { L"\u8006\u5eb7\u6703\u5448\u737b\u003a\u958b\uc380\u0153\ucb8a\u18bf"};

QCOMPARE (sizeof (QChar), (size_t) 2);
QCOMPARE (sizeof (ucs2_data) - 1, (size_t) ucs2_data[0]);
QString ucs2 = dvb_decode_text (&ucs2_data[1], ucs2_data[0], {});
QCOMPARE (ucs2.length(), (int) (ucs2_data[0] - 1) / 2);
QCOMPARE (ucs2, QString::fromWCharArray (wchar_data));
QCOMPARE (ucs2, QString::fromWCharArray (wchar_data.data()));
}

void TestMPEGTables::ParentalRatingDescriptor_test (void)
{
/* from https://forum.mythtv.org/viewtopic.php?p=4376 / #12553 */
const unsigned char si_data[] = {
const std::vector<uint8_t> si_data {
0x55, 0x04, 0x47, 0x42, 0x52, 0x0B
};
ParentalRatingDescriptor desc(si_data);
Expand Down Expand Up @@ -333,26 +332,26 @@ void TestMPEGTables::OTAChannelName_test (void)
/* manually crafted according to A65/2013
* http://atsc.org/wp-content/uploads/2015/03/Program-System-Information-Protocol-for-Terrestrial-Broadcast-and-Cable.pdf
*/
unsigned char tvct_data[] = {
const std::vector<uint8_t> tvct_data {
0xc8, 0xf0, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 'A', 0x00, 'B', 0x00, 'C',
0x00, 'D', 0x00, 'E', 0x00, 'F', 0x00, '\0', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc4, 0x82, 0xb9
};

PSIPTable psip = PSIPTable(tvct_data);
PSIPTable psip = PSIPTable(tvct_data.data());
TerrestrialVirtualChannelTable table(psip);

QVERIFY (table.HasCRC());
QCOMPARE (table.CalcCRC(), table.CRC());
QVERIFY (table.VerifyCRC());

QCOMPARE (table.SectionLength(), (unsigned int)sizeof (tvct_data));
QCOMPARE (table.SectionLength(), static_cast<uint>(tvct_data.size()));

QCOMPARE (table.ChannelCount(), 1U);
QCOMPARE (table.ShortChannelName(0), QString("ABCDEF"));
QCOMPARE (table.ShortChannelName(1), QString());

PSIPTable psip2 = PSIPTable(tvct_data_0000);
PSIPTable psip2 = PSIPTable(tvct_data_0000.data());
TerrestrialVirtualChannelTable tvct(psip2);
QVERIFY (tvct.VerifyCRC());
QVERIFY (tvct.VerifyPSIP(false));
Expand Down
4 changes: 2 additions & 2 deletions mythtv/libs/libmythtv/test/test_mpegtables/test_mpegtables.h
Expand Up @@ -21,8 +21,8 @@
#include <QtTest/QtTest>

/* test data */
extern unsigned char eit_data_0000[];
extern unsigned char tvct_data_0000[];
extern std::array<uint8_t,805> eit_data_0000;
extern std::array<uint8_t,433> tvct_data_0000;

class TestMPEGTables: public QObject
{
Expand Down

0 comments on commit ff59065

Please sign in to comment.