On Saturday 13 September 2008, Laz wrote:
> On Friday 12 September 2008 22:38:02 Fabio Bordin wrote:
> > Hi!
> > Recently I have returned to use softdevice and I have remained indeed
> > surprised by the footsteps before that it has done.
> > I have noticed an annoying problem with the recordings.
> > If I quickly advance the timecode is not correctly adjourned and  when I
> > press the key play I find very more ahead than what I expected.
> > To make an example:
> > I begin to see the recording and I make to go fast forward the first
> > minute. At the desired point the timecode points out 00:03:00 but the
> > images don't correspond. If I restart and I see the recording to normal
> > speed the point in which I had pressed the key play had to point out
> > once inferior, around 00:01:30.
> 
> I've been seeing the same thing since back in May with DirectFB / Matrox G450 
> output with softdevice (see thread "Trickspeed jumps huge distances..." back 
> in May). This was a newly built system but I've not had this problem before 
> with the same type of hardware.

Which version of ffmpeg do you use ?

> 
> My initial suspicions were that it had to do with the virtual function
> cDevice::HasIBPTrickSpeed which was introduced in vdr 1.5.15. However, I've 
> played about enabling and disabling that in softdevice but get the same 
> outcome as you describe.
> 
> I also see poor A-V synch after using fast or slow speeds: this can be 
> corrected by jumping backwards or forwards! I think there is a limit to the 
> A-V offset so that if the offset is greater than that value it is set to 
> zero: I'm pretty sure this is connected with the "position" in the file and 
> the current frames being shown being so far apart after using a fast or slow 
> speed.
> 

For sync issues, you may use attached patch, see below.

> If I jump forward or backwards by a minute, the actual position jumped (as 
> shown by the counter) is something like 1:12 forwards and 50 s backwards, 
> rather than a minute as it should be. Also, when setting a cut mark, the 
> position jumps forward quite a few I-frames, rather than just to the next 
> one.
> 
> I'm pretty sure that all of these are connected but whether it's down to 
> changes in vdr or in softdevice...
> 
> Any clues?


Can you both try attached patch ?

There are 2 changes:
1st Makes use of av_read_frame() selectable via OSD.
    Thats because I noticed some serrious sync issues with my old ffmpeg
    version I use on my prod system. Deactivating av_read_frame() and 
    using av_read_packed() instead solved that for me.
2nd Feature makes field selectable which is displayed in still picture
    mode, but unfortunately this doesn't work at the moment.


-- 
Stefan Lucke
Index: mpeg2decoder.c
===================================================================
RCS file: /cvsroot/softdevice/softdevice/mpeg2decoder.c,v
retrieving revision 1.83
diff -U3 -r1.83 mpeg2decoder.c
--- mpeg2decoder.c      20 Jul 2008 16:41:01 -0000      1.83
+++ mpeg2decoder.c      13 Sep 2008 16:00:13 -0000
@@ -1047,6 +1047,8 @@
   IsSuspended=false;
   Speed=1;
   pb = NULL;
+
+  useAVReadFrame = setupStore->useAVReadFrame;
 }
 
 cMpeg2Decoder::~cMpeg2Decoder()
@@ -1176,15 +1178,21 @@
           usleep(50000);
 
         BUFDEB("av_read_frame start\n");
-        ret = av_read_frame(ic, &pkt);
-        //ret = av_read_packet(ic, &pkt);
+
+        if (useAVReadFrame)
+            ret = av_read_frame(ic, &pkt);
+        else
+            ret = av_read_packet(ic, &pkt);
+
         if (ret < 0) {
             BUFDEB("cMpeg2Decoder Stream Error!\n");
             if (ThreadActive)
-                   usleep(10000);
+                usleep(10000);
             continue;
         }
-        av_dup_packet(&pkt);
+        if (useAVReadFrame)
+            av_dup_packet(&pkt);
+
         PacketCount++;
         BUFDEB("got packet from av_read_frame!\n");
 
@@ -1537,41 +1545,47 @@
 
 /* ----------------------------------------------------------------------------
  */
-
 static uint8_t pes_packet_header[] = {
      0x00,0x00,0x01, 0xe0,           0x00,0x00,   0x84, 0x00, 0x00,0x00};
      // startcode,  video-stream 0, packet length,      no pts
