Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[vdr] Re: Feature request for vdr-subtitles: record allsubtitle languages



On Mon, 2003-12-01 at 19:40, Pekka Virtanen wrote:
> Oskar Signell wrote:
> > Hi
> > 
> > Some channels in Finland contain DVB subtitles in multiple languages.
> > Usually, these are not sent simultaneously, but some programs are
> > subtitled in Finnish and others in Swedish. This can easily be switched
> > via the plug-in menu, but unfortunately this selection also affects the
> > recordings.
> > 
> > This fairly easily leads to missing subtitles for some shows, even
> > though there would be such available.
> > 
> > Could the plug-in record all available subtitles instead of only the
> > selected one?
> 
> I'm implementing secondary language feature for live viewing. It is 
> possible to add that secondary language to recodings also. But I'm not 
> planning to implement recording of arbitrary number of subtitle streams 
> in vdr-1.2 branch.
> 
> Maybe in the vdr 1.3 the plugins can request arbitrary streams to be 
> recorded... Klaus?
> 
> 
> -- pekka
> 
> 

Hi

My opinion is, that both subtitles (teletext and video) should be
features of VDR version 1.x. There is today big problem to get both
working in the same time. I have done a combined patch of both for
version 1.2.5 by some kind of puzzle method (I am not a programmer). It
is not working in all situation, but is in every day use, only replay
and transfer mode of videosubs is not working.

Selecting language during watching, recording and replaying were a most
needed feature to present plugins, too. 

I am keen to test any versions of "beta" programs.


           Timo

     Timo 
diff -B -c /usr/local/src/test1/vdr-1.2.5/dvbplayer.c ./dvbplayer.c
*** /usr/local/src/test1/vdr-1.2.5/dvbplayer.c	2003-05-24 12:04:26.000000000 +0300
--- ./dvbplayer.c	2003-09-28 12:37:44.000000000 +0300
***************
*** 14,19 ****
--- 14,22 ----
  #include "ringbuffer.h"
  #include "thread.h"
  #include "tools.h"
+ #include "rcontroller.h"
+ #include "dvbsub.h"
+ #include "vdrttxtsubshooks.h"
  
  // --- cBackTrace ----------------------------------------------------------
  
***************
*** 323,328 ****
--- 326,344 ----
              int l = b[i + 4] * 256 + b[i + 5] + 6;
              switch (c) {
                case 0xBD: // dolby
+                 #ifdef VDRTTXTSUBSHOOKS
+  		   if (b[i + 8] == 0x24 && b[i + 45] >= 0x10 && b[i + 45] < 0x20) {
+  		     break; // run these through the ring buffer to get somewhat correct
+  		     // timing for the subtitles
+  		   } else
+                 #endif
+ 		if (RecordingPatch::RecordingController.isExtendedPacket( b + i , l ) )
+ 		{
+ 		  //		  RecordingPatch::RecordingController.Receive( b + i, l );
+ 		  //		  memset(&b[i], 0x00, min(l, Length-i));
+ 		  break;
+ 		}
+ 		    
                     if (Except)
                        PlayAudio(&b[i], l);
                     // continue with deleting the data - otherwise it disturbs DVB replay
***************
*** 349,354 ****
--- 365,434 ----
       }
  }
  
