static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ mp_image_t *dmpi; if (mpi->flags&MP_IMGFLAG_DRAW_CALLBACK) return vf_next_put_image(vf,vf->dmpi, pts); dmpi=vf_get_image(vf->next,mpi->imgfmt, MP_IMGTYPE_EXPORT, 0, vf->priv->crop_w, vf->priv->crop_h); if(mpi->flags&MP_IMGFLAG_PLANAR){ dmpi->planes[0]=mpi->planes[0]+ vf->priv->crop_y*mpi->stride[0]+vf->priv->crop_x; dmpi->planes[1]=mpi->planes[1]+ (vf->priv->crop_y>>mpi->chroma_y_shift)*mpi->stride[1]+(vf->priv->crop_x>>mpi->chroma_x_shift); dmpi->planes[2]=mpi->planes[2]+ (vf->priv->crop_y>>mpi->chroma_y_shift)*mpi->stride[2]+(vf->priv->crop_x>>mpi->chroma_x_shift); dmpi->stride[1]=mpi->stride[1]; dmpi->stride[2]=mpi->stride[2]; } else {
/*** * \param vf pointer to vf_instance * \param mpi pointer to mp_image_t structure * \param pts */ static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ struct vf_priv_s *priv = vf->priv; int size = 0; int i; mp_image_t* dmpi; for (i = 0; i < priv->fields; i++) size += jpeg_enc_frame(priv->j, mpi->planes[0] + i*priv->y_stride, mpi->planes[1] + i*priv->c_stride, mpi->planes[2] + i*priv->c_stride, priv->buf + size); dmpi = vf_get_image(vf->next, IMGFMT_ZRMJPEGNI, MP_IMGTYPE_EXPORT, 0, mpi->w, mpi->h); dmpi->planes[0] = (uint8_t*)priv->buf; dmpi->planes[1] = (uint8_t*)size; return vf_next_put_image(vf,dmpi, pts); }
static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ int cw= mpi->w >> mpi->chroma_x_shift; int ch= mpi->h >> mpi->chroma_y_shift; int threshold = vf->priv->luma.threshold || vf->priv->chroma.threshold; mp_image_t *dmpi=vf_get_image(vf->next,mpi->imgfmt, MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE| (threshold ? MP_IMGFLAG_READABLE : 0), mpi->w,mpi->h); assert(mpi->flags&MP_IMGFLAG_PLANAR); blur(dmpi->planes[0], mpi->planes[0], mpi->w,mpi->h, dmpi->stride[0], mpi->stride[0], &vf->priv->luma); blur(dmpi->planes[1], mpi->planes[1], cw , ch , dmpi->stride[1], mpi->stride[1], &vf->priv->chroma); blur(dmpi->planes[2], mpi->planes[2], cw , ch , dmpi->stride[2], mpi->stride[2], &vf->priv->chroma); return vf_next_put_image(vf,dmpi, pts); }
static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ mp_image_t *dmpi; // hope we'll get DR buffer: dmpi=vf_get_image(vf->next,IMGFMT_YUY2, MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, mpi->w, mpi->h); if(mpi->imgfmt==IMGFMT_422P) yuv422ptoyuy2(mpi->planes[0],mpi->planes[1],mpi->planes[2], dmpi->planes[0], mpi->w,mpi->h, mpi->stride[0],mpi->stride[1],dmpi->stride[0]); else yv12toyuy2(mpi->planes[0],mpi->planes[1],mpi->planes[2], dmpi->planes[0], mpi->w,mpi->h, mpi->stride[0],mpi->stride[1],dmpi->stride[0]); vf_clone_mpi_attributes(dmpi, mpi); return vf_next_put_image(vf,dmpi, pts); }
static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ mp_image_t *dmpi; int x, y; int nblack=0, pblack=0; unsigned char *yplane = mpi->planes[0]; unsigned int ystride = mpi->stride[0]; int pict_type = mpi->pict_type; int w = mpi->w, h = mpi->h; int bthresh = vf->priv->bthresh; int bamount = vf->priv->bamount; static const char *picttypes[4] = { "unknown", "I", "P", "B" }; for (y=1; y<=h; y++) { for (x=0; x<w; x++) nblack += yplane[x] < bthresh; pblack = nblack*100/(w*y); if (pblack < bamount) break; yplane += ystride; } if (pict_type > 3 || pict_type < 0) pict_type = 0; if (pict_type == 1) vf->priv->lastkeyframe = vf->priv->frame; if (pblack >= bamount) mp_msg(MSGT_VFILTER, MSGL_INFO,"vf_blackframe: %u, %i%%, %s (I:%u)\n", vf->priv->frame, pblack, picttypes[pict_type], vf->priv->lastkeyframe); vf->priv->frame++; dmpi = vf_get_image(vf->next, mpi->imgfmt, MP_IMGTYPE_EXPORT, 0, mpi->width, mpi->height); dmpi->planes[0] = mpi->planes[0]; dmpi->stride[0] = mpi->stride[0]; dmpi->planes[1] = mpi->planes[1]; dmpi->stride[1] = mpi->stride[1]; dmpi->planes[2] = mpi->planes[2]; dmpi->stride[2] = mpi->stride[2]; vf_clone_mpi_attributes(dmpi, mpi); return vf_next_put_image(vf, dmpi, pts); }
static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ mp_image_t *dmpi; if(!(mpi->flags&MP_IMGFLAG_DIRECT)){ // no DR, so get a new image! hope we'll get DR buffer: dmpi=vf_get_image(vf->next,mpi->imgfmt, MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_PREFER_ALIGNED_STRIDE, mpi->width,mpi->height); vf_clone_mpi_attributes(dmpi, mpi); }else{ dmpi=vf->dmpi; } filter(vf->priv, dmpi->planes[0], mpi->planes[0], dmpi->stride[0], mpi->stride[0], mpi->w, mpi->h, 1); filter(vf->priv, dmpi->planes[1], mpi->planes[1], dmpi->stride[1], mpi->stride[1], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, 0); filter(vf->priv, dmpi->planes[2], mpi->planes[2], dmpi->stride[2], mpi->stride[2], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, 0); return vf_next_put_image(vf,dmpi, pts); }
static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts) { mp_image_t *dmpi; vf->priv->last_mpi = mpi; dmpi = vf_get_image(vf->next, mpi->imgfmt, MP_IMGTYPE_EXPORT, 0, mpi->width, mpi->height); dmpi->planes[0] = mpi->planes[0]; dmpi->stride[0] = mpi->stride[0]; if (dmpi->flags&MP_IMGFLAG_PLANAR) { dmpi->planes[1] = mpi->planes[1]; dmpi->stride[1] = mpi->stride[1]; dmpi->planes[2] = mpi->planes[2]; dmpi->stride[2] = mpi->stride[2]; } return vf_next_put_image(vf, dmpi, pts); }
static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ vf->dmpi=vf_get_image(vf->next,mpi->imgfmt, MP_IMGTYPE_EXPORT, MP_IMGFLAG_ACCEPT_STRIDE, mpi->width, mpi->height/2); // set up mpi as a double-stride image of dmpi: vf->dmpi->planes[0]=mpi->planes[0]+mpi->stride[0]*vf->priv->field; vf->dmpi->stride[0]=2*mpi->stride[0]; if(vf->dmpi->flags&MP_IMGFLAG_PLANAR){ vf->dmpi->planes[1]=mpi->planes[1]+ mpi->stride[1]*vf->priv->field; vf->dmpi->stride[1]=2*mpi->stride[1]; vf->dmpi->planes[2]=mpi->planes[2]+ mpi->stride[2]*vf->priv->field; vf->dmpi->stride[2]=2*mpi->stride[2]; } else vf->dmpi->planes[1]=mpi->planes[1]; // passthru bgr8 palette!!! return vf_next_put_image(vf,vf->dmpi, pts); }
/** * \brief Process a frame. * * \param mpi The image sent to use by the previous filter. * \param dmpi Where we will store the processed output image. * \param vf This is how the filter gets access to it's persistant data. * * \return The return code of the next filter, or 0 on failure/error. * * This function processes an entire frame. The frame is sent by the previous * filter, has the logo removed by the filter, and is then sent to the next * filter. */ static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ mp_image_t *dmpi; dmpi=vf_get_image(vf->next,vf->priv->fmt, MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, mpi->w, mpi->h); /* Check to make sure that the filter image and the video stream are the same size. */ if (vf->priv->filter->width != mpi->w || vf->priv->filter->height != mpi->h) { mp_msg(MSGT_VFILTER,MSGL_ERR, "Filter image and video stream are not of the same size. (Filter: %d x %d, Stream: %d x %d)\n", vf->priv->filter->width, vf->priv->filter->height, mpi->w, mpi->h); return 0; } switch(dmpi->imgfmt){ case IMGFMT_YV12: convert_yv12(vf, mpi->planes[0], mpi->stride[0], mpi, mpi->w, mpi->h, dmpi->planes[0], dmpi->stride[0], mpi->flags & MP_IMGFLAG_DIRECT, vf->priv->filter, 0, vf->priv->bounding_rectangle_posx1, vf->priv->bounding_rectangle_posy1, vf->priv->bounding_rectangle_posx2, vf->priv->bounding_rectangle_posy2); convert_yv12(vf, mpi->planes[1], mpi->stride[1], mpi, mpi->w / 2, mpi->h / 2, dmpi->planes[1], dmpi->stride[1], mpi->flags & MP_IMGFLAG_DIRECT, vf->priv->half_size_filter, 1, vf->priv->bounding_rectangle_half_size_posx1, vf->priv->bounding_rectangle_half_size_posy1, vf->priv->bounding_rectangle_half_size_posx2, vf->priv->bounding_rectangle_half_size_posy2); convert_yv12(vf, mpi->planes[2], mpi->stride[2], mpi, mpi->w / 2, mpi->h / 2, dmpi->planes[2], dmpi->stride[2], mpi->flags & MP_IMGFLAG_DIRECT, vf->priv->half_size_filter, 2, vf->priv->bounding_rectangle_half_size_posx1, vf->priv->bounding_rectangle_half_size_posy1, vf->priv->bounding_rectangle_half_size_posx2, vf->priv->bounding_rectangle_half_size_posy2); break; default: mp_msg(MSGT_VFILTER,MSGL_ERR,"Unhandled format: 0x%X\n",dmpi->imgfmt); return 0; } return vf_next_put_image(vf,dmpi, pts); }
static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ mp_image_t *dmpi; if(mpi->flags&MP_IMGFLAG_DIRECT){ dmpi=(mp_image_t*)mpi->priv; } else { dmpi=vf_get_image(vf->next, mpi->imgfmt, MP_IMGTYPE_EXPORT, 0, mpi->w, mpi->h); assert(mpi->flags&MP_IMGFLAG_PLANAR); dmpi->planes[0]=mpi->planes[0]; dmpi->planes[1]=mpi->planes[2]; dmpi->planes[2]=mpi->planes[1]; dmpi->stride[0]=mpi->stride[0]; dmpi->stride[1]=mpi->stride[2]; dmpi->stride[2]=mpi->stride[1]; dmpi->width=mpi->width; } vf_clone_mpi_attributes(dmpi, mpi); return vf_next_put_image(vf,dmpi, pts); }
static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ mp_image_t* dmpi; int out_size; AVFrame *pic= vf->priv->pic; int ret, got_pkt; AVPacket pkt; pic->data[0]=mpi->planes[0]; pic->data[1]=mpi->planes[1]; pic->data[2]=mpi->planes[2]; pic->linesize[0]=mpi->stride[0]; pic->linesize[1]=mpi->stride[1]; pic->linesize[2]=mpi->stride[2]; av_init_packet(&pkt); pkt.data = vf->priv->outbuf; pkt.size = vf->priv->outbuf_size; ret = avcodec_encode_video2(&lavc_venc_context, &pkt, pic, &got_pkt); if(ret<=0) return 1; if(!got_pkt) return 1; out_size = pkt.size; dmpi=vf_get_image(vf->next,IMGFMT_MPEGPES, MP_IMGTYPE_EXPORT, 0, mpi->w, mpi->h); vf->priv->pes.data=vf->priv->outbuf; vf->priv->pes.size=out_size; vf->priv->pes.id=0x1E0; vf->priv->pes.timestamp=-1; // dunno dmpi->planes[0]=(unsigned char*)&vf->priv->pes; return vf_next_put_image(vf,dmpi, pts); }
static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts) { mp_image_t *dmpi = (mp_image_t *)mpi->priv; if (mpi->flags & MP_IMGFLAG_DRAW_CALLBACK) dmpi = vf->dmpi; else if(!(mpi->flags&MP_IMGFLAG_DIRECT)){ dmpi=vf_get_image(vf->next,mpi->imgfmt, MP_IMGTYPE_EXPORT, 0, mpi->width, mpi->height); vf_clone_mpi_attributes(dmpi, mpi); dmpi->planes[0]=mpi->planes[0]; dmpi->planes[1]=mpi->planes[1]; dmpi->planes[2]=mpi->planes[2]; dmpi->stride[0]=mpi->stride[0]; dmpi->stride[1]=mpi->stride[1]; dmpi->stride[2]=mpi->stride[2]; dmpi->width=mpi->width; dmpi->height=mpi->height; } if(vf->priv->shot) { if (vf->priv->shot==1) vf->priv->shot=0; gen_fname(vf->priv); if (vf->priv->fname[0]) { if (!vf->priv->store_slices) scale_image(vf->priv, dmpi); write_png(vf->priv); } vf->priv->store_slices = 0; } return vf_next_put_image(vf, dmpi, pts); }
static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts) { mp_image_t *dmpi; int ret = 0; int flags = mpi->fields; int state = vf->priv->state; dmpi = vf_get_image(vf->next, mpi->imgfmt, MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_PRESERVE, mpi->width, mpi->height); vf->priv->in++; if ((state == 0 && !(flags & MP_IMGFIELD_TOP_FIRST)) || (state == 1 && flags & MP_IMGFIELD_TOP_FIRST)) { mp_msg(MSGT_VFILTER, MSGL_WARN, "softpulldown: Unexpected field flags: state=%d top_field_first=%d repeat_first_field=%d\n", state, (flags & MP_IMGFIELD_TOP_FIRST) != 0, (flags & MP_IMGFIELD_REPEAT_FIRST) != 0); state ^= 1; } if (state == 0) { ret = vf_next_put_image(vf, mpi, vf_softpulldown_adjust_pts(&vf->priv->ptsbuf, pts, 0, 0, vf->priv->last_frame_duration)); vf->priv->out++; if (flags & MP_IMGFIELD_REPEAT_FIRST) { 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); } state=1; } } else { 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, vf_softpulldown_adjust_pts(&vf->priv->ptsbuf, pts, 0, 0, vf->priv->last_frame_duration)); vf->priv->out++; if (flags & MP_IMGFIELD_REPEAT_FIRST) { vf->priv->buffered_mpi = mpi; vf->priv->buffered_pts = pts; vf->priv->buffered_last_frame_duration = vf->priv->last_frame_duration; vf_queue_frame(vf, continue_buffered_image); } else { 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); } } } vf->priv->state = state; if (flags & MP_IMGFIELD_REPEAT_FIRST) vf->priv->last_frame_duration = 3; else vf->priv->last_frame_duration = 2; return ret; }
static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts) { struct pullup_context *c = vf->priv->ctx; struct pullup_buffer *b; struct pullup_frame *f; mp_image_t *dmpi; int ret; int p; int i; if (!vf->priv->init) init_pullup(vf, mpi); if (mpi->flags & MP_IMGFLAG_DIRECT) { b = mpi->priv; mpi->priv = 0; } else { b = pullup_get_buffer(c, 2); if (!b) { mp_msg(MSGT_VFILTER,MSGL_ERR,"Could not get buffer from pullup!\n"); f = pullup_get_frame(c); pullup_release_frame(f); return 0; } memcpy_pic(b->planes[0], mpi->planes[0], mpi->w, mpi->h, c->stride[0], mpi->stride[0]); if (mpi->flags & MP_IMGFLAG_PLANAR) { memcpy_pic(b->planes[1], mpi->planes[1], mpi->chroma_width, mpi->chroma_height, c->stride[1], mpi->stride[1]); memcpy_pic(b->planes[2], mpi->planes[2], mpi->chroma_width, mpi->chroma_height, c->stride[2], mpi->stride[2]); } } if (mpi->qscale) { fast_memcpy(b->planes[3], mpi->qscale, c->w[3]); fast_memcpy(b->planes[3]+c->w[3], mpi->qscale, c->w[3]); } p = mpi->fields & MP_IMGFIELD_TOP_FIRST ? 0 : (mpi->fields & MP_IMGFIELD_ORDERED ? 1 : 0); pullup_submit_field(c, b, p); pullup_submit_field(c, b, p^1); if (mpi->fields & MP_IMGFIELD_REPEAT_FIRST) pullup_submit_field(c, b, p); pullup_release_buffer(b, 2); f = pullup_get_frame(c); /* Fake yes for first few frames (buffer depth) to keep from * breaking A/V sync with G1's bad architecture... */ if (!f) return vf->priv->fakecount ? (--vf->priv->fakecount,1) : 0; if (f->length < 2) { pullup_release_frame(f); f = pullup_get_frame(c); if (!f) return 0; if (f->length < 2) { pullup_release_frame(f); if (!(mpi->fields & MP_IMGFIELD_REPEAT_FIRST)) return 0; f = pullup_get_frame(c); if (!f) return 0; if (f->length < 2) { pullup_release_frame(f); return 0; } } } #if 0 /* Average qscale tables from both frames. */ if (mpi->qscale) { for (i=0; i<c->w[3]; i++) { vf->priv->qbuf[i] = (f->ofields[0]->planes[3][i] + f->ofields[1]->planes[3][i+c->w[3]])>>1; } } #else /* Take worst of qscale tables from both frames. */ if (mpi->qscale) { for (i=0; i<c->w[3]; i++) { vf->priv->qbuf[i] = MAX(f->ofields[0]->planes[3][i], f->ofields[1]->planes[3][i+c->w[3]]); } } #endif /* If the frame isn't already exportable... */ while (!f->buffer) { dmpi = vf_get_image(vf->next, mpi->imgfmt, MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, mpi->width, mpi->height); /* FIXME: Is it ok to discard dmpi if it's not direct? */ if (!(dmpi->flags & MP_IMGFLAG_DIRECT)) { pullup_pack_frame(c, f); break; } /* Direct render fields into output buffer */ my_memcpy_pic(dmpi->planes[0], f->ofields[0]->planes[0], mpi->w, mpi->h/2, dmpi->stride[0]*2, c->stride[0]*2); my_memcpy_pic(dmpi->planes[0] + dmpi->stride[0], f->ofields[1]->planes[0] + c->stride[0], mpi->w, mpi->h/2, dmpi->stride[0]*2, c->stride[0]*2); if (mpi->flags & MP_IMGFLAG_PLANAR) { my_memcpy_pic(dmpi->planes[1], f->ofields[0]->planes[1], mpi->chroma_width, mpi->chroma_height/2, dmpi->stride[1]*2, c->stride[1]*2); my_memcpy_pic(dmpi->planes[1] + dmpi->stride[1], f->ofields[1]->planes[1] + c->stride[1], mpi->chroma_width, mpi->chroma_height/2, dmpi->stride[1]*2, c->stride[1]*2); my_memcpy_pic(dmpi->planes[2], f->ofields[0]->planes[2], mpi->chroma_width, mpi->chroma_height/2, dmpi->stride[2]*2, c->stride[2]*2); my_memcpy_pic(dmpi->planes[2] + dmpi->stride[2], f->ofields[1]->planes[2] + c->stride[2], mpi->chroma_width, mpi->chroma_height/2, dmpi->stride[2]*2, c->stride[2]*2); } pullup_release_frame(f); if (mpi->qscale) { dmpi->qscale = vf->priv->qbuf; dmpi->qstride = mpi->qstride; dmpi->qscale_type = mpi->qscale_type; } return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE); } dmpi = vf_get_image(vf->next, mpi->imgfmt, MP_IMGTYPE_EXPORT, MP_IMGFLAG_ACCEPT_STRIDE, mpi->width, mpi->height); dmpi->planes[0] = f->buffer->planes[0]; dmpi->planes[1] = f->buffer->planes[1]; dmpi->planes[2] = f->buffer->planes[2]; dmpi->stride[0] = c->stride[0]; dmpi->stride[1] = c->stride[1]; dmpi->stride[2] = c->stride[2]; if (mpi->qscale) { dmpi->qscale = vf->priv->qbuf; dmpi->qstride = mpi->qstride; dmpi->qscale_type = mpi->qscale_type; } ret = vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE); pullup_release_frame(f); return ret; }
static int put_image(struct vf_instance* vf, mp_image_t* mpi, double pts){ int buf_x=0, buf_y=0, buf_pos=0; int have, got, want; int xpos=0, ypos=0, pos=0; unsigned char red=0, green=0, blue=0; int alpha; mp_image_t* dmpi; dmpi = vf_get_image(vf->next, mpi->imgfmt, MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_PREFER_ALIGNED_STRIDE, mpi->w, mpi->h); memcpy_pic( dmpi->planes[0], mpi->planes[0], mpi->width, mpi->height, dmpi->stride[0], mpi->stride[0] ); memcpy_pic( dmpi->planes[1], mpi->planes[1], mpi->chroma_width, mpi->chroma_height, dmpi->stride[1], mpi->stride[1] ); memcpy_pic( dmpi->planes[2], mpi->planes[2], mpi->chroma_width, mpi->chroma_height, dmpi->stride[2], mpi->stride[2] ); if(vf->priv->stream_fd >= 0) { struct timeval tv; int ready; FD_SET( vf->priv->stream_fd, &vf->priv->stream_fdset ); tv.tv_sec=0; tv.tv_usec=0; ready = select( vf->priv->stream_fd+1, &vf->priv->stream_fdset, NULL, NULL, &tv ); if(ready > 0) { // We've got new data from the FIFO char cmd[20], args[100]; int imgw,imgh,imgx,imgy,clear,imgalpha,pxsz=1,command; unsigned char *buffer = NULL; if(! _read_cmd( vf->priv->stream_fd, cmd, args) ) { mp_msg(MSGT_VFILTER, MSGL_ERR, "\nvf_bmovl: Error reading commands: %s\n\n", strerror(errno)); return FALSE; } mp_msg(MSGT_VFILTER, MSGL_DBG2, "\nDEBUG: Got: %s+%s\n", cmd, args); command=NONE; if ( strncmp(cmd,"RGBA32",6)==0 ) { pxsz=4; command = IMG_RGBA32; } else if( strncmp(cmd,"ABGR32",6)==0 ) { pxsz=4; command = IMG_ABGR32; } else if( strncmp(cmd,"RGB24" ,5)==0 ) { pxsz=3; command = IMG_RGB24; } else if( strncmp(cmd,"BGR24" ,5)==0 ) { pxsz=3; command = IMG_BGR24; } else if( strncmp(cmd,"CLEAR" ,5)==0 ) { pxsz=1; command = CMD_CLEAR; } else if( strncmp(cmd,"ALPHA" ,5)==0 ) { pxsz=1; command = CMD_ALPHA; } else if( strncmp(cmd,"OPAQUE",6)==0 ) vf->priv->opaque=TRUE; else if( strncmp(cmd,"SHOW", 4)==0 ) vf->priv->hidden=FALSE; else if( strncmp(cmd,"HIDE", 4)==0 ) vf->priv->hidden=TRUE; else if( strncmp(cmd,"FLUSH" ,5)==0 ) return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE); else { mp_msg(MSGT_VFILTER, MSGL_WARN, "\nvf_bmovl: Unknown command: '%s'. Ignoring.\n", cmd); return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE); } if(command == CMD_ALPHA) { sscanf( args, "%d %d %d %d %d", &imgw, &imgh, &imgx, &imgy, &imgalpha); mp_msg(MSGT_VFILTER, MSGL_DBG2, "\nDEBUG: ALPHA: %d %d %d %d %d\n\n", imgw, imgh, imgx, imgy, imgalpha); if(imgw==0 && imgh==0) vf->priv->opaque=FALSE; } if(command & IS_RAWIMG) { sscanf( args, "%d %d %d %d %d %d", &imgw, &imgh, &imgx, &imgy, &imgalpha, &clear); mp_msg(MSGT_VFILTER, MSGL_DBG2, "\nDEBUG: RAWIMG: %d %d %d %d %d %d\n\n", imgw, imgh, imgx, imgy, imgalpha, clear); buffer = malloc(imgw*imgh*pxsz); if(!buffer) { mp_msg(MSGT_VFILTER, MSGL_WARN, "\nvf_bmovl: Couldn't allocate temporary buffer! Skipping...\n\n"); return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE); } /* pipes/sockets might need multiple calls to read(): */ want = (imgw*imgh*pxsz); have = 0; while (have < want) { got = read( vf->priv->stream_fd, buffer+have, want-have ); if (got == 0) { mp_msg(MSGT_VFILTER, MSGL_WARN, "\nvf_bmovl: premature EOF...\n\n"); break; } if (got < 0) { mp_msg(MSGT_VFILTER, MSGL_WARN, "\nvf_bmovl: read error: %s\n\n", strerror(errno)); break; } have += got; } mp_msg(MSGT_VFILTER, MSGL_DBG2, "Got %d bytes... (wanted %d)\n", have, want ); if(clear) { memset( vf->priv->bitmap.y, 0, vf->priv->w*vf->priv->h ); memset( vf->priv->bitmap.u, 128, vf->priv->w*vf->priv->h/4 ); memset( vf->priv->bitmap.v, 128, vf->priv->w*vf->priv->h/4 ); memset( vf->priv->bitmap.a, 0, vf->priv->w*vf->priv->h ); memset( vf->priv->bitmap.oa, 0, vf->priv->w*vf->priv->h ); vf->priv->x1 = dmpi->width; vf->priv->y1 = dmpi->height; vf->priv->x2 = vf->priv->y2 = 0; } // Define how much of our bitmap that contains graphics! vf->priv->x1 = av_clip(imgx, 0, vf->priv->x1); vf->priv->y1 = av_clip(imgy, 0, vf->priv->y1); vf->priv->x2 = av_clip(imgx + imgw, vf->priv->x2, vf->priv->w); vf->priv->y2 = av_clip(imgy + imgh, vf->priv->y2, vf->priv->h); } if( command == CMD_CLEAR ) { sscanf( args, "%d %d %d %d", &imgw, &imgh, &imgx, &imgy); mp_msg(MSGT_VFILTER, MSGL_DBG2, "\nDEBUG: CLEAR: %d %d %d %d\n\n", imgw, imgh, imgx, imgy); for( ypos=imgy ; (ypos < (imgy+imgh)) && (ypos < vf->priv->y2) ; ypos++ ) { memset( vf->priv->bitmap.y + (ypos*vf->priv->w) + imgx, 0, imgw ); memset( vf->priv->bitmap.a + (ypos*vf->priv->w) + imgx, 0, imgw ); memset( vf->priv->bitmap.oa + (ypos*vf->priv->w) + imgx, 0, imgw ); if(ypos%2) { memset( vf->priv->bitmap.u + ((ypos/2)*dmpi->stride[1]) + (imgx/2), 128, imgw/2 ); memset( vf->priv->bitmap.v + ((ypos/2)*dmpi->stride[2]) + (imgx/2), 128, imgw/2 ); } } // Recalculate area that contains graphics if( (imgx <= vf->priv->x1) && ( (imgw+imgx) >= vf->priv->x2) ) { if( (imgy <= vf->priv->y1) && ( (imgy+imgh) >= vf->priv->y1) ) vf->priv->y1 = imgy+imgh; if( (imgy <= vf->priv->y2) && ( (imgy+imgh) >= vf->priv->y2) ) vf->priv->y2 = imgy; } if( (imgy <= vf->priv->y1) && ( (imgy+imgh) >= vf->priv->y2) ) { if( (imgx <= vf->priv->x1) && ( (imgx+imgw) >= vf->priv->x1) ) vf->priv->x1 = imgx+imgw; if( (imgx <= vf->priv->x2) && ( (imgx+imgw) >= vf->priv->x2) ) vf->priv->x2 = imgx; } return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE); } for( buf_y=0 ; (buf_y < imgh) && (buf_y < (vf->priv->h-imgy)) ; buf_y++ ) { for( buf_x=0 ; (buf_x < (imgw*pxsz)) && (buf_x < ((vf->priv->w+imgx)*pxsz)) ; buf_x += pxsz ) { if(command & IS_RAWIMG) buf_pos = (buf_y * imgw * pxsz) + buf_x; pos = ((buf_y+imgy) * vf->priv->w) + ((buf_x/pxsz)+imgx); switch(command) { case IMG_RGBA32: red = buffer[buf_pos+0]; green = buffer[buf_pos+1]; blue = buffer[buf_pos+2]; alpha = buffer[buf_pos+3]; break; case IMG_ABGR32: alpha = buffer[buf_pos+0]; blue = buffer[buf_pos+1]; green = buffer[buf_pos+2]; red = buffer[buf_pos+3]; break; case IMG_RGB24: red = buffer[buf_pos+0]; green = buffer[buf_pos+1]; blue = buffer[buf_pos+2]; alpha = 0xFF; break; case IMG_BGR24: blue = buffer[buf_pos+0]; green = buffer[buf_pos+1]; red = buffer[buf_pos+2]; alpha = 0xFF; break; case CMD_ALPHA: vf->priv->bitmap.a[pos] = INRANGE((vf->priv->bitmap.oa[pos]+imgalpha),0,255); break; default: mp_msg(MSGT_VFILTER, MSGL_ERR, "vf_bmovl: Internal error!\n"); return FALSE; } if( command & IS_RAWIMG ) { vf->priv->bitmap.y[pos] = rgb2y(red,green,blue); vf->priv->bitmap.oa[pos] = alpha; vf->priv->bitmap.a[pos] = INRANGE((alpha+imgalpha),0,255); if((buf_y%2) && ((buf_x/pxsz)%2)) { pos = ( ((buf_y+imgy)/2) * dmpi->stride[1] ) + (((buf_x/pxsz)+imgx)/2); vf->priv->bitmap.u[pos] = rgb2u(red,green,blue); vf->priv->bitmap.v[pos] = rgb2v(red,green,blue); } } } // for buf_x } // for buf_y free (buffer); } else if(ready < 0) { mp_msg(MSGT_VFILTER, MSGL_WARN, "\nvf_bmovl: Error %d in fifo: %s\n\n", errno, strerror(errno)); } } if(vf->priv->hidden) return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE); if(vf->priv->opaque) { // Just copy buffer memory to screen for( ypos=vf->priv->y1 ; ypos < vf->priv->y2 ; ypos++ ) { fast_memcpy( dmpi->planes[0] + (ypos*dmpi->stride[0]) + vf->priv->x1, vf->priv->bitmap.y + (ypos*vf->priv->w) + vf->priv->x1, vf->priv->x2 - vf->priv->x1 ); if(ypos%2) { fast_memcpy( dmpi->planes[1] + ((ypos/2)*dmpi->stride[1]) + (vf->priv->x1/2), vf->priv->bitmap.u + (((ypos/2)*(vf->priv->w)/2)) + (vf->priv->x1/2), (vf->priv->x2 - vf->priv->x1)/2 ); fast_memcpy( dmpi->planes[2] + ((ypos/2)*dmpi->stride[2]) + (vf->priv->x1/2), vf->priv->bitmap.v + (((ypos/2)*(vf->priv->w)/2)) + (vf->priv->x1/2), (vf->priv->x2 - vf->priv->x1)/2 ); } } } else { // Blit the bitmap to the videoscreen, pixel for pixel for( ypos=vf->priv->y1 ; ypos < vf->priv->y2 ; ypos++ ) { for ( xpos=vf->priv->x1 ; xpos < vf->priv->x2 ; xpos++ ) { pos = (ypos * dmpi->stride[0]) + xpos; alpha = vf->priv->bitmap.a[pos]; if (alpha == 0) continue; // Completly transparent pixel if (alpha == 255) { // Opaque pixel dmpi->planes[0][pos] = vf->priv->bitmap.y[pos]; if ((ypos%2) && (xpos%2)) { pos = ( (ypos/2) * dmpi->stride[1] ) + (xpos/2); dmpi->planes[1][pos] = vf->priv->bitmap.u[pos]; dmpi->planes[2][pos] = vf->priv->bitmap.v[pos]; } } else { // Alphablended pixel dmpi->planes[0][pos] = ((255 - alpha) * (int)dmpi->planes[0][pos] + alpha * (int)vf->priv->bitmap.y[pos]) >> 8; if ((ypos%2) && (xpos%2)) { pos = ( (ypos/2) * dmpi->stride[1] ) + (xpos/2); dmpi->planes[1][pos] = ((255 - alpha) * (int)dmpi->planes[1][pos] + alpha * (int)vf->priv->bitmap.u[pos]) >> 8; dmpi->planes[2][pos] = ((255 - alpha) * (int)dmpi->planes[2][pos] + alpha * (int)vf->priv->bitmap.v[pos]) >> 8; } } } // for xpos } // for ypos } // if !opaque
static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts) { mp_image_t *dmpi; int ret; int w = (IMGFMT_IS_YUVP16(mpi->imgfmt) ? 2 : 1) * mpi->w; int chroma_width = (IMGFMT_IS_YUVP16(mpi->imgfmt) ? 2 : 1) * mpi->chroma_width; vf->priv->frame = (vf->priv->frame+1)%4; dmpi = vf_get_image(vf->next, mpi->imgfmt, MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_PRESERVE, mpi->width, mpi->height); ret = 0; // 0/0 1/1 2/2 2/3 3/0 switch (vf->priv->frame) { case 0: my_memcpy_pic(dmpi->planes[0]+dmpi->stride[0], mpi->planes[0]+mpi->stride[0], 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], 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], chroma_width, mpi->chroma_height/2, dmpi->stride[2]*2, mpi->stride[2]*2); } ret = vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE); /* Fallthrough */ case 1: case 2: memcpy_pic(dmpi->planes[0], mpi->planes[0], w, mpi->h, dmpi->stride[0], mpi->stride[0]); if (mpi->flags & MP_IMGFLAG_PLANAR) { memcpy_pic(dmpi->planes[1], mpi->planes[1], chroma_width, mpi->chroma_height, dmpi->stride[1], mpi->stride[1]); memcpy_pic(dmpi->planes[2], mpi->planes[2], chroma_width, mpi->chroma_height, dmpi->stride[2], mpi->stride[2]); } return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE) || ret; case 3: my_memcpy_pic(dmpi->planes[0]+dmpi->stride[0], mpi->planes[0]+mpi->stride[0], 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], 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], chroma_width, mpi->chroma_height/2, dmpi->stride[2]*2, mpi->stride[2]*2); } ret = vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE); my_memcpy_pic(dmpi->planes[0], mpi->planes[0], 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], chroma_width, mpi->chroma_height/2, dmpi->stride[1]*2, mpi->stride[1]*2); my_memcpy_pic(dmpi->planes[2], mpi->planes[2], chroma_width, mpi->chroma_height/2, dmpi->stride[2]*2, mpi->stride[2]*2); } return ret; } return 0; }
static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ mp_image_t *dmpi; int bpp=mpi->bpp/8; int w,h,x,y,shrink_by; // hope we'll get DR buffer: dmpi=vf_get_image(vf->next,mpi->imgfmt, MP_IMGTYPE_EXPORT, 0, mpi->w, mpi->h); dmpi->planes[0]=mpi->planes[0]; dmpi->planes[1]=mpi->planes[1]; dmpi->planes[2]=mpi->planes[2]; dmpi->stride[0]=mpi->stride[0]; dmpi->stride[1]=mpi->stride[1]; dmpi->stride[2]=mpi->stride[2]; dmpi->width=mpi->width; dmpi->height=mpi->height; if(++vf->priv->fno>0){ // ignore first 2 frames - they may be empty // Reset the crop area every reset_count frames, if reset_count is > 0 if(vf->priv->reset_count > 0 && vf->priv->fno > vf->priv->reset_count){ vf->priv->x1=mpi->w-1; vf->priv->y1=mpi->h-1; vf->priv->x2=0; vf->priv->y2=0; vf->priv->fno=1; } for(y=0;y<vf->priv->y1;y++){ if(checkline(mpi->planes[0]+mpi->stride[0]*y,bpp,mpi->w,bpp)>vf->priv->limit){ vf->priv->y1=y; break; } } for(y=mpi->h-1;y>vf->priv->y2;y--){ if(checkline(mpi->planes[0]+mpi->stride[0]*y,bpp,mpi->w,bpp)>vf->priv->limit){ vf->priv->y2=y; break; } } for(y=0;y<vf->priv->x1;y++){ if(checkline(mpi->planes[0]+bpp*y,mpi->stride[0],mpi->h,bpp)>vf->priv->limit){ vf->priv->x1=y; break; } } for(y=mpi->w-1;y>vf->priv->x2;y--){ if(checkline(mpi->planes[0]+bpp*y,mpi->stride[0],mpi->h,bpp)>vf->priv->limit){ vf->priv->x2=y; break; } } // round x and y (up), important for yuv colorspaces // make sure they stay rounded! x=(vf->priv->x1+1)&(~1); y=(vf->priv->y1+1)&(~1); w = vf->priv->x2 - x + 1; h = vf->priv->y2 - y + 1; // w and h must be divisible by 2 as well because of yuv // colorspace problems. if (vf->priv->round <= 1) vf->priv->round = 16; if (vf->priv->round % 2) vf->priv->round *= 2; shrink_by = w % vf->priv->round; w -= shrink_by; x += (shrink_by / 2 + 1) & ~1; shrink_by = h % vf->priv->round; h -= shrink_by; y += (shrink_by / 2 + 1) & ~1; mp_msg(MSGT_VFILTER, MSGL_INFO, MSGTR_MPCODECS_CropArea, vf->priv->x1,vf->priv->x2, vf->priv->y1,vf->priv->y2, w,h,x,y); } return vf_next_put_image(vf,dmpi, pts); }
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); }
static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts) { mp_image_t *dmpi; int ret = 0; int flags = mpi->fields; int state = vf->priv->state; dmpi = vf_get_image(vf->next, mpi->imgfmt, MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_PRESERVE, mpi->width, mpi->height); vf->priv->in++; if ((state == 0 && !(flags & MP_IMGFIELD_TOP_FIRST)) || (state == 1 && flags & MP_IMGFIELD_TOP_FIRST)) { mp_msg(MSGT_VFILTER, MSGL_WARN, "softpulldown: Unexpected field flags: state=%d top_field_first=%d repeat_first_field=%d\n", state, (flags & MP_IMGFIELD_TOP_FIRST) != 0, (flags & MP_IMGFIELD_REPEAT_FIRST) != 0); state ^= 1; } if (state == 0) { ret = vf_next_put_image(vf, mpi, MP_NOPTS_VALUE); vf->priv->out++; if (flags & MP_IMGFIELD_REPEAT_FIRST) { 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); } state=1; } } else { 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); vf->priv->out++; if (flags & MP_IMGFIELD_REPEAT_FIRST) { ret |= vf_next_put_image(vf, mpi, MP_NOPTS_VALUE); vf->priv->out++; state=0; } else { 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); } } } vf->priv->state = state; return ret; }
/* Filter handler */ static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts) { mp_image_t *dmpi; struct vf_priv_s *priv; int skip; priv = vf->priv; /* Print the 'I' if is a intra frame. The \n advance the current line so you got the * current file time (in second) and the frame number on the console ;-) */ if (priv->dump_iframe) { if (mpi->pict_type == 1) { mp_msg(MSGT_VFILTER, MSGL_INFO, "I!\n"); } } /* decide if frame must be shown */ if (priv->dump_iframe == 2) { /* Only key frame */ skip = mpi->pict_type == 1 ? 0 : 1; } else { /* Only 1 every frame_step */ skip = 0; if ((priv->frame_step != 0) && ((priv->frame_cur % priv->frame_step) != 0)) { skip = 1; } } /* Increment current frame */ ++priv->frame_cur; if (skip == 0) { /* Get image, export type (we don't modify tghe image) */ dmpi = vf_get_image(vf->next, mpi->imgfmt, MP_IMGTYPE_EXPORT, 0, mpi->w, mpi->h); /* Copy only the pointer ( MP_IMGTYPE_EXPORT ! ) */ dmpi->planes[0] = mpi->planes[0]; dmpi->planes[1] = mpi->planes[1]; dmpi->planes[2] = mpi->planes[2]; dmpi->stride[0] = mpi->stride[0]; dmpi->stride[1] = mpi->stride[1]; dmpi->stride[2] = mpi->stride[2]; dmpi->width = mpi->width; dmpi->height = mpi->height; /* Chain to next filter / output ... */ return vf_next_put_image(vf, dmpi, pts); } /* Skip the frame */ return 0; }
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; }
static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ int cw= mpi->w >> mpi->chroma_x_shift; int ch= mpi->h >> mpi->chroma_y_shift; int W = mpi->w, H = mpi->h; const unsigned char *prvp, *prvpp, *prvpn, *prvpnn, *prvppp, *prvp4p, *prvp4n; const unsigned char *srcp_saved; const unsigned char *srcp, *srcpp, *srcpn, *srcpnn, *srcppp, *srcp3p, *srcp3n, *srcp4p, *srcp4n; unsigned char *dstp, *dstp_saved; int src_pitch; int psrc_pitch; int dst_pitch; int x, y, z; int n = vf->priv->frame++; int val, hi, lo, w, h; double valf; int plane; int threshold = vf->priv->thresh; int order = vf->priv->order; int map = vf->priv->map; int sharp = vf->priv->sharp; int twoway = vf->priv->twoway; mp_image_t *dmpi, *pmpi; if(!vf->priv->do_deinterlace) return vf_next_put_image(vf, mpi, pts); dmpi=vf_get_image(vf->next,mpi->imgfmt, MP_IMGTYPE_IP, MP_IMGFLAG_ACCEPT_STRIDE, mpi->w,mpi->h); pmpi=vf_get_image(vf->next,mpi->imgfmt, MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, mpi->w,mpi->h); if(!dmpi) return 0; for (z=0; z<mpi->num_planes; z++) { if (z == 0) plane = PLANAR_Y; else if (z == 1) plane = PLANAR_U; else plane = PLANAR_V; h = plane == PLANAR_Y ? H : ch; w = plane == PLANAR_Y ? W : cw; srcp = srcp_saved = mpi->planes[z]; src_pitch = mpi->stride[z]; psrc_pitch = pmpi->stride[z]; dstp = dstp_saved = dmpi->planes[z]; dst_pitch = dmpi->stride[z]; srcp = srcp_saved + (1-order) * src_pitch; dstp = dstp_saved + (1-order) * dst_pitch; for (y=0; y<h; y+=2) { memcpy(dstp, srcp, w); srcp += 2*src_pitch; dstp += 2*dst_pitch; } // Copy through the lines that will be missed below. memcpy(dstp_saved + order*dst_pitch, srcp_saved + (1-order)*src_pitch, w); memcpy(dstp_saved + (2+order)*dst_pitch, srcp_saved + (3-order)*src_pitch, w); memcpy(dstp_saved + (h-2+order)*dst_pitch, srcp_saved + (h-1-order)*src_pitch, w); memcpy(dstp_saved + (h-4+order)*dst_pitch, srcp_saved + (h-3-order)*src_pitch, w); /* For the other field choose adaptively between using the previous field or the interpolant from the current field. */ prvp = pmpi->planes[z] + 5*psrc_pitch - (1-order)*psrc_pitch; prvpp = prvp - psrc_pitch; prvppp = prvp - 2*psrc_pitch; prvp4p = prvp - 4*psrc_pitch; prvpn = prvp + psrc_pitch; prvpnn = prvp + 2*psrc_pitch; prvp4n = prvp + 4*psrc_pitch; srcp = srcp_saved + 5*src_pitch - (1-order)*src_pitch; srcpp = srcp - src_pitch; srcppp = srcp - 2*src_pitch; srcp3p = srcp - 3*src_pitch; srcp4p = srcp - 4*src_pitch; srcpn = srcp + src_pitch; srcpnn = srcp + 2*src_pitch; srcp3n = srcp + 3*src_pitch; srcp4n = srcp + 4*src_pitch; dstp = dstp_saved + 5*dst_pitch - (1-order)*dst_pitch; for (y = 5 - (1-order); y <= h - 5 - (1-order); y+=2) { for (x = 0; x < w; x++) { if ((threshold == 0) || (n == 0) || (abs((int)prvp[x] - (int)srcp[x]) > threshold) || (abs((int)prvpp[x] - (int)srcpp[x]) > threshold) || (abs((int)prvpn[x] - (int)srcpn[x]) > threshold)) { if (map == 1) { int g = x & ~3; if (IsRGB(mpi) == 1) { dstp[g++] = 255; dstp[g++] = 255; dstp[g++] = 255; dstp[g] = 255; x = g; } else if (IsYUY2(mpi) == 1) { dstp[g++] = 235; dstp[g++] = 128; dstp[g++] = 235; dstp[g] = 128; x = g; } else { if (plane == PLANAR_Y) dstp[x] = 235; else dstp[x] = 128; } } else { if (IsRGB(mpi)) { hi = 255; lo = 0; } else if (IsYUY2(mpi)) { hi = (x & 1) ? 240 : 235; lo = 16; } else { hi = (plane == PLANAR_Y) ? 235 : 240; lo = 16; } if (sharp == 1) { if (twoway == 1) valf = + 0.526*((int)srcpp[x] + (int)srcpn[x]) + 0.170*((int)srcp[x] + (int)prvp[x]) - 0.116*((int)srcppp[x] + (int)srcpnn[x] + (int)prvppp[x] + (int)prvpnn[x]) - 0.026*((int)srcp3p[x] + (int)srcp3n[x]) + 0.031*((int)srcp4p[x] + (int)srcp4n[x] + (int)prvp4p[x] + (int)prvp4n[x]); else valf = + 0.526*((int)srcpp[x] + (int)srcpn[x]) + 0.170*((int)prvp[x]) - 0.116*((int)prvppp[x] + (int)prvpnn[x]) - 0.026*((int)srcp3p[x] + (int)srcp3n[x]) + 0.031*((int)prvp4p[x] + (int)prvp4p[x]); if (valf > hi) valf = hi; else if (valf < lo) valf = lo; dstp[x] = (int) valf; } else { if (twoway == 1) val = (8*((int)srcpp[x] + (int)srcpn[x]) + 2*((int)srcp[x] + (int)prvp[x]) - (int)(srcppp[x]) - (int)(srcpnn[x]) - (int)(prvppp[x]) - (int)(prvpnn[x])) >> 4; else val = (8*((int)srcpp[x] + (int)srcpn[x]) + 2*((int)prvp[x]) - (int)(prvppp[x]) - (int)(prvpnn[x])) >> 4; if (val > hi) val = hi; else if (val < lo) val = lo; dstp[x] = (int) val; } } } else { dstp[x] = srcp[x]; } } prvp += 2*psrc_pitch; prvpp += 2*psrc_pitch; prvppp += 2*psrc_pitch; prvpn += 2*psrc_pitch; prvpnn += 2*psrc_pitch; prvp4p += 2*psrc_pitch; prvp4n += 2*psrc_pitch; srcp += 2*src_pitch; srcpp += 2*src_pitch; srcppp += 2*src_pitch; srcp3p += 2*src_pitch; srcp4p += 2*src_pitch; srcpn += 2*src_pitch; srcpnn += 2*src_pitch; srcp3n += 2*src_pitch; srcp4n += 2*src_pitch; dstp += 2*dst_pitch; }
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); }