Skip to content

Commit

Permalink
avformatdecoder.cpp: precompute parity LUT
Browse files Browse the repository at this point in the history
and move it to the only function using it.
  • Loading branch information
ulmus-scott committed Feb 11, 2022
1 parent 8e9d84b commit 48fc694
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 48 deletions.
71 changes: 26 additions & 45 deletions mythtv/libs/libmythtv/decoders/avformatdecoder.cpp
Expand Up @@ -4,6 +4,7 @@

// C++ headers
#include <algorithm>
#include <array>
#include <cmath>
#include <cstdint>
#include <iostream>
Expand Down Expand Up @@ -124,10 +125,6 @@ __inline AVRational GetAVTimeBaseQ()

static const int max_video_queue_size = 220;

static int cc608_parity(uint8_t byte);
static int cc608_good_parity(const CC608Parity &parity_table, uint16_t data);
static void cc608_build_parity_table(CC608Parity &parity_table);

static bool silence_ffmpeg_logging = false;

static QSize get_video_dim(const AVCodecContext &ctx)
Expand Down Expand Up @@ -311,8 +308,6 @@ AvFormatDecoder::AvFormatDecoder(MythPlayer *parent,
m_audioIn.m_sampleSize = -32;// force SetupAudioStream to run once
m_itv = m_parent->GetInteractiveTV();

cc608_build_parity_table(m_cc608ParityTable);

AvFormatDecoder::SetIdrOnlyKeyframes(true);
m_audioReadAhead = gCoreContext->GetDurSetting<std::chrono::milliseconds>("AudioReadAhead", 100ms);

Expand Down Expand Up @@ -1559,49 +1554,35 @@ void AvFormatDecoder::InitVideoCodec(AVStream *stream, AVCodecContext *enc,
}
}

// CC Parity checking
// taken from xine-lib libspucc

static int cc608_parity(uint8_t byte)
static bool cc608_good_parity(uint16_t data)
{
int ones = 0;

for (int i = 0; i < 7; i++)
{
if (byte & (1 << i))
ones++;
}

return ones & 1;
}

// CC Parity checking
// taken from xine-lib libspucc

static void cc608_build_parity_table(CC608Parity &parity_table)
{
for (uint8_t byte = 0; byte <= 127; byte++)
{
int parity_v = cc608_parity(byte);
/* CC uses odd parity (i.e., # of 1's in byte is odd.) */
parity_table[byte] = parity_v;
parity_table[byte | 0x80] = (parity_v == 0 ? 1 : 0);
}
}

// CC Parity checking
// taken from xine-lib libspucc

static int cc608_good_parity(const CC608Parity &parity_table, uint16_t data)
{
bool ret = (parity_table[data & 0xff] != 0)
&& (parity_table[(data & 0xff00) >> 8] != 0);
static constexpr std::array<uint8_t, 256> odd_parity_LUT
{
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
};
bool ret = (odd_parity_LUT[data & 0xff] == 1) &&
(odd_parity_LUT[(data & 0xff00) >> 8] == 1);
if (!ret)
{
LOG(VB_VBI, LOG_ERR, LOC +
QString("VBI: Bad parity in EIA-608 data (%1)") .arg(data,0,16));
}
return ret ? 1 : 0;
return ret;
}

void AvFormatDecoder::ScanATSCCaptionStreams(int av_index)
Expand Down Expand Up @@ -2840,7 +2821,7 @@ void AvFormatDecoder::DecodeCCx08(const uint8_t *buf, uint buf_size, bool scte)
field = cc_type ^ m_invertScteField;
}

if (cc608_good_parity(m_cc608ParityTable, data))
if (cc608_good_parity(data))
{
// in film mode, we may start at the wrong field;
// correct if XDS start/cont/end code is detected
Expand Down Expand Up @@ -3794,7 +3775,7 @@ void AvFormatDecoder::ProcessVBIDataPacket(
if (21 == line)
{
int data = (buf[2] << 8) | buf[1];
if (cc608_good_parity(m_cc608ParityTable, data))
if (cc608_good_parity(data))
m_ccd608->FormatCCField(duration_cast<std::chrono::milliseconds>(utc), field, data);
utc += 33367us;
}
Expand Down
4 changes: 1 addition & 3 deletions mythtv/libs/libmythtv/decoders/avformatdecoder.h
Expand Up @@ -2,6 +2,7 @@
#ifndef AVFORMATDECODER_H_
#define AVFORMATDECODER_H_

#include <array>
#include <cstdint>

extern "C" {
Expand Down Expand Up @@ -38,8 +39,6 @@ struct SwsContext;

extern "C" void HandleStreamChange(void *data);

using CC608Parity = std::array<int,256>;

class AudioInfo
{
public:
Expand Down Expand Up @@ -328,7 +327,6 @@ class AvFormatDecoder : public DecoderBase
CC608Decoder *m_ccd608 {nullptr};
CC708Decoder *m_ccd708 {nullptr};
TeletextDecoder *m_ttd {nullptr};
CC608Parity m_cc608ParityTable {0};
/// Lookup table for whether a stream was seen in the PMT
/// entries 0-3 correspond to CEA-608 CC1 through CC4, while
/// entries 4-67 corresport to CEA-708 streams 0 through 64
Expand Down

0 comments on commit 48fc694

Please sign in to comment.