From e18ced341115dbf9c25f14b2a39e164308197a7b Mon Sep 17 00:00:00 2001 From: TangoCash Date: Sun, 17 Oct 2021 15:23:05 +0200 Subject: [PATCH 1/2] add screenshots for pip devices, with new parameter x e.g. for main and pip1: grab -p -x1 /tmp/test.png --- main.c | 239 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 134 insertions(+), 105 deletions(-) diff --git a/main.c b/main.c index e05c78c..18c8c37 100644 --- a/main.c +++ b/main.c @@ -122,6 +122,36 @@ int timeval_subtract (struct timeval *result, struct timeval *x, struct timeval } #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" // dont change SPARE_RAM and DMA_BLOCKSIZE until you really know what you are doing !!! @@ -146,11 +176,12 @@ static const int yuv2rgbtable_bv[256] = { }; 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 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__) @@ -170,18 +201,18 @@ static int quiet = 0; 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"; @@ -611,7 +642,7 @@ int main(int argc, char **argv) } // process command line - while ((c = getopt (argc, argv, "dhj:lbnopqr:sv")) != -1) + while ((c = getopt (argc, argv, "dhj:lbnopqr:svx:")) != -1) { switch (c) { @@ -684,6 +715,14 @@ int main(int argc, char **argv) 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 @@ -695,6 +734,12 @@ int main(int argc, char **argv) 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) @@ -713,7 +758,26 @@ int main(int argc, char **argv) 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 { @@ -734,41 +798,11 @@ int main(int argc, char **argv) } 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; } @@ -828,7 +862,7 @@ int main(int argc, char **argv) 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); @@ -852,7 +886,10 @@ int main(int argc, char **argv) { 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 ? @@ -1040,11 +1077,13 @@ int main(int argc, char **argv) // grabing the video picture -void getvideo2(unsigned char *video, int *xres, int *yres) +void getvideo2(unsigned char *video, int *xres, int *yres, int dev) { - int fd_video = open("/dev/dvb/adapter0/video0", O_RDONLY); + char vdev[64]; + sprintf(vdev, "/dev/dvb/adapter0/video%d", dev); + int fd_video = open(vdev, O_RDONLY); if (fd_video < 0) { - perror("/dev/dvb/adapter0/video0"); + perror(vdev); return; } ssize_t r = read(fd_video, video, 1920 * 1080 * 3); @@ -1109,10 +1148,7 @@ void getvideo(unsigned char *video, int *xres, int *yres) 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) { @@ -1507,25 +1543,8 @@ void getvideo(unsigned char *video, int *xres, int *yres) *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; @@ -1678,24 +1697,8 @@ void getvideo(unsigned char *video, int *xres, int *yres) *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; @@ -1922,24 +1925,8 @@ void getvideo(unsigned char *video, int *xres, int *yres) 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))) { @@ -2452,6 +2439,48 @@ void fast_resize(const unsigned char *source, unsigned char *dest, int xsource, } } } +// 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) -- 2.20.1