mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Improved handling PES video packets with zero length when converting from TS to PES
This commit is contained in:
parent
3c7d1a16ac
commit
22feb7bf1c
1
HISTORY
1
HISTORY
@ -5840,3 +5840,4 @@ Video Disk Recorder Revision History
|
|||||||
and Edgar Hucek).
|
and Edgar Hucek).
|
||||||
- The cDvbTuner::IsTunedTo() function now also checks the symbol rate in case of
|
- The cDvbTuner::IsTunedTo() function now also checks the symbol rate in case of
|
||||||
DVB-S and DVB-C.
|
DVB-S and DVB-C.
|
||||||
|
- Improved handling PES video packets with zero length when converting from TS to PES.
|
||||||
|
16
device.c
16
device.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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"
|
#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
|
// 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:
|
// a PES packet when the next TS packet that starts a payload comes in:
|
||||||
if (TsPayloadStart(Data)) {
|
if (TsPayloadStart(Data)) {
|
||||||
if (const uchar *p = tsToPesVideo.GetPes(Length)) {
|
int l;
|
||||||
int w = PlayVideo(p, Length);
|
while (const uchar *p = tsToPesVideo.GetPes(l)) {
|
||||||
if (w > 0)
|
int w = PlayVideo(p, l);
|
||||||
tsToPesVideo.Reset();
|
if (w < 0)
|
||||||
else
|
return w;
|
||||||
return w;
|
}
|
||||||
}
|
tsToPesVideo.Reset();
|
||||||
}
|
}
|
||||||
tsToPesVideo.PutTs(Data, Length);
|
tsToPesVideo.PutTs(Data, Length);
|
||||||
return Length;
|
return Length;
|
||||||
|
17
dvbdevice.c
17
dvbdevice.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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"
|
#include "dvbdevice.h"
|
||||||
@ -1266,18 +1266,25 @@ bool cDvbDevice::Flush(int TimeoutMs)
|
|||||||
|
|
||||||
int cDvbDevice::PlayVideo(const uchar *Data, int Length)
|
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)
|
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)
|
int cDvbDevice::PlayTsVideo(const uchar *Data, int Length)
|
||||||
{
|
{
|
||||||
Length = TsGetPayload(&Data);
|
return cDevice::PlayTsVideo(Data, Length);
|
||||||
return PlayVideo(Data, Length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int cDvbDevice::PlayTsAudio(const uchar *Data, int Length)
|
int cDvbDevice::PlayTsAudio(const uchar *Data, int Length)
|
||||||
|
37
remux.c
37
remux.c
@ -11,7 +11,7 @@
|
|||||||
* The cRepacker family's code was originally written by Reinhard Nissl <rnissl@gmx.de>,
|
* 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.
|
* 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"
|
#include "remux.h"
|
||||||
@ -2578,7 +2578,7 @@ void cPatPmtParser::ParsePmt(const uchar *Data, int Length)
|
|||||||
cTsToPes::cTsToPes(void)
|
cTsToPes::cTsToPes(void)
|
||||||
{
|
{
|
||||||
data = NULL;
|
data = NULL;
|
||||||
size = length = 0;
|
size = length = offset = 0;
|
||||||
synced = false;
|
synced = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2602,12 +2602,35 @@ void cTsToPes::PutTs(const uchar *Data, int Length)
|
|||||||
length += Length;
|
length += Length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define MAXPESLENGTH 0xFFF0
|
||||||
|
|
||||||
const uchar *cTsToPes::GetPes(int &Length)
|
const uchar *cTsToPes::GetPes(int &Length)
|
||||||
{
|
{
|
||||||
if (PesLongEnough(length)) {
|
if (offset < length && PesLongEnough(length)) {
|
||||||
Length = PesLength(data);
|
if (!PesHasLength(data)) // this is a video PES packet with undefined length
|
||||||
if (Length <= length) {
|
offset = 6; // trigger setting PES length for initial slice
|
||||||
Length = length; // in case the PES packet has no explicit length, as is the case for video PES
|
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;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2616,7 +2639,7 @@ const uchar *cTsToPes::GetPes(int &Length)
|
|||||||
|
|
||||||
void cTsToPes::Reset(void)
|
void cTsToPes::Reset(void)
|
||||||
{
|
{
|
||||||
length = 0;
|
length = offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Some helper functions for debugging -----------------------------------
|
// --- Some helper functions for debugging -----------------------------------
|
||||||
|
8
remux.h
8
remux.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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
|
#ifndef __REMUX_H
|
||||||
@ -138,6 +138,11 @@ inline bool PesLongEnough(int Length)
|
|||||||
return Length >= 6;
|
return Length >= 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool PesHasLength(const uchar *p)
|
||||||
|
{
|
||||||
|
return p[4] | p[5];
|
||||||
|
}
|
||||||
|
|
||||||
inline int PesLength(const uchar *p)
|
inline int PesLength(const uchar *p)
|
||||||
{
|
{
|
||||||
return 6 + p[4] * 256 + p[5];
|
return 6 + p[4] * 256 + p[5];
|
||||||
@ -241,6 +246,7 @@ private:
|
|||||||
uchar *data;
|
uchar *data;
|
||||||
int size;
|
int size;
|
||||||
int length;
|
int length;
|
||||||
|
int offset;
|
||||||
bool synced;
|
bool synced;
|
||||||
public:
|
public:
|
||||||
cTsToPes(void);
|
cTsToPes(void);
|
||||||
|
Loading…
Reference in New Issue
Block a user