Exemple #1
0
static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
{
    AVFilterBufferRef *buf;
    mp_image_t *cmpi = NULL;

    if (!(mpi->flags & MP_IMGFLAG_DIRECT)) {
        cmpi = vf_get_image(vf, mpi->imgfmt, MP_IMGTYPE_TEMP,
                            MP_IMGFLAG_PREFER_ALIGNED_STRIDE,
                            mpi->w, mpi->h);
        copy_mpi(cmpi, mpi);
        buf = cmpi->priv;
    } else {
        buf = mpi->priv;
    }
    buf->video->key_frame = mpi->pict_type == 1;
    buf->video->pict_type = mpi->pict_type; /* seems to be the same code */
    buf->video->interlaced = !!(mpi->fields & MP_IMGFIELD_INTERLACED);
    buf->video->top_field_first = !!(mpi->fields & MP_IMGFIELD_TOP_FIRST);
    vf->priv->in_buf = buf;
    if (pts != MP_NOPTS_VALUE)
        buf->pts = pts * AV_TIME_BASE;
    while (avfilter_poll_frame(vf->priv->out->inputs[0])) {
        if (avfilter_request_frame(vf->priv->out->inputs[0]))
            break;
    }
    return 1;
}
Exemple #2
0
static void draw_osd(struct vo *vo, struct osd_state *osd)
{
    struct priv *p = vo->priv;

    struct mp_image img = get_x_buffer(p);

    struct mp_osd_res res = {
        .w = img.w,
        .h = img.h,
        .display_par = vo->monitor_par,
        .video_par = vo->aspdat.par,
    };

    osd_draw_on_image_bk(osd, res, osd->vo_pts, 0, p->osd_backup, &img);
}

static mp_image_t *get_screenshot(struct vo *vo)
{
    struct priv *p = vo->priv;

    struct mp_image img = get_x_buffer(p);
    struct mp_image *res = alloc_mpi(img.w, img.h, img.imgfmt);
    copy_mpi(res, &img);
    mp_draw_sub_backup_restore(p->osd_backup, res);

    return res;
}

static int redraw_frame(struct vo *vo)
{
    struct priv *p = vo->priv;

    struct mp_image img = get_x_buffer(p);
    mp_draw_sub_backup_restore(p->osd_backup, &img);

    return true;
}

static void flip_page(struct vo *vo)
{
    struct priv *p = vo->priv;
    Display_Image(p, p->myximage, p->ImageData);
    XSync(vo->x11->display, False);
}

static int draw_slice(struct vo *vo, uint8_t *src[], int stride[], int w, int h,
                      int x, int y)
{
    struct priv *p = vo->priv;
    uint8_t *dst[MP_MAX_PLANES] = {NULL};
    int dstStride[MP_MAX_PLANES] = {0};

    if ((p->old_vo_dwidth != vo->dwidth || p->old_vo_dheight != vo->dheight)
        /*&& y==0 */ && p->zoomFlag)
    {
        int newW = vo->dwidth;
        int newH = vo->dheight;
        struct SwsContext *oldContext = p->swsContext;

        p->old_vo_dwidth = vo->dwidth;
        p->old_vo_dheight = vo->dheight;

        if (vo_fs)
            aspect(vo, &newW, &newH, A_ZOOM);
        if (sws_flags == 0)
            newW &= (~31);      // not needed but, if the user wants the FAST_BILINEAR SCALER, then its needed

        p->swsContext
            = sws_getContextFromCmdLine(p->srcW, p->srcH, p->in_format, newW,
                                        newH, p->out_format);
        if (p->swsContext) {
            p->image_width = (newW + 7) & (~7);
            p->image_height = newH;

            freeMyXImage(p);
            getMyXImage(p);
            sws_freeContext(oldContext);
        } else
            p->swsContext = oldContext;
        p->dst_width = newW;
    }

    dstStride[0] = p->image_width * ((p->bpp + 7) / 8);
    dst[0] = p->ImageData;
    if (p->Flip_Flag) {
        dst[0] += dstStride[0] * (p->image_height - 1);
        dstStride[0] = -dstStride[0];
    }
    sws_scale(p->swsContext, (const uint8_t **)src, stride, y, h, dst,
              dstStride);
    mp_draw_sub_backup_reset(p->osd_backup);
    return 0;
}

