diff --git a/package/aio-grab/patches/0001-automake_macros.patch b/package/aio-grab/patches/0001-automake_macros.patch new file mode 100644 index 00000000..e6715737 --- /dev/null +++ b/package/aio-grab/patches/0001-automake_macros.patch @@ -0,0 +1,11 @@ +--- a/configure.ac ++++ b/configure.ac +@@ -1,5 +1,6 @@ +-AC_INIT(main.c) +-AM_INIT_AUTOMAKE(grab,1.0) ++AC_INIT([grab], [1.0]) ++AC_CONFIG_SRCDIR([main.c]) ++AM_INIT_AUTOMAKE + + AC_PROG_CC + AC_OPENMP() diff --git a/package/aio-grab/patches/0002-screenshots-for-pip-devices.patch b/package/aio-grab/patches/0002-screenshots-for-pip-devices.patch new file mode 100644 index 00000000..4fde1256 --- /dev/null +++ b/package/aio-grab/patches/0002-screenshots-for-pip-devices.patch @@ -0,0 +1,368 @@ +--- 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 +@@ -700,6 +740,12 @@ + mallocsize=720*576; + + 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 +764,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 +804,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 +868,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 +892,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 +1083,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 +1154,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 +1549,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 +1703,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 +1931,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 +2445,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)