Beispiel #1
0
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;
}
Beispiel #2
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 {
Beispiel #3
0
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);
}
Beispiel #4
0
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);
}
Beispiel #5
0
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;
}
Beispiel #6
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 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);
}
Beispiel #7
0
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);
}
Beispiel #8
0
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);
}
Beispiel #9
0
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);
}
Beispiel #10
0
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;
}
Beispiel #11
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);
}
Beispiel #12
0
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;
}
Beispiel #13
0
int8_t format_get_bytes(const format_t *fmt)
{
    return mp_imgfmt_get_desc(fmt->mp_format).bytes[0];
}