mirror of
				https://projects.vdr-developer.org/git/vdr-plugin-streamdev.git
				synced 2023-10-10 17:16:51 +00:00 
			
		
		
		
	- increased WRITERBUFSIZE - buffer was too small for high bandwidth content - removed cStreamdevStreamer::m_Running - eliminated potential busy waits in remuxers - updated cTSRemux static helpers to code of their VDR 1.6.0 counterparts - re-enabled PES vor VDR 1.7.3+. Streamdev now uses a copy of VDR 1.6.0's cRemux for TS to PES remuxing. - make sure that only complete TS packets are written to ringbuffers - use signaling instead of sleeps when writing to ringbuffers - optimized cStreamdevPatFilter PAT packet initialization - fixed cStreamdevPatFilter not processing PATs with length > TS_SIZE - 5 - use a small ringbuffer for cStreamdevPatFilter instead of writing to cStreamdevStreamers SendBuffer as two threads mustn't write to the same ringbuffer Modified Files: CONTRIBUTORS HISTORY Makefile common.c common.h streamdev-server.c libdvbmpeg/transform.h remux/extern.c remux/extern.h remux/ts2es.c remux/ts2es.h remux/ts2ps.c remux/ts2ps.h remux/tsremux.c remux/tsremux.h server/connectionHTTP.c server/connectionVTP.c server/livestreamer.c server/livestreamer.h server/menuHTTP.c server/streamer.c server/streamer.h Added Files: remux/ts2pes.c remux/ts2pes.h
		
			
				
	
	
		
			88 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			88 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#include "remux/tsremux.h"
 | 
						|
 | 
						|
#define SC_PICTURE  0x00  // "picture header"
 | 
						|
#define PID_MASK_HI 0x1F
 | 
						|
#define VIDEO_STREAM_S   0xE0
 | 
						|
 | 
						|
using namespace Streamdev;
 | 
						|
 | 
						|
void cTSRemux::SetBrokenLink(uchar *Data, int Length)
 | 
						|
{
 | 
						|
  int PesPayloadOffset = 0;
 | 
						|
  if (AnalyzePesHeader(Data, Length, PesPayloadOffset) >= phMPEG1 && (Data[3] & 0xF0) == VIDEO_STREAM_S) {
 | 
						|
     for (int i = PesPayloadOffset; i < Length - 7; i++) {
 | 
						|
         if (Data[i] == 0 && Data[i + 1] == 0 && Data[i + 2] == 1 && Data[i + 3] == 0xB8) {
 | 
						|
            if (!(Data[i + 7] & 0x40)) // set flag only if GOP is not closed
 | 
						|
               Data[i + 7] |= 0x20;
 | 
						|
            return;
 | 
						|
            }
 | 
						|
         }
 | 
						|
     dsyslog("SetBrokenLink: no GOP header found in video packet");
 | 
						|
     }
 | 
						|
  else
 | 
						|
     dsyslog("SetBrokenLink: no video packet in frame");
 | 
						|
}
 | 
						|
 | 
						|
int cTSRemux::GetPid(const uchar *Data)
 | 
						|
{
 | 
						|
  return (((uint16_t)Data[0] & PID_MASK_HI) << 8) | (Data[1] & 0xFF);
 | 
						|
}
 | 
						|
 | 
						|
int cTSRemux::GetPacketLength(const uchar *Data, int Count, int Offset)
 | 
						|
{
 | 
						|
  // Returns the length of the packet starting at Offset, or -1 if Count is
 | 
						|
  // too small to contain the entire packet.
 | 
						|
  int Length = (Offset + 5 < Count) ? (Data[Offset + 4] << 8) + Data[Offset + 5] + 6 : -1;
 | 
						|
  if (Length > 0 && Offset + Length <= Count)
 | 
						|
     return Length;
 | 
						|
  return -1;
 | 
						|
}
 | 
						|
 | 
						|
int cTSRemux::ScanVideoPacket(const uchar *Data, int Count, int Offset, uchar &PictureType)
 | 
						|
{
 | 
						|
  // Scans the video packet starting at Offset and returns its length.
 | 
						|
  // If the return value is -1 the packet was not completely in the buffer.
 | 
						|
  int Length = GetPacketLength(Data, Count, Offset);
 | 
						|
  if (Length > 0) {
 | 
						|
     int PesPayloadOffset = 0;
 | 
						|
     if (AnalyzePesHeader(Data + Offset, Length, PesPayloadOffset) >= phMPEG1) {
 | 
						|
        const uchar *p = Data + Offset + PesPayloadOffset + 2;
 | 
						|
        const uchar *pLimit = Data + Offset + Length - 3;
 | 
						|
#ifdef TEST_cVideoRepacker
 | 
						|
        // cVideoRepacker ensures that a new PES packet is started for a new sequence,
 | 
						|
        // group or picture which allows us to easily skip scanning through a huge
 | 
						|
        // amount of video data.
 | 
						|
        if (p < pLimit) {
 | 
						|
           if (p[-2] || p[-1] || p[0] != 0x01)
 | 
						|
              pLimit = 0; // skip scanning: packet doesn't start with 0x000001
 | 
						|
           else {
 | 
						|
              switch (p[1]) {
 | 
						|
                case SC_SEQUENCE:
 | 
						|
                case SC_GROUP:
 | 
						|
                case SC_PICTURE:
 | 
						|
                     break;
 | 
						|
                default: // skip scanning: packet doesn't start a new sequence, group or picture
 | 
						|
                     pLimit = 0;
 | 
						|
                }
 | 
						|
              }
 | 
						|
           }
 | 
						|
#endif
 | 
						|
        while (p < pLimit && (p = (const uchar *)memchr(p, 0x01, pLimit - p))) {
 | 
						|
              if (!p[-2] && !p[-1]) { // found 0x000001
 | 
						|
                 switch (p[1]) {
 | 
						|
                   case SC_PICTURE: PictureType = (p[3] >> 3) & 0x07;
 | 
						|
                                    return Length;
 | 
						|
                   }
 | 
						|
                 p += 4; // continue scanning after 0x01ssxxyy
 | 
						|
                 }
 | 
						|
              else
 | 
						|
                 p += 3; // continue scanning after 0x01xxyy
 | 
						|
              }
 | 
						|
        }
 | 
						|
     PictureType = NO_PICTURE;
 | 
						|
     return Length;
 | 
						|
     }
 | 
						|
  return -1;
 | 
						|
}
 | 
						|
 |