static void allocate_xvimage(struct vo *vo, int foo) { struct xvctx *ctx = vo->priv; struct vo_x11_state *x11 = vo->x11; // align it for faster OSD rendering (draw_bmp.c swscale usage) int aligned_w = FFALIGN(ctx->image_width, 32); #ifdef HAVE_SHM if (x11->display_is_local && XShmQueryExtension(x11->display)) ctx->Shmem_Flag = 1; else { ctx->Shmem_Flag = 0; mp_tmsg(MSGT_VO, MSGL_INFO, "[VO_XV] Shared memory not supported\nReverting to normal Xv.\n"); } if (ctx->Shmem_Flag) { ctx->xvimage[foo] = (XvImage *) XvShmCreateImage(x11->display, x11->xv_port, ctx->xv_format, NULL, aligned_w, ctx->image_height, &ctx->Shminfo[foo]); ctx->Shminfo[foo].shmid = shmget(IPC_PRIVATE, ctx->xvimage[foo]->data_size, IPC_CREAT | 0777); ctx->Shminfo[foo].shmaddr = (char *) shmat(ctx->Shminfo[foo].shmid, 0, 0); ctx->Shminfo[foo].readOnly = False; ctx->xvimage[foo]->data = ctx->Shminfo[foo].shmaddr; XShmAttach(x11->display, &ctx->Shminfo[foo]); XSync(x11->display, False); shmctl(ctx->Shminfo[foo].shmid, IPC_RMID, 0); } else #endif { ctx->xvimage[foo] = (XvImage *) XvCreateImage(x11->display, x11->xv_port, ctx->xv_format, NULL, aligned_w, ctx->image_height); ctx->xvimage[foo]->data = av_malloc(ctx->xvimage[foo]->data_size); XSync(x11->display, False); } struct mp_image img = get_xv_buffer(vo, foo); vf_mpi_clear(&img, 0, 0, img.w, img.h); return; }
static void remove_func_2(int x0,int y0, int w,int h){ // TODO: let's cleanup the place //printf("OSD clear: %d;%d %dx%d \n",x0,y0,w,h); vf_mpi_clear(vf->dmpi,x0,y0,w,h); }
static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) { int ret = 0; mp_image_t *dmpi; switch (vf->priv->mode) { case 0: dmpi = vf->priv->dmpi; if (dmpi == NULL) { dmpi = vf_get_image(vf->next, mpi->imgfmt, MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_PRESERVE, mpi->width, mpi->height*2); vf->priv->dmpi = dmpi; memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h, dmpi->stride[0]*2, mpi->stride[0]); if (mpi->flags & MP_IMGFLAG_PLANAR) { memcpy_pic(dmpi->planes[1], mpi->planes[1], mpi->chroma_width, mpi->chroma_height, dmpi->stride[1]*2, mpi->stride[1]); memcpy_pic(dmpi->planes[2], mpi->planes[2], mpi->chroma_width, mpi->chroma_height, dmpi->stride[2]*2, mpi->stride[2]); } } else { vf->priv->dmpi = NULL; memcpy_pic(dmpi->planes[0]+dmpi->stride[0], mpi->planes[0], mpi->w, mpi->h, dmpi->stride[0]*2, mpi->stride[0]); if (mpi->flags & MP_IMGFLAG_PLANAR) { memcpy_pic(dmpi->planes[1]+dmpi->stride[1], mpi->planes[1], mpi->chroma_width, mpi->chroma_height, dmpi->stride[1]*2, mpi->stride[1]); memcpy_pic(dmpi->planes[2]+dmpi->stride[2], mpi->planes[2], mpi->chroma_width, mpi->chroma_height, dmpi->stride[2]*2, mpi->stride[2]); } ret = vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE); } break; case 1: if (vf->priv->frame & 1) ret = vf_next_put_image(vf, mpi, MP_NOPTS_VALUE); break; case 2: if ((vf->priv->frame & 1) == 0) ret = vf_next_put_image(vf, mpi, MP_NOPTS_VALUE); break; case 3: dmpi = vf_get_image(vf->next, mpi->imgfmt, MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, mpi->width, mpi->height*2); /* fixme, just clear alternate lines */ vf_mpi_clear(dmpi, 0, 0, dmpi->w, dmpi->h); if ((vf->priv->frame & 1) == 0) { memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h, dmpi->stride[0]*2, mpi->stride[0]); if (mpi->flags & MP_IMGFLAG_PLANAR) { memcpy_pic(dmpi->planes[1], mpi->planes[1], mpi->chroma_width, mpi->chroma_height, dmpi->stride[1]*2, mpi->stride[1]); memcpy_pic(dmpi->planes[2], mpi->planes[2], mpi->chroma_width, mpi->chroma_height, dmpi->stride[2]*2, mpi->stride[2]); } } else { memcpy_pic(dmpi->planes[0]+dmpi->stride[0], mpi->planes[0], mpi->w, mpi->h, dmpi->stride[0]*2, mpi->stride[0]); if (mpi->flags & MP_IMGFLAG_PLANAR) { memcpy_pic(dmpi->planes[1]+dmpi->stride[1], mpi->planes[1], mpi->chroma_width, mpi->chroma_height, dmpi->stride[1]*2, mpi->stride[1]); memcpy_pic(dmpi->planes[2]+dmpi->stride[2], mpi->planes[2], mpi->chroma_width, mpi->chroma_height, dmpi->stride[2]*2, mpi->stride[2]); } } ret = vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE); break; case 4: // Interleave even lines (only) from Frame 'i' with odd // lines (only) from Frame 'i+1', halving the Frame // rate and preserving image height. dmpi = vf->priv->dmpi; // @@ Need help: Should I set dmpi->fields to indicate // that the (new) frame will be interlaced!? E.g. ... // dmpi->fields |= MP_IMGFIELD_INTERLACED; // dmpi->fields |= MP_IMGFIELD_TOP_FIRST; // etc. if (dmpi == NULL) { dmpi = vf_get_image(vf->next, mpi->imgfmt, MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_PRESERVE, mpi->width, mpi->height); vf->priv->dmpi = dmpi; my_memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h/2, dmpi->stride[0]*2, mpi->stride[0]*2); if (mpi->flags & MP_IMGFLAG_PLANAR) { my_memcpy_pic(dmpi->planes[1], mpi->planes[1], mpi->chroma_width, mpi->chroma_height/2, dmpi->stride[1]*2, mpi->stride[1]*2); my_memcpy_pic(dmpi->planes[2], mpi->planes[2], mpi->chroma_width, mpi->chroma_height/2, dmpi->stride[2]*2, mpi->stride[2]*2); } } else { vf->priv->dmpi = NULL; my_memcpy_pic(dmpi->planes[0]+dmpi->stride[0], mpi->planes[0]+mpi->stride[0], mpi->w, mpi->h/2, dmpi->stride[0]*2, mpi->stride[0]*2); if (mpi->flags & MP_IMGFLAG_PLANAR) { my_memcpy_pic(dmpi->planes[1]+dmpi->stride[1], mpi->planes[1]+mpi->stride[1], mpi->chroma_width, mpi->chroma_height/2, dmpi->stride[1]*2, mpi->stride[1]*2); my_memcpy_pic(dmpi->planes[2]+dmpi->stride[2], mpi->planes[2]+mpi->stride[2], mpi->chroma_width, mpi->chroma_height/2, dmpi->stride[2]*2, mpi->stride[2]*2); } ret = vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE); } break; } vf->priv->frame++; return ret; }