00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <stdio.h>
00020 #include <stdlib.h>
00021 #include <string.h>
00022 #include <inttypes.h>
00023
00024 #include "config.h"
00025 #include "mp_msg.h"
00026
00027 #include "img_format.h"
00028 #include "mp_image.h"
00029 #include "vf.h"
00030
00031 struct vf_priv_s {
00032 int w, h;
00033 int method;
00034 int round;
00035 float aspect;
00036 };
00037
00038 static int config(struct vf_instance *vf,
00039 int width, int height, int d_width, int d_height,
00040 unsigned int flags, unsigned int outfmt)
00041 {
00042 if (vf->priv->aspect < 0.001) {
00043 if (vf->priv->w == 0) vf->priv->w = d_width;
00044 if (vf->priv->h == 0) vf->priv->h = d_height;
00045 if (vf->priv->w == -1) vf->priv->w = width;
00046 if (vf->priv->h == -1) vf->priv->h = height;
00047 if (vf->priv->w == -2) vf->priv->w = vf->priv->h * (double)d_width / d_height;
00048 if (vf->priv->w == -3) vf->priv->w = vf->priv->h * (double)width / height;
00049 if (vf->priv->h == -2) vf->priv->h = vf->priv->w * (double)d_height / d_width;
00050 if (vf->priv->h == -3) vf->priv->h = vf->priv->w * (double)height / width;
00051 if (vf->priv->method > -1) {
00052 double aspect = (vf->priv->method & 2) ? ((double)height / width) : ((double)d_height / d_width);
00053 if ((vf->priv->h > vf->priv->w * aspect) ^ (vf->priv->method & 1)) {
00054 vf->priv->h = vf->priv->w * aspect;
00055 } else {
00056 vf->priv->w = vf->priv->h / aspect;
00057 }
00058 }
00059 if (vf->priv->round > 1) {
00060 vf->priv->w += (vf->priv->round - 1 - (vf->priv->w - 1) % vf->priv->round);
00061 vf->priv->h += (vf->priv->round - 1 - (vf->priv->h - 1) % vf->priv->round);
00062 }
00063 d_width = vf->priv->w;
00064 d_height = vf->priv->h;
00065 } else {
00066 if (vf->priv->aspect * height > width) {
00067 d_width = height * vf->priv->aspect + .5;
00068 d_height = height;
00069 } else {
00070 d_height = width / vf->priv->aspect + .5;
00071 d_width = width;
00072 }
00073 }
00074 return vf_next_config(vf, width, height, d_width, d_height, flags, outfmt);
00075 }
00076
00077 static void uninit(vf_instance_t *vf) {
00078 free(vf->priv);
00079 vf->priv = NULL;
00080 }
00081
00082 static int vf_open(vf_instance_t *vf, char *args)
00083 {
00084 vf->config = config;
00085 vf->draw_slice = vf_next_draw_slice;
00086 vf->uninit = uninit;
00087
00088 vf->priv = calloc(sizeof(struct vf_priv_s), 1);
00089 vf->priv->aspect = 0.;
00090 vf->priv->w = -1;
00091 vf->priv->h = -1;
00092 vf->priv->method = -1;
00093 vf->priv->round = 1;
00094 if (args) {
00095 if (strchr(args, '/')) {
00096 int w, h;
00097 sscanf(args, "%d/%d", &w, &h);
00098 vf->priv->aspect = (float)w/h;
00099 } else if (strchr(args, '.')) {
00100 sscanf(args, "%f", &vf->priv->aspect);
00101 } else {
00102 sscanf(args, "%d:%d:%d:%d", &vf->priv->w, &vf->priv->h, &vf->priv->method, &vf->priv->round);
00103 }
00104 }
00105 if ((vf->priv->aspect < 0.) || (vf->priv->w < -3) || (vf->priv->h < -3) ||
00106 ((vf->priv->w < -1) && (vf->priv->h < -1)) ||
00107 (vf->priv->method < -1) || (vf->priv->method > 3) ||
00108 (vf->priv->round < 0)) {
00109 mp_msg(MSGT_VFILTER, MSGL_ERR, "[dsize] Illegal value(s): aspect: %f w: %d h: %d aspect_method: %d round: %d\n", vf->priv->aspect, vf->priv->w, vf->priv->h, vf->priv->method, vf->priv->round);
00110 free(vf->priv); vf->priv = NULL;
00111 return -1;
00112 }
00113 return 1;
00114 }
00115
00116 const vf_info_t vf_info_dsize = {
00117 "reset displaysize/aspect",
00118 "dsize",
00119 "Rich Felker",
00120 "",
00121 vf_open,
00122 NULL
00123 };