You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

383 lines
11 KiB

--- a/main.c
+++ b/main.c
@@ -121,6 +121,36 @@
return x->tv_sec < y->tv_sec;
}
#endif
+
+int proc_get(const char *path, char *value, const int len)
+{
+ int ret, ret2;
+ int pfd = open(path, O_RDONLY);
+ if (pfd < 0)
+ return pfd;
+ ret = read(pfd, value, len);
+ value[len-1] = '\0'; /* make sure string is terminated */
+ if (ret >= 0)
+ {
+ while (ret > 0 && isspace(value[ret-1]))
+ ret--; /* remove trailing whitespace */
+ value[ret] = '\0'; /* terminate, even if ret = 0 */
+ }
+ ret2 = close(pfd);
+ if (ret2 < 0)
+ return ret2;
+ return ret;
+}
+
+unsigned int proc_get_hex(const char *path)
+{
+ unsigned int n, ret = 0;
+ char buf[16];
+ n = proc_get(path, buf, 16);
+ if (n > 0)
+ sscanf(buf, "%x", &ret);
+ return ret;
+}
#define VIDEO_DEV "/dev/video"
@@ -146,11 +176,12 @@
};
void getvideo(unsigned char *video, int *xres, int *yres);
-void getvideo2(unsigned char *video, int *xres, int *yres);
+void getvideo2(unsigned char *video, int *xres, int *yres, int video_dev);
void getosd(unsigned char *osd, int *xres, int *yres);
void smooth_resize(const unsigned char *source, unsigned char *dest, int xsource, int ysource, int xdest, int ydest, int colors);
void fast_resize(const unsigned char *source, unsigned char *dest, int xsource, int ysource, int xdest, int ydest, int colors);
void (*resize)(const unsigned char *source, unsigned char *dest, int xsource, int ysource, int xdest, int ydest, int colors);
+void combine_video(unsigned char *output, const unsigned char *input, int xres, int yres, int pip);
void combine(unsigned char *output, const unsigned char *video, const unsigned char *osd, int vleft, int vtop, int vwidth, int vheight, int xres, int yres);
#if !defined(__sh__)
@@ -171,18 +202,18 @@
int main(int argc, char **argv)
{
int xres_v,yres_v,xres_o,yres_o,xres,yres,aspect;
- int c,osd_only,video_only,use_osd_res,width,use_png,use_jpg,jpg_quality,no_aspect,use_letterbox;
+ int c,osd_only,video_only,use_osd_res,width,use_png,use_jpg,jpg_quality,no_aspect,use_letterbox,pips;
// we use fast resize as standard now
resize = &fast_resize;
- osd_only=video_only=use_osd_res=width=use_png=use_jpg=no_aspect=use_letterbox=0;
+ osd_only=video_only=use_osd_res=width=use_png=use_jpg=no_aspect=use_letterbox=pips=0;
jpg_quality=50;
aspect=1;
int dst_left = 0, dst_top = 0, dst_width = 0, dst_height = 0;
- unsigned char *video, *osd, *output;
+ unsigned char *video, *video1, *video2, *video3, *osd, *output;
int output_bytes=3;
const char* filename = "/tmp/screenshot.bmp";
@@ -612,7 +643,7 @@
}
// process command line
- while ((c = getopt (argc, argv, "dhj:lbnopqr:svi:")) != -1)
+ while ((c = getopt (argc, argv, "dhj:lbnopqr:svix:")) != -1)
{
switch (c)
{
@@ -634,6 +665,7 @@
"-p produce png files instead of bmp\n"
"-q Quiet mode, don't output debug messages\n"
"-s write to stdout instead of a file\n"
+ "-x (count) additional PIP count (count 1-3)\n"
"-h this help screen\n\n"
"If no command is given the complete picture will be grabbed.\n"
"If no filename is given /tmp/screenshot.[bmp/jpg/png] will be used.\n");
@@ -689,6 +721,14 @@
case 'n':
no_aspect=1;
break;
+ case 'x':
+ pips=atoi(optarg);
+ if (pips > 3)
+ {
+ fprintf(stderr, "Error: -x (additional PIP count) is limited to 3 !\n");
+ return 1;
+ }
+ break;
}
}
if (optind < argc) // filename
@@ -699,7 +739,26 @@
if (stb_type == VULCAN || stb_type == PALLAS)
mallocsize=720*576;
+ /*
+ if (pips == 0)
+ {
+ for (int p=1; p < 4; p++)
+ {
+ char pipbuf[25];
+ sprintf(pipbuf,"/proc/stb/vmpeg/%d/xres", p);
+ if ((int)proc_get_hex(pipbuf) > 0)
+ pips = p;
+ }
+ }
+ */
+
video = (unsigned char *)malloc(mallocsize*3);
+ if (pips > 0)
+ video1 = (unsigned char *)malloc(mallocsize*3);
+ if (pips > 1)
+ video2 = (unsigned char *)malloc(mallocsize*3);
+ if (pips > 2)
+ video3 = (unsigned char *)malloc(mallocsize*3);
osd = (unsigned char *)malloc(mallocsize*4);
if ((stb_type == VULCAN || stb_type == PALLAS) && width > 720)
@@ -718,7 +775,26 @@
fprintf(stderr, "Grabbing Video ...\n");
if (stb_type == BRCM7366 || stb_type == BRCM7251 || stb_type == BRCM7252 || stb_type == BRCM7252S || stb_type == BRCM7444 || stb_type == BRCM72604VU || stb_type == BRCM7278 || stb_type == HISIL_ARM)
{
- getvideo2(video, &xres_v,&yres_v);
+ getvideo2(video, &xres_v,&yres_v, 0);
+ if (pips > 0)
+ {
+ memset(video, 0, xres_v * yres_v * 3);
+ getvideo2(video1, &xres_v,&yres_v, 0);
+ combine_video(video, video1, xres_v, yres_v, 0);
+ memset(video1, 0, xres_v * yres_v * 3);
+ getvideo2(video1, &xres_v,&yres_v, 1);
+ combine_video(video, video1, xres_v, yres_v, 1);
+ }
+ if (pips > 1)
+ {
+ getvideo2(video2, &xres_v,&yres_v, 2);
+ combine_video(video, video2, xres_v, yres_v, 2);
+ }
+ if (pips > 2)
+ {
+ getvideo2(video3, &xres_v,&yres_v, 3);
+ combine_video(video, video3, xres_v, yres_v, 3);
+ }
}
else
{
@@ -739,41 +815,11 @@
}
else
{
- fp = fopen("/proc/stb/vmpeg/0/aspect", "r");
- if (fp)
- {
- while (fgets(buf,sizeof(buf), fp))
- sscanf(buf,"%x",&aspect);
- fclose(fp);
- }
- fp = fopen("/proc/stb/vmpeg/0/dst_width", "r");
- if (fp)
- {
- while (fgets(buf,sizeof(buf), fp))
- sscanf(buf,"%x",&dst_width);
- fclose(fp);
- }
- fp = fopen("/proc/stb/vmpeg/0/dst_height", "r");
- if (fp)
- {
- while (fgets(buf,sizeof(buf), fp))
- sscanf(buf,"%x",&dst_height);
- fclose(fp);
- }
- fp = fopen("/proc/stb/vmpeg/0/dst_top", "r");
- if (fp)
- {
- while (fgets(buf,sizeof(buf), fp))
- sscanf(buf,"%x",&dst_top);
- fclose(fp);
- }
- fp = fopen("/proc/stb/vmpeg/0/dst_left", "r");
- if (fp)
- {
- while (fgets(buf,sizeof(buf), fp))
- sscanf(buf,"%x",&dst_left);
- fclose(fp);
- }
+ aspect = proc_get_hex("/proc/stb/vmpeg/0/aspect");
+ dst_width = proc_get_hex("/proc/stb/vmpeg/0/dst_width");
+ dst_height = proc_get_hex("/proc/stb/vmpeg/0/dst_height");
+ dst_top = proc_get_hex("/proc/stb/vmpeg/0/dst_top");
+ dst_left = proc_get_hex("/proc/stb/vmpeg/0/dst_left");
if (dst_width == 720) dst_width = 0;
if (dst_height == 576) dst_height = 0;
}
@@ -833,7 +879,7 @@
resize(osd, output, xres_o, yres_o, xres, yres, 4);
memcpy(osd, output, xres * yres * 4);
}
- if (xres_v != dst_width || yres_v != dst_height)
+ if ((xres_v != dst_width || yres_v != dst_height) && (pips == 0))
{
if (!quiet)
fprintf(stderr, "Resizing Video to %d x %d ...\n", dst_width, dst_height);
@@ -857,7 +903,10 @@
{
if (!quiet)
fprintf(stderr, "Merge Video with Framebuffer ...\n");
- combine(output, video, osd, dst_left, dst_top, dst_width ? dst_width : xres, dst_height ? dst_height : yres, xres, yres);
+ if (pips == 0)
+ combine(output, video, osd, dst_left, dst_top, dst_width ? dst_width : xres, dst_height ? dst_height : yres, xres, yres);
+ else
+ combine(output, video, osd, 0, 0, xres, yres, xres, yres);
}
// resize to specific width ?
@@ -1045,7 +1094,7 @@
// grabing the video picture
-void getvideo2(unsigned char *video, int *xres, int *yres)
+void getvideo2(unsigned char *video, int *xres, int *yres, int video_dev)
{
char buf[256];
sprintf(buf, "/dev/dvb/adapter0/video%d", video_dev);
@@ -1116,10 +1165,7 @@
munmap((void*)data, 100);
- fp=fopen("/proc/stb/vmpeg/0/yres","r");
- while (fgets(buf,sizeof(buf),fp))
- sscanf(buf,"%x",&res);
- fclose(fp);
+ res = proc_get_hex("/proc/stb/vmpeg/0/yres");
if (!adr || !adr2)
{
@@ -1514,25 +1560,8 @@
*xres=0;
*yres=0;
- fp = fopen("/proc/stb/vmpeg/0/xres","r");
- if (fp)
- {
- while (fgets(buf,sizeof(buf),fp))
- {
- sscanf(buf,"%x",&stride);
- }
- fclose(fp);
- }
-
- fp = fopen("/proc/stb/vmpeg/0/yres","r");
- if (fp)
- {
- while (fgets(buf,sizeof(buf),fp))
- {
- sscanf(buf,"%x",&res);
- }
- fclose(fp);
- }
+ stride = proc_get_hex("/proc/stb/vmpeg/0/xres");
+ res = proc_get_hex("/proc/stb/vmpeg/0/yres");
if((stride == 0) || (res == 0)) return;
@@ -1685,24 +1714,8 @@
*xres=0;
*yres=0;
- fp = fopen("/proc/stb/vmpeg/0/xres","r");
- if (fp)
- {
- while (fgets(buf,sizeof(buf),fp))
- {
- sscanf(buf,"%x",&stride);
- }
- fclose(fp);
- }
- fp = fopen("/proc/stb/vmpeg/0/yres","r");
- if (fp)
- {
- while (fgets(buf,sizeof(buf),fp))
- {
- sscanf(buf,"%x",&res);
- }
- fclose(fp);
- }
+ stride = proc_get_hex("/proc/stb/vmpeg/0/xres");
+ res = proc_get_hex("/proc/stb/vmpeg/0/yres");
//if stride and res are zero return (please note that stillpictures will not be captured)
if((stride == 0)&&(res == 0)) return;
@@ -1929,24 +1942,8 @@
else if (stb_type == XILLEON)
{
// grab xilleon pic from decoder memory
- fp = fopen("/proc/stb/vmpeg/0/xres","r");
- if (fp)
- {
- while (fgets(buf,sizeof(buf),fp))
- {
- sscanf(buf,"%x",&stride);
- }
- fclose(fp);
- }
- fp = fopen("/proc/stb/vmpeg/0/yres","r");
- if (fp)
- {
- while (fgets(buf,sizeof(buf),fp))
- {
- sscanf(buf,"%x",&res);
- }
- fclose(fp);
- }
+ stride = proc_get_hex("/proc/stb/vmpeg/0/xres");
+ res = proc_get_hex("/proc/stb/vmpeg/0/yres");
if(!(memory = (unsigned char*)mmap(0, 1920*1152*6, PROT_READ, MAP_SHARED, mem_fd, 0x6000000)))
{
@@ -2459,6 +2456,48 @@
}
}
}
+// combining 2 videos
+void combine_video(unsigned char *output, const unsigned char *input, int xres, int yres, int pip)
+{
+ printf("combine video %d\n", pip);
+ int dst_width, dst_height;
+ int dst_x,dst_y;
+ char vmpeg[64];
+ unsigned char *r_input;
+
+ sprintf(vmpeg, "/proc/stb/vmpeg/%d/dst_width", pip);
+ dst_width = proc_get_hex(vmpeg);
+ dst_width = (int)(dst_width*xres/720);
+
+ sprintf(vmpeg, "/proc/stb/vmpeg/%d/dst_height", pip);
+ dst_height = proc_get_hex(vmpeg);
+ dst_height = (int)(dst_height*yres/576);
+
+ sprintf(vmpeg, "/proc/stb/vmpeg/%d/dst_left", pip);
+ dst_x = proc_get_hex(vmpeg);
+ dst_x = (int)(dst_x*xres/720);
+
+ sprintf(vmpeg, "/proc/stb/vmpeg/%d/dst_top", pip);
+ dst_y = proc_get_hex(vmpeg);
+ dst_y = (int)(dst_y*yres/576);
+
+ r_input = (unsigned char *)malloc(dst_width*dst_height*3);
+ fprintf(stderr, "Resizing Video to %d x %d ...\n", dst_width, dst_height);
+ resize(input, r_input, xres, yres, dst_width, dst_height, 3);
+
+ int ypos,xpos;
+ for (ypos = dst_y; ypos < dst_y+dst_height; ypos++)
+ {
+ int o_pos = ypos * xres * 3;
+ for (xpos = dst_x; xpos < dst_x+dst_width; xpos++)
+ {
+ int pixel = ((ypos - dst_y) * dst_width + (xpos - dst_x)) * 3;
+ output[dst_x*3+o_pos++] = r_input[pixel];
+ output[dst_x*3+o_pos++] = r_input[pixel + 1];
+ output[dst_x*3+o_pos++] = r_input[pixel + 2];
+ }
+ }
+}
// combining pixmaps by using an alphamap
void combine(unsigned char *output, const unsigned char *video, const unsigned char *osd, int vleft, int vtop, int vwidth, int vheight, int xres, int yres)