diff options
author | Klaus Schmidinger <vdr@tvdr.de> | 2008-12-13 14:43:22 +0100 |
---|---|---|
committer | Klaus Schmidinger <vdr@tvdr.de> | 2008-12-13 14:43:22 +0100 |
commit | 22feb7bf1cfc0bff0742fd23657de853b63f1890 (patch) | |
tree | b6c7434ae85cdcd507277ea622c2b5d34f0ccc23 | |
parent | 3c7d1a16aca49c647320c0ee67759007fa06a845 (diff) | |
download | vdr-22feb7bf1cfc0bff0742fd23657de853b63f1890.tar.gz vdr-22feb7bf1cfc0bff0742fd23657de853b63f1890.tar.bz2 |
Improved handling PES video packets with zero length when converting from TS to PES
-rw-r--r-- | HISTORY | 1 | ||||
-rw-r--r-- | device.c | 16 | ||||
-rw-r--r-- | dvbdevice.c | 17 | ||||
-rw-r--r-- | remux.c | 37 | ||||
-rw-r--r-- | remux.h | 8 |
5 files changed, 58 insertions, 21 deletions
@@ -5840,3 +5840,4 @@ Video Disk Recorder Revision History and Edgar Hucek). - The cDvbTuner::IsTunedTo() function now also checks the symbol rate in case of DVB-S and DVB-C. +- Improved handling PES video packets with zero length when converting from TS to PES. @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: device.c 2.3 2008/07/06 13:22:21 kls Exp $ + * $Id: device.c 2.4 2008/12/13 14:30:28 kls Exp $ */ #include "device.h" @@ -1228,13 +1228,13 @@ int cDevice::PlayTsVideo(const uchar *Data, int Length) // Video PES has no explicit length, so we can only determine the end of // a PES packet when the next TS packet that starts a payload comes in: if (TsPayloadStart(Data)) { - if (const uchar *p = tsToPesVideo.GetPes(Length)) { - int w = PlayVideo(p, Length); - if (w > 0) - tsToPesVideo.Reset(); - else - return w; - } + int l; + while (const uchar *p = tsToPesVideo.GetPes(l)) { + int w = PlayVideo(p, l); + if (w < 0) + return w; + } + tsToPesVideo.Reset(); } tsToPesVideo.PutTs(Data, Length); return Length; diff --git a/dvbdevice.c b/dvbdevice.c index 18caabd8..e0b05a15 100644 --- a/dvbdevice.c +++ b/dvbdevice.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbdevice.c 2.5 2008/12/13 12:22:36 kls Exp $ + * $Id: dvbdevice.c 2.6 2008/12/13 14:38:07 kls Exp $ */ #include "dvbdevice.h" @@ -1266,18 +1266,25 @@ bool cDvbDevice::Flush(int TimeoutMs) int cDvbDevice::PlayVideo(const uchar *Data, int Length) { - return WriteAllOrNothing(fd_video, Data, Length, 1000, 10); + int w; + do { + w = WriteAllOrNothing(fd_video, Data, Length, 1000, 10); + } while (w != Length); + return w; } int cDvbDevice::PlayAudio(const uchar *Data, int Length, uchar Id) { - return WriteAllOrNothing(fd_audio, Data, Length, 1000, 10); + int w; + do { + w = WriteAllOrNothing(fd_audio, Data, Length, 1000, 10); + } while (w != Length); + return w; } int cDvbDevice::PlayTsVideo(const uchar *Data, int Length) { - Length = TsGetPayload(&Data); - return PlayVideo(Data, Length); + return cDevice::PlayTsVideo(Data, Length); } int cDvbDevice::PlayTsAudio(const uchar *Data, int Length) @@ -11,7 +11,7 @@ * The cRepacker family's code was originally written by Reinhard Nissl <rnissl@gmx.de>, * and adapted to the VDR coding style by Klaus.Schmidinger@cadsoft.de. * - * $Id: remux.c 2.1 2008/08/15 14:49:34 kls Exp $ + * $Id: remux.c 2.2 2008/12/13 14:30:15 kls Exp $ */ #include "remux.h" @@ -2578,7 +2578,7 @@ void cPatPmtParser::ParsePmt(const uchar *Data, int Length) cTsToPes::cTsToPes(void) { data = NULL; - size = length = 0; + size = length = offset = 0; synced = false; } @@ -2602,12 +2602,35 @@ void cTsToPes::PutTs(const uchar *Data, int Length) length += Length; } +#define MAXPESLENGTH 0xFFF0 + const uchar *cTsToPes::GetPes(int &Length) { - if (PesLongEnough(length)) { - Length = PesLength(data); - if (Length <= length) { - Length = length; // in case the PES packet has no explicit length, as is the case for video PES + if (offset < length && PesLongEnough(length)) { + if (!PesHasLength(data)) // this is a video PES packet with undefined length + offset = 6; // trigger setting PES length for initial slice + if (offset) { + uchar *p = data + offset - 6; + if (p != data) { + p -= 3; + memmove(p, data, 4); + } + int l = min(length - offset, MAXPESLENGTH); + offset += l; + if (p != data) { + l += 3; + p[6] = 0x80; + p[7] = 0x00; + p[8] = 0x00; + } + p[4] = l / 256; + p[5] = l & 0xFF; + Length = l + 6; + return p; + } + else { + Length = PesLength(data); + offset = Length; // to make sure we break out in case of garbage data return data; } } @@ -2616,7 +2639,7 @@ const uchar *cTsToPes::GetPes(int &Length) void cTsToPes::Reset(void) { - length = 0; + length = offset = 0; } // --- Some helper functions for debugging ----------------------------------- @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: remux.h 2.2 2008/09/06 14:48:28 kls Exp $ + * $Id: remux.h 2.3 2008/12/13 13:55:07 kls Exp $ */ #ifndef __REMUX_H @@ -138,6 +138,11 @@ inline bool PesLongEnough(int Length) return Length >= 6; } +inline bool PesHasLength(const uchar *p) +{ + return p[4] | p[5]; +} + inline int PesLength(const uchar *p) { return 6 + p[4] * 256 + p[5]; @@ -241,6 +246,7 @@ private: uchar *data; int size; int length; + int offset; bool synced; public: cTsToPes(void); |