Hi,

Andre Neumann schrieb:
> 
> Hi list,
>  
> i've just tested the very good xineliboutput plugin for vdr. Since im
> only using softdevice till now, i know how
> good softdevice works. Again my respect to Stefan, Martin and the others.
>  
> While testing the xineliboutput plugin i noticed some really nice features.
>  
> The xineliboutput plugins features a autocrop mode. That means, when
> using a 16:9 TV and when watching a 4:3 movie with black bars, the
> plugin sets the crop mode to 16:9 automaticly. And it also zooms slowly
> into that
> crop mode. Very nice feature i think. My girlfriend likes it, and me too :)
>  
> I know that this feature is from the xine-lib, but maybe it is possible
> to integrate it into softdevice.
>  
> One person from vdrportal.de a while ago posted such patches, but they
> do not work for me. The smooth zoom patch does not work at all, the
> autocrop patch works, but not as good as the xine think.
>  
I personally don't own a 16:9 screen, so I would not use such a
feature... However I had a look at the patch by [EMAIL PROTECTED] and
updated them to the softdevice cvs. I also improved some things, and
made it possible to switch the border detection on and of. I also tried
a smooth zoom, but with video-xv the video will flicker during the zoom,
so I left it out for now. Also currently the aspect is switched for the
every frame, I think it would be better to wait until one detects a
aspect change in a series of frames and switch the aspect only once.

I attached the result, please try it and tell me if you like it/ what
could be improved.

Bye,

martin
Index: VideoFilter.c
===================================================================
RCS file: /cvsroot/softdevice/softdevice/VideoFilter.c,v
retrieving revision 1.3
diff -u -r1.3 VideoFilter.c
--- VideoFilter.c       30 May 2006 18:57:21 -0000      1.3
+++ VideoFilter.c       25 Mar 2007 09:08:41 -0000
@@ -41,6 +41,7 @@
                 if (!dest) 
                         return false;
         };
+        dest->edge_width=dest->edge_height=0;
         return true;
 };
 
@@ -268,6 +269,127 @@
                 return;
         }
     CopyPicBufferContext(dest,orig);
+}
+
+/*---------------------------cBorderDetect---------------------------------*/
+/*
+
+How Borderdetection works:
+
+
+*/
+
+cBorderDetect::cBorderDetect(cVideoOut *vOut) 
+        : cVideoFilter(vOut), currOrigAspect(-1.0), currDetAspect(-1.0),
+          currBlackBorder(0) {
+        
+};
+
+cBorderDetect::~cBorderDetect() {
+};
+
+void cBorderDetect::Filter(sPicBuffer *&dest, sPicBuffer *orig) {
+    int black_border=0;
+
+    dest = orig; // "copy" do not modify
+
+    double tmp_asp = currDetAspect;
+    
+    if (orig->aspect_ratio > 1.43) 
+            // 16/9 Frame
+            return;
+
+    int width=orig->width/6;
+    int height=orig->height/6;
+    int not_black_count=0;
+        
+    // 4/3 Frame
+    // start of first line
+    uint8_t *pic_start=orig->pixel[0]
+            +(orig->edge_height)*orig->stride[0]
+            +orig->edge_width;
+    // start of last line
+    uint8_t *pic_end=orig->pixel[0]
+            +(orig->edge_height+orig->height-1)*orig->stride[0]
+            +orig->edge_width;
+
+    // scan 1/6 from top and bottom border
+    for (black_border=0; black_border < height; black_border++) {
+            int brightness=0;
+
+            // scan 4/6 of line
+            for (int y = width ; y < width*5; y++) {
+                    // scan upper border (4/6)
+                    brightness += *(pic_start+y);
+                    // scan lower border (4/6)
+                    brightness += *(pic_end+y);
+            }
+            brightness -= width*4*16;
+            brightness /= width * 8;
+
+            if (brightness > BORDER_BLACK) 
+                    not_black_count++;
+            else not_black_count=0;
+
+            // break if we have found BORDER_MIN_SIZE non black lines
+            if (not_black_count>BORDER_MIN_SIZE)
+                    break;
+
+            // next lines
+            pic_start+=orig->stride[0];
+            pic_end-=orig->stride[0];
+    }
+    black_border-=BORDER_MIN_SIZE;
+            
+
+    // scan inner rectangle (4/6) x (4/6)
+    // start of first line of inner rectangle
+    pic_start=orig->pixel[0]
+            +(orig->edge_height+orig->height/6)*orig->stride[0]
+            +orig->edge_width;
+    // start of last line
+    int brightness=0;
+    for (int x = height; x < height * 5; x++) {
+            brightness=0;
+            for (int y = width ; y < width * 5; y++) {
+                    brightness += *(pic_start + y );
+            }
+            brightness -= width *16;
+            brightness /= width * 4;
+            if (brightness > BORDER_MINBRIGHT) // is a bright line there?
+                    break;
+
+            pic_start+=orig->stride[0];
+    }
+    if (brightness > BORDER_MINBRIGHT) {
+            //printf("Picture is bright enough\n");
+            // calculate new aspect with the detected borders
+            float new_aspect = orig->aspect_ratio * float(orig->height) 
+                    / (float)(orig->height - black_border * 2);
+
+            // 4/3 = 1.33  16/9 = 1.77  mid = 1,55
+            if (new_aspect > 1.65) 
+                    tmp_asp = 16.0 / 9.0;
+            else if (new_aspect > 1.45) 
+                    tmp_asp = 14.0 / 9.0; //4.0 / 3.0;
+            else tmp_asp = 4.0 / 3.0;
+            //printf("Bordersize: %d  Calculated aspect %f\n",black_border, 
new_aspect);
+    }
+
+    if (tmp_asp != currDetAspect) {
+            currDetAspect=tmp_asp;
+            currBlackBorder=black_border;
+            fprintf(stderr,"new Aspect detected %f\n", tmp_asp);
+    }
+
+    if (currDetAspect>0.0) {
+            orig->aspect_ratio=currDetAspect;
+            orig->edge_height+=currBlackBorder;
+            orig->height-=2*currBlackBorder;
+/*            printf("%f %d edge_height %d height %d\n",
+                            currDetAspect,currBlackBorder, 
+                            orig->edge_height, orig->height);*/  
+    }
 }
 
 /*---------------------------cLibAvPostProc---------------------------------*/
