struct vpu_display * ipu_display_open(struct decode *dec, int nframes, struct rot rotation, Rect cropRect) { int width = dec->picwidth; int height = dec->picheight; int left = cropRect.left; int top = cropRect.top; int right = cropRect.right; int bottom = cropRect.bottom; int disp_width = dec->cmdl->width; int disp_height = dec->cmdl->height; int disp_left = dec->cmdl->loff; int disp_top = dec->cmdl->toff; char motion_mode = dec->cmdl->vdi_motion; int err = 0, i; struct vpu_display *disp; struct mxcfb_gbl_alpha alpha; struct fb_var_screeninfo fb_var; disp = (struct vpu_display *)calloc(1, sizeof(struct vpu_display)); if (disp == NULL) { err_msg("falied to allocate vpu_display\n"); return NULL; } /* set alpha */ #ifdef BUILD_FOR_ANDROID disp->fd = open("/dev/graphics/fb0", O_RDWR, 0); #else disp->fd = open("/dev/fb0", O_RDWR, 0); #endif if (disp->fd < 0) { err_msg("unable to open fb0\n"); free(disp); return NULL; } alpha.alpha = 0; alpha.enable = 1; if (ioctl(disp->fd, MXCFB_SET_GBL_ALPHA, &alpha) < 0) { err_msg("set alpha blending failed\n"); close(disp->fd); free(disp); return NULL; } if ( ioctl(disp->fd, FBIOGET_VSCREENINFO, &fb_var) < 0) { err_msg("Get FB var info failed!\n"); close(disp->fd); free(disp); return NULL; } if (!disp_width || !disp_height) { disp_width = fb_var.xres; disp_height = fb_var.yres; } if (rotation.rot_en) { if (rotation.rot_angle == 90 || rotation.rot_angle == 270) { i = width; width = height; height = i; } dprintf(3, "VPU rot: width = %d; height = %d\n", width, height); } /* allocate buffers, use an extra buf for init buf */ disp->nframes = nframes; disp->frame_size = width*height*3/2; for (i=0;i<nframes;i++) { err = ipu_memory_alloc(disp->frame_size, 1, &(disp->ipu_bufs[i].ipu_paddr), &(disp->ipu_bufs[i].ipu_vaddr), disp->fd); if ( err < 0) { err_msg("ipu_memory_alloc failed\n"); free(disp); return NULL; } } memset(&(disp->ipu_handle), 0, sizeof(ipu_lib_handle_t)); memset(&(disp->input), 0, sizeof(ipu_lib_input_param_t)); memset(&(disp->output), 0, sizeof(ipu_lib_output_param_t)); disp->input.width = width; disp->input.height = height; disp->input.input_crop_win.pos.x = left; disp->input.input_crop_win.pos.y = top; disp->input.input_crop_win.win_w = right - left; disp->input.input_crop_win.win_h = bottom - top; /* Set VDI motion algorithm. */ if (motion_mode) { if (motion_mode == 'h') { disp->input.motion_sel = HIGH_MOTION; } else if (motion_mode == 'l') { disp->input.motion_sel = LOW_MOTION; } else if (motion_mode == 'm') { disp->input.motion_sel = MED_MOTION; } else { disp->input.motion_sel = MED_MOTION; info_msg("%c unknown motion mode, medium, the default is used\n", motion_mode); } } if (dec->cmdl->chromaInterleave == 0) disp->input.fmt = V4L2_PIX_FMT_YUV420; else disp->input.fmt = V4L2_PIX_FMT_NV12; disp->output.width = disp_width; disp->output.height = disp_height; disp->output.fmt = V4L2_PIX_FMT_UYVY; if (rotation.ipu_rot_en && (rotation.rot_angle != 0)) { if (rotation.rot_angle == 90) disp->output.rot = IPU_ROTATE_90_RIGHT; else if (rotation.rot_angle == 180) disp->output.rot = IPU_ROTATE_180; else if (rotation.rot_angle == 270) disp->output.rot = IPU_ROTATE_90_LEFT; } disp->output.fb_disp.pos.x = disp_left; disp->output.fb_disp.pos.y = disp_top; disp->output.show_to_fb = 1; disp->output.fb_disp.fb_num = 2; info_msg("Display to %d %d, top offset %d, left offset %d\n", disp_width, disp_height, disp_top, disp_left); disp->ipu_q.tail = disp->ipu_q.head = 0; disp->stopping = 0; dec->disp = disp; pthread_mutex_init(&ipu_mutex, NULL); pthread_cond_init(&ipu_cond, NULL); /* start disp loop thread */ pthread_create(&(disp->ipu_disp_loop_thread), NULL, (void *)ipu_disp_loop_thread, (void *)dec); return disp; }
struct vpu_display * ipu_display_open(struct DecodingInstance *dec, int nframes, int w, int h, int x, int y) { int width = dec->picwidth; int height = dec->picheight; int disp_width = w; int disp_height = h; int disp_left = x; int disp_top = y; char motion_mode = 0; int err = 0, i; struct vpu_display *disp; struct mxcfb_gbl_alpha alpha; struct fb_var_screeninfo fb_var; disp = (struct vpu_display *)calloc(1, sizeof(struct vpu_display)); if (disp == NULL) { fputs("falied to allocate vpu_display\n", stderr); return NULL; } /* set alpha */ #ifdef BUILD_FOR_ANDROID disp->fd = open("/dev/graphics/fb0", O_RDWR, 0); #else disp->fd = open("/dev/fb0", O_RDWR, 0); #endif if (disp->fd < 0) { fputs("unable to open fb0\n", stderr); free(disp); return NULL; } alpha.alpha = 0; alpha.enable = 1; if (ioctl(disp->fd, MXCFB_SET_GBL_ALPHA, &alpha) < 0) { fputs("set alpha blending failed\n", stderr); close(disp->fd); free(disp); return NULL; } if ( ioctl(disp->fd, FBIOGET_VSCREENINFO, &fb_var) < 0) { fputs("Get FB var info failed!\n", stderr); close(disp->fd); free(disp); return NULL; } if (!disp_width || !disp_height) { disp_width = fb_var.xres; disp_height = fb_var.yres; } /* allocate buffers, use an extra buf for init buf */ disp->nframes = nframes; disp->frame_size = width*height*3/2; for (i=0;i<nframes;i++) { err = ipu_memory_alloc(disp->frame_size, 1, &(disp->ipu_bufs[i].ipu_paddr), &(disp->ipu_bufs[i].ipu_vaddr), disp->fd); if ( err < 0) { fputs("ipu_memory_alloc failed\n", stderr); free(disp); return NULL; } } memset(&(disp->ipu_handle), 0, sizeof(ipu_lib_handle_t)); memset(&(disp->input), 0, sizeof(ipu_lib_input_param_t)); memset(&(disp->output), 0, sizeof(ipu_lib_output_param_t)); disp->input.width = width; disp->input.height = height; disp->input.input_crop_win.pos.x = 0; disp->input.input_crop_win.pos.y = 0; disp->input.input_crop_win.win_w = 0; disp->input.input_crop_win.win_h = 0; /* Set VDI motion algorithm. */ if (motion_mode) { if (motion_mode == 'h') { disp->input.motion_sel = HIGH_MOTION; } else if (motion_mode == 'l') { disp->input.motion_sel = LOW_MOTION; } else if (motion_mode == 'm') { disp->input.motion_sel = MED_MOTION; } else { disp->input.motion_sel = MED_MOTION; fprintf(stderr, "%c unknown motion mode, medium, the default is used\n", motion_mode); } } disp->input.fmt = V4L2_PIX_FMT_YUV420; disp->output.width = disp_width; disp->output.height = disp_height; disp->output.fmt = V4L2_PIX_FMT_UYVY; disp->output.fb_disp.pos.x = disp_left; disp->output.fb_disp.pos.y = disp_top; disp->output.show_to_fb = 1; disp->output.fb_disp.fb_num = 2; fprintf(stderr, "Display to %d %d, top offset %d, left offset %d\n", disp_width, disp_height, disp_top, disp_left); disp->ipu_q.tail = disp->ipu_q.head = 0; disp->stopping = 0; dec->disp = disp; pthread_mutex_init(&ipu_mutex, NULL); pthread_cond_init(&ipu_cond, NULL); /* start disp loop thread */ pthread_create(&(disp->ipu_disp_loop_thread), NULL, (void*)ipu_disp_loop_thread, (void *)dec); return disp; }