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 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;
00079 if (vf->next->draw_slice) vf->draw_slice=vf_next_draw_slice;
00080
00081
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
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];
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
00120 switch(fmt) {
00121 case IMGFMT_YV12:
00122 case IMGFMT_I420:
00123 case IMGFMT_IYUV:
00124 case IMGFMT_YVU9:
00125
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