static int reconfig(struct vf_instance *vf, struct mp_image_params *in, struct mp_image_params *out) { struct vf_priv_s *p = vf->priv; *out = *in; p->fmt_in = *in; if (reinit_vs(vf) < 0) return -1; const VSVideoInfo *vi = p->vsapi->getVideoInfo(p->out_node); out->w = vi->width; out->h = vi->height; out->imgfmt = mp_from_vs(vi->format->id); if (!out->imgfmt) { MP_FATAL(vf, "Unsupported output format.\n"); destroy_vs(vf); return -1; } struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(in->imgfmt); if (in->w % desc.align_x || in->h % desc.align_y) { MP_FATAL(vf, "VapourSynth does not allow unaligned/cropped video sizes.\n"); destroy_vs(vf); return -1; } return 0; }
void VdaMixer::adjust(VideoFormatData *data, const mp_image *mpi) { Q_ASSERT(data->imgfmt == IMGFMT_VDA); auto buffer = (CVPixelBufferRef)mpi->planes[3]; switch (CVPixelBufferGetPixelFormatType(buffer)) { case kCVPixelFormatType_422YpCbCr8: data->type = IMGFMT_UYVY; break; case kCVPixelFormatType_422YpCbCr8_yuvs: data->type = IMGFMT_YUYV; break; case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange: data->type = IMGFMT_NV12; break; case kCVPixelFormatType_420YpCbCr8Planar: data->type = IMGFMT_420P; break; default: _Error("Not supported format."); data->type = IMGFMT_NONE; } auto desc = mp_imgfmt_get_desc(data->type); if (CVPixelBufferIsPlanar(buffer)) { data->planes = CVPixelBufferGetPlaneCount(buffer); Q_ASSERT(data->planes == desc.num_planes); for (int i=0; i<data->planes; ++i) { data->alignedByteSize[i].rwidth() = CVPixelBufferGetBytesPerRowOfPlane(buffer, i); data->alignedByteSize[i].rheight() = CVPixelBufferGetHeightOfPlane(buffer, i); data->bpp += desc.bpp[i] >> (desc.xs[i] + desc.ys[i]); } } else {
static int config(struct vf_instance *vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt) { // calculate the missing parameters: if(vf->priv->crop_w<=0 || vf->priv->crop_w>width) vf->priv->crop_w=width; if(vf->priv->crop_h<=0 || vf->priv->crop_h>height) vf->priv->crop_h=height; if(vf->priv->crop_x<0) vf->priv->crop_x=(width-vf->priv->crop_w)/2; if(vf->priv->crop_y<0) vf->priv->crop_y=(height-vf->priv->crop_h)/2; // rounding: struct mp_imgfmt_desc fmt = mp_imgfmt_get_desc(outfmt); vf->priv->crop_x = MP_ALIGN_DOWN(vf->priv->crop_x, fmt.align_x); vf->priv->crop_y = MP_ALIGN_DOWN(vf->priv->crop_y, fmt.align_y); // check: if(vf->priv->crop_w+vf->priv->crop_x>width || vf->priv->crop_h+vf->priv->crop_y>height){ mp_tmsg(MSGT_VFILTER, MSGL_WARN, "[CROP] Bad position/width/height - cropped area outside of the original!\n"); return 0; } vf_rescale_dsize(&d_width, &d_height, width, height, vf->priv->crop_w, vf->priv->crop_h); return vf_next_config(vf,vf->priv->crop_w,vf->priv->crop_h,d_width,d_height,flags,outfmt); }
static int query_format(struct vf_instance *vf, unsigned int fmt) { struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(fmt); if (!(desc.flags & MP_IMGFLAG_BYTE_ALIGNED)) return 0; return vf_next_query_format(vf, fmt); }
static bool is_compatible(int fmt1, int fmt2) { struct mp_imgfmt_desc d1 = mp_imgfmt_get_desc(fmt1); struct mp_imgfmt_desc d2 = mp_imgfmt_get_desc(fmt2); if (d1.num_planes < d2.num_planes) return false; if (!(d1.flags & MP_IMGFLAG_BYTE_ALIGNED) || !(d2.flags & MP_IMGFLAG_BYTE_ALIGNED)) return false; for (int n = 0; n < MPMIN(d1.num_planes, d2.num_planes); n++) { if (d1.bytes[n] != d2.bytes[n]) return false; if (d1.xs[n] != d2.xs[n] || d1.ys[n] != d2.ys[n]) return false; } return true; }
static int config(struct vf_instance *vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int fmt) { struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(fmt); int a_w = MP_ALIGN_DOWN(width, desc.align_x); vf_rescale_dsize(&d_width, &d_height, width, height, a_w, height); return vf_next_config(vf, a_w, height, d_width, d_height, flags, fmt); }
static int query_format(struct vf_instance *vf, unsigned int fmt) { struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(fmt); if (!(desc.flags & MP_IMGFLAG_BYTE_ALIGNED)) return 0; if (desc.chroma_xs != desc.chroma_ys) return 0; if (desc.num_planes == 1 && (desc.chroma_xs || desc.chroma_ys)) return 0; return vf_next_query_format(vf, fmt); }
static int config(struct vf_instance *vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt) { vf->priv->exp_x = vf->priv->cfg_exp_x; vf->priv->exp_y = vf->priv->cfg_exp_y; vf->priv->exp_w = vf->priv->cfg_exp_w; vf->priv->exp_h = vf->priv->cfg_exp_h; // calculate the missing parameters: #if 0 if(vf->priv->exp_w<width) vf->priv->exp_w=width; if(vf->priv->exp_h<height) vf->priv->exp_h=height; #else if ( vf->priv->exp_w == -1 ) vf->priv->exp_w=width; else if (vf->priv->exp_w < -1 ) vf->priv->exp_w=width - vf->priv->exp_w; else if ( vf->priv->exp_w<width ) vf->priv->exp_w=width; if ( vf->priv->exp_h == -1 ) vf->priv->exp_h=height; else if ( vf->priv->exp_h < -1 ) vf->priv->exp_h=height - vf->priv->exp_h; else if( vf->priv->exp_h<height ) vf->priv->exp_h=height; #endif if (vf->priv->aspect) { float adjusted_aspect = vf->priv->aspect; adjusted_aspect *= ((double)width/height) / ((double)d_width/d_height); if (vf->priv->exp_h < vf->priv->exp_w / adjusted_aspect) { vf->priv->exp_h = vf->priv->exp_w / adjusted_aspect + 0.5; } else { vf->priv->exp_w = vf->priv->exp_h * adjusted_aspect + 0.5; } } if (vf->priv->round > 1) { // round up. vf->priv->exp_w = (1 + (vf->priv->exp_w - 1) / vf->priv->round) * vf->priv->round; vf->priv->exp_h = (1 + (vf->priv->exp_h - 1) / vf->priv->round) * vf->priv->round; } if(vf->priv->exp_x<0 || vf->priv->exp_x+width>vf->priv->exp_w) vf->priv->exp_x=(vf->priv->exp_w-width)/2; if(vf->priv->exp_y<0 || vf->priv->exp_y+height>vf->priv->exp_h) vf->priv->exp_y=(vf->priv->exp_h-height)/2; struct mp_imgfmt_desc fmt = mp_imgfmt_get_desc(outfmt); vf->priv->exp_x = MP_ALIGN_DOWN(vf->priv->exp_x, fmt.align_x); vf->priv->exp_y = MP_ALIGN_DOWN(vf->priv->exp_y, fmt.align_y); vf_rescale_dsize(&d_width, &d_height, width, height, vf->priv->exp_w, vf->priv->exp_h); return vf_next_config(vf,vf->priv->exp_w,vf->priv->exp_h,d_width,d_height,flags,outfmt); }
static int reconfig(struct vf_instance *vf, struct mp_image_params *p, int flags) { if (vf->priv->direction & 4) { if (p->w < p->h) vf->priv->direction &= 3; } if (vf->priv->direction & 4) return vf_next_reconfig(vf, p, flags); struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(p->imgfmt); int a_w = MP_ALIGN_DOWN(p->w, desc.align_x); int a_h = MP_ALIGN_DOWN(p->h, desc.align_y); vf_rescale_dsize(&p->d_w, &p->d_h, p->w, p->h, a_w, a_h); p->w = a_h; p->h = a_w; int t = p->d_w; p->d_w = p->d_h; p->d_h = t; return vf_next_reconfig(vf, p, flags); }
static int reconfig(struct vf_instance *vf, struct mp_image_params *in, struct mp_image_params *out) { int width = in->w, height = in->h; // calculate the missing parameters: if(vf->priv->crop_w<=0 || vf->priv->crop_w>width) vf->priv->crop_w=width; if(vf->priv->crop_h<=0 || vf->priv->crop_h>height) vf->priv->crop_h=height; if(vf->priv->crop_x<0) vf->priv->crop_x=(width-vf->priv->crop_w)/2; if(vf->priv->crop_y<0) vf->priv->crop_y=(height-vf->priv->crop_h)/2; // rounding: int orig_x = vf->priv->crop_x; int orig_y = vf->priv->crop_y; struct mp_imgfmt_desc fmt = mp_imgfmt_get_desc(in->imgfmt); if (fmt.flags & MP_IMGFLAG_HWACCEL) { vf->priv->crop_x = 0; vf->priv->crop_y = 0; } else { vf->priv->crop_x = MP_ALIGN_DOWN(vf->priv->crop_x, fmt.align_x); vf->priv->crop_y = MP_ALIGN_DOWN(vf->priv->crop_y, fmt.align_y); } if (vf->priv->crop_x != orig_x || vf->priv->crop_y != orig_y) { MP_WARN(vf, "Adjusting crop origin to %d/%d for pixel format alignment.\n", vf->priv->crop_x, vf->priv->crop_y); } // check: if(vf->priv->crop_w+vf->priv->crop_x>width || vf->priv->crop_h+vf->priv->crop_y>height){ MP_WARN(vf, "Bad position/width/height - cropped area outside of the original!\n"); return -1; } *out = *in; out->w = vf->priv->crop_w; out->h = vf->priv->crop_h; return 0; }
static int config(struct vf_instance *vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int fmt) { struct vf_priv_s *p = vf->priv; p->fmt_in = (struct mp_image_params){ .imgfmt = fmt, .w = width, .h = height, .d_w = d_width, .d_h = d_height, }; if (reinit_vs(vf) < 0) return 0; const VSVideoInfo *vi = p->vsapi->getVideoInfo(p->out_node); fmt = mp_from_vs(vi->format->id); if (!fmt) { MP_FATAL(vf, "Unsupported output format.\n"); destroy_vs(vf); return 0; } struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(fmt); if (width % desc.align_x || height % desc.align_y) { MP_FATAL(vf, "VapourSynth does not allow unaligned/cropped video sizes.\n"); destroy_vs(vf); return 0; } vf_rescale_dsize(&d_width, &d_height, width, height, vi->width, vi->height); return vf_next_config(vf, vi->width, vi->height, d_width, d_height, flags, fmt); }
static int reconfig(struct vf_instance *vf, struct mp_image_params *in, struct mp_image_params *out) { int width = in->w, height = in->h, d_width = in->d_w, d_height = in->d_h; unsigned int outfmt = in->imgfmt; unsigned int best = find_best_out(vf, outfmt); int round_w = 0, round_h = 0; if (!best) { MP_WARN(vf, "SwScale: no supported outfmt found :(\n"); return -1; } vf->next->query_format(vf->next, best); vf->priv->w = vf->priv->cfg_w; vf->priv->h = vf->priv->cfg_h; if (vf->priv->w <= -8) { vf->priv->w += 8; round_w = 1; } if (vf->priv->h <= -8) { vf->priv->h += 8; round_h = 1; } if (vf->priv->w < -3 || vf->priv->h < -3 || (vf->priv->w < -1 && vf->priv->h < -1)) { // TODO: establish a direct connection to the user's brain // and find out what the heck he thinks MPlayer should do // with this nonsense. MP_ERR(vf, "SwScale: EUSERBROKEN Check your parameters, they make no sense!\n"); return -1; } if (vf->priv->w == -1) vf->priv->w = width; if (vf->priv->w == 0) vf->priv->w = d_width; if (vf->priv->h == -1) vf->priv->h = height; if (vf->priv->h == 0) vf->priv->h = d_height; if (vf->priv->w == -3) vf->priv->w = vf->priv->h * width / height; if (vf->priv->w == -2) vf->priv->w = vf->priv->h * d_width / d_height; if (vf->priv->h == -3) vf->priv->h = vf->priv->w * height / width; if (vf->priv->h == -2) vf->priv->h = vf->priv->w * d_height / d_width; if (round_w) vf->priv->w = ((vf->priv->w + 8) / 16) * 16; if (round_h) vf->priv->h = ((vf->priv->h + 8) / 16) * 16; // check for upscaling, now that all parameters had been applied if (vf->priv->noup) { if ((vf->priv->w > width) + (vf->priv->h > height) >= vf->priv->noup) { vf->priv->w = width; vf->priv->h = height; } } MP_DBG(vf, "SwScale: scaling %dx%d %s to %dx%d %s \n", width, height, vo_format_name(outfmt), vf->priv->w, vf->priv->h, vo_format_name(best)); // Compute new d_width and d_height, preserving aspect // while ensuring that both are >= output size in pixels. if (vf->priv->h * d_width > vf->priv->w * d_height) { d_width = vf->priv->h * d_width / d_height; d_height = vf->priv->h; } else { d_height = vf->priv->w * d_height / d_width; d_width = vf->priv->w; } *out = *in; out->w = vf->priv->w; out->h = vf->priv->h; out->d_w = d_width; out->d_h = d_height; out->imgfmt = best; // Second-guess what libswscale is going to output and what not. // It depends what libswscale supports for in/output, and what makes sense. struct mp_imgfmt_desc s_fmt = mp_imgfmt_get_desc(in->imgfmt); struct mp_imgfmt_desc d_fmt = mp_imgfmt_get_desc(out->imgfmt); // keep colorspace settings if the data stays in yuv if (!(s_fmt.flags & MP_IMGFLAG_YUV) || !(d_fmt.flags & MP_IMGFLAG_YUV)) { out->colorspace = MP_CSP_AUTO; out->colorlevels = MP_CSP_LEVELS_AUTO; } mp_image_params_guess_csp(out); mp_sws_set_from_cmdline(vf->priv->sws, vf->chain->opts->vo.sws_opts); vf->priv->sws->flags |= vf->priv->v_chr_drop << SWS_SRC_V_CHR_DROP_SHIFT; vf->priv->sws->flags |= vf->priv->accurate_rnd * SWS_ACCURATE_RND; vf->priv->sws->src = *in; vf->priv->sws->dst = *out; if (mp_sws_reinit(vf->priv->sws) < 0) { // error... MP_WARN(vf, "Couldn't init libswscale for this setup\n"); return -1; } return 0; }
int8_t format_get_bytes(const format_t *fmt) { return mp_imgfmt_get_desc(fmt->mp_format).bytes[0]; }