mirror of
				https://github.com/vdr-projects/vdr.git
				synced 2025-03-01 10:50:46 +00:00 
			
		
		
		
	Improved handling PES video packets with zero length when converting from TS to PES
This commit is contained in:
		
							
								
								
									
										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.
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										12
									
								
								device.c
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								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)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										35
									
								
								remux.c
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								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)) {
 | 
				
			||||||
 | 
					     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);
 | 
					        Length = PesLength(data);
 | 
				
			||||||
     if (Length <= length) {
 | 
					        offset = Length; // to make sure we break out in case of garbage data
 | 
				
			||||||
        Length = length; // in case the PES packet has no explicit length, as is the case for video PES
 | 
					 | 
				
			||||||
        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);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user