[Softdevice-devel] Problems with softdevice (&softplay) with vdr-1.6.0

Stefan Lucke stefan at lucke.in-berlin.de
Sat Apr 12 13:17:13 CEST 2008


On Friday 11 April 2008, Malcolm Caldwell wrote:
> On Thu, 2008-04-10 at 09:08 +0200, Stefan Lucke wrote:
> > On Wednesday 09 April 2008, Malcolm Caldwell wrote:
> > > Hi,
> > > 
> > > 
> > > On Thu, 2008-04-03 at 20:02 +0200, Martin Wache wrote:
> > > > Hi Malcolm,
> > > > 
> > > > sorry for my late answer...
> > > > 
> > > > Malcolm Caldwell schrieb:
> > > > > Any idea on this?
> > > > > 
> > > > > I hope to get in and have a look myself, but I don't really want to do
> > > > > it on my production vdr system.
> > > > > 
> > > > It would be great if you could solve this problem. I currently don't
> > > > have much time left to work on the softdevice and softplay. I'm sorry...
> > > 
> > > I have found what triggers the segfault.
> > > 
> > > In setup.conf, if softplay.UseReceiver = 1 then vdr segfaults when
> > > softplay opens a file.  Set it to 0 and no segfault.  (I don't know why
> > > yet)
> > 
> > This segfault is still not reproducable for me, even while viewing TV
> > during MP3 playback ;-) (Was not aware of that option).
> 
> Ok got it.
> 
> My trigger was I don't have a channel 1. 
> 
> I really don't know why calls to cDevice::CurrentChannel() were
> returning 1 but they were (On two different machines), and that made for
> problems later on.
> 
> The following patch fixes this:
> 
> --- SoftPlayer.c.orig	2008-03-30 22:08:08.000000000 +0930
> +++ SoftPlayer.c	2008-04-12 00:19:02.000000000 +0930
> @@ -326,8 +326,9 @@
>          };
>  
>   	//SoftDevice->SetPlayMode( (ePlayMode) pmAudioVideo );
> + 	PLDBG("softplay action, use receiver = %d, channel=%d\n",SoftplaySetup.UseReceiver(),cDevice::CurrentChannel());
>          if (SoftplaySetup.UseReceiver()) {
> -                const cChannel *channel=Channels.GetByNumber(cDevice::CurrentChannel());
> +	          const cChannel *channel=Channels.GetByNumber(cDevice::CurrentChannel(),true);

2nd parameter should be integer type. But in any case, channel has
to be checked for != NULL.

>                  Receiver=new cSoftplayReceiver(channel,
>                                  cDevice::PrimaryDevice(),SoftHandles);
>  #if VDRVERSNUM >= 10500 
> 
> 
> 
> (My guess is that an invalid receiver fed null frames into the stream)
> 
> 
> (NOW I can watch my old recordings with softplay.  All I have to do is
> work out WHY my old recordings don't play as recordings.  As mentioned
> previously audio plays stuttering and FAST, advancing approx 10 seconds
> for every minute of playback)

Martin's posted patch only does the read_frame replacement..
Here is another version (from Martin too and a bit older) which
does a different pts handling

http://www.linuxtv.org/pipermail/vdr/2007-March/012476.html

> (However, even softplay is not much of a 'solution' here is audio sync
> is out 2 seconds or so, but at least its constant!)
> 


Stefan Lucke
-------------- next part --------------
Index: mpeg2decoder.c
===================================================================
RCS file: /cvsroot/softdevice/softdevice/mpeg2decoder.c,v
retrieving revision 1.72
diff -u -r1.72 mpeg2decoder.c
--- mpeg2decoder.c	26 Feb 2007 23:00:34 -0000	1.72
+++ mpeg2decoder.c	17 Mar 2007 20:51:17 -0000
@@ -174,7 +174,7 @@
   freezeMode=false;
   AVPacket *pkt;
 
-  while ( PacketQueue.Available() < 7 && active) {
+  while ( PacketQueue.Available() < 3 && active) {
     BUFDEB("wait while loop packets %d StreamDecoder  pid:%d type %d\n",
       PacketQueue.Available(),getpid(),context->codec_type );
     usleep(10000);
@@ -1115,20 +1115,31 @@
           usleep(50000);
 
         BUFDEB("av_read_frame start\n");
-        //ret = av_read_frame(ic, &pkt);
-        ret = av_read_packet(ic, &pkt);
+        ret = av_read_frame(ic, &pkt);
+        //ret = av_read_packet(ic, &pkt);
         if (ret < 0) {
             BUFDEB("cMpeg2Decoder Stream Error!\n");
             if (ThreadActive)
 		    usleep(10000);
             continue;
         }
-        //av_dup_packet(&pkt);
+        av_dup_packet(&pkt);
         PacketCount++;
         BUFDEB("got packet from av_read_frame!\n");
 
+#if LIBAVFORMAT_BUILD > 4623
+        AVRational time_base;
+        time_base=ic->streams[pkt.stream_index]->time_base;
+        if ( pkt.pts != (int64_t) AV_NOPTS_VALUE ) {
+                pkt.pts=av_rescale(pkt.pts, AV_TIME_BASE* (int64_t)time_base.num, time_base.den)/100 ;
+        };
+
+        //printf("PTS: %lld new %lld num %d den %d\n",PTS,pkt.pts,
+        //                time_base.num,time_base.den);
+#else
         if ( pkt.pts != (int64_t) AV_NOPTS_VALUE )
           pkt.pts/=9;
+#endif
 
         QueuePacket(ic,pkt,packetMode);
 
@@ -1184,9 +1195,6 @@
 void cMpeg2Decoder::QueuePacket(const AVFormatContext *ic, AVPacket &pkt,
 		bool PacketMode)
 {
-  BUFDEB("QueuePacket AudioIdx: %d VideoIdx %d pkt.stream_index: %d\n",
-    AudioIdx,VideoIdx,pkt.stream_index);
-
   if (!ic) {
         fprintf(stderr,"Error: ic is null!\n");
         av_free_packet(&pkt);
@@ -1212,6 +1220,8 @@
           BUFDEB("Unknown packet type! Return;\n");
           return;
   };
+  BUFDEB("QueuePacket AudioIdx: %d VideoIdx %d pkt.stream_index: %d, packet_type: %d\n",
+    AudioIdx,VideoIdx,pkt.stream_index,packet_type);
 
   // check if there are new streams
   if ( AudioIdx != DONT_PLAY && packet_type == CODEC_TYPE_AUDIO


More information about the Softdevice-devel mailing list