Index: VideoFilter.h
===================================================================
RCS file: /cvsroot/softdevice/softdevice/VideoFilter.h,v
retrieving revision 1.1
diff -u -r1.1 VideoFilter.h
--- VideoFilter.h       27 May 2006 19:12:41 -0000      1.1
+++ VideoFilter.h       25 Mar 2007 09:08:41 -0000
@@ -68,6 +68,22 @@
         virtual void Filter(sPicBuffer *&dest, sPicBuffer *orig);
 };
 
+#define BORDER_MIN_SIZE 3
+#define BORDER_BLACK 10
+#define BORDER_MINBRIGHT 30
+class cBorderDetect : public cVideoFilter {
+private:
+        double currOrigAspect;
+        double currDetAspect;
+        int currBlackBorder;
+
+public:
+        cBorderDetect(cVideoOut *VideoOut);
+        virtual ~cBorderDetect();
+   
+        virtual void Filter(sPicBuffer *&dest, sPicBuffer *orig);
+};
+
 #ifdef PP_LIBAVCODEC
 class cLibAvPostProc : public cVideoFilter {
         int width, height;
Index: mpeg2decoder.c
===================================================================
RCS file: /cvsroot/softdevice/softdevice/mpeg2decoder.c,v
retrieving revision 1.72
diff -u -r1.72 mpeg2decoder.c
@@ -552,19 +552,20 @@
     const int v_shift= i==0 ? 0 : v_chroma_shift;
 
     pic->base[i]= buf->pixel[i];
-    if(EmuEdge) {
+    if(EmuEdge) 
       pic->data[i] = buf->pixel[i];
-      buf->edge_width=buf->edge_height=0;
-    } else {
-      buf->edge_width=buf->edge_height=EDGE_WIDTH;
+     else 
       pic->data[i] = buf->pixel[i] + (buf->stride[i]*
           EDGE_WIDTH>>v_shift) + (EDGE_WIDTH>>h_shift);
       //pic->data[i] = buf->pixel[i] + ALIGN((buf->stride[i]*
       //              EDGE_WIDTH>>v_shift) + (EDGE_WIDTH>>h_shift),
       //              STRIDE_ALIGN);
-    };
     pic->linesize[i]= buf->stride[i];
   }
+  if(EmuEdge) 
+    buf->edge_width=buf->edge_height=0;
+  else 
+    buf->edge_width=buf->edge_height=EDGE_WIDTH;
   pic->age=buf->age;
 
   return 1;
@@ -587,7 +588,7 @@
                                          int Trickspeed,
                                          bool packetMode)
      : cStreamDecoder(Context, packetMode), Mirror(VideoOut),
-       DeintLibav(VideoOut)
+       DeintLibav(VideoOut), BorderDetect(VideoOut)
 #ifdef PP_LIBAVCODEC
        ,LibAvPostProc(VideoOut)
 #endif
