summaryrefslogtreecommitdiff
path: root/gr-dtv/lib/dvb/dvb_bbheader_bb_impl.cc
diff options
context:
space:
mode:
authorRon Economos <w6rz@comcast.net>2015-02-20 16:31:55 -0800
committerRon Economos <w6rz@comcast.net>2015-02-20 16:31:55 -0800
commit1c75d25b1e6fb3aaa265303a723ec0cffd92ce8c (patch)
treee97f4163ffacb48a6e0397f1e164f1d20fc320ca /gr-dtv/lib/dvb/dvb_bbheader_bb_impl.cc
parent0b01346bd36151e4b5f880a87ba7f391c2784e69 (diff)
gr-dtv: Add code review updates.
Diffstat (limited to 'gr-dtv/lib/dvb/dvb_bbheader_bb_impl.cc')
-rw-r--r--gr-dtv/lib/dvb/dvb_bbheader_bb_impl.cc521
1 files changed, 521 insertions, 0 deletions
diff --git a/gr-dtv/lib/dvb/dvb_bbheader_bb_impl.cc b/gr-dtv/lib/dvb/dvb_bbheader_bb_impl.cc
new file mode 100644
index 0000000000..e0c80ea304
--- /dev/null
+++ b/gr-dtv/lib/dvb/dvb_bbheader_bb_impl.cc
@@ -0,0 +1,521 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2015 Free Software Foundation, Inc.
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gnuradio/io_signature.h>
+#include "dvb_bbheader_bb_impl.h"
+#include <stdio.h>
+
+namespace gr {
+ namespace dtv {
+
+ dvb_bbheader_bb::sptr
+ dvb_bbheader_bb::make(dvb_standard_t standard, dvb_framesize_t framesize, dvb_code_rate_t rate, dvbs2_rolloff_factor_t rolloff, dvbt2_inputmode_t mode, dvbt2_inband_t inband, int fecblocks, int tsrate)
+ {
+ return gnuradio::get_initial_sptr
+ (new dvb_bbheader_bb_impl(standard, framesize, rate, rolloff, mode, inband, fecblocks, tsrate));
+ }
+
+ /*
+ * The private constructor
+ */
+ dvb_bbheader_bb_impl::dvb_bbheader_bb_impl(dvb_standard_t standard, dvb_framesize_t framesize, dvb_code_rate_t rate, dvbs2_rolloff_factor_t rolloff, dvbt2_inputmode_t mode, dvbt2_inband_t inband, int fecblocks, int tsrate)
+ : gr::block("dvb_bbheader_bb",
+ gr::io_signature::make(1, 1, sizeof(unsigned char)),
+ gr::io_signature::make(1, 1, sizeof(unsigned char)))
+ {
+ count = 0;
+ crc = 0x0;
+ dvbs2x = FALSE;
+ alternate = TRUE;
+ BBHeader *f = &m_format[0].bb_header;
+ if (framesize == FECFRAME_NORMAL) {
+ switch (rate) {
+ case C1_4:
+ kbch = 16008;
+ break;
+ case C1_3:
+ kbch = 21408;
+ break;
+ case C2_5:
+ kbch = 25728;
+ break;
+ case C1_2:
+ kbch = 32208;
+ break;
+ case C3_5:
+ kbch = 38688;
+ break;
+ case C2_3:
+ kbch = 43040;
+ break;
+ case C3_4:
+ kbch = 48408;
+ break;
+ case C4_5:
+ kbch = 51648;
+ break;
+ case C5_6:
+ kbch = 53840;
+ break;
+ case C8_9:
+ kbch = 57472;
+ break;
+ case C9_10:
+ kbch = 58192;
+ break;
+ case C13_45:
+ kbch = 18528;
+ break;
+ case C9_20:
+ kbch = 28968;
+ break;
+ case C90_180:
+ kbch = 32208;
+ break;
+ case C96_180:
+ kbch = 34368;
+ break;
+ case C11_20:
+ kbch = 35448;
+ break;
+ case C100_180:
+ kbch = 35808;
+ break;
+ case C104_180:
+ kbch = 37248;
+ break;
+ case C26_45:
+ kbch = 37248;
+ break;
+ case C18_30:
+ kbch = 38688;
+ break;
+ case C28_45:
+ kbch = 40128;
+ break;
+ case C23_36:
+ kbch = 41208;
+ break;
+ case C116_180:
+ kbch = 41568;
+ break;
+ case C20_30:
+ kbch = 43008;
+ break;
+ case C124_180:
+ kbch = 44448;
+ break;
+ case C25_36:
+ kbch = 44808;
+ break;
+ case C128_180:
+ kbch = 45888;
+ break;
+ case C13_18:
+ kbch = 46608;
+ break;
+ case C132_180:
+ kbch = 47328;
+ break;
+ case C22_30:
+ kbch = 47328;
+ break;
+ case C135_180:
+ kbch = 48408;
+ break;
+ case C140_180:
+ kbch = 50208;
+ break;
+ case C7_9:
+ kbch = 50208;
+ break;
+ case C154_180:
+ kbch = 55248;
+ break;
+ default:
+ kbch = 0;
+ break;
+ }
+ }
+ else {
+ switch (rate) {
+ case C1_4:
+ kbch = 3072;
+ break;
+ case C1_3:
+ kbch = 5232;
+ break;
+ case C2_5:
+ kbch = 6312;
+ break;
+ case C1_2:
+ kbch = 7032;
+ break;
+ case C3_5:
+ kbch = 9552;
+ break;
+ case C2_3:
+ kbch = 10632;
+ break;
+ case C3_4:
+ kbch = 11712;
+ break;
+ case C4_5:
+ kbch = 12432;
+ break;
+ case C5_6:
+ kbch = 13152;
+ break;
+ case C8_9:
+ kbch = 14232;
+ break;
+ case C11_45:
+ kbch = 3792;
+ break;
+ case C4_15:
+ kbch = 4152;
+ break;
+ case C14_45:
+ kbch = 4872;
+ break;
+ case C7_15:
+ kbch = 7392;
+ break;
+ case C8_15:
+ kbch = 8472;
+ break;
+ case C26_45:
+ kbch = 9192;
+ break;
+ case C32_45:
+ kbch = 11352;
+ break;
+ default:
+ kbch = 0;
+ break;
+ }
+ }
+
+ if (standard == STANDARD_DVBS2) {
+ mode = INPUTMODE_NORMAL;
+ inband_type_b = FALSE;
+ }
+ f->ts_gs = TS_GS_TRANSPORT;
+ f->sis_mis = SIS_MIS_SINGLE;
+ f->ccm_acm = CCM;
+ f->issyi = ISSYI_NOT_ACTIVE;
+ f->npd = NPD_NOT_ACTIVE;
+ if (mode == INPUTMODE_NORMAL) {
+ f->upl = 188 * 8;
+ f->dfl = kbch - 80;
+ f->sync = 0x47;
+ }
+ else {
+ f->upl = 0;
+ f->dfl = kbch - 80;
+ f->sync = 0;
+ }
+ if (standard == STANDARD_DVBS2) {
+ if (rolloff & 0x4) {
+ dvbs2x = TRUE;
+ }
+ f->ro = rolloff & 0x3;
+ }
+ else {
+ f->ro = 0;
+ }
+
+ build_crc8_table();
+ input_mode = mode;
+ inband_type_b = inband;
+ fec_blocks = fecblocks;
+ fec_block = 0;
+ ts_rate = tsrate;
+ extra = (((kbch - 80) / 8) / 187) + 1;
+ set_output_multiple(kbch);
+ }
+
+ /*
+ * Our virtual destructor.
+ */
+ dvb_bbheader_bb_impl::~dvb_bbheader_bb_impl()
+ {
+ }
+
+ void
+ dvb_bbheader_bb_impl::forecast (int noutput_items, gr_vector_int &ninput_items_required)
+ {
+ if (input_mode == INPUTMODE_NORMAL) {
+ ninput_items_required[0] = ((noutput_items - 80) / 8);
+ }
+ else {
+ ninput_items_required[0] = ((noutput_items - 80) / 8) + extra;
+ }
+ }
+
+#define CRC_POLY 0xAB
+// Reversed
+#define CRC_POLYR 0xD5
+
+ void
+ dvb_bbheader_bb_impl::build_crc8_table(void)
+ {
+ int r,crc;
+
+ for (int i = 0; i < 256; i++) {
+ r = i;
+ crc = 0;
+ for (int j = 7; j >= 0; j--) {
+ if ((r & (1 << j) ? 1 : 0) ^ ((crc & 0x80) ? 1 : 0)) {
+ crc = (crc << 1) ^ CRC_POLYR;
+ }
+ else {
+ crc <<= 1;
+ }
+ }
+ crc_tab[i] = crc;
+ }
+ }
+
+ /*
+ * MSB is sent first
+ *
+ * The polynomial has been reversed
+ */
+ int
+ dvb_bbheader_bb_impl::add_crc8_bits(unsigned char *in, int length)
+ {
+ int crc = 0;
+ int b;
+ int i = 0;
+
+ for (int n = 0; n < length; n++) {
+ b = in[i++] ^ (crc & 0x01);
+ crc >>= 1;
+ if (b) {
+ crc ^= CRC_POLY;
+ }
+ }
+
+ if (input_mode == INPUTMODE_HIEFF) {
+ crc ^= 0x80;
+ }
+
+ for (int n = 0; n < 8; n++) {
+ in[i++] = (crc & (1 << n)) ? 1 : 0;
+ }
+ return 8;// Length of CRC
+ }
+
+ void
+ dvb_bbheader_bb_impl::add_bbheader(unsigned char *out, int count, int padding)
+ {
+ int temp, m_frame_offset_bits;
+ unsigned char *m_frame = out;
+ BBHeader *h = &m_format[0].bb_header;
+
+ m_frame[0] = h->ts_gs >> 1;
+ m_frame[1] = h->ts_gs & 1;
+ m_frame[2] = h->sis_mis;
+ m_frame[3] = h->ccm_acm;
+ m_frame[4] = h->issyi & 1;
+ m_frame[5] = h->npd & 1;
+ if (dvbs2x == TRUE) {
+ if (alternate == TRUE) {
+ alternate = FALSE;
+ m_frame[6] = 1;
+ m_frame[7] = 1;
+ }
+ else {
+ alternate = TRUE;
+ m_frame[6] = h->ro >> 1;
+ m_frame[7] = h->ro & 1;
+ }
+ }
+ else {
+ m_frame[6] = h->ro >> 1;
+ m_frame[7] = h->ro & 1;
+ }
+ m_frame_offset_bits = 8;
+ if (h->sis_mis == SIS_MIS_MULTIPLE) {
+ temp = h->isi;
+ for (int n = 7; n >= 0; n--) {
+ m_frame[m_frame_offset_bits++] = temp & (1 << n) ? 1 : 0;
+ }
+ }
+ else {
+ for (int n = 7; n >= 0; n--) {
+ m_frame[m_frame_offset_bits++] = 0;
+ }
+ }
+ temp = h->upl;
+ for (int n = 15; n >= 0; n--) {
+ m_frame[m_frame_offset_bits++] = temp & (1 << n) ? 1 : 0;
+ }
+ temp = h->dfl - padding;
+ for (int n = 15; n >= 0; n--) {
+ m_frame[m_frame_offset_bits++] = temp & (1 << n) ? 1 : 0;
+ }
+ temp = h->sync;
+ for (int n = 7; n >= 0; n--) {
+ m_frame[m_frame_offset_bits++] = temp & (1 << n) ? 1 : 0;
+ }
+ // Calculate syncd, this should point to the MSB of the CRC
+ temp = count;
+ if (temp == 0) {
+ temp = count;
+ }
+ else {
+ temp = (188 - count) * 8;
+ }
+ for (int n = 15; n >= 0; n--) {
+ m_frame[m_frame_offset_bits++] = temp & (1 << n) ? 1 : 0;
+ }
+ // Add CRC to BB header, at end
+ int len = BB_HEADER_LENGTH_BITS;
+ m_frame_offset_bits += add_crc8_bits(m_frame, len);
+ }
+
+ void
+ dvb_bbheader_bb_impl::add_inband_type_b(unsigned char *out, int ts_rate)
+ {
+ int temp, m_frame_offset_bits;
+ unsigned char *m_frame = out;
+
+ m_frame[0] = 0;
+ m_frame[1] = 1;
+ m_frame_offset_bits = 2;
+ temp = 0;
+ for (int n = 30; n >= 0; n--) {
+ m_frame[m_frame_offset_bits++] = temp & (1 << n) ? 1 : 0;
+ }
+ temp = 0;
+ for (int n = 21; n >= 0; n--) {
+ m_frame[m_frame_offset_bits++] = temp & (1 << n) ? 1 : 0;
+ }
+ temp = 0;
+ for (int n = 1; n >= 0; n--) {
+ m_frame[m_frame_offset_bits++] = temp & (1 << n) ? 1 : 0;
+ }
+ temp = 0;
+ for (int n = 9; n >= 0; n--) {
+ m_frame[m_frame_offset_bits++] = temp & (1 << n) ? 1 : 0;
+ }
+ temp = ts_rate;
+ for (int n = 26; n >= 0; n--) {
+ m_frame[m_frame_offset_bits++] = temp & (1 << n) ? 1 : 0;
+ }
+ temp = 0;
+ for (int n = 9; n >= 0; n--) {
+ m_frame[m_frame_offset_bits++] = temp & (1 << n) ? 1 : 0;
+ }
+ }
+
+ int
+ dvb_bbheader_bb_impl::general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ const unsigned char *in = (const unsigned char *) input_items[0];
+ unsigned char *out = (unsigned char *) output_items[0];
+ int consumed = 0;
+ int offset = 0;
+ int padding;
+ unsigned char b;
+
+ for (int i = 0; i < noutput_items; i += kbch) {
+ if (fec_block == 0 && inband_type_b == TRUE) {
+ padding = 104;
+ }
+ else {
+ padding = 0;
+ }
+ add_bbheader(&out[offset], count, padding);
+ offset = offset + 80;
+
+ if (input_mode == INPUTMODE_HIEFF) {
+ for (int j = 0; j < (int)((kbch - 80 - padding) / 8); j++) {
+ if (count == 0) {
+ if (*in != 0x47) {
+ printf("Transport Stream sync error!\n");
+ }
+ j--;
+ in++;
+ }
+ else {
+ b = *in++;
+ for (int n = 7; n >= 0; n--) {
+ out[offset++] = b & (1 << n) ? 1 : 0;
+ }
+ }
+ count = (count + 1) % 188;
+ consumed++;
+ }
+ if (fec_block == 0 && inband_type_b == TRUE) {
+ add_inband_type_b(&out[offset], ts_rate);
+ offset = offset + 104;
+ }
+ }
+ else {
+ for (int j = 0; j < (int)((kbch - 80 - padding) / 8); j++) {
+ if (count == 0) {
+ if (*in != 0x47) {
+ printf("Transport Stream sync error!\n");
+ }
+ in++;
+ b = crc;
+ crc = 0;
+ }
+ else {
+ b = *in++;
+ crc = crc_tab[b ^ crc];
+ }
+ count = (count + 1) % 188;
+ consumed++;
+ for (int n = 7; n >= 0; n--) {
+ out[offset++] = b & (1 << n) ? 1 : 0;
+ }
+ }
+ if (fec_block == 0 && inband_type_b == TRUE) {
+ add_inband_type_b(&out[offset], ts_rate);
+ offset = offset + 104;
+ }
+ }
+ if (inband_type_b == TRUE) {
+ fec_block = (fec_block + 1) % fec_blocks;
+ }
+ }
+
+ // Tell runtime system how many input items we consumed on
+ // each input stream.
+ consume_each (consumed);
+
+ // Tell runtime system how many output items we produced.
+ return noutput_items;
+ }
+
+ } /* namespace dtv */
+} /* namespace gr */
+