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 #include "help_mp.h"
00027
00028 #include "img_format.h"
00029 #include "mp_image.h"
00030 #include "vf.h"
00031
00032 struct vf_priv_s {
00033 int x1,y1,x2,y2;
00034 int limit;
00035 int round;
00036 int reset_count;
00037 int fno;
00038 };
00039
00040 static int checkline(unsigned char* src,int stride,int len,int bpp){
00041 int total=0;
00042 int div=len;
00043 switch(bpp){
00044 case 1:
00045 while(--len>=0){
00046 total+=src[0]; src+=stride;
00047 }
00048 break;
00049 case 3:
00050 case 4:
00051 while(--len>=0){
00052 total+=src[0]+src[1]+src[2]; src+=stride;
00053 }
00054 div*=3;
00055 break;
00056 }
00057 total/=div;
00058
00059 return total;
00060 }
00061
00062
00063
00064 static int config(struct vf_instance *vf,
00065 int width, int height, int d_width, int d_height,
00066 unsigned int flags, unsigned int outfmt){
00067 vf->priv->x1=width - 1;
00068 vf->priv->y1=height - 1;
00069 vf->priv->x2=0;
00070 vf->priv->y2=0;
00071 vf->priv->fno=-2;
00072 return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
00073 }
00074
00075 static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
00076 mp_image_t *dmpi;
00077 int bpp=mpi->bpp/8;
00078 int w,h,x,y,shrink_by;
00079
00080
00081 dmpi=vf_get_image(vf->next,mpi->imgfmt,
00082 MP_IMGTYPE_EXPORT, 0,
00083 mpi->w, mpi->h);
00084
00085 dmpi->planes[0]=mpi->planes[0];
00086 dmpi->planes[1]=mpi->planes[1];
00087 dmpi->planes[2]=mpi->planes[2];
00088 dmpi->stride[0]=mpi->stride[0];
00089 dmpi->stride[1]=mpi->stride[1];
00090 dmpi->stride[2]=mpi->stride[2];
00091 dmpi->width=mpi->width;
00092 dmpi->height=mpi->height;
00093
00094 if(++vf->priv->fno>0){
00095
00096
00097 if(vf->priv->reset_count > 0 && vf->priv->fno > vf->priv->reset_count){
00098 vf->priv->x1=mpi->w-1;
00099 vf->priv->y1=mpi->h-1;
00100 vf->priv->x2=0;
00101 vf->priv->y2=0;
00102 vf->priv->fno=1;
00103 }
00104
00105 for(y=0;y<vf->priv->y1;y++){
00106 if(checkline(mpi->planes[0]+mpi->stride[0]*y,bpp,mpi->w,bpp)>vf->priv->limit){
00107 vf->priv->y1=y;
00108 break;
00109 }
00110 }
00111
00112 for(y=mpi->h-1;y>vf->priv->y2;y--){
00113 if(checkline(mpi->planes[0]+mpi->stride[0]*y,bpp,mpi->w,bpp)>vf->priv->limit){
00114 vf->priv->y2=y;
00115 break;
00116 }
00117 }
00118
00119 for(y=0;y<vf->priv->x1;y++){
00120 if(checkline(mpi->planes[0]+bpp*y,mpi->stride[0],mpi->h,bpp)>vf->priv->limit){
00121 vf->priv->x1=y;
00122 break;
00123 }
00124 }
00125
00126 for(y=mpi->w-1;y>vf->priv->x2;y--){
00127 if(checkline(mpi->planes[0]+bpp*y,mpi->stride[0],mpi->h,bpp)>vf->priv->limit){
00128 vf->priv->x2=y;
00129 break;
00130 }
00131 }
00132
00133
00134
00135 x=(vf->priv->x1+1)&(~1);
00136 y=(vf->priv->y1+1)&(~1);
00137
00138 w = vf->priv->x2 - x + 1;
00139 h = vf->priv->y2 - y + 1;
00140
00141
00142
00143 if (vf->priv->round <= 1)
00144 vf->priv->round = 16;
00145 if (vf->priv->round % 2)
00146 vf->priv->round *= 2;
00147
00148 shrink_by = w % vf->priv->round;
00149 w -= shrink_by;
00150 x += (shrink_by / 2 + 1) & ~1;
00151
00152 shrink_by = h % vf->priv->round;
00153 h -= shrink_by;
00154 y += (shrink_by / 2 + 1) & ~1;
00155
00156 mp_msg(MSGT_VFILTER, MSGL_INFO, MSGTR_MPCODECS_CropArea,
00157 vf->priv->x1,vf->priv->x2,
00158 vf->priv->y1,vf->priv->y2,
00159 w,h,x,y);
00160
00161
00162 }
00163
00164 return vf_next_put_image(vf,dmpi, pts);
00165 }
00166
00167 static int query_format(struct vf_instance *vf, unsigned int fmt) {
00168 switch(fmt) {
00169
00170 case IMGFMT_YV12:
00171 return vf_next_query_format(vf, fmt);
00172 }
00173 return 0;
00174 }
00175
00176
00177 static int vf_open(vf_instance_t *vf, char *args){
00178 vf->config=config;
00179 vf->put_image=put_image;
00180 vf->query_format=query_format;
00181 vf->priv=malloc(sizeof(struct vf_priv_s));
00182 vf->priv->limit=24;
00183 vf->priv->round = 0;
00184 vf->priv->reset_count = 0;
00185 if(args) sscanf(args, "%d:%d:%d",
00186 &vf->priv->limit,
00187 &vf->priv->round,
00188 &vf->priv->reset_count);
00189 return 1;
00190 }
00191
00192 const vf_info_t vf_info_cropdetect = {
00193 "autodetect crop size",
00194 "cropdetect",
00195 "A'rpi",
00196 "",
00197 vf_open,
00198 NULL
00199 };
00200
00201