static int decode_pip(struct vidfilt_dec_st *st, struct vidframe *frame) { struct selfview_dec *dec = (struct selfview_dec *)st; struct selfview *sv = dec->selfview; if (!frame) return 0; lock_read_get(sv->lock); if (sv->frame) { struct vidrect rect; rect.w = min(sv->frame->size.w, frame->size.w/2); rect.h = min(sv->frame->size.h, frame->size.h/2); if (rect.w <= (frame->size.w - 10)) rect.x = frame->size.w - rect.w - 10; else rect.x = frame->size.w/2; if (rect.h <= (frame->size.h - 10)) rect.y = frame->size.h - rect.h - 10; else rect.y = frame->size.h/2; vidconv(frame, sv->frame, &rect); vidframe_draw_rect(frame, rect.x, rect.y, rect.w, rect.h, 127, 127, 127); } lock_rel(sv->lock); return 0; }
static int encode_pip(struct vidfilt_enc_st *st, struct vidframe *frame) { struct selfview_enc *enc = (struct selfview_enc *)st; struct selfview *selfview = enc->selfview; int err = 0; if (!frame) return 0; lock_write_get(selfview->lock); if (!selfview->frame) { struct vidsz sz; /* Use size if configured, or else 20% of main window */ if (selfview_size.w && selfview_size.h) { sz = selfview_size; } else { sz.w = frame->size.w / 5; sz.h = frame->size.h / 5; } err = vidframe_alloc(&selfview->frame, VID_FMT_YUV420P, &sz); } if (!err) vidconv(selfview->frame, frame, NULL); lock_rel(selfview->lock); return err; }
static int display(struct vidisp_st *st, const char *title, const struct vidframe *frame) { struct vidframe frame_rgb; int err = 0; if (!vidsz_cmp(&st->size, &frame->size)) { char capt[256]; if (st->size.w && st->size.h) { info("x11: reset: %u x %u ---> %u x %u\n", st->size.w, st->size.h, frame->size.w, frame->size.h); } if (st->internal && !st->win) err = create_window(st, &frame->size); err |= x11_reset(st, &frame->size); if (err) return err; if (title) { re_snprintf(capt, sizeof(capt), "%s - %u x %u", title, frame->size.w, frame->size.h); } else { re_snprintf(capt, sizeof(capt), "%u x %u", frame->size.w, frame->size.h); } XStoreName(st->disp, st->win, capt); } /* Convert from YUV420P to RGB */ vidframe_init_buf(&frame_rgb, st->pixfmt, &frame->size, (uint8_t *)st->shm.shmaddr); vidconv(&frame_rgb, frame, 0); /* draw */ if (st->xshmat) XShmPutImage(st->disp, st->win, st->gc, st->image, 0, 0, 0, 0, st->size.w, st->size.h, false); else XPutImage(st->disp, st->win, st->gc, st->image, 0, 0, 0, 0, st->size.w, st->size.h); XSync(st->disp, false); return err; }
static int draw_text(struct panel *panel, struct vidframe *frame) { char buf[256]; int width = panel->size_text.w; int height = panel->size_text.h; struct vidframe f; struct vidframe *f2 = NULL; cairo_t *cr = panel->cr; double tx, ty; int err; tx = 1; ty = height - 3; /* draw background */ cairo_rectangle (cr, 0, 0, width, height); cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); cairo_fill (cr); /* Draw text */ if (re_snprintf(buf, sizeof(buf), "%s %2.2f fps", panel->label, panel->fps) < 0) return ENOMEM; cairo_move_to (cr, tx, ty); cairo_text_path (cr, buf); cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); cairo_fill_preserve (cr); cairo_set_line_width (cr, 0.6); cairo_stroke (cr); vidframe_init_buf(&f, VID_FMT_ARGB, &panel->size_text, cairo_image_surface_get_data(panel->surface)); err = vidframe_alloc(&f2, frame->fmt, &panel->size_text); if (err) goto out; vidconv(f2, &f, 0); overlay(frame, panel->yoffs, f2); out: mem_deref(f2); return err; }
static int decode_pip(struct vidfilt_st *st, struct vidframe *frame) { struct selfview *sv = (struct selfview *)st; if (!frame) return 0; lock_read_get(sv->lock); if (sv->frame) { struct vidrect rect; rect.w = sv->frame->size.w; rect.h = sv->frame->size.h; rect.x = frame->size.w - rect.w - 10; rect.y = frame->size.h - rect.h - 10; vidconv(frame, sv->frame, &rect); } lock_rel(sv->lock); return 0; }
static int encode_pip(struct vidfilt_st *st, struct vidframe *frame) { struct selfview *sv = (struct selfview *)st; int err = 0; if (!frame) return 0; lock_write_get(sv->lock); if (!sv->frame) { struct vidsz sz; sz.w = frame->size.w / 5; sz.h = frame->size.h / 5; err = vidframe_alloc(&sv->frame, VID_FMT_YUV420P, &sz); } if (!err) vidconv(sv->frame, frame, NULL); lock_rel(sv->lock); return err; }
int png_save_vidframe(const struct vidframe *vf, const char *filename) { png_byte **png_row_pointers = NULL; png_byte *row; const png_byte *p; png_byte red, green, blue; png_structp png_ptr = NULL; png_infop info_ptr = NULL; FILE *fp = NULL; size_t x, y; unsigned int width = vf->size.w & ~1; unsigned int height = vf->size.h & ~1; unsigned int bytes_per_pixel = 3; /* RGB format */ struct vidframe *f2 = NULL; int err = 0; if (vf->fmt != VID_FMT_RGB32) { err = vidframe_alloc(&f2, VID_FMT_RGB32, &vf->size); if (err) goto out; vidconv(f2, vf, NULL); vf = f2; } /* Initialize the write struct. */ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr == NULL) { err = ENOMEM; goto out; } /* Initialize the info struct. */ info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { err = ENOMEM; goto out; } /* Set up error handling. */ if (setjmp(png_jmpbuf(png_ptr))) { err = ENOMEM; goto out; } /* Set image attributes. */ png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); /* Initialize rows of PNG * bytes_per_row = width * bytes_per_pixel; */ png_row_pointers = png_malloc(png_ptr, height * sizeof(png_byte *)); for (y = 0; y < height; ++y) { png_row_pointers[y] = (png_byte *) png_malloc(png_ptr, width * sizeof(uint8_t) * bytes_per_pixel); } p = vf->data[0]; for (y = 0; y < height; ++y) { row = png_row_pointers[y]; for (x = 0; x < width; ++x) { red = *p++; green = *p++; blue = *p++; *row++ = blue; *row++ = green; *row++ = red; ++p; /* skip alpha */ } } /* Write the image data. */ fp = fopen(filename, "wb"); if (fp == NULL) { err = errno; goto out; } png_init_io(png_ptr, fp); png_set_rows(png_ptr, info_ptr, png_row_pointers); png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); re_printf("wrote %u x %u pixels to %s\n", vf->size.w, vf->size.h, filename); out: /* Finish writing. */ mem_deref(f2); png_save_free(png_ptr, png_row_pointers, height); png_destroy_write_struct(&png_ptr, &info_ptr); if (fp) fclose(fp); return 0; }
static int display(struct vidisp_st *st, const char *title, const struct vidframe *frame) { struct vidframe frame_rgb; int err = 0; if (!st->disp) return ENODEV; /* * check for window delete - without blocking * the switch handles both the override redirect window * and the "standard" window manager managed window. */ while (XPending(st->disp)) { XEvent e; XNextEvent(st->disp, &e); switch (e.type) { case ClientMessage: if ((Atom) e.xclient.data.l[0] == st->XwinDeleted) { info("x11: window deleted\n"); /* * we have to bail as all of the display * pointers are bad. */ close_window(st); return ENODEV; } break; case ButtonPress: st->button_is_down = 1; break; case ButtonRelease: st->button_is_down = 0; break; case MotionNotify: if (st->button_is_down == 0) break; if ((e.xmotion.time - st->last_time) < 32) break; XMoveWindow(st->disp, st->win, e.xmotion.x_root - 16, e.xmotion.y_root - 16); st->last_time = e.xmotion.time; break; default: break; } } if (!vidsz_cmp(&st->size, &frame->size)) { char capt[256]; if (st->size.w && st->size.h) { info("x11: reset: %u x %u ---> %u x %u\n", st->size.w, st->size.h, frame->size.w, frame->size.h); } if (st->internal && !st->win) err = create_window(st, &frame->size); err |= x11_reset(st, &frame->size); if (err) return err; if (title) { re_snprintf(capt, sizeof(capt), "%s - %u x %u", title, frame->size.w, frame->size.h); } else { re_snprintf(capt, sizeof(capt), "%u x %u", frame->size.w, frame->size.h); } XStoreName(st->disp, st->win, capt); } /* Convert from YUV420P to RGB */ vidframe_init_buf(&frame_rgb, st->pixfmt, &frame->size, (uint8_t *)st->shm.shmaddr); vidconv(&frame_rgb, frame, 0); /* draw */ if (st->xshmat) XShmPutImage(st->disp, st->win, st->gc, st->image, 0, 0, 0, 0, st->size.w, st->size.h, false); else XPutImage(st->disp, st->win, st->gc, st->image, 0, 0, 0, 0, st->size.w, st->size.h); XSync(st->disp, false); return err; }
int jpg_save_vidframe(const struct vidframe *vf, const char *path) { struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; JSAMPROW row_pointer[1]; unsigned char *imgdata,*src,*dst; int row_stride,pixs; FILE * fp; char filename_buf[64]; struct vidframe *f2 = NULL; int err = 0; unsigned int width = vf->size.w & ~1; unsigned int height = vf->size.h & ~1; time_t tnow; struct tm *tmx; // 0 tnow = time(NULL); tmx = localtime(&tnow); imgdata = vf->data[0]; if (vf->fmt != VID_FMT_RGB32) { err = vidframe_alloc(&f2, VID_FMT_RGB32, &vf->size); if (err) goto out; vidconv(f2, vf, NULL); imgdata = f2->data[0]; } fp = fopen(jpg_filename(tmx, path, filename_buf, sizeof(filename_buf)), "wb"); if (fp == NULL) { err = errno; goto out; } // 32bpp -> 24bpp pixs = width*height; src = imgdata; dst = imgdata; while (pixs--) { *dst++=*src++; //R *dst++=*src++; //G *dst++=*src++; //B src++; //A } // create jpg structures cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); jpeg_stdio_dest(&cinfo, fp); cinfo.image_width = width; cinfo.image_height = height; cinfo.input_components = 3; // 24 bpp // I wonder if this will make double conversion. cinfo.in_color_space = JCS_EXT_BGR; jpeg_set_defaults(&cinfo); jpeg_set_quality(&cinfo, 85 , TRUE); // quality 85% // compress jpeg_start_compress(&cinfo, TRUE); row_stride = width * cinfo.input_components; //buffer = (JSAMPARRAY) imgdata; while (cinfo.next_scanline < cinfo.image_height) { row_pointer[0] = & imgdata[cinfo.next_scanline * row_stride]; (void) jpeg_write_scanlines(&cinfo, row_pointer, 1); } jpeg_finish_compress(&cinfo); /* Finish writing. */ out: jpeg_destroy_compress(&cinfo); mem_deref(f2); if (fp) fclose(fp); return 0; }
static int display(struct vidisp_st *st, const char *title, const struct vidframe *frame) { struct vidframe frame_rgb; int err = 0; if (!st->disp) return ENODEV; /* * check for window delete - without blocking */ while (XPending(st->disp)) { XEvent e; XNextEvent(st->disp, &e); if (e.type == ClientMessage) { if ((Atom) e.xclient.data.l[0] == st->XwinDeleted) { info("x11: window deleted\n"); /* * we have to bail as all of the display * pointers are bad. */ close_window(st); return ENODEV; } } } if (!vidsz_cmp(&st->size, &frame->size)) { char capt[256]; if (st->size.w && st->size.h) { info("x11: reset: %u x %u ---> %u x %u\n", st->size.w, st->size.h, frame->size.w, frame->size.h); } if (st->internal && !st->win) err = create_window(st, &frame->size); err |= x11_reset(st, &frame->size); if (err) return err; if (title) { re_snprintf(capt, sizeof(capt), "%s - %u x %u", title, frame->size.w, frame->size.h); } else { re_snprintf(capt, sizeof(capt), "%u x %u", frame->size.w, frame->size.h); } XStoreName(st->disp, st->win, capt); } /* Convert from YUV420P to RGB */ vidframe_init_buf(&frame_rgb, st->pixfmt, &frame->size, (uint8_t *)st->shm.shmaddr); vidconv(&frame_rgb, frame, 0); /* draw */ if (st->xshmat) XShmPutImage(st->disp, st->win, st->gc, st->image, 0, 0, 0, 0, st->size.w, st->size.h, false); else XPutImage(st->disp, st->win, st->gc, st->image, 0, 0, 0, 0, st->size.w, st->size.h); XSync(st->disp, false); return err; }