void vf_split(struct video_frame *out, struct video_frame *src, unsigned int x_count, unsigned int y_count, int preallocate) { unsigned int tile_idx, line_idx; struct tile *cur_tiles; unsigned int tile_line = 0; out->color_spec = src->color_spec; out->fps = src->fps; //out->aux = src->aux | AUX_TILED; assert(vf_get_tile(src, 0)->width % x_count == 0u && vf_get_tile(src, 0)->height % y_count == 0u); for(tile_idx = 0u; tile_idx < x_count * y_count; ++tile_idx) { out->tiles[tile_idx].width = vf_get_tile(src, 0)->width / x_count; out->tiles[tile_idx].height = vf_get_tile(src, 0)->height / y_count; out->tiles[tile_idx].linesize = vc_get_linesize(out->tiles[tile_idx].width, src->color_spec); out->tiles[tile_idx].data_len = out->tiles[tile_idx].linesize * out->tiles[tile_idx].height; } cur_tiles = &out->tiles[0]; for(line_idx = 0u; line_idx < vf_get_tile(src, 0)->height; ++line_idx, ++tile_line) { unsigned int cur_tile_idx; unsigned int byte = 0u; if (line_idx % (vf_get_tile(src, 0)->height / y_count) == 0u) /* next tiles*/ { tile_line = 0u; if (line_idx != 0u) cur_tiles += x_count; if (preallocate) { for (cur_tile_idx = 0u; cur_tile_idx < x_count; ++cur_tile_idx) { cur_tiles[cur_tile_idx].data = malloc(cur_tiles[cur_tile_idx]. data_len); } } } for(cur_tile_idx = 0u; cur_tile_idx < x_count; ++cur_tile_idx) { memcpy((void *) &cur_tiles[cur_tile_idx].data[ tile_line * cur_tiles[cur_tile_idx].linesize], (void *) &src->tiles[0].data[line_idx * src->tiles[0].linesize + byte], cur_tiles[cur_tile_idx].width * get_bpp(src->color_spec)); byte += cur_tiles[cur_tile_idx].width * get_bpp(src->color_spec); } } }
void rgb_to_565(GF_VideoSurface *vs, unsigned char *src, u32 src_stride, u32 src_w, u32 src_h, u32 src_pf, const GF_Window *src_wnd) { u32 i, j, r, g, b; u32 BPP = get_bpp(src_pf); unsigned char *dst, *cur; if (!BPP) return; /*go to start of src*/ src += src_stride*src_wnd->y + BPP * src_wnd->x; if (src_pf==vs->pixel_format) { for (i=0; i<src_wnd->h; i++) { memcpy(vs->video_buffer + i*vs->pitch_y, src, sizeof(unsigned char) * BPP * src_wnd->w); } return; } /*nope get all pixels*/ switch (src_pf) { case GF_PIXEL_RGB_24: case GF_PIXEL_RGBS: for (i=0; i<src_wnd->h; i++) { dst = vs->video_buffer + i*vs->pitch_y; cur = src + i*src_stride; for (j=0; j<src_wnd->w; j++) { r = *cur++; g = *cur++; b = *cur++; * ((unsigned short *)dst) = GF_COL_565(r, g, b); dst += 2; } } break; } }
void rgb_to_24(GF_VideoSurface *vs, unsigned char *src, u32 src_stride, u32 src_w, u32 src_h, u32 src_pf, const GF_Window *src_wnd) { u32 i; u32 BPP = get_bpp(src_pf); if (!BPP) return; /*go to start of src*/ src += src_stride*src_wnd->y + BPP * src_wnd->x; if (src_pf==vs->pixel_format) { for (i=0; i<src_wnd->h; i++) { memcpy(vs->video_buffer + i*vs->pitch_y, src, sizeof(unsigned char) * BPP * src_wnd->w); src += src_stride; } return; } }
static int vidcap_testcard_init(const struct vidcap_params *params, void **state) { struct testcard_state *s; char *filename; const char *strip_fmt = NULL; FILE *in = NULL; unsigned int i, j; unsigned int rect_size = COL_NUM; codec_t codec = RGBA; int aligned_x; char *save_ptr = NULL; if (vidcap_params_get_fmt(params) == NULL || strcmp(vidcap_params_get_fmt(params), "help") == 0) { printf("testcard options:\n"); printf("\t-t testcard:<width>:<height>:<fps>:<codec>[:filename=<filename>][:p][:s=<X>x<Y>][:i|:sf][:still][:pattern=bars|blank|noise]\n"); printf("\t<filename> - use file named filename instead of default bars\n"); printf("\tp - pan with frame\n"); printf("\ts - split the frames into XxY separate tiles\n"); printf("\ti|sf - send as interlaced or segmented frame (if none of those is set, progressive is assumed)\n"); printf("\tstill - send still image\n"); printf("\tpattern - pattern to use\n"); show_codec_help("testcard", codecs_8b, codecs_10b); return VIDCAP_INIT_NOERR; } s = new testcard_state(); if (!s) return VIDCAP_INIT_FAIL; s->frame = vf_alloc(1); char *fmt = strdup(vidcap_params_get_fmt(params)); char *tmp; int h_align = 0; double bpp = 0; if (strlen(fmt) == 0) { free(fmt); fmt = strdup(DEFAULT_FORMAT); } tmp = strtok_r(fmt, ":", &save_ptr); if (!tmp) { fprintf(stderr, "Wrong format for testcard '%s'\n", fmt); goto error; } vf_get_tile(s->frame, 0)->width = atoi(tmp); tmp = strtok_r(NULL, ":", &save_ptr); if (!tmp) { fprintf(stderr, "Wrong format for testcard '%s'\n", fmt); goto error; } vf_get_tile(s->frame, 0)->height = atoi(tmp); tmp = strtok_r(NULL, ":", &save_ptr); if (!tmp) { fprintf(stderr, "Wrong format for testcard '%s'\n", fmt); goto error; } s->frame->fps = atof(tmp); tmp = strtok_r(NULL, ":", &save_ptr); if (!tmp) { fprintf(stderr, "Wrong format for testcard '%s'\n", fmt); goto error; } codec = get_codec_from_name(tmp); if (codec == VIDEO_CODEC_NONE) { fprintf(stderr, "Unknown codec '%s'\n", tmp); goto error; } { const codec_t *sets[] = {codecs_8b, codecs_10b}; bool supported = false; for (int i = 0; i < 2; ++i) { const codec_t *it = sets[i]; while (*it != VIDEO_CODEC_NONE) { if (codec == *it++) { supported = true; } } } if (!supported) { log_msg(LOG_LEVEL_ERROR, "Unsupported codec '%s'\n", tmp); goto error; } } h_align = get_halign(codec); bpp = get_bpp(codec); s->frame->color_spec = codec; s->still_image = FALSE; if(bpp == 0) { fprintf(stderr, "Unsupported codec '%s'\n", tmp); goto error; } aligned_x = vf_get_tile(s->frame, 0)->width; if (h_align) { aligned_x = (aligned_x + h_align - 1) / h_align * h_align; } rect_size = (vf_get_tile(s->frame, 0)->width + rect_size - 1) / rect_size; s->frame_linesize = aligned_x * bpp; s->frame->interlacing = PROGRESSIVE; s->size = aligned_x * vf_get_tile(s->frame, 0)->height * bpp; filename = NULL; tmp = strtok_r(NULL, ":", &save_ptr); while (tmp) { if (strcmp(tmp, "p") == 0) { s->pan = 48; } else if (strncmp(tmp, "filename=", strlen("filename=")) == 0) { filename = tmp + strlen("filename="); in = fopen(filename, "r"); if (!in) { perror("fopen"); goto error; } fseek(in, 0L, SEEK_END); long filesize = ftell(in); assert(filesize >= 0); fseek(in, 0L, SEEK_SET); s->data = (char *) malloc(s->size * bpp * 2); if (s->size != filesize) { fprintf(stderr, "Error wrong file size for selected " "resolution and codec. File size %ld, " "computed size %d\n", filesize, s->size); goto error; } if (!in || fread(s->data, filesize, 1, in) == 0) { fprintf(stderr, "Cannot read file %s\n", filename); goto error; } fclose(in); in = NULL; memcpy(s->data + s->size, s->data, s->size); vf_get_tile(s->frame, 0)->data = s->data; } else if (strncmp(tmp, "s=", 2) == 0) { strip_fmt = tmp; } else if (strcmp(tmp, "i") == 0) { s->frame->interlacing = INTERLACED_MERGED; } else if (strcmp(tmp, "sf") == 0) { s->frame->interlacing = SEGMENTED_FRAME; } else if (strcmp(tmp, "still") == 0) { s->still_image = TRUE; } else if (strncmp(tmp, "pattern=", strlen("pattern=")) == 0) { const char *pattern = tmp + strlen("pattern="); if (strcmp(pattern, "bars") == 0) { s->pattern = image_pattern::BARS; } else if (strcmp(pattern, "blank") == 0) { s->pattern = image_pattern::BLANK; } else if (strcmp(pattern, "noise") == 0) { s->pattern = image_pattern::NOISE; } else { fprintf(stderr, "[testcard] Unknown pattern!\n");; goto error; } } else { fprintf(stderr, "[testcard] Unknown option: %s\n", tmp); goto error; } tmp = strtok_r(NULL, ":", &save_ptr); } if (!filename) { struct testcard_rect r; int col_num = 0; s->pixmap.w = aligned_x; s->pixmap.h = vf_get_tile(s->frame, 0)->height * 2; int pixmap_len = s->pixmap.w * s->pixmap.h * 4; // maximal size (RGBA/r10k - has 4 bpp) s->pixmap.data = malloc(pixmap_len); if (s->pattern == image_pattern::BLANK) { memset(s->pixmap.data, 0, pixmap_len); } else if (s->pattern == image_pattern::NOISE) { uint8_t *sample = (uint8_t *) s->pixmap.data; for (int i = 0; i < pixmap_len; ++i) { *sample++ = rand() % 0xff; } } else { assert (s->pattern == image_pattern::BARS); for (j = 0; j < vf_get_tile(s->frame, 0)->height; j += rect_size) { int grey = 0xff010101; if (j == rect_size * 2) { r.w = vf_get_tile(s->frame, 0)->width; r.h = rect_size / 4; r.x = 0; r.y = j; testcard_fillRect(&s->pixmap, &r, 0xffffffff); r.h = rect_size - (rect_size * 3 / 4); r.y = j + rect_size * 3 / 4; testcard_fillRect(&s->pixmap, &r, 0xff000000); } for (i = 0; i < vf_get_tile(s->frame, 0)->width; i += rect_size) { r.w = rect_size; r.h = rect_size; r.x = i; r.y = j; printf("Fill rect at %d,%d\n", r.x, r.y); if (j != rect_size * 2) { testcard_fillRect(&s->pixmap, &r, rect_colors[col_num]); col_num = (col_num + 1) % COL_NUM; } else { r.h = rect_size / 2; r.y += rect_size / 4; testcard_fillRect(&s->pixmap, &r, grey); grey += 0x00010101 * (255 / COL_NUM); } } } } s->data = (char *) s->pixmap.data; if (codec == UYVY || codec == v210) { rgb2yuv422((unsigned char *) s->data, aligned_x, vf_get_tile(s->frame, 0)->height); } if (codec == v210) { s->data = (char *)tov210((unsigned char *) s->data, aligned_x, aligned_x, vf_get_tile(s->frame, 0)->height, bpp); free(s->pixmap.data); } if (codec == R10k) { toR10k((unsigned char *) s->data, vf_get_tile(s->frame, 0)->width, vf_get_tile(s->frame, 0)->height); } if(codec == RGB) { s->data = (char *)toRGB((unsigned char *) s->data, vf_get_tile(s->frame, 0)->width, vf_get_tile(s->frame, 0)->height); free(s->pixmap.data); } tmp = filename; vf_get_tile(s->frame, 0)->data = (char *) malloc(2 * s->size); memcpy(vf_get_tile(s->frame, 0)->data, s->data, s->size); memcpy(vf_get_tile(s->frame, 0)->data + s->size, vf_get_tile(s->frame, 0)->data, s->size); free(s->data); s->data = vf_get_tile(s->frame, 0)->data; } s->count = 0; s->last_frame_time = std::chrono::steady_clock::now(); printf("Testcard capture set to %dx%d, bpp %f\n", vf_get_tile(s->frame, 0)->width, vf_get_tile(s->frame, 0)->height, bpp); vf_get_tile(s->frame, 0)->data_len = s->size; if(strip_fmt != NULL) { if(configure_tiling(s, strip_fmt) != 0) { goto error; } } if(vidcap_params_get_flags(params) & VIDCAP_FLAG_AUDIO_EMBEDDED) { s->grab_audio = TRUE; if(configure_audio(s) != 0) { s->grab_audio = FALSE; fprintf(stderr, "[testcard] Disabling audio output. " "SDL-mixer missing, running on Mac or other problem.\n"); } } else { s->grab_audio = FALSE; } free(fmt); *state = s; return VIDCAP_INIT_OK; error: free(fmt); free(s->data); vf_free(s->frame); if (in) fclose(in); delete s; return VIDCAP_INIT_FAIL; }
void rgb_to_32(GF_VideoSurface *vs, unsigned char *src, u32 src_stride, u32 src_w, u32 src_h, u32 src_pf, const GF_Window *src_wnd) { u32 i, j; Bool isBGR; u32 BPP = get_bpp(src_pf); unsigned char *dst, *cur; if (!BPP) return; /*go to start of src*/ src += src_stride*src_wnd->y + BPP * src_wnd->x; if (src_pf==vs->pixel_format) { for (i=0; i<src_wnd->h; i++) { memcpy(vs->video_buffer + i*vs->pitch_y, src, sizeof(unsigned char) * BPP * src_wnd->w); } return; } /*get all pixels*/ isBGR = vs->pixel_format==GF_PIXEL_BGR_32; if (isBGR) { switch (src_pf) { case GF_PIXEL_RGB_24: case GF_PIXEL_RGBS: for (i=0; i<src_wnd->h; i++) { dst = vs->video_buffer + i*vs->pitch_y; cur = src + i*src_stride; for (j=0; j<src_wnd->w; j++) { dst[0] = *cur++; dst[1] = *cur++; dst[2] = *cur++; dst += 4; } } break; case GF_PIXEL_RGBDS: case GF_PIXEL_RGBD: for (i=0; i<src_wnd->h; i++) { dst = vs->video_buffer + i*vs->pitch_y; cur = src + i*src_stride; for (j=0; j<src_wnd->w; j++) { dst[0] = *cur++; dst[1] = *cur++; dst[2] = *cur++; cur++; dst += 4; } } break; case GF_PIXEL_BGR_24: for (i=0; i<src_wnd->h; i++) { dst = vs->video_buffer + i*vs->pitch_y; cur = src + i*src_stride; for (j=0; j<src_wnd->w; j++) { dst[2] = *cur++; dst[1] = *cur++; dst[0] = *cur++; dst += 4; } } break; } } else { switch (src_pf) { case GF_PIXEL_RGB_24: case GF_PIXEL_RGBS: for (i=0; i<src_wnd->h; i++) { dst = vs->video_buffer + i*vs->pitch_y; cur = src + i*src_stride; for (j=0; j<src_wnd->w; j++) { dst[2] = *cur++; dst[1] = *cur++; dst[0] = *cur++; dst += 4; } } break; case GF_PIXEL_RGBD: case GF_PIXEL_RGBDS: for (i=0; i<src_wnd->h; i++) { dst = vs->video_buffer + i*vs->pitch_y; cur = src + i*src_stride; for (j=0; j<src_wnd->w; j++) { dst[2] = *cur++; dst[1] = *cur++; dst[0] = *cur++; cur++; dst += 4; } } break; case GF_PIXEL_BGR_24: for (i=0; i<src_wnd->h; i++) { dst = vs->video_buffer + i*vs->pitch_y; cur = src + i*src_stride; for (j=0; j<src_wnd->w; j++) { dst[0] = *cur++; dst[1] = *cur++; dst[2] = *cur++; dst += 4; } } break; } } }
static int write_gif_info(const psx_image* image, image_writer_fn func, void* param, float quality, psx_image_header* header) { size_t buf_size; #if GIFLIB_MAJOR >= 5 int errorcode = 0; #endif struct gif_image_ctx* ctx = (struct gif_image_ctx*)calloc(1, sizeof(struct gif_image_ctx)); if (!ctx) { return -1; // out of memory. } ctx->writer = func; ctx->writer_param = param; #if GIFLIB_MAJOR >= 5 if ((ctx->gif = EGifOpen((void*)ctx, write_gif_from_memory, &errorcode)) == NULL) { free(ctx); return -1; } if (image->num_frames > 1) { EGifSetGifVersion(ctx->gif, true); } #else if ((ctx->gif = EGifOpen((void*)ctx, write_gif_from_memory)) == NULL) { free(ctx); return -1; } if (image->num_frames > 1) { EGifSetGifVersion("89a"); } else { EGifSetGifVersion("87a"); } #endif if (EGifPutScreenDesc(ctx->gif, image->width, image->height, 8, 0, NULL) == GIF_ERROR) { GIF_CLOSE_EFILE(ctx->gif); free(ctx); return -1; } if (image->num_frames > 1) { // add netscape2.0 application extension to an animation gif. #if GIFLIB_MAJOR >= 5 EGifPutExtensionLeader(ctx->gif, APPLICATION_EXT_FUNC_CODE); EGifPutExtensionBlock(ctx->gif, 11, "NETSCAPE2.0"); EGifPutExtensionBlock(ctx->gif, 3, "\x01\x00\x00"); EGifPutExtensionTrailer(ctx->gif); #else EGifPutExtensionFirst(ctx->gif, APPLICATION_EXT_FUNC_CODE, 11, "NETSCAPE2.0"); EGifPutExtensionLast(ctx->gif, APPLICATION_EXT_FUNC_CODE, 3, "\x01\x00\x00"); #endif } buf_size = image->width * image->height * sizeof(GifByteType); ctx->red_buf = (GifByteType*)malloc(buf_size); ctx->green_buf = (GifByteType*)malloc(buf_size); ctx->blue_buf = (GifByteType*)malloc(buf_size); ctx->output_buffer = (GifByteType*)malloc(buf_size); if (!ctx->red_buf || !ctx->green_buf || !ctx->blue_buf || !ctx->output_buffer) { GIF_CLOSE_EFILE(ctx->gif); if (ctx->red_buf) free(ctx->red_buf); if (ctx->green_buf) free(ctx->green_buf); if (ctx->blue_buf) free(ctx->blue_buf); if (ctx->output_buffer) free(ctx->output_buffer); free(ctx); return -1; } header->priv = ctx; header->width = image->width; header->height = image->height; header->pitch = image->pitch; header->depth = get_depth(image->format); header->bpp = get_bpp(image->format); header->format = (int)image->format; header->alpha = 1; header->frames = (int)image->num_frames; return 0; }
int omap_setup_vrfb_buffer(struct dss2_ovl_info *ovl_info) { int i = 0; int mode = ovl_info->cfg.color_mode; int got_vrfb_mapped_buf = 0; if (!have_vrfb_ctx) { pr_err("%s: No VRFB context available for setup\n", __func__); return 1; } for (i = 0; i < VRFB_NUM_SLOTS; i++) { if (ion_vrfb_t[i].ba == ovl_info->ba) { if (ion_vrfb_t[i].ismapped) { if (check_vrfb_params( &ion_vrfb_t[i].vrfb_context, ovl_info)) { got_vrfb_mapped_buf = 0; ion_vrfb_t[i].ismapped = 0; } else { ovl_info->ba = ion_vrfb_t[i]. vrfb_context. paddr[ovl_info->cfg.rotation] + omap_get_vrfb_offset( &ion_vrfb_t[i].vrfb_context, ovl_info->cfg.rotation); got_vrfb_mapped_buf = 1; } } break; } } if (!got_vrfb_mapped_buf) { omap_vrfb_setup(&ion_vrfb_t[i].vrfb_context, ovl_info->ba, ovl_info->cfg.crop.w, ovl_info->cfg.crop.h, get_bpp(mode), is_yuv_mode(mode)); ovl_info->ba = ion_vrfb_t[i]. vrfb_context.paddr[ovl_info->cfg.rotation] + omap_get_vrfb_offset( &ion_vrfb_t[i].vrfb_context, ovl_info->cfg.rotation); ion_vrfb_t[i].ismapped = 1; } if (ovl_info->cfg.rotation & 1) { #if 0 //[email protected] ti patch for HDMI ovl_info->cfg.win.w = (ovl_info->cfg.win.h * ovl_info->cfg.win.h) / ovl_info->cfg.win.w; #else ovl_info->cfg.win.w = (ovl_info->cfg.win.w * ovl_info->cfg.win.h) / ovl_info->cfg.win.h; #endif } ovl_info->cfg.stride = VRFB_LINE_LENGTH * 2; return 0; }