static int query_format(struct vo *vo, uint32_t format)
{
    mp_msg(MSGT_VO, MSGL_DBG2,
           "vo_x11: query_format was called: %x (%s)\n", format,
           vo_format_name(format));
    if (IMGFMT_IS_BGR(format)) {
        if (IMGFMT_BGR_DEPTH(format) <= 8)
            return 0;           // TODO 8bpp not yet fully implemented
        if (IMGFMT_BGR_DEPTH(format) == vo->x11->depthonscreen)
            return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW |
                   VFCAP_OSD | VFCAP_FLIP |
                   VFCAP_ACCEPT_STRIDE;
        else
            return VFCAP_CSP_SUPPORTED | VFCAP_OSD |
                   VFCAP_FLIP |
                   VFCAP_ACCEPT_STRIDE;
    }

    switch (format) {
    case IMGFMT_I420:
    case IMGFMT_IYUV:
    case IMGFMT_YV12:
        return VFCAP_CSP_SUPPORTED | VFCAP_OSD |
               VFCAP_ACCEPT_STRIDE;
    }
    return 0;
}
Exemple #3
0
static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){
  mp_image_t *dmpi = NULL;

  if (vf->priv->passthrough) {
    dmpi=vf_get_image(vf->next, IMGFMT_MPEGPES, MP_IMGTYPE_EXPORT,
                      0, mpi->w, mpi->h);
    dmpi->planes[0]=mpi->planes[0];
    return vf_next_put_image(vf,dmpi, pts);
  }

  if(vf->priv->current->show 
  || (vf->priv->current->parent && vf->priv->current->parent->show)) {
  // Close all menu who requested it
  while(vf->priv->current->cl && vf->priv->current != vf->priv->root) {
    menu_t* m = vf->priv->current;
    vf->priv->current = m->parent ? m->parent :  vf->priv->root;
    menu_close(m);
  }

  // Step 1 : save the picture
  while(go2pause == 1) {
    static char delay = 0; // Hack : wait the 2 frame to be sure to show the right picture
    delay ^= 1; // after a seek
    if(!delay) break;

    if(pause_mpi && (mpi->w != pause_mpi->w || mpi->h != pause_mpi->h ||
		     mpi->imgfmt != pause_mpi->imgfmt)) {
      free_mp_image(pause_mpi);
      pause_mpi = NULL;
    }
    if(!pause_mpi)
      pause_mpi = alloc_mpi(mpi->w,mpi->h,mpi->imgfmt);
    copy_mpi(pause_mpi,mpi);
    mp_input_queue_cmd(mp_input_parse_cmd("pause"));
    go2pause = 2;
    break;
  }

  // Grab // Ungrab the keys
  if(!mp_input_key_cb && vf->priv->current->show)
    mp_input_key_cb = key_cb;
  if(mp_input_key_cb && !vf->priv->current->show)
    mp_input_key_cb = NULL;

  if(mpi->flags&MP_IMGFLAG_DIRECT)
    dmpi = mpi->priv;
  else {
    dmpi = vf_get_image(vf->next,mpi->imgfmt,
			MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
			mpi->w,mpi->h);
    copy_mpi(dmpi,mpi);
  }
  menu_draw(vf->priv->current,dmpi);

  } else {
    if(mp_input_key_cb)
      mp_input_key_cb = NULL;

    if(mpi->flags&MP_IMGFLAG_DIRECT)
      dmpi = mpi->priv;
    else {
      dmpi = vf_get_image(vf->next,mpi->imgfmt,
                          MP_IMGTYPE_EXPORT, MP_IMGFLAG_ACCEPT_STRIDE,
                          mpi->w,mpi->h);

      dmpi->stride[0] = mpi->stride[0];
      dmpi->stride[1] = mpi->stride[1];
      dmpi->stride[2] = mpi->stride[2];
      dmpi->planes[0] = mpi->planes[0];
      dmpi->planes[1] = mpi->planes[1];
      dmpi->planes[2] = mpi->planes[2];
      dmpi->priv      = mpi->priv;
    }
  }
  return vf_next_put_image(vf,dmpi, pts);
}
Exemple #4
0
static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
  mp_image_t *dmpi = NULL;

  if (vf->priv->passthrough) {
    dmpi=vf_get_image(vf->next, IMGFMT_MPEGPES, MP_IMGTYPE_EXPORT,
                      0, mpi->w, mpi->h);
    dmpi->planes[0]=mpi->planes[0];
    return vf_next_put_image(vf,dmpi, pts);
  }

  // Close all menu who requested it
  while(vf->priv->current->cl && vf->priv->current != vf->priv->root) {
    menu_t* m = vf->priv->current;
    vf->priv->current = m->parent ? m->parent :  vf->priv->root;
    menu_close(m);
  }

    // Try to capture the last frame before pause, or fallback to use
    // last captured frame.
    if(pause_mpi && (mpi->w != pause_mpi->w || mpi->h != pause_mpi->h ||
		     mpi->imgfmt != pause_mpi->imgfmt)) {
      free_mp_image(pause_mpi);
      pause_mpi = NULL;
    }
  if (!pause_mpi) {
    pause_mpi = alloc_mpi(mpi->w,mpi->h,mpi->imgfmt);
    copy_mpi(pause_mpi,mpi);
  }
  else if (mpctx_get_osd_function(vf->priv->root->ctx) == OSD_PAUSE)
    copy_mpi(pause_mpi,mpi);

  if (vf->priv->current->show) {
    if (!mp_input_key_cb)
      mp_input_key_cb = key_cb;

  if(mpi->flags&MP_IMGFLAG_DIRECT)
    dmpi = mpi->priv;
  else {
    dmpi = vf_get_image(vf->next,mpi->imgfmt,
			MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
			mpi->w,mpi->h);
    copy_mpi(dmpi,mpi);
  }
  menu_draw(vf->priv->current,dmpi);

  } else {
    if(mp_input_key_cb)
      mp_input_key_cb = NULL;

    if(mpi->flags&MP_IMGFLAG_DIRECT)
      dmpi = mpi->priv;
    else {
      dmpi = vf_get_image(vf->next,mpi->imgfmt,
                          MP_IMGTYPE_EXPORT, MP_IMGFLAG_ACCEPT_STRIDE,
                          mpi->w,mpi->h);

      dmpi->stride[0] = mpi->stride[0];
      dmpi->stride[1] = mpi->stride[1];
      dmpi->stride[2] = mpi->stride[2];
      dmpi->planes[0] = mpi->planes[0];
      dmpi->planes[1] = mpi->planes[1];
      dmpi->planes[2] = mpi->planes[2];
      dmpi->priv      = mpi->priv;
    }
  }
  return vf_next_put_image(vf,dmpi, pts);
}
Exemple #5
0
Fichier : vo_xv.c Projet : kax4/mpv
static void draw_osd(struct vo *vo, struct osd_state *osd)
{
    struct xvctx *ctx = vo->priv;

    struct mp_image img = get_xv_buffer(vo, ctx->current_buf);

    struct mp_rect *src = &ctx->src_rect;
    struct mp_rect *dst = &ctx->dst_rect;
    int dw = dst->x1 - dst->x0, dh = dst->y1 - dst->y0;
    int sw = src->x1 - src->x0, sh = src->y1 - src->y0;
    double xvpar = (double)dw / dh * sh / sw;

    struct mp_osd_res res = {
        .w = ctx->image_width,
        .h = ctx->image_height,
        .display_par = vo->monitor_par / xvpar,
        .video_par = vo->aspdat.par,
    };

    osd_draw_on_image_bk(osd, res, osd->vo_pts, 0, ctx->osd_backup, &img);
}

