Mailing List archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[vdr] SPEEDUP: processing audio in transfer thread
Hi,
some time ago, I've asked why watching channels/recordings with dolby audio
over vdr-xine consumes much more CPU time (e. g. 30 % vs. 17 % on my system).
Today, I've accidentially found the reason: the transfer thread plays dolby
audio via PlayAudio() and then zeros out the dolby packets, so that they don't
get played again, when the packet is later sent via PlayVideo().
The higher CPU load is caused by xine's demuxer when it is skipping the huge
amount of zero bytes while looking for the next packet start indication (0x00
0x00 0x01). The next release of vdr-xine will also contain a fix for xine, to
speed up syncing on the next packet.
Back to VDR: typically -- if the stream is not distorted by bad reception for
example -- the transfer thread operates on a buffer with a single complete PES
packet. Zeroing out a dolby packet then means to zero out the whole buffer.
The attached patch checks for this case and simply drops the complete buffer
then. The result is, that a memset(), a buffer transfer to xine and a resync
loop in xine get saved.
The patch could be further optimized: instead of zeroing out a PES packet in
the case where more than one packet is in the buffer, the packet's stream id
could simply be changed to 0xBE. This would make the packet part of an padding
stream. According to the PES specs, a padding packet should be filled with
padding bytes, which have the value 0xFF, but xine doesn't demand on it. The
biggest improvement in xine would therefore be, that there is no resync loop
necessary to skip the packet.
As I don't own a full featured card, I only can test with xine. That's why I
didn't implement the optimization described above. Therefore, maybe people
with full featured cards should implement and test the described optimization.
Bye.
--
Dipl.-Inform. (FH) Reinhard Nissl
mailto:rnissl@gmx.de
--- ../vdr-1.3.11-orig/transfer.c 2004-03-07 15:40:15.000000000 +0100
+++ transfer.c 2004-06-23 21:51:46.157015872 +0200
@@ -96,7 +98,8 @@ void cTransfer::Action(void)
uchar *p = remux->Process(b, Count, Result);
ringBuffer->Del(Count);
if (p) {
- StripAudioPackets(p, Result, audioTrack);
+ if (StripAudioPackets(p, Result, audioTrack))
+ continue; // drop complete frame
while (Result > 0 && active) {
cPoller Poller;
if (DevicePoll(Poller, 100)) {
@@ -126,7 +129,7 @@ void cTransfer::Action(void)
}
}
-void cTransfer::StripAudioPackets(uchar *b, int Length, uchar Except)
+bool cTransfer::StripAudioPackets(uchar *b, int Length, uchar Except)
{
for (int i = 0; i < Length - 6; i++) {
if (b[i] == 0x00 && b[i + 1] == 0x00 && b[i + 2] == 0x01) {
@@ -140,8 +143,11 @@ void cTransfer::StripAudioPackets(uchar
case 0xC0 ... 0xC1: // audio
if (c == 0xC1)
canToggleAudioTrack = true;
- if (!Except || c != Except)
+ if (!Except || c != Except) {
+ if (i == 0 && l == Length)
+ return true; // drop complete frame
memset(&b[i], 0x00, min(l, Length-i));
+ }
break;
case 0xE0 ... 0xEF: // video
break;
@@ -157,6 +163,7 @@ void cTransfer::StripAudioPackets(uchar
esyslog("ERROR: broken packet header");
XXX*/
}
+ return false;
}
int cTransfer::NumAudioTracks(void) const
--- ../vdr-1.3.11-orig/transfer.h 2003-05-11 10:48:36.000000000 +0200
+++ transfer.h 2004-06-23 21:43:56.782495041 +0200
@@ -24,7 +24,7 @@ private:
uchar audioTrack;
bool gotBufferReserve;
bool active;
- void StripAudioPackets(uchar *b, int Length, uchar Except = 0x00);
+ bool StripAudioPackets(uchar *b, int Length, uchar Except = 0x00);
protected:
virtual void Activate(bool On);
virtual void Receive(uchar *Data, int Length);
Home |
Main Index |
Thread Index