@@ -1057,7 +1057,7 @@
};
int cMpeg2Decoder::seek(offset_t offset, int whence) {
- printf("unimplemented: seek offset %lld whence %d\n",offset,whence);
+ printf("unimplemented: seek offset %lld whence %d\n", (long long int)offset, whence);
return -EINVAL;
};
@@ -59,7 +59,7 @@
char *pix_fmt [] = {
"I420",
"YV12",
- "YUV2",
+ "YUY2",
NULL
};
@@ -154,6 +154,8 @@
outputMethod = 0;
cropMode = 0;
cropModeToggleKey = 0;
+ cropTopLines = 0;
+ cropBottomLines = 0;
deintMethod = 0;
ppMethod = 0;
ppQuality = 0;
@@ -224,6 +226,16 @@
"[setup-softdevice] cropping mode toggle key set to %d (%s)\n",
cropModeToggleKey,
userKeyUsage [cropModeToggleKey]);
+ } else if(!strcasecmp(Name,"CropTopLines")) {
+ cropTopLines = atoi(Value);
+ cropTopLines = clamp (0, cropTopLines, 100);
+ fprintf(stderr,"[setup-softdevice] Cropping %d lines from top\n",
+ cropTopLines);
+ } else if(!strcasecmp(Name,"CropBottomLines")) {
+ cropBottomLines = atoi(Value);
+ cropBottomLines = clamp (0, cropBottomLines, 100);
+ fprintf(stderr,"[setup-softdevice] Cropping %d lines from bottom\n",
+ cropBottomLines);
} else if (!strcasecmp(Name,"PixelFormat")) {
pixelFormat = atoi(Value);
pixelFormat = clamp (0, pixelFormat, 2);
@@ -370,6 +380,16 @@
10,
userKeyUsage));
+ Add(new cMenuEditIntItem(tr("Crop lines from top"),
+ &data->cropTopLines,
+ 0,
+ 100));
+
+ Add(new cMenuEditIntItem(tr("Crop lines from bottom"),
+ &data->cropBottomLines,
+ 0,
+ 100));
+
if (data->outputMethod == VOUT_FB)
{
Add(new cMenuEditStraItem(tr("Deinterlace Method"),
@@ -483,6 +503,8 @@
//SetupStore ("Xv-MaxArea", setupStore.xvMaxArea);
SetupStore ("CropMode", setupStore.cropMode);
SetupStore ("CropModeToggleKey", setupStore.cropModeToggleKey);
+ SetupStore ("CropTopLines", setupStore.cropTopLines);
+ SetupStore ("CropBottomLines", setupStore.cropBottomLines);
SetupStore ("Deinterlace Method", setupStore.deintMethod);
SetupStore ("Postprocess Method", setupStore.ppMethod);
SetupStore ("Postprocess Quality", setupStore.ppQuality);
@@ -21,6 +21,7 @@
class cSetupStore {
public:
cSetupStore ();
+ virtual ~cSetupStore () {};
bool SetupParse(const char *Name, const char *Value);
char *getPPdeintValue(void);
char *getPPValue(void);
@@ -35,6 +36,8 @@
int pixelFormat;
int cropMode;
int cropModeToggleKey;
+ int cropTopLines;
+ int cropBottomLines;
int deintMethod;
int ppMethod;
int ppQuality;
@@ -20,6 +20,79 @@
#include "utils.h"
#include "setup-softdevice.h"
+void yv12_to_yuy2(const uint8_t *ysrc, const uint8_t *usrc, const uint8_t *vsrc, uint8_t *dst,
+ int width, int height, int lumStride, int chromStride, int dstStride)
+{
+#ifndef USE_MMX
+ const unsigned chromWidth = width >> 1;
+
+ for(int y=0; y<height; y++)
+ {
+ uint32_t *idst = (uint32_t *) dst;
+ const uint8_t *yc = ysrc, *uc = usrc, *vc = vsrc;
+
+ for(unsigned i = 0; i < chromWidth; i++)
+ {
+ *idst++ = (yc[0] << 0)+ (uc[0] << 8) + (yc[1] << 16) + (vc[0] << 24);
+ yc += 2;
+ uc++;
+ vc++;
+ }
+
+ if( (y&1) == 1)
+ {
+ usrc += chromStride;
+ vsrc += chromStride;
+ }
+
+ ysrc += lumStride;
+ dst += dstStride;
+ }
+#else
+ for (int i=0; i<height; i++)
+ {
+ const uint8_t *pu, *pv, *py;
+ uint8_t *srfc;
+
+ pu = usrc;
+ pv = vsrc;
+ py = ysrc;
+
+ srfc = dst;
+
+ for (int j =0; j < width/8; j++)
+ {
+ movd_m2r(*pu, mm1); // mm1 = 00 00 00 00 U3 U2 U1 U0
+ movd_m2r(*pv, mm2); // mm2 = 00 00 00 00 V3 V2 V1 V0
+ movq_m2r(*py, mm0); // mm0 = Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
+ punpcklbw_r2r(mm2, mm1); // mm1 = V3 U3 V2 U2 V1 U1 V0 U0
+ movq_r2r(mm0,mm3); // mm3 = Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
+ movq_r2r(mm1,mm4); // mm4 = V3 U3 V2 U2 V1 U1 V0 U0
+ punpcklbw_r2r(mm1, mm0); // mm0 = V1 Y3 U1 Y2 V0 Y1 U0 Y0
+ punpckhbw_r2r(mm4, mm3); // mm3 = V3 Y7 U3 Y6 V2 Y5 U2 Y4
+
+ movntq(mm0,*srfc); // Am Meisten brauchen die Speicherzugriffe
+ srfc+=8;
+ py+=8;
+ pu+=4;
+ pv+=4;
+ movntq(mm3,*srfc); // wenn movntq nicht geht, dann movq verwenden
+ srfc+=8;
+ }
+
+ ysrc += lumStride;;
+
+ if (i % 2 == 1)
+ {
+ usrc += chromStride;
+ vsrc += chromStride;
+ }
+
+ dst += width*2;
+ }
+#endif
+}
+
#define VERT_SCALING
void (*mmx_unpack)(uint8_t * image, int lines, int stride);
@@ -341,7 +414,8 @@
: "memory");\
}
- void * fast_memcpy(void * to, const void * from, size_t len)
+#if 0
+void * fast_memcpy(void * to, const void * from, size_t len)
{
void *retval;
size_t i;
@@ -380,7 +454,7 @@
*/
// Align destination at BLOCK_SIZE boundary
- for(; ((int)to & (BLOCK_SIZE-1)) && i>0; i--)
+ for(; ((long)to & (BLOCK_SIZE-1)) && i>0; i--)
{
__asm__ __volatile__ (
#ifdef USE_MMX2
@@ -512,5 +586,4 @@
if(len) small_memcpy(to, from, len);
return retval;
}
-
-
+#endif
@@ -19,10 +19,17 @@
#define movntq(src,dest) do { movq_r2m (src, dest); } while (0);
#endif
-/* else \
- movq_r2m (src, dest); \
-} while (0)
-*/
+void yv12_to_yuy2( const uint8_t *ysrc,
+ const uint8_t *usrc,
+ const uint8_t *vsrc,
+ uint8_t *dst,
+ int width,
+ int height,
+ int lumStride,
+ int chromStride,
+ int dstStride
+ );
+
void yuv_to_rgb (uint8_t * image, uint8_t * py,
uint8_t * pu, uint8_t * pv,
int width, int height,
@@ -757,6 +757,7 @@
alpha+=8;
dest+=8;
}
+ EMMS;
#endif //USE_MMX
//fallback version and the last missing bytes...
@@ -571,6 +571,8 @@
}
}
+static int cutTop, cutBottom;
+
/* ---------------------------------------------------------------------------
*/
void cDFBVideoOut::SetParams()
@@ -581,11 +583,13 @@
if (videoLayer || useStretchBlit)
{
- if (!videoSurface ||
- aspect_changed ||
- currentPixelFormat != setupStore->pixelFormat)
+ if ( ! videoSurface || aspect_changed || currentPixelFormat != setupStore->pixelFormat ||
+ cutTop != setupStore->cropTopLines || cutBottom != setupStore->cropBottomLines )
{
+ cutTop = setupStore->cropTopLines;
+ cutBottom = setupStore->cropBottomLines;
+
fprintf(stderr,
"[dfb] (re)configuring Videolayer to %d x %d (%dx%d)\n",
fwidth,fheight,swidth,sheight);
@@ -600,8 +606,8 @@
else if (setupStore->pixelFormat == 2)
{
dlc.pixelformat = DSPF_YUY2;
- useStretchBlit = true;
- OSDpseudo_alpha = false;
+// useStretchBlit = true;
+// OSDpseudo_alpha = false;
}
#if HAVE_SetSourceLocation
@@ -1026,23 +1035,29 @@
dst += pitch / 2;
}
#else
+ Py += (Ystride * syoff) + Ystride * cutTop * 2;
+ Pv += (UVstride * syoff/2) + UVstride * cutTop;
+ Pu += (UVstride * syoff/2) + UVstride * cutTop;
- Py += (Ystride * syoff);
- Pv += (UVstride * syoff/2);
- Pu += (UVstride * syoff/2);
+ dst += pitch * cutTop * 2;
- for(hi=0; hi < sheight; hi++){
+ for(hi=cutTop*2; hi < sheight-cutBottom*2; hi++){
memcpy(dst, Py+sxoff, swidth);
Py += Ystride;
dst += pitch;
}
- for(hi=0; hi < sheight/2; hi++) {
+
+ dst += pitch * cutBottom * 2 + pitch * cutTop / 2;
+
+ for(hi=cutTop; hi < sheight/2-cutBottom; hi++) {
memcpy(dst, Pu+sxoff/2, swidth/2);
Pu += UVstride;
dst += pitch / 2;
}
- for(hi=0; hi < sheight/2; hi++) {
+ dst += pitch * cutBottom / 2 + pitch * cutTop / 2;
+
+ for(hi=cutTop; hi < sheight/2-cutBottom; hi++) {
memcpy(dst, Pv+sxoff/2, swidth/2);
Pv += UVstride;
dst += pitch / 2;
@@ -1050,59 +1065,9 @@
#endif
} else if (pixelformat == DSPF_YUY2) {
-#ifndef USE_MMX
-//#if 1
- /* reference implementation */
- int p = pitch - Width*2;
- for (int i=0; i<Height; i++) {
- for (int j =0; j < Width/2; j++) {
- *dst = *(Py + (j*2) + i * Ystride);
- dst +=1;
- *dst = *(Pu + j + (i/2) * UVstride);
- dst +=1;
- *dst = *(Py + (j*2)+1 + i * Ystride);
- dst +=1;
- *dst = *(Pv + j + (i/2) * UVstride);
- dst +=1;
- }
- dst +=p;
- }
-#else
- /* deltas */
- for (int i=0; i<Height; i++) {
- uint8_t *pu, *pv, *py, *srfc;
-
- pu = Pu;
- pv = Pv;
- py = Py;
- srfc = dst;
- for (int j =0; j < Width/8; j++) {
- movd_m2r(*pu, mm1); // mm1 = 00 00 00 00 U3 U2 U1 U0
- movd_m2r(*pv, mm2); // mm2 = 00 00 00 00 V3 V2 V1 V0
- movq_m2r(*py, mm0); // mm0 = Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
- punpcklbw_r2r(mm2, mm1); // mm1 = V3 U3 V2 U2 V1 U1 V0 U0
- movq_r2r(mm0,mm3); // mm3 = Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
- movq_r2r(mm1,mm4); // mm4 = V3 U3 V2 U2 V1 U1 V0 U0
- punpcklbw_r2r(mm1, mm0); // mm0 = V1 Y3 U1 Y2 V0 Y1 U0 Y0
- punpckhbw_r2r(mm4, mm3); // mm3 = V3 Y7 U3 Y6 V2 Y5 U2 Y4
-
- movntq(mm0,*srfc); // Am Meisten brauchen die Speicherzugriffe
- srfc+=8;
- py+=8;
- pu+=4;
- pv+=4;
- movntq(mm3,*srfc); // wenn movntq nicht geht, dann movq verwenden
- srfc+=8;
- }
- Py += Ystride;;
- if (i % 2 == 1) {
- Pu += UVstride;
- Pv += UVstride;
- }
- dst += pitch;
- }
-#endif
+ yv12_to_yuy2(Py, Pu, Pv, dst, Width, Height, Ystride, UVstride, pitch);
}
+
videoSurface->Unlock();
try {
@@ -133,7 +133,7 @@
printf("cVidixVideoOut: vidix version: %i\n", vidix_version);
- vidix_handler = vdlOpen(VIDIX_DIR, NULL, TYPE_OUTPUT, 1);
+ vidix_handler = vdlOpen(VIDIX_DIR, NULL, TYPE_OUTPUT, 0);
if( !vidix_handler )
{
@@ -161,7 +161,6 @@
currentPixelFormat = setupStore->pixelFormat;
screenPixelAspect = -1;
- vdlQueryFourcc(vidix_handler, &vidix_fourcc);
if (vdlQueryFourcc(vidix_handler, &vidix_fourcc))
{
if (!MatchPixelFormat())
@@ -312,10 +311,17 @@
{
uint8_t *dst;
int hi, wi;
+
+ static int cutTop, cutBottom;
+
START;
TIMINGS("start...\n");
- if (aspect_changed || currentPixelFormat != setupStore->pixelFormat)
+ if (aspect_changed || currentPixelFormat != setupStore->pixelFormat ||
+ cutTop != setupStore->cropTopLines || cutBottom != setupStore->cropBottomLines )
{
+ cutTop = setupStore->cropTopLines;
+ cutBottom = setupStore->cropBottomLines;
+
printf("cVidixVideoOut: Video changed format to %dx%d\n", Width, Height);
if((Xres > Width || Yres > Height) &&
@@ -400,20 +407,44 @@
if (currentPixelFormat == 0 || currentPixelFormat == 1)
{
#if VDRVERSNUM >= 10307
- if (OSDpresent && current_osdMode==OSDMODE_SOFTWARE) {
+ if (OSDpresent && current_osdMode==OSDMODE_SOFTWARE)
+ {
for(hi=0; hi < sheight; hi++){
- AlphaBlend(dst,OsdPy+hi*OSD_FULL_WIDTH,
- Py + sxoff,
- OsdPAlphaY+hi*OSD_FULL_WIDTH,swidth);
+ AlphaBlend(dst, OsdPy+hi*OSD_FULL_WIDTH, Py + sxoff, OsdPAlphaY+hi*OSD_FULL_WIDTH, swidth);
Py += Ystride;
dst += dstrides.y;
+ }
+
+ // Plane U
+ dst = (uint8_t *)vidix_play.dga_addr + vidix_play.offsets[next_frame] + vidix_play.offset.u;
+ for(hi=0; hi < sheight/2; hi++){
+ AlphaBlend(dst,OsdPu+hi*OSD_FULL_WIDTH/2, Pu + sxoff/2, OsdPAlphaUV+hi*OSD_FULL_WIDTH/2,swidth/2);
+ Pu += UVstride;
+ dst += dstrides.y / 2;
+ }
+ // Plane V
+ dst = (uint8_t *)vidix_play.dga_addr + vidix_play.offsets[next_frame] + vidix_play.offset.v;
+ for(hi=0; hi < sheight/2; hi++) {
+ AlphaBlend(dst, OsdPv+hi*OSD_FULL_WIDTH/2, Pv + sxoff/2, OsdPAlphaUV+hi*OSD_FULL_WIDTH/2, swidth/2);
+ Pv += UVstride;
+ dst += dstrides.v / 2;
}
- EMMS;
} else
#endif
+ {
+ int chromaWidth = swidth >> 1;
+ int chromaOffset = sxoff >> 1;
- for(hi=0; hi < sheight; hi++){
+ Py += Ystride * cutTop * 2;
+ Pv += UVstride * cutTop;
+ Pu += UVstride * cutTop;
+
+ dst += dstrides.y * cutTop * 2;
+
+
+ for(hi=cutTop*2; hi < sheight-cutBottom*2; hi++)
+ {
memcpy(dst, Py+sxoff, swidth);
Py += Ystride;
dst += dstrides.y;
@@ -423,15 +454,22 @@
if (vidix_play.flags & VID_PLAY_INTERLEAVED_UV)
{
- dst = (uint8_t *)vidix_play.dga_addr + vidix_play.offsets[next_frame] + vidix_play.offset.v;
+ int dstStride = dstrides.v << 1;
+ dst = (uint8_t *)vidix_play.dga_addr + vidix_play.offsets[next_frame] + vidix_play.offset.v + dstStride * cutTop;
+
+ for(hi = cutTop; hi < sheight/2; hi++)
+ {
+ uint16_t *idst = (uint16_t *) dst;
+ uint8_t *usrc = Pu + chromaOffset, *vsrc = Pv + chromaOffset;
- for(hi = 0; hi < sheight/2; hi++) {
- for(wi = 0; wi < swidth/2; wi++) {
- dst[2*wi+0] = Pu[wi+sxoff/2];
- dst[2*wi+1] = Pv[wi+sxoff/2];
+ for(wi = 0; wi < chromaWidth; wi++)
+ {
+ *idst++ = ( usrc[0] << 8 ) + vsrc[0];
+ usrc++;
+ vsrc++;
}
- dst += dstrides.y;
+ dst += dstStride;
Pu += UVstride;
Pv += UVstride;
}
@@ -435,48 +473,33 @@
Pu += UVstride;
Pv += UVstride;
}
+
} else {
+ int dstStride;
+
// Plane U
- dst = (uint8_t *)vidix_play.dga_addr + vidix_play.offsets[next_frame] + vidix_play.offset.u;
+ dstStride = dstrides.u >> 1;
+ dst = (uint8_t *)vidix_play.dga_addr + vidix_play.offsets[next_frame] + vidix_play.offset.u + dstStride * cutTop;
-#if VDRVERSNUM >= 10307
- if (OSDpresent && current_osdMode==OSDMODE_SOFTWARE) {
- for(hi=0; hi < sheight/2; hi++){
- AlphaBlend(dst,OsdPu+hi*OSD_FULL_WIDTH/2,
- Pu + sxoff/2,
- OsdPAlphaUV+hi*OSD_FULL_WIDTH/2,swidth/2);
+ for(hi=cutTop; hi < sheight/2 - cutBottom; hi++)
+ {
+ memcpy(dst, Pu+chromaOffset, chromaWidth);
Pu += UVstride;
- dst += dstrides.y / 2;
+ dst += dstStride;
}
// Plane V
- dst = (uint8_t *)vidix_play.dga_addr + vidix_play.offsets[next_frame] + vidix_play.offset.v;
- for(hi=0; hi < sheight/2; hi++) {
- AlphaBlend(dst, OsdPv+hi*OSD_FULL_WIDTH/2,
- Pv + sxoff/2,
- OsdPAlphaUV+hi*OSD_FULL_WIDTH/2, swidth/2);
- Pv += UVstride;
- dst += dstrides.v / 2;
- }
+ dstStride = dstrides.v >> 1;
+ dst = (uint8_t *)vidix_play.dga_addr + vidix_play.offsets[next_frame] + vidix_play.offset.v + dstStride * cutTop;
- EMMS;
- } else
-#endif
+ for(hi=cutTop; hi < sheight/2 - cutBottom; hi++)
{
- for(hi=0; hi < sheight/2; hi++) {
- memcpy(dst, Pu+sxoff/2, swidth/2);
- Pu += UVstride;
- dst += dstrides.u / 2;
- }
-
- // Plane V
- dst = (uint8_t *)vidix_play.dga_addr + vidix_play.offsets[next_frame] + vidix_play.offset.v;
- for(hi=0; hi < sheight/2; hi++) {
- memcpy(dst, Pv+sxoff/2, swidth/2);
+ memcpy(dst, Pv+chromaOffset, chromaWidth);
Pv += UVstride;
- dst += dstrides.v / 2;
+ dst += dstStride;
}
+
}
}
} else if (currentPixelFormat == 2) {
@@ -481,58 +504,7 @@
}
} else if (currentPixelFormat == 2) {
-#ifndef USE_MMX
-
- /* reference implementation */
- //int p = vidix_play.src.pitch.y - Width*2;
- for (int i=0; i<Height; i++) {
- for (int j =0; j < Width/2; j++) {
- *dst = *(Py + (j*2) + i * Ystride);
- dst +=1;
- *dst = *(Pu + j + (i/2) * UVstride);
- dst +=1;
- *dst = *(Py + (j*2)+1 + i * Ystride);
- dst +=1;
- *dst = *(Pv + j + (i/2) * UVstride);
- dst +=1;
- }
- //dst +=p;
- }
-#else
- /* deltas */
- for (int i=0; i<Height; i++) {
- uint8_t *pu, *pv, *py, *srfc;
-
- pu = Pu;
- pv = Pv;
- py = Py;
- srfc = dst;
- for (int j =0; j < Width/8; j++) {
- movd_m2r(*pu, mm1); // mm1 = 00 00 00 00 U3 U2 U1 U0
- movd_m2r(*pv, mm2); // mm2 = 00 00 00 00 V3 V2 V1 V0
- movq_m2r(*py, mm0); // mm0 = Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
- punpcklbw_r2r(mm2, mm1); // mm1 = V3 U3 V2 U2 V1 U1 V0 U0
- movq_r2r(mm0,mm3); // mm3 = Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
- movq_r2r(mm1,mm4); // mm4 = V3 U3 V2 U2 V1 U1 V0 U0
- punpcklbw_r2r(mm1, mm0); // mm0 = V1 Y3 U1 Y2 V0 Y1 U0 Y0
- punpckhbw_r2r(mm4, mm3); // mm3 = V3 Y7 U3 Y6 V2 Y5 U2 Y4
-
- movntq(mm0,*srfc); // Am Meisten brauchen die Speicherzugriffe
- srfc+=8;
- py+=8;
- pu+=4;
- pv+=4;
- movntq(mm3,*srfc); // wenn movntq nicht geht, dann movq verwenden
- srfc+=8;
- }
- Py += Ystride;;
- if (i % 2 == 1) {
- Pu += UVstride;
- Pv += UVstride;
- }
- dst += Width*2;
- }
-#endif
+ yv12_to_yuy2(Py, Pu, Pv, dst, Width, Height, Ystride, UVstride, dstrides.y*2);
}
TIMINGS("After UV\n");