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 };