[mythtv-users] backend takes 100% CPU recording DVB-T
Stephen Williams
stephen.gw at gmail.com
Wed Apr 19 12:47:07 UTC 2006
It looks like ticket #1694 is related. This ticket (unfortunately
closed) proposed the backporting of a number of EIT efficiency fixes
to the 0.19-fixes branch with the aim of reducing CPU usage.
I've put together a unified patch for the fixes mentioned in that
ticket (attached below). I'm not in a position to try this out myself
for a day or two but if anybody feels like giving it a whirl then I
think we'd all be interested to know if this has any beneficial
effect.
Stephen
>>>>>
Index: /trunk/mythtv/libs/libmythtv/mpeg/dvbdescriptors.cpp
===================================================================
--- /trunk/mythtv/libs/libmythtv/mpeg/dvbdescriptors.cpp (revision 9157)
+++ /trunk/mythtv/libs/libmythtv/mpeg/dvbdescriptors.cpp (revision 9220)
@@ -5,64 +5,86 @@
#include <qdeepcopy.h>
+// Only some of the QTextCodec calls are reenterant.
+// If you use this please verify that you are using a reenterant call.
+static const QTextCodec *iso8859_codecs[16] =
+{
+ QTextCodec::codecForName("Latin1"),
+ QTextCodec::codecForName("ISO8859-1"), // Western
+ QTextCodec::codecForName("ISO8859-2"), // Central European
+ QTextCodec::codecForName("ISO8859-3"), // Central European
+ QTextCodec::codecForName("ISO8859-4"), // Baltic
+ QTextCodec::codecForName("ISO8859-5"), // Cyrillic
+ QTextCodec::codecForName("ISO8859-6"), // Arabic
+ QTextCodec::codecForName("ISO8859-7"), // Greek
+ QTextCodec::codecForName("ISO8859-8"), // Hebrew, visually ordered
+ QTextCodec::codecForName("ISO8859-9"), // Turkish
+ QTextCodec::codecForName("ISO8859-10"),
+ QTextCodec::codecForName("ISO8859-11"),
+ QTextCodec::codecForName("ISO8859-12"),
+ QTextCodec::codecForName("ISO8859-13"),
+ QTextCodec::codecForName("ISO8859-14"),
+ QTextCodec::codecForName("ISO8859-15"), // Western
+};
+
// Decode a text string according to ETSI EN 300 468 Annex A
-QString dvb_decode_text(const unsigned char *src, uint length)
-{
- QString result;
-
+QString dvb_decode_text(const unsigned char *src, uint raw_length)
+{
+ if (!raw_length)
+ return "";
+
+ if ((0x10 < src[0]) && (src[0] < 0x20))
+ {
+ // TODO: Handle multi-byte encodings
+ VERBOSE(VB_SIPARSER, "dvb_decode_text: "
+ "Multi-byte coded text is not yet supported.");
+ return "";
+ }
+
+ // Strip formatting characters
+ char dst[raw_length];
+ uint length = 0;
+ for (uint i = 0; i < raw_length; i++)
+ {
+ if ((src[i] < 0x80) || (src[i] > 0x9F))
+ {
+ dst[length] = src[i];
+ length++;
+ }
+ }
+ const char *buf = dst;
+
+ // Exit on empty string, sans formatting.
if (!length)
- return QString("");
-
- unsigned char buf[length];
- memcpy(buf, src, length);
-
- if ((buf[0] <= 0x10) || (buf[0] >= 0x20))
- {
- // Strip formatting characters
- for (uint p = 0; p < length; p++)
- {
- if ((buf[p] >= 0x80) && (buf[p] <= 0x9F))
- memmove(buf + p, buf + p + 1, --length - p);
- }
-
- if (buf[0] >= 0x20)
- {
- result = QString::fromLatin1((const char*)buf, length);
- }
- else if ((buf[0] >= 0x01) && (buf[0] <= 0x0B))
- {
- QString coding = "ISO8859-" + QString::number(4 + buf[0]);
- QTextCodec *codec = QTextCodec::codecForName(coding);
- result = codec->toUnicode((const char*)buf + 1, length - 1);
- }
- else if (buf[0] == 0x10)
- {
- // If the first byte of the text field has a value "0x10"
- // then the following two bytes carry a 16-bit value (uimsbf) N
- // to indicate that the remaining data of the text field is
- // coded using the character code table specified by
- // ISO Standard 8859, parts 1 to 9
-
- uint code = 1;
- swab(buf + 1, &code, 2);
- QString coding = "ISO8859-" + QString::number(code);
- QTextCodec *codec = QTextCodec::codecForName(coding);
- result = codec->toUnicode((const char*)buf + 3, length - 3);
- }
+ return "";
+
+ // Decode using the correct text codec
+ if (buf[0] >= 0x20)
+ {
+ return QString::fromLatin1(buf, length);
+ }
+ else if ((buf[0] >= 0x01) && (buf[0] <= 0x0B))
+ {
+ return iso8859_codecs[4 + buf[0]]->toUnicode(buf + 1, length - 1);
+ }
+ else if (buf[0] == 0x10)
+ {
+ // If the first byte of the text field has a value "0x10"
+ // then the following two bytes carry a 16-bit value (uimsbf) N
+ // to indicate that the remaining data of the text field is
+ // coded using the character code table specified by
+ // ISO Standard 8859, parts 1 to 9
+
+ uint code = 1;
+ swab(buf + 1, &code, 2);
+ if (code <= 15)
+ return iso8859_codecs[code]->toUnicode(buf + 3, length - 3);
else
- {
- // Unknown/invalid encoding - assume local8Bit
- result = QString::fromLocal8Bit((const char*)buf + 1, length - 1);
- }
+ return QString::fromLocal8Bit(buf + 3, length - 3);
}
else
{
- // TODO: Handle multi-byte encodings
-
- VERBOSE(VB_SIPARSER, "dvbdescriptors.cpp: "
- "Multi-byte coded text - not supported!");
- result = "N/A";
- }
-
- return result;
+ // Unknown/invalid encoding - assume local8Bit
+ return QString::fromLocal8Bit(buf + 1, length - 1);
+ }
}
Index: trunk/mythtv/libs/libmythtv/mpeg/pespacket.cpp
===================================================================
--- trunk/mythtv/libs/libmythtv/mpeg/pespacket.cpp (revision 9203)
+++ trunk/mythtv/libs/libmythtv/mpeg/pespacket.cpp (revision 9337)
@@ -136,13 +146,14 @@
static map<unsigned char*, bool> alloc4096;
-#define BLOCKS188 1000
+#define BLOCKS188 512
static unsigned char* get_188_block()
{
- if (!free188.size())
+ if (free188.empty())
{
mem188.push_back((unsigned char*) malloc(188 * BLOCKS188));
free188.reserve(BLOCKS188);
+ unsigned char* block_start = mem188.back();
for (uint i = 0; i < BLOCKS188; ++i)
- free188.push_back(i*188 + mem188.back());
+ free188.push_back(i*188 + block_start);
}
@@ -162,7 +173,7 @@
{
alloc188.erase(ptr);
- if (alloc188.size())
- free188.push_back(ptr);
- else
+ free188.push_back(ptr);
+ // free the allocator only if more than 1 block was used
+ if (alloc188.empty() && mem188.size() > 1)
{
vector<unsigned char*>::iterator it;
@@ -175,13 +186,14 @@
}
-#define BLOCKS4096 256
+#define BLOCKS4096 128
static unsigned char* get_4096_block()
{
- if (!free4096.size())
+ if (free4096.empty())
{
mem4096.push_back((unsigned char*) malloc(4096 * BLOCKS4096));
free4096.reserve(BLOCKS4096);
+ unsigned char* block_start = mem4096.back();
for (uint i = 0; i < BLOCKS4096; ++i)
- free4096.push_back(i*4096 + mem4096.back());
+ free4096.push_back(i*4096 + block_start);
}
@@ -201,7 +213,5 @@
{
alloc4096.erase(ptr);
- if (alloc4096.size())
- {
- free4096.push_back(ptr);
+ free4096.push_back(ptr);
#if 0 // enable this to debug memory leaks
@@ -221,6 +231,7 @@
}
#endif
- }
- else
+
+ // free the allocator only if more than 1 block was used
+ if (alloc4096.empty() && mem4096.size() > 1)
{
vector<unsigned char*>::iterator it;
More information about the mythtv-users
mailing list