+
+/* ----------------------------------------------------------------------------
+ */
 int cMpeg2Decoder::StillPicture(uchar *Data, int Length)
 {
-  bool has_pesheader=false;
-  CMDDEB("StillPicture %p length %d \n",Data,Length);
+  bool has_pesheader = false;
+  CMDDEB("StillPicture %p length %d \n", Data,Length);
   // XXX hack to ingore audio junk sent by vdr in the still picture
-  AudioIdx=DONT_PLAY;
+  AudioIdx = DONT_PLAY;
 
   // check if data contains a valid pes header
 #define SEARCH_LENGTH 64
-  if (Length>SEARCH_LENGTH) {
-    uchar *start=Data+1;
+  if (Length > SEARCH_LENGTH) {
+    uchar *start = Data + 1;
     do {
       start++;
-      start=(uchar *)memchr(start,0x01,Data+SEARCH_LENGTH-start);
-      if ( start && start[-1]==0 && start[-2] == 0
-          && ((start[1] &0xF0)==0xe0) ) { // video stream pes header
-        has_pesheader=true;
+      start = (uchar *) memchr (start, 0x01, Data + SEARCH_LENGTH - start);
+      if ( start &&
+           start[-1] == 0 && start[-2] == 0 && 
+           ((start[1] &0xF0) == 0xe0) ) { // video stream pes header
+        has_pesheader = true;
         break;
-      };
-    } while (start<Data+SEARCH_LENGTH && start);
-  };
+      }
+    } while (start < Data + SEARCH_LENGTH && start);
+  }
 
-  for (int i=0; 4>i;i++) {
+  videoOut->SetStillPictureMode (true);
+  for (int i = 0; 4 > i; i++) {
     if (!has_pesheader) {
       // send a fake pes header
-      pes_packet_header[4]=(Length+2)>>8 & 0xFF;
-      pes_packet_header[5]=(Length+2) & 0xFF;
-      Decode(pes_packet_header,9);
-    };
-    Decode(Data,Length);
+      pes_packet_header[4] = (Length + 2) >> 8 & 0xFF;
+      pes_packet_header[5] = (Length + 2) & 0xFF;
+      Decode (pes_packet_header, 9);
+    }
+    Decode (Data,Length);
   }
+  //videoOut->SetStillPictureMode (false);
+
   CMDDEB("StillPicture end \n");
   return Length;
 }
Index: mpeg2decoder.h
===================================================================
RCS file: /cvsroot/softdevice/softdevice/mpeg2decoder.h,v
retrieving revision 1.44
diff -U3 -r1.44 mpeg2decoder.h
--- mpeg2decoder.h      26 Feb 2008 08:06:18 -0000      1.44
+++ mpeg2decoder.h      13 Sep 2008 16:00:14 -0000
@@ -284,6 +284,7 @@
 
     AVFormatContext *ic;
     ByteIOContext   *pb;
+    bool            useAVReadFrame;
     int LastSize;
     cMutex  mutex;
     cSigTimer EnablePutSignal;
Index: setup-softdevice.c
===================================================================
RCS file: /cvsroot/softdevice/softdevice/setup-softdevice.c,v
retrieving revision 1.56
diff -U3 -r1.56 setup-softdevice.c
--- setup-softdevice.c  20 Jul 2008 16:41:01 -0000      1.56
+++ setup-softdevice.c  13 Sep 2008 16:00:14 -0000
@@ -74,6 +74,8 @@
 
 const char *fieldOrderNames[SETUP_FIELD_ORDER_NAMES];
 
+const char *preferredFieldNames[SETUP_PREFERRED_FIELD_NAMES];
+
 /* ----------------------------------------------------------------------------
  */
 cSetupStore *setupStore=NULL;
@@ -116,6 +118,8 @@
   useStretchBlit    = 0;
   stretchBlitLocked = false;
   fieldOrderMode    = 2;
+  preferredField    = bothFields;
+  useAVReadFrame    = true;
   bufferMode      = 0;
   mainMenu  = 1;
   syncTimerMode = 2;
@@ -209,6 +213,11 @@
   fieldOrderNames[1] = "Top field first";
   fieldOrderNames[2] = "Auto";
   fieldOrderNames[3] = NULL;
