summaryrefslogtreecommitdiffstats
path: root/src/Dmb.cpp
diff options
context:
space:
mode:
authorMatthias (think) <matthias@mpb.li>2012-07-11 11:49:12 +0200
committerMatthias (think) <matthias@mpb.li>2012-07-11 11:49:12 +0200
commitbbab73a63b8c7b50e8a8cb228999d45024fad984 (patch)
tree81a822aa9bd33cae8a5fb8ade4faa83b652316d9 /src/Dmb.cpp
downloaddabmux-bbab73a63b8c7b50e8a8cb228999d45024fad984.tar.gz
dabmux-bbab73a63b8c7b50e8a8cb228999d45024fad984.tar.bz2
dabmux-bbab73a63b8c7b50e8a8cb228999d45024fad984.zip
added unmodified mmbtools
Diffstat (limited to 'src/Dmb.cpp')
-rw-r--r--src/Dmb.cpp280
1 files changed, 280 insertions, 0 deletions
diff --git a/src/Dmb.cpp b/src/Dmb.cpp
new file mode 100644
index 0000000..95742d0
--- /dev/null
+++ b/src/Dmb.cpp
@@ -0,0 +1,280 @@
+/*
+ Copyright (C) 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in Right
+ of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-DabMux 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 of the
+ License, or (at your option) any later version.
+
+ CRC-DabMux 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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Dmb.h"
+
+#include <string.h>
+
+
+#ifdef _WIN32
+# define bzero(a, b) memset((a), 0, (b))
+#endif // _WIN32
+
+
+DmbStats::DmbStats()
+{
+ reset();
+}
+
+
+void DmbStats::reset()
+{
+ memset(this, 0, sizeof(*this));
+}
+
+
+Dmb::Dmb(bool reverse) :
+interleaver(12, 17),
+encoder(204, 188)
+{
+ buffer = NULL;
+ bufferSize = 0;
+ setReverse(reverse);
+}
+
+
+Dmb::~Dmb()
+{
+ if (buffer != NULL) {
+ delete[] buffer;
+ }
+}
+
+
+void Dmb::setReverse(bool state)
+{
+ reverse = state;
+ reset();
+
+ interleaver.setReverse(state);
+ encoder.setReverse(state);
+ stats.reset();
+}
+
+
+void Dmb::reset()
+{
+ bufferOffset = 0;
+ bufferLength = 0;
+ inputOffset = 0;
+ outputOffset = 0;
+// padding = 0;
+}
+
+
+#include <stdio.h>
+int Dmb::encode(
+ void* dataIn,
+ unsigned long sizeIn,
+ void* dataOut,
+ unsigned long sizeOut
+ )
+{
+ int ret = 0;
+ char* input = reinterpret_cast<char*>(dataIn);
+ char* output = reinterpret_cast<char*>(dataOut);
+
+ if (bufferSize < sizeIn + 204) {
+ if (buffer != NULL) {
+ delete[] buffer;
+ }
+ unsigned char* oldBuffer = buffer;
+ bufferSize = sizeIn + 204;
+ buffer = new unsigned char[bufferSize];
+ memcpy(buffer, oldBuffer, bufferLength);
+ }
+
+ if (reverse) {
+// fprintf(stderr, "*** Decode ***\n");
+// fprintf(stderr, " sizeIn: %i\n", sizeIn);
+// fprintf(stderr, " inputOffset: %i\n", inputOffset);
+// fprintf(stderr, " bufferLength: %i\n", bufferLength);
+// fprintf(stderr, " bufferOffset: %i\n", bufferOffset);
+// fprintf(stderr, " outputOffset: %i\n", outputOffset);
+
+ if (inputOffset == 0) {
+ ++stats.dmbFrame;
+ stats.rcvBytes += sizeIn;
+ }
+
+ memcpy(&buffer[bufferLength], &input[inputOffset],
+ sizeIn - inputOffset);
+ interleaver.encode(&buffer[bufferLength], sizeIn - inputOffset);
+ bufferLength += sizeIn - inputOffset;
+ inputOffset += sizeIn - inputOffset;
+ while (bufferLength - bufferOffset >= 204) {
+ if (buffer[bufferOffset] != 0x47) {
+ int offset = sync(&buffer[bufferOffset],
+ bufferLength - bufferOffset);
+ if (offset == 0) {
+ bufferLength = 0;
+ bufferOffset = 0;
+ } else {
+ bufferOffset += offset;
+ }
+ } else {
+ if (outputOffset + 188 <= sizeOut) { // If enough place
+ int error = encoder.encode(&buffer[bufferOffset], 204);
+ if (error != -1) {
+// if (true) {
+ if (error > 0) {
+ stats.corBytes += error;
+ }
+ memcpy(&output[outputOffset], &buffer[bufferOffset],
+ 188);
+ if (((buffer[bufferOffset + 1] & 0x1f) == 0x1f) &&
+ (buffer[bufferOffset + 2] == 0xff)) {
+ stats.nulBytes += 188;
+ } else {
+ ret += 188;
+ stats.sndBytes += 188;
+ outputOffset += 188;
+ }
+ bufferOffset += 204;
+ ++stats.mpgFrame;
+ } else {
+// interleaver.reset();
+// padding = 0;
+// bufferLength = 0;
+// inputOffset = 0;
+// stats.errBytes += 188;
+ bufferOffset += 12;
+ stats.errBytes += 12;
+ ++stats.synFrame;
+ int offset = sync (&buffer[bufferOffset],
+ bufferLength - bufferOffset);
+ if (offset == 0) {
+ stats.errBytes += bufferLength - bufferOffset;
+ bufferOffset = 0;
+ bufferLength = 0;
+ } else {
+ stats.errBytes += offset;
+ bufferOffset += offset;
+ }
+ }
+ } else {
+ outputOffset = 0;
+ goto ENCODE_END;
+ }
+ }
+ }
+ memmove(buffer, &buffer[bufferOffset], bufferLength - bufferOffset);
+ bufferLength -= bufferOffset;
+ bufferOffset = 0;
+ if (ret == 0) {
+ inputOffset = 0;
+ } else {
+ outputOffset = 0;
+ }
+// fprintf(stderr, " ret: %i\n\n", ret);
+ } else {
+ if (sizeIn == 0) {
+ bzero(&output[outputOffset], sizeOut - outputOffset);
+ interleaver.encode(&output[outputOffset], sizeOut - outputOffset);
+ outputOffset = 0;
+ ++stats.dmbFrame;
+ stats.sndBytes += sizeOut;
+ goto ENCODE_END;
+ }
+
+ if (bufferLength == 204) { // If buffer is not empty
+ // If there's more data in buffer than place in output
+ if (204 - bufferOffset > sizeOut - outputOffset) {
+ memcpy(&output[outputOffset], &buffer[bufferOffset],
+ sizeOut - outputOffset);
+ bufferOffset += sizeOut - outputOffset;
+ outputOffset = 0;
+ ++stats.dmbFrame;
+ stats.sndBytes += sizeOut;
+ goto ENCODE_END;
+ }
+ memcpy(&output[outputOffset], &buffer[bufferOffset],
+ 204 - bufferOffset);
+ outputOffset += 204 - bufferOffset;
+ bufferOffset = 0;
+ bufferLength = 0;
+ }
+
+ while (true) {
+ // If there's not enought input data
+ if (sizeIn - inputOffset < 188 - bufferLength) {
+ memcpy(&buffer[bufferLength], &input[inputOffset],
+ sizeIn - inputOffset);
+ bufferLength += sizeIn - inputOffset;
+ ret = outputOffset;
+ inputOffset = 0;
+ goto ENCODE_END;
+ }
+ if (buffer[bufferLength] == 0x47) {
+ ++stats.mpgFrame;
+ }
+// fprintf(stderr, "++mpg: %i, sizeIn: %i, inputOffset: %i\n",
+// stats.mpgFrame, sizeIn, inputOffset);
+ stats.rcvBytes += 188;
+
+ memcpy(&buffer[bufferLength], &input[inputOffset],
+ 188 - bufferLength);
+ inputOffset += 188 - bufferLength;
+
+ encoder.encode(buffer, 188);
+ interleaver.encode(buffer, 204);
+ bufferLength = 204;
+
+ if (sizeOut - outputOffset < 204) {
+ memcpy(&output[outputOffset], buffer, sizeOut - outputOffset);
+ bufferOffset += sizeOut - outputOffset;
+ outputOffset = 0;
+ ++stats.dmbFrame;
+ stats.sndBytes += sizeOut;
+ goto ENCODE_END;
+ }
+ memcpy(&output[outputOffset], buffer, 204);
+ outputOffset += 204;
+ bufferLength = 0;
+ }
+ }
+
+ENCODE_END:
+ return ret;
+}
+
+
+int Dmb::sync(void* dataIn, unsigned long sizeIn)
+{
+ char* input = reinterpret_cast<char*>(dataIn);
+ char* sync = input;
+ unsigned long size = sizeIn;
+
+ while (sync != NULL) {
+ sync = (char*)memchr(sync, 0x47, size);
+ if (sync != NULL) {
+ int offset = sync - input;
+ if (offset % 12 != 0) {
+ offset = ((offset / 12) * 12) + 12;
+ sync = &input[offset];
+ size = sizeIn - offset;
+ } else {
+ return offset;
+ }
+ }
+ }
+ return 0;
+}