Hi,

Reinhard Nissl schrieb:

> attached you'll find updated patches for VDR-1.5.13.
> 
> The patch named *-dvbs2-* additionally adds DVB-S2 support to VDR
> (thanks to Marco Schlüßler) and requires to use the DVB drivers
> from the multi-proto tree (see URL below for further details).
> 
> The other patch is without DVB-S2 support and therefore most
> suitable for DVB-C users.
> 
> The patches have been extended to also include the recently
> released bugfixes, addons, forgotten speedup patches and LIRC
> changes. Additionally, cDvbTuner::IsTunedTo() and the channel
> editor have been fixed / enhanced to deal with modulation systems.

The attached addon to these patches will detect H.264
automatically in cRemux. Furthermore it will remove the vpid
offset 10000 from H.264 channels, so applications like
streamdev-server or femon should work now without adding support
for the above offset.

Please have a look into VDR's logfile where cVideoRepacker will
log it's operating mode and report any incorrect decisions here.

> Have a look at this page for more instructions on this concern:
> 
> http://www.vdr-wiki.de/wiki/index.php/OpenSuSE_DVB-S2_-_Step_by_Step_Installationsanleitung_%28Achtung_Beta%29

Bye.
-- 
Dipl.-Inform. (FH) Reinhard Nissl
mailto:[EMAIL PROTECTED]
--- ../vdr-1.5.13-dvbs2-other/channels.h	2008-01-19 23:22:17.000000000 +0100
+++ channels.h	2008-01-20 22:00:07.000000000 +0100
@@ -50,7 +50,7 @@
 // VPID can be in the range 0...8191. Offsets of 10000 are used to indicate special video codings.
 #define VPID_OFFSET_BASE         10000
 #define VPID_FROM_ANY(pid)       ((pid) % VPID_OFFSET_BASE) // returns the plain VPID
-#define VPID_TO_XXX(pid, offset) (pid + offset)
+#define VPID_TO_XXX(pid, offset) (pid /* + offset */)
 #define VPID_IS_XXX(pid, offset) ((pid - VPID_FROM_ANY(pid)) == offset)
 // 1. special video coding: H.264
 #define VPID_OFFSET_H264         (1 * VPID_OFFSET_BASE)
--- ../vdr-1.5.13-dvbs2-other/remux.c	2008-01-19 23:43:30.000000000 +0100
+++ remux.c	2008-01-20 21:59:00.000000000 +0100
@@ -375,6 +375,9 @@ void cAudGenerator::Generate(cRingBuffer
 // --- cVideoRepacker --------------------------------------------------------
 
 #define IPACKS 2048
+#define SC_SEQUENCE 0xB3  // "sequence header code"
+#define SC_GROUP    0xB8  // "group start code"
+#define SC_PICTURE  0x00  // "picture start code"
 
 class cVideoRepacker : public cCommonRepacker {
 private:
@@ -389,6 +392,7 @@ private:
   bool collectChunkData;
   H264::cSimpleBuffer chunkData;
   H264::cParser *h264Parser;
+  bool &h264;
   int sliceSeen;
   bool audSeen;
   cAudGenerator *audGenerator;
@@ -415,19 +419,23 @@ private:
   void EndCollectingPictureExtension(void);
   bool DetermineFramePicture(void);
   void GenerateFieldPicturesHint(bool FramePicture, const uchar *const Data, const uchar AndMask, const uchar OrMask);
+  void SwitchToMpeg12(void);
 protected:
   virtual int Put(cRingBufferLinear *ResultBuffer, const uchar *Data, int Count, int CapacityNeeded);
 public:
-  cVideoRepacker(bool H264);
+  cVideoRepacker(bool &H264);
   ~cVideoRepacker();
   virtual void Reset(void);
   virtual void Repack(cRingBufferLinear *ResultBuffer, const uchar *Data, int Count);
   virtual int BreakAt(const uchar *Data, int Count);
   };
 
-cVideoRepacker::cVideoRepacker(bool H264)
+cVideoRepacker::cVideoRepacker(bool &H264)
 : chunkData(1024)
+, h264(H264)
 {
+  // assume H.264 -- we'll fallback to MPEG1/2 when necessary
+  h264 = true;
   h264Parser = (H264 ? new H264::cParser() : 0);
   audGenerator = 0;
   Reset();
@@ -458,6 +466,18 @@ void cVideoRepacker::Reset(void)
   startCodeLocationsPrepared = false;
 }
 
+void cVideoRepacker::SwitchToMpeg12(void)
+{
+  if (!h264Parser)
+     return;
+  dsyslog("cVideoRepacker: switching to MPEG1/2 mode");
+  delete h264Parser;
+  h264Parser = 0;
+  delete audGenerator;
+  audGenerator = 0;
+  h264 = false;
+}
+
 int cVideoRepacker::Put(cRingBufferLinear *ResultBuffer, const uchar *Data, int Count, int CapacityNeeded)
 {
   if (!audGenerator)
@@ -476,6 +496,20 @@ void cVideoRepacker::CollectData(const u
 
 void cVideoRepacker::HandleNalUnit(const uchar *const Data, cRingBufferLinear *const ResultBuffer, const uchar *&Payload, const uchar StreamID, const ePesHeader MpegLevel, const uchar *&NalPayload)
 {
+  // check whether we need to fall back to MPEG1/2
+  if (initiallySyncing) {
+     switch (*Data) {
+       case SC_SEQUENCE:
+       case SC_GROUP:
+       case SC_PICTURE:
+            // the above start codes do not appear in H.264 so let's switch to MPEG1/2 
+            SwitchToMpeg12();
+            // delegate startcode to appropriate handler
+            HandleStartCode(Data, ResultBuffer, Payload, StreamID, MpegLevel, NalPayload);
+            return;
+       }
+     }
+
   // valid NAL units start with a zero bit
   if (*Data & 0x80) {
      LOG("cVideoRepacker: found invalid NAL unit: stream seems to be scrambled or not demultiplexed");
@@ -683,8 +717,10 @@ void cVideoRepacker::PushOutCurrentFrame
   if (state != syncing)
      return;
   // we're synced to a picture so prepare a new packet
-  if (initiallySyncing) // omit report for the typical initial case
+  if (initiallySyncing) { // omit report for the typical initial case
      initiallySyncing = false;
+     isyslog("cVideoRepacker: operating in %s mode", h264Parser ? "H.264" : "MPEG1/2");
+     }
   else if (skippedBytes > SkippedBytesLimit) // report that syncing dropped some bytes
      LOG("cVideoRepacker: skipped %d bytes to sync on next picture", skippedBytes - SkippedBytesLimit);
   skippedBytes = 0;
@@ -2492,7 +2528,7 @@ int cRingBufferLinearPes::DataReady(cons
 
 cRemux::cRemux(int VPid, const int *APids, const int *DPids, const int *SPids, bool ExitOnFailure, bool SyncEarly)
 {
-  h264 = VPID_IS_H264(VPid);
+  h264 = false; //VPID_IS_H264(VPid);
   VPid = VPID_FROM_ANY(VPid);
   exitOnFailure = ExitOnFailure;
   noVideo = VPid == 0 || VPid == 1 || VPid == 0x1FFF;
_______________________________________________
vdr mailing list
vdr@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr

Reply via email to