+
+  preferredFieldNames[0] = tr("Both Fields");
+  preferredFieldNames[1] = tr("First Field");
+  preferredFieldNames[2] = tr("Later Field");
+  preferredFieldNames[3] = NULL;
 }
 
 bool cSetupStore::SetupParse(const char *Name, const char *Value)
@@ -381,6 +390,14 @@
     fieldOrderMode = clamp (0, fieldOrderMode, 2);
     fprintf(stderr, "[setup-softdevice] fieldOrderMode: %s\n",
             fieldOrderNames[fieldOrderMode]);
+  } else if (!strcasecmp(Name, "preferredField")) {
+    preferredField = (tPreferredField) atoi (Value);
+    preferredField = (tPreferredField) clamp (bothFields, preferredField, 
laterField);
+    fprintf(stderr, "[setup-softdevice] preferrenField: %s\n",
+            preferredFieldNames[preferredField]);
+  } else if (!strcasecmp(Name, "useAVReadFrame")) {
+    useAVReadFrame = (bool) atoi (Value);
+    fprintf(stderr, "[setup-softdevice] useAVReadFrame: %s\n", 
(useAVReadFrame) ? "yes": "no");
   } else if (!strcasecmp(Name, "vidBrightness")) {
     vidBrightness = atoi (Value);
     vidBrightness = clamp (-1, vidBrightness, 100);
Index: setup-softdevice.h
===================================================================
RCS file: /cvsroot/softdevice/softdevice/setup-softdevice.h,v
retrieving revision 1.46
diff -U3 -r1.46 setup-softdevice.h
--- setup-softdevice.h  10 Sep 2008 17:15:38 -0000      1.46
+++ setup-softdevice.h  13 Sep 2008 16:00:14 -0000
@@ -105,6 +105,9 @@
 #define SETUP_FIELD_ORDER_NAMES  4
 extern const char *fieldOrderNames[SETUP_FIELD_ORDER_NAMES];
 
+#define SETUP_PREFERRED_FIELD_NAMES  4
+extern const char *preferredFieldNames[SETUP_PREFERRED_FIELD_NAMES];
+
 /* ----------------------------------------------------------------------------
  * allow changing of output pixfmt
  */
@@ -116,6 +119,14 @@
 #define SETUP_SUSPENDVIDEO 3
 extern const char *suspendVideo[SETUP_SUSPENDVIDEO];
 
+/*-----------------------------------------------------------------------------
+ */
+typedef enum preferredField {
+        bothFields,
+        earlierField,
+        laterField
+} tPreferredField;
+
 /* ---------------------------------------------------------------------------
  */
 struct cSetupStore {
@@ -149,6 +160,7 @@
     int   ppQuality;
     int   mirror;
     int   syncOnFrames;
+    bool  useAVReadFrame;
     int   avOffset;
     int   screenPixelAspect;
     int   zoom;
@@ -182,6 +194,8 @@
     char  alsaAC3Device [ALSA_DEVICE_NAME_LENGTH];
 
     int   setupStoreShmid;
+
+    tPreferredField   preferredField;
 };
 
 #define OSDMODE_PSEUDO    0
Index: setup-softdevice-menu.c
===================================================================
RCS file: /cvsroot/softdevice/softdevice/setup-softdevice-menu.c,v
retrieving revision 1.15
diff -U3 -r1.15 setup-softdevice-menu.c
--- setup-softdevice-menu.c     20 Jul 2008 16:41:01 -0000      1.15
+++ setup-softdevice-menu.c     13 Sep 2008 16:00:14 -0000
@@ -370,6 +370,15 @@
                             (SETUP_FIELD_ORDER_NAMES-1),
                             fieldOrderNames));
 
+  Add(new cMenuEditStraItem(tr("Still Picture Field"),
+                            (int *) &data->preferredField,
+                            (SETUP_PREFERRED_FIELD_NAMES-1),
+                            preferredFieldNames));
+
+  Add(new cMenuEditBoolItem(tr("Use av_read_frame()"),
+                            (int *) &data->useAVReadFrame, tr("no"), 
tr("yes")));
+
+
 #if VDRVERSNUM >= 10334
   Add(new cOsdItem(" ", osUnknown, false));
 #else
