• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

libavfilter/libmpcodecs/vf_rotate.c

Go to the documentation of this file.
00001 /*
00002  * This file is part of MPlayer.
00003  *
00004  * MPlayer is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation; either version 2 of the License, or
00007  * (at your option) any later version.
00008  *
00009  * MPlayer is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License along
00015  * with MPlayer; if not, write to the Free Software Foundation, Inc.,
00016  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
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 direction;
00033 };
00034 
00035 static void rotate(unsigned char* dst,unsigned char* src,int dststride,int srcstride,int w,int h,int bpp,int dir){
00036     int y;
00037     if(dir&1){
00038         src+=srcstride*(w-1);
00039         srcstride*=-1;
00040     }
00041     if(dir&2){
00042         dst+=dststride*(h-1);
00043         dststride*=-1;
00044     }
00045 
00046     for(y=0;y<h;y++){
00047         int x;
00048         switch(bpp){
00049         case 1:
00050             for(x=0;x<w;x++) dst[x]=src[y+x*srcstride];
00051             break;
00052         case 2:
00053             for(x=0;x<w;x++) *((short*)(dst+x*2))=*((short*)(src+y*2+x*srcstride));
00054             break;
00055         case 3:
00056             for(x=0;x<w;x++){
00057                 dst[x*3+0]=src[0+y*3+x*srcstride];
00058                 dst[x*3+1]=src[1+y*3+x*srcstride];
00059                 dst[x*3+2]=src[2+y*3+x*srcstride];
00060             }
00061             break;
00062         case 4:
00063             for(x=0;x<w;x++) *((int*)(dst+x*4))=*((int*)(src+y*4+x*srcstride));
00064         }
00065         dst+=dststride;
00066     }
00067 }
00068 
00069 //===========================================================================//
00070 
00071 static int config(struct vf_instance *vf,
00072         int width, int height, int d_width, int d_height,
00073         unsigned int flags, unsigned int outfmt){
00074     if (vf->priv->direction & 4) {
00075         if (width<height) vf->priv->direction&=3;
00076     }
00077     if (vf->priv->direction & 4){
00078         vf->put_image=vf_next_put_image; // passthru mode!
00079         if (vf->next->draw_slice) vf->draw_slice=vf_next_draw_slice;
00080 /* FIXME: this should be in an other procedure in vf.c; that should always check
00081      whether the filter after the passthrough one still (not)supports slices */
00082         return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
00083     }
00084     return vf_next_config(vf,height,width,d_height,d_width,flags,outfmt);
00085 }
00086 
00087 static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
00088     mp_image_t *dmpi;
00089 
00090     // hope we'll get DR buffer:
00091     dmpi=vf_get_image(vf->next,mpi->imgfmt,
00092         MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
00093         mpi->h, mpi->w);
00094 
00095     if(mpi->flags&MP_IMGFLAG_PLANAR){
00096         rotate(dmpi->planes[0],mpi->planes[0],
00097                dmpi->stride[0],mpi->stride[0],
00098                dmpi->w,dmpi->h,1,vf->priv->direction);
00099         rotate(dmpi->planes[1],mpi->planes[1],
00100                dmpi->stride[1],mpi->stride[1],
00101                dmpi->w>>mpi->chroma_x_shift,dmpi->h>>mpi->chroma_y_shift,1,vf->priv->direction);
00102         rotate(dmpi->planes[2],mpi->planes[2],
00103                dmpi->stride[2],mpi->stride[2],
00104                dmpi->w>>mpi->chroma_x_shift,dmpi->h>>mpi->chroma_y_shift,1,vf->priv->direction);
00105     } else {
00106         rotate(dmpi->planes[0],mpi->planes[0],
00107                dmpi->stride[0],mpi->stride[0],
00108                dmpi->w,dmpi->h,dmpi->bpp>>3,vf->priv->direction);
00109         dmpi->planes[1] = mpi->planes[1]; // passthrough rgb8 palette
00110     }
00111 
00112     return vf_next_put_image(vf,dmpi, pts);
00113 }
00114 
00115 //===========================================================================//
00116 
00117 static int query_format(struct vf_instance *vf, unsigned int fmt){
00118     if(IMGFMT_IS_RGB(fmt) || IMGFMT_IS_BGR(fmt)) return vf_next_query_format(vf, fmt);
00119     // we can support only symmetric (chroma_x_shift==chroma_y_shift) YUV formats:
00120     switch(fmt) {
00121         case IMGFMT_YV12:
00122         case IMGFMT_I420:
00123         case IMGFMT_IYUV:
00124         case IMGFMT_YVU9:
00125 //        case IMGFMT_IF09:
00126         case IMGFMT_Y8:
00127         case IMGFMT_Y800:
00128         case IMGFMT_444P:
00129             return vf_next_query_format(vf, fmt);
00130     }
00131     return 0;
00132 }
00133 
00134 static int vf_open(vf_instance_t *vf, char *args){
00135     vf->config=config;
00136     vf->put_image=put_image;
00137     vf->query_format=query_format;
00138     vf->priv=malloc(sizeof(struct vf_priv_s));
00139     vf->priv->direction=args?atoi(args):0;
00140     return 1;
00141 }
00142 
00143 const vf_info_t vf_info_rotate = {
00144     "rotate",
00145     "rotate",
00146     "A'rpi",
00147     "",
00148     vf_open,
00149     NULL
00150 };
00151 
00152 //===========================================================================//

Generated on Wed Apr 11 2012 07:31:36 for FFmpeg by  doxygen 1.7.1