static int redraw_frame(struct vo *vo)
{
    struct xvctx *ctx = vo->priv;

    struct mp_image img = get_xv_buffer(vo, ctx->visible_buf);
    mp_draw_sub_backup_restore(ctx->osd_backup, &img);
    ctx->current_buf = ctx->visible_buf;

    return true;
}

static void flip_page(struct vo *vo)
{
    struct xvctx *ctx = vo->priv;
    put_xvimage(vo, ctx->xvimage[ctx->current_buf]);

    /* remember the currently visible buffer */
    ctx->visible_buf = ctx->current_buf;

    ctx->current_buf = (ctx->current_buf + 1) % ctx->num_buffers;
    XFlush(vo->x11->display);
    return;
}

static int draw_slice(struct vo *vo, uint8_t *image[], int stride[], int w,
                      int h, int x, int y)
{
    struct xvctx *ctx = vo->priv;
    uint8_t *dst;
    XvImage *current_image = ctx->xvimage[ctx->current_buf];

    dst = current_image->data + current_image->offsets[0]
        + current_image->pitches[0] * y + x;
    memcpy_pic(dst, image[0], w, h, current_image->pitches[0], stride[0]);

    x /= 2;
    y /= 2;
    w /= 2;
    h /= 2;

    dst = current_image->data + current_image->offsets[1]
        + current_image->pitches[1] * y + x;
    if (ctx->image_format != IMGFMT_YV12)
        memcpy_pic(dst, image[1], w, h, current_image->pitches[1], stride[1]);
    else
        memcpy_pic(dst, image[2], w, h, current_image->pitches[1], stride[2]);

    dst = current_image->data + current_image->offsets[2]
        + current_image->pitches[2] * y + x;
    if (ctx->image_format == IMGFMT_YV12)
        memcpy_pic(dst, image[1], w, h, current_image->pitches[1], stride[1]);
    else
        memcpy_pic(dst, image[2], w, h, current_image->pitches[1], stride[2]);

    mp_draw_sub_backup_reset(ctx->osd_backup);

    return 0;
}