@@ -489,6 +498,8 @@
   SetupStore ("mainMenu",             setupStore->mainMenu);
   SetupStore ("syncTimerMode",        setupStore->syncTimerMode);
   SetupStore ("fieldOrderMode",       setupStore->fieldOrderMode);
+  SetupStore ("preferredField",       setupStore->preferredField);
+  SetupStore ("useAVReadFrame",       setupStore->useAVReadFrame);
   SetupStore ("vidBrightness",        setupStore->vidBrightness);
   SetupStore ("vidContrast",          setupStore->vidContrast);
   SetupStore ("vidHue",               setupStore->vidHue);
Index: video.c
===================================================================
RCS file: /cvsroot/softdevice/softdevice/video.c,v
retrieving revision 1.77
diff -U3 -r1.77 video.c
--- video.c     20 Jul 2008 16:41:01 -0000      1.77
+++ video.c     13 Sep 2008 16:00:15 -0000
@@ -461,6 +461,56 @@
 
 /* ---------------------------------------------------------------------------
  */
+void cVideoOut::SetStillPictureMode(bool on)
+{
+fprintf(stderr,"%s", on ? "ON " : "OFF ");
+    stillPictureMode = on;
+}
+
+/* ---------------------------------------------------------------------------
+ */
+void cVideoOut::SelectField (sPicBuffer *pic)
+{
+                unsigned char   *dest, 
+                                *src;
+
+fprintf(stderr,"1");
+        if (!pic->interlaced_frame)
+                return;
+fprintf(stderr,"2");
+        if (setupStore->preferredField == bothFields)
+                return;
+
+fprintf(stderr,"3");
+        dest = src  = pic->pixel[0];
+
+        if (setupStore->preferredField == earlierField) {
+
+fprintf(stderr,"4");
+                if (pic->top_field_first)
+                        dest += pic->stride[0];
+                else
+                        src  += pic->stride[0];
+
+        } else {
+
+fprintf(stderr,"5");
+                if (pic->top_field_first)
+                        src  += pic->stride[0];
+                else
+                        dest += pic->stride[0];
+        }
+
+fprintf(stderr,"6");
+        for (int i = 0; i < pic->height; i += 2) {
+            memcpy (dest, src, pic->stride[0]);
+            dest += 2 * pic->stride[0];
+            src  += 2 * pic->stride[0];
+        }
+}
+
+/* ---------------------------------------------------------------------------
+ */
 void cVideoOut::DrawVideo_420pl(cSyncTimer *syncTimer,
                                 sPicBuffer *pic)
 {
@@ -472,6 +522,12 @@
     return;
   }
 
+  if (stillPictureMode) {
+    stillPictureMode = false;
+fprintf(stderr,"0");
+    SelectField (pic);
+  }
+
   sPicBuffer *scale_pic=NULL;
   if (scaleVid != 0) {
           scale_pic=GetBuffer(pic->format,pic->max_width,pic->max_height);
@@ -554,7 +610,7 @@
   offsetIndex %= AVRG_OFF_CNT;
 
   softlog->Log(SOFT_LOG_TRACE, 0,
-                  "[VideoOut] A/V (%d - %d) off = %d avoff = %d\n",
+                  "[VideoOut] A/V (%lld - %lld) off = %d avoff = %d\n",
                   aPTS, pts, offset, offsetAverage);
 
   dropOffset = (useAverage4Drop) ? offsetAverage : offset;
Index: video.h
===================================================================
RCS file: /cvsroot/softdevice/softdevice/video.h,v
retrieving revision 1.56
diff -U3 -r1.56 video.h
--- video.h     20 Jul 2008 16:41:01 -0000      1.56
+++ video.h     13 Sep 2008 16:00:15 -0000
@@ -66,6 +66,7 @@
     //
     sPicBuffer  *oldPicture;
     cMutex      oldPictureMutex;
+    bool        stillPictureMode;
     void        SetOldPicture(sPicBuffer *pic);
 
 protected:
@@ -192,6 +193,8 @@
             oldPictureMutex.Unlock();
     };
 
+    virtual void SetStillPictureMode (bool on);
+    virtual void SelectField (sPicBuffer *pic);
 
     virtual void Action(void);
     // osd control thread. Refreshes the osd on dimension changes and
_______________________________________________
Softdevice-devel mailing list
Softdevice-devel@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/softdevice-devel

Reply via email to