diff options
-rw-r--r-- | dabplussnoop.cpp | 149 | ||||
-rw-r--r-- | dabplussnoop.h | 20 | ||||
-rw-r--r-- | etisnoop.cpp | 60 |
3 files changed, 175 insertions, 54 deletions
diff --git a/dabplussnoop.cpp b/dabplussnoop.cpp index 40cb124..c0fbcca 100644 --- a/dabplussnoop.cpp +++ b/dabplussnoop.cpp @@ -26,6 +26,7 @@ #include <stdlib.h> #include <string.h> #include <string> +#include <cassert> #include <sstream> #include <algorithm> #include <vector> @@ -34,7 +35,9 @@ #include "lib_crc.h" #define DPS_INDENT "\t\t" -#define DPS_PREFIX "DABPLUS:" +#define DPS_PREFIX "DAB+ decode:" + +#define DPS_DEBUG 0 using namespace std; @@ -82,13 +85,17 @@ bool DabPlusSnoop::seek_valid_firecode() } if (crc_ok) { - fprintf(stderr, DPS_PREFIX " Found valid FireCode at %zu\n", i); +#if DPS_DEBUG + printf(DPS_PREFIX " Found valid FireCode at %zu\n", i); +#endif m_data.erase(m_data.begin(), m_data.begin() + i); return true; } else { - fprintf(stderr, DPS_PREFIX " No valid FireCode found\n"); +#if DPS_DEBUG + printf(DPS_PREFIX " No valid FireCode found\n"); +#endif m_data.clear(); return false; @@ -97,9 +104,11 @@ bool DabPlusSnoop::seek_valid_firecode() bool DabPlusSnoop::decode() { - fprintf(stderr, DPS_PREFIX " We have %zu bytes of data\n", m_data.size()); +#if DPS_DEBUG + printf(DPS_PREFIX " We have %zu bytes of data\n", m_data.size()); +#endif - if (m_subchannel_index && m_data.size() >= m_subchannel_index * 110) { + if (m_subchannel_index && m_data.size() >= m_subchannel_index * 120) { uint8_t* b = &m_data[0]; @@ -125,8 +134,7 @@ bool DabPlusSnoop::decode() else if ((dac_rate == 1) && (sbr_flag == 0)) num_aus = 6; // AAC core sampling rate 48 kHz - fprintf(stderr, - DPS_INDENT DPS_PREFIX "\n" + printf( DPS_INDENT DPS_PREFIX "\n" DPS_INDENT "\tfirecode 0x%x\n" DPS_INDENT "\trfa %d\n" DPS_INDENT "\tdac_rate %d\n" @@ -151,20 +159,15 @@ bool DabPlusSnoop::decode() char nibble = b[i/2] >> 4; au_start_nibbles.push_back( nibble ); - - fprintf(stderr, "0x%1x", nibble); } else { char nibble = b[i/2] & 0x0F; au_start_nibbles.push_back( nibble ); - - fprintf(stderr, "0x%1x", nibble); } } - fprintf(stderr, "\n"); vector<int> au_start(num_aus); @@ -179,7 +182,6 @@ bool DabPlusSnoop::decode() int nib = 0; - fprintf(stderr, DPS_INDENT DPS_PREFIX " AU start\n"); for (int au = 1; au < num_aus; au++) { au_start[au] = au_start_nibbles[nib] << 8 | \ au_start_nibbles[nib+1] << 4 | \ @@ -188,41 +190,41 @@ bool DabPlusSnoop::decode() nib += 3; } +#if DPS_DEBUG + printf(DPS_INDENT DPS_PREFIX " AU start\n"); for (int au = 0; au < num_aus; au++) { - fprintf(stderr, DPS_INDENT "\tAU[%d] %d 0x%x\n", au, + printf(DPS_INDENT "\tAU[%d] %d 0x%x\n", au, au_start[au], au_start[au]); } +#endif - return analyse_au(au_start); + return extract_au(au_start); } else { return false; } } -bool DabPlusSnoop::analyse_au(vector<int> au_start) +bool DabPlusSnoop::extract_au(vector<int> au_start) { - - /* - for (int i = 0; i < au_start.length - 1; i++) { - byte[] new_frame = Arrays.copyOfRange(frame, au_start[i], au_start[i+1] - 2); - - int current_crc = MiscTools.getUInt16(frame, au_start[i+1] - 2); - int crc = MiscTools.calcCRC(new_frame, MiscTools.crc_mode.CRC_16_CCITT); - } -*/ - vector<vector<uint8_t> > aus(au_start.size()); + // The last entry of au_start must the end of valid + // AU data. We stop at m_subchannel_index * 110 because + // what comes after is RS parity au_start.push_back(m_subchannel_index * 110); + bool all_crc_ok = true; + for (size_t au = 0; au < aus.size(); au++) { - fprintf(stderr, DPS_PREFIX DPS_INDENT +#if DPS_DEBUG + printf(DPS_PREFIX DPS_INDENT "Copy au %zu of size %zu\n", au, au_start[au+1] - au_start[au]-2 ); +#endif aus[au].resize(au_start[au+1] - au_start[au]-2); std::copy( @@ -242,11 +244,94 @@ bool DabPlusSnoop::analyse_au(vector<int> au_start) } calc_crc =~ calc_crc; - fprintf(stderr, DPS_PREFIX DPS_INDENT - " AU H: %04x C: %04x\n" - " DAU H: %u C: %u\n", - au_crc, calc_crc, - au_crc, calc_crc); + if (calc_crc != au_crc) { + printf(DPS_INDENT DPS_PREFIX + "Erroneous CRC for au %zu\n", au); + + all_crc_ok = false; + } + } + + if (all_crc_ok) { + return analyse_au(aus); + } + else { + return false; + } +} + +bool DabPlusSnoop::analyse_au(vector<vector<uint8_t> >& aus) +{ + for (size_t i_au = 0; i_au < aus.size(); i_au++) { + size_t i = 0; + + vector<uint8_t>& au = aus[i_au]; + + bool continue_au = true; + while (continue_au && i < au.size()) { + printf("R at %zu\n", i); + int id_syn_ele = (au[i] & 0xE0) >> 5; + + /* Debugging print */ + stringstream ss; + ss << DPS_INDENT << "\tID_SYN_ELE: "; + + switch (id_syn_ele) { + case ID_SCE: ss << "Single Channel Element"; break; + case ID_CPE: ss << "Channel Pair Element"; break; + case ID_CCE: ss << "Coupling Channel Element"; break; + case ID_LFE: ss << "LFE Channel Element"; break; + case ID_DSE: ss << "Data Stream Element"; break; + case ID_PCE: ss << "Program Config Element"; break; + case ID_FIL: ss << "Fill Element"; break; + case ID_END: ss << "Terminator"; break; + case ID_EXT: ss << "Extension Payload"; break; + case ID_SCAL: ss << "AAC scalable element"; break; + default: ss << "Unknown (" << id_syn_ele << ")"; break; + } + + int element_instance_tag = (au[i] & 0x78) >> 1; + ss << " [" << element_instance_tag << "]"; + + + // Keep track of index increment in bits + size_t inc = 7; // eat id_syn_ele, element_instance_tag + + if (id_syn_ele == ID_DSE) { + bool data_byte_align_flag = (au[i] & 0x01); + inc++; + + ss << "\n" DPS_INDENT "\t\t"; + if (data_byte_align_flag) { + ss << " <byte align flag>"; + } + + + uint8_t count = au[1]; + int cnt = count; + inc += 8; + + if (count == 255) { + uint8_t esc_count = au[2]; + inc += 8; + + cnt += esc_count; + } + + ss << " cnt:" << cnt; + inc += 8*cnt; + + } + else + { + continue_au = false; + } + + printf("%s\n", ss.str().c_str()); + + assert (inc % 8 == 0); + i += inc / 8; + } } return true; diff --git a/dabplussnoop.h b/dabplussnoop.h index ef0807b..28f94ba 100644 --- a/dabplussnoop.h +++ b/dabplussnoop.h @@ -80,6 +80,23 @@ he_aac_super_frame(subchannel_index) #ifndef __DABPLUSSNOOP_H_ #define __DABPLUSSNOOP_H_ +/** MP4 Element IDs. */ +typedef enum +{ + ID_NONE = -1, /**< Invalid Element helper ID. */ + ID_SCE = 0, /**< Single Channel Element. */ + ID_CPE = 1, /**< Channel Pair Element. */ + ID_CCE = 2, /**< Coupling Channel Element. */ + ID_LFE = 3, /**< LFE Channel Element. */ + ID_DSE = 4, /**< Currently one Data Stream Element for ancillary data is supported. */ + ID_PCE = 5, /**< Program Config Element. */ + ID_FIL = 6, /**< Fill Element. */ + ID_END = 7, /**< Arnie (End Element = Terminator). */ + ID_EXT = 8, /**< Extension Payload (ER only). */ + ID_SCAL = 9, /**< AAC scalable element (ER only). */ + ID_LAST +} MP4_ELEMENT_ID; + class DabPlusSnoop { public: @@ -97,7 +114,8 @@ class DabPlusSnoop private: bool seek_valid_firecode(void); bool decode(void); - bool analyse_au(std::vector<int> au_start); + bool extract_au(std::vector<int> au_start); + bool analyse_au(std::vector<std::vector<uint8_t> >& aus); unsigned m_subchannel_index; std::vector<uint8_t> m_data; diff --git a/etisnoop.cpp b/etisnoop.cpp index 9786fc3..e81741e 100644 --- a/etisnoop.cpp +++ b/etisnoop.cpp @@ -46,6 +46,8 @@ using namespace std; +static int verbosity; + void printbuf(string header, int indent_level, unsigned char* buffer, @@ -59,7 +61,6 @@ void decodeFIG(unsigned char* figdata, struct eti_analyse_config_t { int etifd; - int verbosity; bool ignore_error; std::map<int, DabPlusSnoop> streams_to_decode; }; @@ -94,7 +95,7 @@ int main(int argc, char *argv[]) string file_name("-"); map<int, DabPlusSnoop> streams_to_decode; - int verbosity = 0; + verbosity = 0; bool ignore_error = false; while(ch != -1) { @@ -139,7 +140,6 @@ int main(int argc, char *argv[]) eti_analyse_config_t config = { .etifd = etifd, - .verbosity = verbosity, .ignore_error = ignore_error, .streams_to_decode = streams_to_decode }; @@ -431,8 +431,18 @@ int eti_analyse(eti_analyse_config_t& config) unsigned char streamdata[684*8]; memcpy(streamdata, p + 12 + 4*nst + ficf*ficl*4 + offset, stl[i]*8); offset += stl[i] * 8; - sprintf(sdesc, "id %d, len %d", i, stl[i]*8); - printbuf("Stream Data", 1, streamdata, stl[i]*8, sdesc); + if (config.streams_to_decode.count(i) > 0) { + sprintf(sdesc, "id %d, len %d, selected for decoding", i, stl[i]*8); + } + else { + sprintf(sdesc, "id %d, len %d, not selected for decoding", i, stl[i]*8); + } + if (verbosity > 1) { + printbuf("Stream Data", 1, streamdata, stl[i]*8, sdesc); + } + else { + printbuf("Stream Data", 1, streamdata, 0, sdesc); + } if (config.streams_to_decode.count(i) > 0) { config.streams_to_decode[i].push(streamdata, stl[i]*8); @@ -466,7 +476,9 @@ int eti_analyse(eti_analyse_config_t& config) printbuf("TIST - Time Stamp", 1, p+12+4*nst+ficf*ficl*4+offset+4, 4, sdesc); - printf("-------------------------------------------------------------------------------------------------------------\n"); + if (verbosity) { + printf("-------------------------------------------------------------------------------------------------------------\n"); + } } return 0; } @@ -477,28 +489,34 @@ void printbuf(string header, size_t size, string desc) { - for (int i = 0; i < indent_level; i++) { - printf("\t"); - } + if (verbosity > 0) { + for (int i = 0; i < indent_level; i++) { + printf("\t"); + } - printf("%s", header.c_str()); - if (size != 0) { - printf(": "); - } + printf("%s", header.c_str()); + if (size != 0) { + printf(": "); + } - for (size_t i = 0; i < size; i++) { - printf("%02x ", buffer[i]); - } + for (size_t i = 0; i < size; i++) { + printf("%02x ", buffer[i]); + } - if (desc != "") { - printf(" [%s] ", desc.c_str()); - } + if (desc != "") { + printf(" [%s] ", desc.c_str()); + } - printf("\n"); + printf("\n"); + } } -void decodeFIG(unsigned char* f, unsigned char figlen,unsigned short int figtype, unsigned short int indent) { +void decodeFIG(unsigned char* f, + unsigned char figlen, + unsigned short int figtype, + unsigned short int indent) +{ char desc[256]; |