Hello,
here is a small patch for avirec, which allows to crop the edge pixels
to get rid of the garbage or the dark space, which wastes the bandwidth.
The -x and -y options still specify the dimensions of the output image
and with the -L,-R,-T,-B options you specify the additional margins
which will be grabbed and then discarded. I didn't notice any
performance decrease using this patch.
Regards,
--
Jindrich Makovicka
diff -ur vanilla/avirec.cpp mod/avirec.cpp
--- vanilla/avirec.cpp Mon Jun 3 10:55:22 2002
+++ mod/avirec.cpp Thu Jul 25 12:26:15 2002
@@ -56,6 +56,10 @@
char *attributes[10];
int width;
int height;
+ int over_l;
+ int over_r;
+ int over_t;
+ int over_b;
int quality;
int keyframes;
int audio_channels;
@@ -75,6 +79,10 @@
{NULL},
384,
288,
+ 0,
+ 0,
+ 0,
+ 0,
95,
15,
2,
@@ -150,20 +158,21 @@
avm::vector<avm::string>::const_iterator sit;
GetCodecAttr(*it, inf_it->GetName(), defval);
- printf(" %s = %s (", inf_it->GetName(),
inf_it->options[defval].c_str());
+ printf(" %s = %s (", inf_it->GetName(),
+inf_it->options[defval].c_str());
for (sit = (inf_it->options).begin(); sit !=
(inf_it->options).end(); sit++)
printf("%s ", sit->c_str());
- printf("\n");
+ printf(")\n");
}
-
+ break;
case AttributeInfo::String:
{
char def_str[256];
GetCodecAttr(*it, it->GetName(), def_str, 256);
printf(" %s = '%s'\n", inf_it->GetName(), def_str);
}
+ break;
}
}
@@ -195,7 +204,12 @@
" -r | --rgb off capture in rgb color space\n"
" -t | --rectime time 60s set time limit (s,m,h,d,w)\n"
" -x | --width cols 384 set capture width\n"
- " -y | --height rows 288 set capture height\n", arg0);
+ " -y | --height rows 288 set capture height\n"
+ " -L | --over-l cols 0 set left overscan\n"
+ " -R | --over-r cols 0 set right overscan\n"
+ " -T | --over-t rows 0 set top overscan\n"
+ " -B | --over-b rows 0 set bottom overscan\n"
+ , arg0);
}
int time_interval(char *str)
@@ -297,6 +311,12 @@
pcc->samplesize = 16; // make configurable
pcc->res_w = pconf->width;
pcc->res_h = pconf->height;
+
+ pcc->over_l = pconf->over_l;
+ pcc->over_r = pconf->over_r;
+ pcc->over_t = pconf->over_t;
+ pcc->over_b = pconf->over_b;
+
pcc->timelimit = pconf->timelimit;
pcc->sizelimit = -1; // make configurable
pcc->fps = pconf->fps;
@@ -390,19 +410,24 @@
{"input", 0, NULL, 'i'},
{"keyframes", 0, NULL, 'k'},
{"list", 0, NULL, 'l'},
- {"list-audio", 0, NULL, 'L'},
+ {"list-audio", 0, NULL, 'C'},
{"audiomode", 0, NULL, 'm'},
{"quality", 0, NULL, 'q'},
{"rgb", 0, NULL, 'r'},
{"rectime", 0, NULL, 't'},
{"width", 0, NULL, 'x'},
{"height", 0, NULL, 'y'}, // -h already given for help...
+ {"over-l", 0, NULL, 'L'},
+ {"over-r", 0, NULL, 'R'},
+ {"over-t", 0, NULL, 'T'},
+ {"over-b", 0, NULL, 'B'},
+
{NULL, 0, NULL, 0 }
};
int this_option_optind = optind ? optind : 1;
int option_index = 0;
- c = getopt_long (argc, argv, "a:b:c:dF:g:G:hi:k:lLm:n:q:rt:x:y:",
+ c = getopt_long (argc, argv, "a:b:Cc:dF:g:G:hi:k:lm:n:q:rt:x:y:L:R:T:B:",
long_options, &option_index);
if (c == -1)
break;
@@ -442,7 +467,7 @@
ListCodecs(video_codecs);
do_rec = 0;
break;
- case 'L':
+ case 'C':
ListCodecs(audio_codecs);
do_rec = 0;
break;
@@ -488,6 +513,18 @@
break;
case 'y':
conf.height = atoi(optarg);
+ break;
+ case 'L':
+ conf.over_l = atoi(optarg);
+ break;
+ case 'R':
+ conf.over_r = atoi(optarg);
+ break;
+ case 'T':
+ conf.over_t = atoi(optarg);
+ break;
+ case 'B':
+ conf.over_b = atoi(optarg);
break;
}
}
diff -ur vanilla/capproc.cpp mod/capproc.cpp
--- vanilla/capproc.cpp Mon Jul 8 13:49:04 2002
+++ mod/capproc.cpp Wed Jul 24 18:43:13 2002
@@ -67,6 +67,10 @@
i++;
if (restable[i].res == res)
{
+ over_l = 0;
+ over_r = 0;
+ over_t = 0;
+ over_b = 0;
res_w = restable[i].width;
res_h = restable[i].height;
cout<<"Resolution: "<<res_w<<" x "<<res_h<<endl;
@@ -263,24 +267,24 @@
{
case cspRGB24:
default:
- m_v4l->grabSetParams(m_conf.res_w, m_conf.res_h, VIDEO_PALETTE_RGB24);
+ m_v4l->grabSetParams(m_conf.res_w+m_conf.over_l+m_conf.over_r,
+m_conf.res_h+m_conf.over_t+m_conf.over_b, VIDEO_PALETTE_RGB24);
bpp=24;
break;
case cspRGB15:
- m_v4l->grabSetParams(m_conf.res_w, m_conf.res_h, VIDEO_PALETTE_RGB555);
+ m_v4l->grabSetParams(m_conf.res_w+m_conf.over_l+m_conf.over_r,
+m_conf.res_h+m_conf.over_t+m_conf.over_b, VIDEO_PALETTE_RGB555);
bpp=16;
break;
case cspRGB32:
- m_v4l->grabSetParams(m_conf.res_w, m_conf.res_h, VIDEO_PALETTE_RGB32);
+ m_v4l->grabSetParams(m_conf.res_w+m_conf.over_l+m_conf.over_r,
+m_conf.res_h+m_conf.over_t+m_conf.over_b, VIDEO_PALETTE_RGB32);
bpp=32;
break;
case cspYUY2:
- m_v4l->grabSetParams(m_conf.res_w, m_conf.res_h, VIDEO_PALETTE_YUV422);
+ m_v4l->grabSetParams(m_conf.res_w+m_conf.over_l+m_conf.over_r,
+m_conf.res_h+m_conf.over_t+m_conf.over_b, VIDEO_PALETTE_YUV422);
bpp=16;
break;
case cspYV12:
case cspI420:
- m_v4l->grabSetParams(m_conf.res_w, m_conf.res_h, VIDEO_PALETTE_YUV420P);
+ m_v4l->grabSetParams(m_conf.res_w+m_conf.over_l+m_conf.over_r,
+m_conf.res_h+m_conf.over_t+m_conf.over_b, VIDEO_PALETTE_YUV420P);
bpp=12;
break;
}
@@ -381,6 +385,11 @@
int w=m_conf.res_w;
int h=m_conf.res_h;
+
+ int start_pad = (w+m_conf.over_l+m_conf.over_r)*m_conf.over_t+m_conf.over_l;
+ int line_stride = m_conf.over_l+m_conf.over_r+w;
+ int end_pad = (w+m_conf.over_l+m_conf.over_r)*m_conf.over_b+m_conf.over_r;
+
//printf("FPS %f\n", fps);
while (!m_quit)
{
@@ -405,6 +414,7 @@
char* z = m_v4l->grabCapture(false);
// char* tmpframe=new char[w*h*3];
char* tmpframe=m_pAllocator->alloc();
+ char *zptr, *fptr;
// printf("%f %x %x\n", dist, z, tmpframe);
if (tmpframe)
{
@@ -413,23 +423,74 @@
{
case cspRGB24:
default:
+ zptr = z + start_pad*3+(h-1)*line_stride*3;
+ fptr = tmpframe;
+ for(i=0; i<h; i++) {
+ memcpy(fptr, zptr, w*3);
+ fptr += w*3;
+ zptr -= line_stride*3;
+ }
+/*
bpl=3*w;
for(i=0; i<h; i++)
memcpy(tmpframe+i*bpl, z+(h-i-1)*bpl, bpl);
+*/
break;
case cspYUY2:
- memcpy(tmpframe, z, 2*w*h);
+ zptr = z + start_pad*2;
+ fptr = tmpframe;
+ for(i=0; i<h; i++) {
+ memcpy(fptr, zptr, w*2);
+ fptr += w*2;
+ zptr += line_stride*2;
+ }
+// memcpy(tmpframe, z, 2*w*h);
break;
case cspI420:
- memcpy(tmpframe, z, 3*w*h/2);
+ zptr = z + start_pad*3/2;
+ fptr = tmpframe;
+ for(i=0; i<h; i++) {
+ memcpy(fptr, zptr, w*3/2);
+ fptr += w*3/2;
+ zptr += line_stride*3/2;
+ }
+// memcpy(tmpframe, z, 3*w*h/2);
break;
case cspYV12:
// LINUX v4l knows only I420 planar format
// so let's just swap two last planes
// and prepare YV12 planar surface
+ zptr = z + start_pad;
+ fptr = tmpframe;
+
+ for(i=0; i<h; i++) {
+ memcpy(fptr, zptr, w);
+ fptr += w;
+ zptr += line_stride;
+ }
+ zptr += end_pad;
+
+ zptr += start_pad/4;
+ fptr = tmpframe + (w * h) * 5 / 4;
+ for(i=0; i<h; i++) {
+ memcpy(fptr, zptr, w/4);
+ fptr += w/4;
+ zptr += line_stride/4;
+ }
+ zptr += end_pad / 4;
+
+ zptr += start_pad/4;
+ fptr = tmpframe + (w * h);
+ for(i=0; i<h; i++) {
+ memcpy(fptr, zptr, w/4);
+ fptr += w/4;
+ zptr += line_stride/4;
+ }
+/*
memcpy(tmpframe, z, w*h);
memcpy(tmpframe + (w * h) * 5 / 4, z + w * h, w * h / 4);
memcpy(tmpframe + (w * h), z + (w * h) * 5 / 4, w * h / 4);
+*/
break;
}
}
diff -ur vanilla/capproc.h mod/capproc.h
--- vanilla/capproc.h Mon Apr 29 00:26:56 2002
+++ mod/capproc.h Wed Jul 24 18:43:13 2002
@@ -191,6 +191,7 @@
int chan;
int res_w;
int res_h;
+ int over_t, over_b, over_l, over_r;
int timelimit; //in seconds. -1 if no limit
int sizelimit; //in Kbytes. -1 if no limit
float fps;