+ #ifdef VDRTTXTSUBSHOOKS
+ static void StripTtxtPackets(uchar *b, int Length)
+ {
+   for (int i = 0; i < Length - 6; i++) {
+     if (b[i] == 0x00 && b[i + 1] == 0x00 && b[i + 2] == 0x01) {
+       uchar c = b[i + 3];
+       int l = b[i + 4] * 256 + b[i + 5] + 6;
+       switch (c) {
+       case 0xBD: // dolby
+ 	{
+ 	  if (b[i + 8] == 0x24 && b[i + 45] >= 0x10 && b[i + 45] < 0x20) {
+ 	    // EBU Teletext data, ETSI EN 300 472
+ 	    cVDRTtxtsubsHookListener::Hook()->PlayerTeletextData(&b[i], l);
+ 	  }
+ 	  // continue with deleting the data - otherwise it disturbs DVB replay
+ 	  int n = l;
+ 	  for (int j = i; j < Length && n--; j++)
+ 	    b[j] = 0x00;
+ 	  break;
+ 	}
+       default:
+ 	break;
+       }
+       if (l)
+ 	i += l - 1; // the loop increments, too!
+     }
+     /*XXX
+       else
+       esyslog("ERROR: broken packet header");
+       XXX*/
+   }
+ }
+ #endif
+ 
+ 
+ static void StripExtendedPackets(uchar *b, int Length)
+ {
+   for (int i = 0; i < Length - 6; i++) {
+     if (b[i] == 0x00 && b[i + 1] == 0x00 && b[i + 2] == 0x01) 
+     {
+       uchar c = b[i + 3];
+       int l = b[i + 4] * 256 + b[i + 5] + 6;
+       switch (c) {
+       case 0xBD: // dolby
+ 	{
+ 	    
+ 	  if (RecordingPatch::RecordingController.isExtendedPacket(b + i , l))
+ 	    RecordingPatch::RecordingController.Receive( b + i, l );
+ 
+ 	// continue with deleting the data - otherwise it disturbs DVB replay
+ 	  int n = l;
+ 	  for (int j = i; j < Length && n--; j++)
+ 	    b[j] = 0x00;
+ 	  break;
+ 	}
+     default:
+       break;
+     }
+     if (l)
+       i += l - 1; // the loop increments, too!
+     }
+   }
+ }
+ 
  bool cDvbPlayer::NextFile(uchar FileNumber, int FileOffset)
  {
    if (FileNumber > 0)
***************
*** 524,529 ****
--- 606,618 ----
                         StripAudioPackets(p, pc, AudioTrack);
                      }
                   }