@@ -877,6 +878,9 @@
     if (setupStore.deintMethod == 1)
       DeintLibav.Filter(pic,pic);
 
+    if (setupStore.autodetectAspect)
+            BorderDetect.Filter(pic,pic);
+    
 #ifdef PP_LIBAVCODEC
 #ifdef FB_SUPPORT
     if (setupStore.deintMethod > 2 || setupStore.ppMethod!=0 )
Index: mpeg2decoder.h
===================================================================
RCS file: /cvsroot/softdevice/softdevice/mpeg2decoder.h,v
retrieving revision 1.41
diff -u -r1.41 mpeg2decoder.h
--- mpeg2decoder.h      25 Mar 2007 08:54:12 -0000      1.41
+++ mpeg2decoder.h      25 Mar 2007 09:08:44 -0000
@@ -231,6 +231,7 @@
 
     cVideoMirror        Mirror;
     cDeintLibav         DeintLibav;
+    cBorderDetect       BorderDetect;
 #ifdef PP_LIBAVCODEC
     cLibAvPostProc      LibAvPostProc;
 #endif //PP_LIBAVCODEC
Index: setup-softdevice-menu.c
===================================================================
RCS file: /cvsroot/softdevice/softdevice/setup-softdevice-menu.c,v
retrieving revision 1.10
diff -u -r1.10 setup-softdevice-menu.c
--- setup-softdevice-menu.c     4 Mar 2007 17:45:38 -0000       1.10
+++ setup-softdevice-menu.c     25 Mar 2007 09:08:44 -0000
@@ -311,6 +311,9 @@
                             SETUP_VIDEOASPECTNAMES_COUNT,
                             videoAspectNames));
 
+  Add(new cMenuEditBoolItem(tr("Autodetect Movie Aspect"),
+                            &data->autodetectAspect, tr("no"), tr("yes")));
+
   if (data->outputMethod == VOUT_XV || data->outputMethod == VOUT_VIDIX
       || data->outputMethod == VOUT_SHM )
   {
@@ -483,4 +486,7 @@
   SetupStore ("vidContrast",          setupStore.vidContrast);
   SetupStore ("vidHue",               setupStore.vidHue);
   SetupStore ("vidSaturation",        setupStore.vidSaturation);
+  SetupStore ("ExpandTopBottomLines", setupStore.expandTopBottomLines);
+  SetupStore ("ExpandLeftRightCols",  setupStore.expandLeftRightCols);
+  SetupStore ("autodetectAspect",     setupStore.autodetectAspect);
 }
Index: setup-softdevice.c
===================================================================
RCS file: /cvsroot/softdevice/softdevice/setup-softdevice.c,v
retrieving revision 1.50
diff -u -r1.50 setup-softdevice.c
--- setup-softdevice.c  4 Mar 2007 17:45:38 -0000       1.50
+++ setup-softdevice.c  25 Mar 2007 09:08:45 -0000
@@ -91,6 +91,7 @@
   cropRightCols     = 0;
   expandTopBottomLines = 0;
   expandLeftRightCols = 0;
+  autodetectAspect = 0;
   deintMethod   = 0;
   ppMethod   = 0;
   ppQuality   = 0;
@@ -279,6 +280,11 @@
     expandLeftRightCols = clamp (0, expandLeftRightCols, MAX_CROP_COLS/2);
     fprintf(stderr,"[setup-softdevice] Expanding %d columns at left and 
right\n",
             expandLeftRightCols);
+  } else if(!strcasecmp(Name,"autodetectAspect")) {
+    autodetectAspect = atoi(Value);
+    autodetectAspect = clamp (0, autodetectAspect, 1);
+    fprintf(stderr,"[setup-softdevice] autodetectAspect %d\n",
+            autodetectAspect);
   } else if (!strcasecmp(Name,"PixelFormat")) {
     pixelFormat = atoi(Value);
     pixelFormat = clamp (0, pixelFormat, 2);
Index: setup-softdevice.h
===================================================================
RCS file: /cvsroot/softdevice/softdevice/setup-softdevice.h,v
retrieving revision 1.38
diff -u -r1.38 setup-softdevice.h
--- setup-softdevice.h  4 Mar 2007 17:45:38 -0000       1.38
+++ setup-softdevice.h  25 Mar 2007 09:08:47 -0000
@@ -140,6 +140,7 @@
     int   cropRightCols;
     int   expandTopBottomLines;
     int   expandLeftRightCols;
+    int   autodetectAspect;
     int   deintMethod;
     int   ppMethod;
     int   ppQuality;

_______________________________________________
Softdevice-devel mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/softdevice-devel

Reply via email to