00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #include <stdio.h>
00053 #include <stdlib.h>
00054 #include <string.h>
00055
00056 #include "config.h"
00057 #include "mp_msg.h"
00058 #include "help_mp.h"
00059 #include "cpudetect.h"
00060
00061 #include "img_format.h"
00062 #include "mp_image.h"
00063 #include "vf.h"
00064
00065 #include "libvo/fastmemcpy.h"
00066
00067
00068 struct vf_priv_s {
00069
00070
00071 int xtile;
00072 int ytile;
00073
00074 int xytile;
00075
00076 int start;
00077
00078 int delta;
00079
00080
00081
00082
00083 int frame_cur;
00084 };
00085
00086
00087 static int config(struct vf_instance *vf,
00088 int width, int height, int d_width, int d_height,
00089 unsigned int flags, unsigned int outfmt){
00090
00091 struct vf_priv_s *priv;
00092 int xw;
00093 int yh;
00094
00095
00096 priv = vf->priv;
00097 xw = priv->start * 2 +
00098 priv->xtile * width +
00099 (priv->xtile - 1) * priv->delta;
00100 yh = priv->start * 2 +
00101 priv->ytile * height +
00102 (priv->ytile - 1) * priv->delta;
00103
00104 mp_msg(MSGT_VFILTER,MSGL_V,"vf_tile:config size set to %d * %d\n", xw, yh);
00105
00106 return vf_next_config(vf, xw, yh, xw, yh, flags, outfmt);
00107 }
00108
00109
00110 static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
00111 {
00112 mp_image_t *dmpi;
00113 struct vf_priv_s *priv;
00114 int t;
00115 int xw;
00116 int yh;
00117 int xi;
00118 int yi;
00119 int by;
00120 int dw;
00121
00122
00123 priv = vf->priv;
00124 xw = priv->start * 2 +
00125 priv->xtile * mpi->w +
00126 (priv->xtile - 1) * priv->delta;
00127 yh = priv->start * 2 +
00128 priv->ytile * mpi->h+
00129 (priv->ytile - 1) * priv->delta;
00130
00131
00132 dmpi=vf_get_image(vf->next, mpi->imgfmt,
00133 MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE,
00134 xw, yh);
00135
00136
00137 if (mpi->flags & MP_IMGFLAG_PLANAR) {
00138 by = 1;
00139 dw = mpi->w;
00140 }
00141 else {
00142 by = (mpi->bpp + 7) / 8;
00143 dw = mpi->w * by;
00144 }
00145
00146 t = priv->frame_cur % priv->xytile;
00147
00148
00149
00150
00151
00152
00153 xi = priv->start + (mpi->w + priv->delta) * (t % priv->xtile);
00154 yi = priv->start + (mpi->h + priv->delta) * (t / priv->xtile);
00155
00156
00157 memcpy_pic( dmpi->planes[0] + xi * by + yi * dmpi->stride[0],
00158 mpi->planes[0],
00159 dw,
00160 mpi->h,
00161 dmpi->stride[0],
00162 mpi->stride[0]);
00163
00164 if (mpi->flags & MP_IMGFLAG_PLANAR) {
00165
00166 memcpy_pic( dmpi->planes[1] + (xi >> mpi->chroma_x_shift) + (yi >> mpi->chroma_y_shift) * dmpi->stride[1],
00167 mpi->planes[1],
00168 mpi->chroma_width,
00169 mpi->chroma_height,
00170 dmpi->stride[1],
00171 mpi->stride[1]);
00172 memcpy_pic( dmpi->planes[2] + (xi >> mpi->chroma_x_shift) + (yi >> mpi->chroma_y_shift) * dmpi->stride[2],
00173 mpi->planes[2],
00174 mpi->chroma_width,
00175 mpi->chroma_height,
00176 dmpi->stride[2],
00177 mpi->stride[2]);
00178 }
00179
00180
00181 ++priv->frame_cur;
00182
00183 if (t == priv->xytile - 1) {
00184
00185 dmpi->width = xw;
00186 dmpi->height = yh;
00187 return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
00188 }
00189 else {
00190
00191 return 0;
00192 }
00193 }
00194
00195 static void uninit(struct vf_instance *vf)
00196 {
00197
00198 free(vf->priv);
00199 }
00200
00201
00202 static int query_format(struct vf_instance *vf, unsigned int fmt)
00203 {
00204 switch (fmt) {
00205
00206 case IMGFMT_RGB12:
00207 case IMGFMT_RGB15:
00208 case IMGFMT_RGB16:
00209 case IMGFMT_RGB24:
00210 case IMGFMT_RGB32:
00211
00212 case IMGFMT_BGR12:
00213 case IMGFMT_BGR15:
00214 case IMGFMT_BGR16:
00215 case IMGFMT_BGR24:
00216 case IMGFMT_BGR32:
00217
00218 case IMGFMT_444P:
00219 case IMGFMT_422P:
00220 case IMGFMT_411P:
00221 case IMGFMT_YUY2:
00222 case IMGFMT_YV12:
00223 case IMGFMT_I420:
00224 case IMGFMT_YVU9:
00225 case IMGFMT_IF09:
00226 case IMGFMT_IYUV:
00227 return vf_next_query_format(vf, fmt);
00228 }
00229 return 0;
00230 }
00231
00232
00233
00234
00235
00236
00237
00238 static int parse_int(char **s, int *rt, int def_val)
00239 {
00240
00241 int t = 0;
00242
00243 if (**s) {
00244
00245 t = strtol( *s, s, 0 );
00246
00247
00248 if (t < 0) {
00249 t = def_val;
00250 }
00251
00252 if (**s == ':') {
00253
00254 ++(*s);
00255 }
00256 else if (**s != '\0') {
00257
00258 return 1;
00259 }
00260 }
00261 else {
00262 t = def_val;
00263 }
00264
00265 *rt = t;
00266 return 0;
00267
00268 }
00269
00270
00271 static int vf_open(vf_instance_t *vf, char *args)
00272 {
00273 struct vf_priv_s *p;
00274 int er;
00275
00276 vf->put_image = put_image;
00277 vf->query_format = query_format;
00278 vf->config = config;
00279 vf->uninit = uninit;
00280 vf->default_reqs = VFCAP_ACCEPT_STRIDE;
00281
00282 vf->priv = p = calloc(1, sizeof(struct vf_priv_s));
00283 if (p == NULL) {
00284 return 0;
00285 }
00286
00287 if (args == NULL) {
00288
00289 args = "";
00290 }
00291
00292 er = parse_int( &args, &p->xtile, 5 );
00293 er |= parse_int( &args, &p->ytile, 5 );
00294 er |= parse_int( &args, &p->xytile, 0 );
00295 er |= parse_int( &args, &p->start, 2 );
00296 er |= parse_int( &args, &p->delta, 4 );
00297
00298
00299 if (er) {
00300 mp_msg(MSGT_VFILTER, MSGL_ERR, MSGTR_MPCODECS_ErrorParsingArgument);
00301 return 0;
00302 }
00303
00304 if ((p->xytile <= 0) || (p->xytile > p->xtile * p->ytile)) {
00305 p->xytile = p->xtile * p->ytile;
00306 }
00307
00308
00309 if ( mp_msg_test(MSGT_VFILTER,MSGL_V) ) {
00310 printf("vf_tile: tiling %d * %d, output every %d frames\n",
00311 p->xtile,
00312 p->ytile,
00313 p->xytile);
00314 printf("vf_tile: start pixel %d, delta pixel %d\n",
00315 p->start,
00316 p->delta);
00317
00318
00319 }
00320 return 1;
00321 }
00322
00323 const vf_info_t vf_info_tile = {
00324 "Make a single image tiling x/y images",
00325 "tile",
00326 "Daniele Forghieri",
00327 "",
00328 vf_open,
00329 NULL
00330 };