static mp_image_t *get_screenshot(struct vo *vo)
{
    struct xvctx *ctx = vo->priv;

    struct mp_image img = get_xv_buffer(vo, ctx->visible_buf);
    struct mp_image *res = alloc_mpi(img.w, img.h, img.imgfmt);
    copy_mpi(res, &img);
    vf_clone_mpi_attributes(res, &img);
    // try to get an image without OSD
    mp_draw_sub_backup_restore(ctx->osd_backup, res);
    res->display_w = vo->aspdat.prew;
    res->display_h = vo->aspdat.preh;

    return res;
}

static uint32_t draw_image(struct vo *vo, mp_image_t *mpi)
{
    struct xvctx *ctx = vo->priv;

    if (mpi->flags & MP_IMGFLAG_DRAW_CALLBACK)
        ; // done
    else if (mpi->flags & MP_IMGFLAG_PLANAR)
        draw_slice(vo, mpi->planes, mpi->stride, mpi->w, mpi->h, 0, 0);
    else if (mpi->flags & MP_IMGFLAG_YUV)
        // packed YUV:
        memcpy_pic(ctx->xvimage[ctx->current_buf]->data +
                   ctx->xvimage[ctx->current_buf]->offsets[0], mpi->planes[0],
                   mpi->w * (mpi->bpp / 8), mpi->h,
                   ctx->xvimage[ctx->current_buf]->pitches[0], mpi->stride[0]);
    else
          return false;

    mp_draw_sub_backup_reset(ctx->osd_backup);

    return true;
}

static int query_format(struct xvctx *ctx, uint32_t format)
{
    uint32_t i;
    int flag = VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_OSD | VFCAP_ACCEPT_STRIDE;       // FIXME! check for DOWN

    /* check image formats */
    for (i = 0; i < ctx->formats; i++) {
        if (ctx->fo[i].id == format)
            return flag;        //xv_format = fo[i].id;
    }
    return 0;
}