+            #ifdef VDRTTXTSUBSHOOKS
+  	          // pick out the teletext packets here
+  	             if(p)
+  		     StripTtxtPackets((uchar *) p, pc);
+            #endif
+ 	      if (p)
+ 		StripExtendedPackets((uchar*)p, pc);
                if (p) {
                   int w = PlayVideo(p, pc);
                   if (w > 0) {
Only in .: dvbsub.c
Only in .: dvbsub.h
Only in .: DVBsubs.patch
Common subdirectories: /usr/local/src/test1/vdr-1.2.5/libdtv and ./libdtv
Only in .: Make.config
diff -B -c /usr/local/src/test1/vdr-1.2.5/Makefile ./Makefile
*** /usr/local/src/test1/vdr-1.2.5/Makefile	2003-08-09 14:09:45.000000000 +0300
--- ./Makefile	2003-09-25 22:36:23.000000000 +0300
***************
*** 37,44 ****
         dvbplayer.o dvbspu.o eit.o eitscan.o font.o i18n.o interface.o keys.o\
         lirc.o menu.o menuitems.o osdbase.o osd.o player.o plugin.o rcu.o\
         receiver.o recorder.o recording.o remote.o remux.o ringbuffer.o sources.o\
!        spu.o status.o svdrp.o thread.o timers.o tools.o transfer.o vdr.o videodir.o
! 
  OSDFONT = -adobe-helvetica-medium-r-normal--23-*-100-100-p-*-iso8859-1
  FIXFONT = -adobe-courier-bold-r-normal--25-*-100-100-m-*-iso8859-1
  
--- 37,44 ----
         dvbplayer.o dvbspu.o eit.o eitscan.o font.o i18n.o interface.o keys.o\
         lirc.o menu.o menuitems.o osdbase.o osd.o player.o plugin.o rcu.o\
         receiver.o recorder.o recording.o remote.o remux.o ringbuffer.o sources.o\
!        spu.o status.o svdrp.o thread.o timers.o tools.o transfer.o vdr.o videodir.o\
!        osdcontroller.o rcontroller.o dvbsub.o  vdrttxtsubshooks.o
  OSDFONT = -adobe-helvetica-medium-r-normal--23-*-100-100-p-*-iso8859-1
  FIXFONT = -adobe-courier-bold-r-normal--25-*-100-100-m-*-iso8859-1
  
diff -B -c /usr/local/src/test1/vdr-1.2.5/menu.c ./menu.c
*** /usr/local/src/test1/vdr-1.2.5/menu.c	2003-09-14 13:49:28.000000000 +0300
--- ./menu.c	2003-09-27 22:41:56.000000000 +0300
***************
*** 27,32 ****
--- 27,33 ----
  #include "timers.h"
  #include "transfer.h"
  #include "videodir.h"
+ #include "dvbsub.h"
  
  #define MENUTIMEOUT     120 // seconds
  #define MAXWAIT4EPGINFO   3 // seconds
***************
*** 3014,3021 ****
    isyslog("record %s", fileName);
    if (MakeDirs(fileName, true)) {
       const cChannel *ch = timer->Channel();
!      recorder = new cRecorder(fileName, ch->Ca(), timer->Priority(), ch->Vpid(), ch->Apid1(), ch->Apid2(), ch->Dpid1(), ch->Dpid2());
       if (device->AttachReceiver(recorder)) {
          Recording.WriteSummary();
          cStatus::MsgRecording(device, Recording.Name());
          if (!Timer && !cReplayControl::LastReplayed()) // an instant recording, maybe from cRecordControls::PauseLiveVideo()
--- 3015,3035 ----
    isyslog("record %s", fileName);
    if (MakeDirs(fileName, true)) {
       const cChannel *ch = timer->Channel();
!  #ifdef VDRTTXTSUBSHOOKS
!    cTtxtSubsRecorderBase *subsRecorder = cVDRTtxtsubsHookListener::Hook()
!      ->NewTtxtSubsRecorder(device, ch);
!    int SubPid1 = DvbSubtitlesRecording.GetPidByChannel( ch );
! int SubPid2 = DvbSubtitlesRecording.GetPidByChannel( ch );
!    recorder = new cRecorder(fileName, ch->Ca(), timer->Priority(), ch->Vpid(), ch->Apid1(), ch->Apid2(), ch->Dpid1(), ch->Dpid2(), SubPid1, SubPid2, subsRecorder);
!  #else
!     int SubPid1 = DvbSubtitlesRecording.GetPidByChannel( ch );
!      recorder = new cRecorder(fileName, ch->Ca(), timer->Priority(), ch->Vpid(), ch->Apid1(), ch->Apid2(), ch->Dpid1(), ch->Dpid2(), SubPid1);
!  #endif    
       if (device->AttachReceiver(recorder)) {
+ #ifdef VDRTTXTSUBSHOOKS
+       if(subsRecorder)
+         subsRecorder->DeviceAttach();
+  #endif
          Recording.WriteSummary();
          cStatus::MsgRecording(device, Recording.Name());
          if (!Timer && !cReplayControl::LastReplayed()) // an instant recording, maybe from cRecordControls::PauseLiveVideo()
diff -B -c /usr/local/src/test1/vdr-1.2.5/menu.h ./menu.h
*** /usr/local/src/test1/vdr-1.2.5/menu.h	2003-08-03 12:37:18.000000000 +0300
--- ./menu.h	2003-09-26 23:54:37.000000000 +0300
***************
*** 14,19 ****
--- 14,20 ----
  #include "device.h"
  #include "osd.h"
  #include "dvbplayer.h"
+ #include "vdrttxtsubshooks.h"
  #include "recorder.h"
  #include "recording.h"
  
diff -B -c /usr/local/src/test1/vdr-1.2.5/osd.c ./osd.c
*** /usr/local/src/test1/vdr-1.2.5/osd.c	2003-06-04 19:13:00.000000000 +0300
--- ./osd.c	2003-09-26 23:58:38.000000000 +0300
***************
*** 12,18 ****
  #include "device.h"
  #include "i18n.h"
  #include "status.h"
! 
  // --- cOsd ------------------------------------------------------------------
  
  #ifdef DEBUG_OSD
--- 12,19 ----
  #include "device.h"
  #include "i18n.h"
  #include "status.h"
! #include "vdrttxtsubshooks.h"
! #include "osdcontroller.h"
  // --- cOsd ------------------------------------------------------------------
  
  #ifdef DEBUG_OSD
***************
*** 60,70 ****
  }
  #endif
  
! cOsdBase *cOsd::OpenRaw(int x, int y)
  {
  #ifdef DEBUG_OSD
    return NULL;
  #else
    return osd ? NULL : cDevice::PrimaryDevice()->NewOsd(x, y);
  #endif
  }
--- 61,73 ----
  }
  #endif
  
! cOsdBase *cOsd::OpenRaw(int x, int y, bool dontHide)
  {
  #ifdef DEBUG_OSD
    return NULL;
  #else
+   if ( !dontHide )
+     NonInteractiveOsdPatch::OsdController.Hide();
    return osd ? NULL : cDevice::PrimaryDevice()->NewOsd(x, y);
  #endif
  }
***************
*** 96,101 ****
--- 99,107 ----
    d *= lineHeight;
    int x = (720 - w + charWidth) / 2; //TODO PAL vs. NTSC???
    int y = (576 - Setup.OSDheight * lineHeight) / 2 + d;
+ #ifdef VDRTTXTSUBSHOOKS
+   cVDRTtxtsubsHookListener::Hook()->HideOSD();
+ #endif
    //XXX
    osd = OpenRaw(x, y);
    //XXX TODO this should be transferred to the places where the individual windows are requested (there's too much detailed knowledge here!)
***************
*** 137,143 ****
--- 143,153 ----
  #else
    delete osd;
    osd = NULL;
+ #ifdef VDRTTXTSUBSHOOKS
+   cVDRTtxtsubsHookListener::Hook()->ShowOSD();
+ #endif
  #endif
+   NonInteractiveOsdPatch::OsdController.Show();
  }
  
  void cOsd::Clear(void)
Only in .: osdcontroller.c
Only in .: osdcontroller.h
diff -B -c /usr/local/src/test1/vdr-1.2.5/osd.h ./osd.h
*** /usr/local/src/test1/vdr-1.2.5/osd.h	2003-09-14 13:59:22.000000000 +0300
--- ./osd.h	2003-09-25 00:15:31.000000000 +0300
***************
*** 69,75 ****
  public:
    static void Initialize(void);
    static void Shutdown(void);
!   static cOsdBase *OpenRaw(int x, int y);
         // Returns a raw OSD without any predefined windows or colors.
         // If the "normal" OSD is currently in use, NULL will be returned.
         // The caller must delete this object before the "normal" OSD is used again!
--- 69,75 ----
  public:
    static void Initialize(void);
    static void Shutdown(void);
!   static cOsdBase *OpenRaw(int x, int y, bool dontHide=false);
         // Returns a raw OSD without any predefined windows or colors.
         // If the "normal" OSD is currently in use, NULL will be returned.
         // The caller must delete this object before the "normal" OSD is used again!
Common subdirectories: /usr/local/src/test1/vdr-1.2.5/PLUGINS and ./PLUGINS
Only in .: rcontroller.c
Only in .: rcontroller.h
diff -B -c /usr/local/src/test1/vdr-1.2.5/recorder.c ./recorder.c
*** /usr/local/src/test1/vdr-1.2.5/recorder.c	2003-08-02 16:01:19.000000000 +0300
--- ./recorder.c	2003-09-27 22:46:02.000000000 +0300
***************
*** 10,15 ****
--- 10,17 ----
  #include <stdarg.h>
  #include <stdio.h>
  #include <unistd.h>
+ #include <stdint.h>
+ #include "vdrttxtsubshooks.h"
  #include "recorder.h"
  
  // The size of the array used to buffer video data:
***************
*** 23,30 ****
  #define MINFREEDISKSPACE    (512) // MB
  #define DISKCHECKINTERVAL   100 // seconds
  
! cRecorder::cRecorder(const char *FileName, int Ca, int Priority, int VPid, int APid1, int APid2, int DPid1, int DPid2)
! :cReceiver(Ca, Priority, 5, VPid, APid1, APid2, DPid1, DPid2)
  {
    ringBuffer = NULL;
    remux = NULL;
--- 25,37 ----
  #define MINFREEDISKSPACE    (512) // MB
  #define DISKCHECKINTERVAL   100 // seconds
  
! 
! #ifdef VDRTTXTSUBSHOOKS
! cRecorder::cRecorder(const char *FileName, int Ca, int Priority, int VPid, int APid1, int APid2, int DPid1, int DPid2, int SubPid1, int SubPid2, cTtxtSubsRecorderBase *tsr)
! #else
! cRecorder::cRecorder(const char *FileName, int Ca, int Priority, int VPid, int APid1, int APid2, int DPid1, int DPid2, int SubPid1, int SubPid2)
! #endif
! :cReceiver(Ca, Priority, 7, VPid, APid1, APid2, DPid1, DPid2, SubPid1, SubPid2)
  {
    ringBuffer = NULL;
    remux = NULL;
***************
*** 34,46 ****
    fileSize = 0;
    active = false;
    lastDiskSpaceCheck = time(NULL);
  
    // Make sure the disk is up and running:
  
    SpinUpDisk(FileName);
  
    ringBuffer = new cRingBufferLinear(VIDEOBUFSIZE, TS_SIZE * 2, true);
!   remux = new cRemux(VPid, APid1, APid2, DPid1, DPid2, true);
    fileName = new cFileName(FileName, true);
    recordFile = fileName->Open();
    if (recordFile < 0)
--- 41,56 ----
    fileSize = 0;
    active = false;
    lastDiskSpaceCheck = time(NULL);
+ #ifdef VDRTTXTSUBSHOOKS
+   ttxtSubsRecorder = tsr;
+ #endif
  
    // Make sure the disk is up and running:
  
    SpinUpDisk(FileName);
  
    ringBuffer = new cRingBufferLinear(VIDEOBUFSIZE, TS_SIZE * 2, true);
!   remux = new cRemux(VPid, APid1, APid2, DPid1, DPid2, true, SubPid1, SubPid2);
    fileName = new cFileName(FileName, true);
    recordFile = fileName->Open();
    if (recordFile < 0)
***************
*** 55,60 ****
--- 65,74 ----
  cRecorder::~cRecorder()
  {
    Detach();
+ #ifdef VDRTTXTSUBSHOOKS
+   if(ttxtSubsRecorder)
+     delete ttxtSubsRecorder;
+ #endif
    delete index;
    delete fileName;
    delete remux;
***************
*** 129,134 ****
--- 143,161 ----
                      break;
                      }
                   fileSize += Result;
+ #ifdef VDRTTXTSUBSHOOKS
+ 		 // not sure if the pictureType test is needed, but it seems we can get
+ 		 // incomplete pes packets from remux if we are not getting pictures?
+ 		 if (ttxtSubsRecorder && pictureType != NO_PICTURE) {
+ 		    uint8_t *subsp;
+ 		    size_t len;
+ 		    if(ttxtSubsRecorder->GetPacket(&subsp, &len)) {
+ 		       safe_write(recordFile, subsp, len);
+ 		       fileSize += len;
+ 		       // fprintf(stderr, "cRecorder::Action: Wrote ttxtsubs data len %d\n", len); // XXX
+ 		       }
+ 		    }
+ #endif
                   }
                else
                   break;
diff -B -c /usr/local/src/test1/vdr-1.2.5/recorder.h ./recorder.h
*** /usr/local/src/test1/vdr-1.2.5/recorder.h	2002-06-08 12:35:03.000000000 +0300
--- ./recorder.h	2003-09-27 22:37:34.000000000 +0300
***************
*** 15,20 ****
--- 15,21 ----
  #include "remux.h"
  #include "ringbuffer.h"
  #include "thread.h"
+ #include "vdrttxtsubshooks.h"
  
  class cRecorder : public cReceiver, cThread {
  private:
***************
*** 29,40 ****
    time_t lastDiskSpaceCheck;
    bool RunningLowOnDiskSpace(void);
    bool NextFile(void);
  protected:
    virtual void Activate(bool On);
    virtual void Receive(uchar *Data, int Length);
    virtual void Action(void);
  public:
!   cRecorder(const char *FileName, int Ca, int Priority, int VPid, int APid1, int APid2, int DPid1, int DPid2);
                 // Creates a new recorder that requires conditional access Ca, has
                 // the given Priority and will record the given PIDs into the file FileName.
    virtual ~cRecorder();
--- 30,49 ----
    time_t lastDiskSpaceCheck;
    bool RunningLowOnDiskSpace(void);
    bool NextFile(void);
+ #ifdef VDRTTXTSUBSHOOKS
+   cTtxtSubsRecorderBase *ttxtSubsRecorder;
+ #endif
  protected:
    virtual void Activate(bool On);
    virtual void Receive(uchar *Data, int Length);
    virtual void Action(void);
  public:
! #ifdef VDRTTXTSUBSHOOKS
!   cRecorder(const char *FileName, int Ca, int Priority, int VPid, int APid1, int APid2, int DPid1, int DPid2, int SubPid1, int SubPid2, cTtxtSubsRecorderBase *tsr);
! #else
!    cRecorder(const char *FileName, int Ca, int Priority, int VPid, int APid1, int APid2, int DPid1, int DPid2, int SubPid1 = 0, int SubPid2 = 0);
! #endif
!   
                 // Creates a new recorder that requires conditional access Ca, has
                 // the given Priority and will record the given PIDs into the file FileName.
    virtual ~cRecorder();
diff -B -c /usr/local/src/test1/vdr-1.2.5/remux.c ./remux.c
*** /usr/local/src/test1/vdr-1.2.5/remux.c	2003-09-14 13:34:39.000000000 +0300
--- ./remux.c	2003-09-25 00:15:31.000000000 +0300
***************
*** 96,101 ****
--- 96,104 ----
  //pts_dts flags
  #define PTS_ONLY         0x80
  
+ #define PES_EXTENSION    0x01
+ #define PES_EXTENSION2   0x01
+ 
  #define TS_SIZE        188
  #define PID_MASK_HI    0x1F
  #define CONT_CNT_MASK  0x0F
***************
*** 137,158 ****
    int tsErrors;
    int ccErrors;
    int ccCounter;
    static uint8_t headr[];
    void store(uint8_t *Data, int Count);
    void reset_ipack(void);
    void send_ipack(void);
    void write_ipack(const uint8_t *Data, int Count);
    void instant_repack(const uint8_t *Buf, int Count);
  public:
!   cTS2PES(uint8_t *ResultBuffer, int *ResultCount, int Size, uint8_t AudioCid = 0x00);
    ~cTS2PES();
    void ts_to_pes(const uint8_t *Buf); // don't need count (=188)
    void Clear(void);
    };
  
  uint8_t cTS2PES::headr[] = { 0x00, 0x00, 0x01 };
  
! cTS2PES::cTS2PES(uint8_t *ResultBuffer, int *ResultCount, int Size, uint8_t AudioCid)
  {
    resultBuffer = ResultBuffer;
    resultCount = ResultCount;
--- 140,164 ----
    int tsErrors;
    int ccErrors;
    int ccCounter;
+   uint8_t dataIdentifier;
    static uint8_t headr[];
+   static uint8_t eHeadr[];
    void store(uint8_t *Data, int Count);
    void reset_ipack(void);
    void send_ipack(void);
    void write_ipack(const uint8_t *Data, int Count);
    void instant_repack(const uint8_t *Buf, int Count);
  public:
!   cTS2PES(uint8_t *ResultBuffer, int *ResultCount, int Size, uint8_t AudioCid = 0x00, uint8_t DataIndentifier = 0x00);
    ~cTS2PES();
    void ts_to_pes(const uint8_t *Buf); // don't need count (=188)
    void Clear(void);
    };
  
  uint8_t cTS2PES::headr[] = { 0x00, 0x00, 0x01 };
+ uint8_t cTS2PES::eHeadr[] = { 0x01, 0x81 }; // extension header
  
! cTS2PES::cTS2PES(uint8_t *ResultBuffer, int *ResultCount, int Size, uint8_t AudioCid, uint8_t DataIdentifier)
  {
    resultBuffer = ResultBuffer;
    resultCount = ResultCount;
***************
*** 162,167 ****
--- 168,174 ----
    tsErrors = 0;
    ccErrors = 0;
    ccCounter = -1;
+   dataIdentifier = DataIdentifier;
  
    if (!(buf = MALLOC(uint8_t, size)))
       esyslog("Not enough memory for ts_transform");
***************
*** 217,226 ****
--- 224,243 ----
  
    switch (mpeg) {
      case 2:
+       if ( dataIdentifier == 0 ) {
              buf[6] = 0x80;
              buf[7] = 0x00;
              buf[8] = 0x00;
              count = 9;
+       } else {
+             buf[6] = 0x80;
+             buf[7] = 0x01; // pes_extension_flag == 1
+             buf[8] = 0x03; // pes_header_data_length == 3
+             buf[9] = 0x01; // pes_extension_flag_2=1
+             buf[10]= 0x81; // marker_bit=1, pes_extension_data_length=1 
+             buf[11] = dataIdentifier;
+             count = 12;
+       }
              break;
      case 1:
              buf[6] = 0x0F;
***************
*** 331,342 ****
--- 348,367 ----
            case 7:
                    if (!done && mpeg == 2) {
                       flag2 = Buf[c++];
+ 		     if ( dataIdentifier && (flag2 & PES_EXTENSION) ) {
+ 		       esyslog("Error: cannot add extension to pes packet. Disabling.");
+ 		       dataIdentifier = 0;
+ 		     } else {
+ 		       flag2 |= PES_EXTENSION;
+ 		     }
                       found++;
                       }
                    break;
            case 8:
                    if (!done && mpeg == 2) {
                       hlength = Buf[c++];
+ 		     if ( dataIdentifier )
+ 		       hlength += 3;
                       found++;
                       }
                    break;
***************
*** 373,387 ****
                    return;
                 }
  
              while (c < Count && found < plength + 6) {
-                   int l = Count - c;
-                   if (l + found > plength + 6)
-                      l = plength + 6 - found;
-                   write_ipack(Buf + c, l);
-                   found += l;
-                   c += l;
-                   }
  
              break;
         }
  
--- 398,425 ----
                    return;
                 }
  
+ 	    // Write header one byte at a time
+ 	    // Remove from hlength size of our header (3)
+ 	    if ( dataIdentifier ) {
+ 	      while (c < Count && (found < (hlength + 9-3)) && found < plength+6) {
+ 		write_ipack(Buf + c, 1);
+ 		c++;
+ 		found++;
+ 	      }
+ 	      if ( found == (hlength+9-3) ) {
+ 		write_ipack(eHeadr, 2); 
+ 		write_ipack(&dataIdentifier, 1);
+ 	      }
+ 	    }
              while (c < Count && found < plength + 6) {
  
+ 	      int l = Count - c;
+ 	      if (l + found > plength + 6)
+ 		l = plength + 6 - found;
+ 	      write_ipack(Buf + c, l);
+ 	      found += l;
+ 	      c += l;
+ 	    }
              break;
         }
  
***************
*** 451,463 ****
  
  // --- cRemux ----------------------------------------------------------------
  
! cRemux::cRemux(int VPid, int APid1, int APid2, int DPid1, int DPid2, bool ExitOnFailure)
  {
    vPid = VPid;
    aPid1 = APid1;
    aPid2 = APid2;
    dPid1 = DPid1;
    dPid2 = DPid2;
    exitOnFailure = ExitOnFailure;
    synced = false;
    skipped = 0;
--- 489,503 ----
  
  // --- cRemux ----------------------------------------------------------------
  
! cRemux::cRemux(int VPid, int APid1, int APid2, int DPid1, int DPid2, bool ExitOnFailure, int SubPid1, int SubPid2)
  {
    vPid = VPid;
    aPid1 = APid1;
    aPid2 = APid2;
    dPid1 = DPid1;
    dPid2 = DPid2;
+   sPid1 = SubPid1;
+   sPid2 = SubPid2;
    exitOnFailure = ExitOnFailure;
    synced = false;
    skipped = 0;
***************
*** 468,473 ****
--- 508,515 ----
    dTS2PES1 = dPid1 ? new cTS2PES(resultBuffer, &resultCount, IPACKS)       : NULL;
    //XXX don't yet know how to tell apart primary and secondary DD data...
    dTS2PES2 = /*XXX dPid2 ? new cTS2PES(resultBuffer, &resultCount, IPACKS) : XXX*/ NULL;
+   sTS2PES1 = SubPid1 ? new cTS2PES(resultBuffer, &resultCount, IPACKS, 0x00, 0x28) : NULL;
+   sTS2PES2 = SubPid2 ? new cTS2PES(resultBuffer, &resultCount, IPACKS, 0x00, 0x29) : NULL;
  }
  
  cRemux::~cRemux()
***************
*** 565,570 ****
--- 607,614 ----
           else if (pid == aPid2 && aTS2PES2) aTS2PES2->ts_to_pes(Data + i);
           else if (pid == dPid1 && dTS2PES1) dTS2PES1->ts_to_pes(Data + i);
           else if (pid == dPid2 && dTS2PES2) dTS2PES2->ts_to_pes(Data + i);
+ 	 else if (pid == sPid1 && sTS2PES1) sTS2PES1->ts_to_pes(Data + i);
+ 	 else if (pid == sPid2 && sTS2PES2) sTS2PES2->ts_to_pes(Data + i);
           }
        used += TS_SIZE;
        if (resultCount > (int)sizeof(resultBuffer) / 2)
diff -B -c /usr/local/src/test1/vdr-1.2.5/remux.h ./remux.h
*** /usr/local/src/test1/vdr-1.2.5/remux.h	2003-04-26 17:13:11.000000000 +0300
--- ./remux.h	2003-09-25 00:15:31.000000000 +0300
***************
*** 32,39 ****
    bool exitOnFailure;
    bool synced;
    int skipped;
!   int vPid, aPid1, aPid2, dPid1, dPid2;
!   cTS2PES *vTS2PES, *aTS2PES1, *aTS2PES2, *dTS2PES1, *dTS2PES2;
    uchar resultBuffer[RESULTBUFFERSIZE];
    int resultCount;
    int resultDelivered;
--- 32,39 ----
    bool exitOnFailure;
    bool synced;
    int skipped;
!   int vPid, aPid1, aPid2, dPid1, dPid2,sPid1, sPid2;
!   cTS2PES *vTS2PES, *aTS2PES1, *aTS2PES2, *dTS2PES1, *dTS2PES2, *sTS2PES1, *sTS2PES2;
    uchar resultBuffer[RESULTBUFFERSIZE];
    int resultCount;
    int resultDelivered;
***************
*** 41,47 ****
    int GetPacketLength(const uchar *Data, int Count, int Offset);
    int ScanVideoPacket(const uchar *Data, int Count, int Offset, uchar &PictureType);
  public:
!   cRemux(int VPid, int APid1, int APid2, int DPid1, int DPid2, bool ExitOnFailure = false);
    ~cRemux();
    uchar *Process(const uchar *Data, int &Count, int &Result, uchar *PictureType = NULL);
    static void SetBrokenLink(uchar *Data, int Length);
--- 41,47 ----
    int GetPacketLength(const uchar *Data, int Count, int Offset);
    int ScanVideoPacket(const uchar *Data, int Count, int Offset, uchar &PictureType);
  public:
!   cRemux(int VPid, int APid1, int APid2, int DPid1, int DPid2, bool ExitOnFailure = false, int SubPid1 = 0, int SubPid2 = 0);
    ~cRemux();
    uchar *Process(const uchar *Data, int &Count, int &Result, uchar *PictureType = NULL);
    static void SetBrokenLink(uchar *Data, int Length);
Only in .: VDR.1.1.25.patch
Only in .: VDR.patch
Only in .: VDRSubs.diff
Only in .: vdrttxtsubshooks.c
Only in .: vdrttxtsubshooks.h

Home | Main Index | Thread Index