1 /*
2  * This file is part of MPlayer.
3  *
4  * MPlayer is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * MPlayer is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <inttypes.h>
23 
24 #include "config.h"
25 #include "mp_msg.h"
26 
27 #include "img_format.h"
28 #include "mp_image.h"
29 #include "vf.h"
30 
31 //===========================================================================//
32 
33 static const unsigned int bgr_list[]={
34     IMGFMT_Y800,
35     IMGFMT_Y8,
36     IMGFMT_BGR8,
37     IMGFMT_RGB8,
38 
39     IMGFMT_YVU9,
40     IMGFMT_411P,
41     IMGFMT_YV12,
42     IMGFMT_I420,
43     IMGFMT_IYUV,
44     IMGFMT_422P,
45     IMGFMT_444P,
46 
47     IMGFMT_YUY2,
48     IMGFMT_BGR12,
49     IMGFMT_RGB12,
50     IMGFMT_BGR15,
51     IMGFMT_RGB15,
52     IMGFMT_BGR16,
53     IMGFMT_RGB16,
54 
55     IMGFMT_BGR32,
56     IMGFMT_RGB32,
57 
58 //    IMGFMT_BGR24,
59 //    IMGFMT_RGB24,
60     0
61 };
62 
find_best(struct vf_instance * vf)63 static unsigned int find_best(struct vf_instance *vf){
64     unsigned int best=0;
65     int ret;
66     const unsigned int* p=bgr_list;
67     while(*p){
68 	ret=vf->next->query_format(vf->next,*p);
69 	mp_msg(MSGT_VFILTER,MSGL_V,"[%s] query(%s) -> %d\n",vf->info->name,vo_format_name(*p),ret&3);
70 	if(ret&VFCAP_CSP_SUPPORTED_BY_HW){ best=*p; break;} // no conversion -> bingo!
71 	if(ret&VFCAP_CSP_SUPPORTED && !best) best=*p; // best with conversion
72 	++p;
73     }
74     return best;
75 }
76 
77 //===========================================================================//
78 
79 struct vf_priv_s {
80     unsigned int fmt;
81 };
82 
config(struct vf_instance * vf,int width,int height,int d_width,int d_height,unsigned int flags,unsigned int outfmt)83 static int config(struct vf_instance *vf,
84         int width, int height, int d_width, int d_height,
85 	unsigned int flags, unsigned int outfmt){
86     if (!vf->priv->fmt)
87 	vf->priv->fmt=find_best(vf);
88     if(!vf->priv->fmt){
89 	// no matching fmt, so force one...
90 	if(outfmt==IMGFMT_RGB8) vf->priv->fmt=IMGFMT_RGB32;
91 	else if(outfmt==IMGFMT_BGR8) vf->priv->fmt=IMGFMT_BGR32;
92 	else return 0;
93     }
94     return vf_next_config(vf,width,height,d_width,d_height,flags,vf->priv->fmt);
95 }
96 
97 static const int bittab[8]={128,64,32,16,8,4,2,1};
98 
convert(mp_image_t * mpi,mp_image_t * dmpi,int value0,int value1,int bpp)99 static void convert(mp_image_t *mpi, mp_image_t *dmpi, int value0, int value1,int bpp){
100     int y;
101     for(y=0;y<mpi->h;y++){
102 	unsigned char* src=mpi->planes[0]+mpi->stride[0]*y;
103 	switch(bpp){
104 	case 1: {
105 	    unsigned char* dst=dmpi->planes[0]+dmpi->stride[0]*y;
106 	    int x;
107 	    for(x=0;x<mpi->w;x++)
108 		dst[x]=(src[x>>3]&bittab[x&7]) ? value1 : value0;
109 	    break; }
110 	case 2: {
111 	    uint16_t* dst=(uint16_t*)(dmpi->planes[0]+dmpi->stride[0]*y);
112 	    int x;
113 	    for(x=0;x<mpi->w;x++)
114 		dst[x]=(src[x>>3]&bittab[x&7]) ? value1 : value0;
115 	    break; }
116 	case 4: {
117 	    uint32_t* dst=(uint32_t*)(dmpi->planes[0]+dmpi->stride[0]*y);
118 	    int x;
119 	    for(x=0;x<mpi->w;x++)
120 		dst[x]=(src[x>>3]&bittab[x&7]) ? value1 : value0;
121 	    break; }
122 	}
123     }
124 }
125 
put_image(struct vf_instance * vf,mp_image_t * mpi,double pts,double endpts)126 static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
127     mp_image_t *dmpi;
128 
129     // hope we'll get DR buffer:
130     dmpi=vf_get_image(vf->next,vf->priv->fmt,
131 	MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
132 	mpi->w, mpi->h);
133 
134     switch(dmpi->imgfmt){
135     case IMGFMT_Y800:
136     case IMGFMT_Y8:
137     case IMGFMT_BGR8:
138     case IMGFMT_RGB8:
139 	convert(mpi,dmpi,0,255,1);
140 	break;
141     case IMGFMT_YVU9:
142     case IMGFMT_411P:
143     case IMGFMT_YV12:
144     case IMGFMT_I420:
145     case IMGFMT_IYUV:
146     case IMGFMT_422P:
147     case IMGFMT_444P:
148 	convert(mpi,dmpi,0,255,1);
149 	memset(dmpi->planes[1],128,dmpi->stride[1]*dmpi->chroma_height);
150 	memset(dmpi->planes[2],128,dmpi->stride[2]*dmpi->chroma_height);
151 	break;
152     case IMGFMT_YUY2:
153 	convert(mpi,dmpi,0x8000,0x80ff,2);
154 	break;
155     case IMGFMT_BGR12:
156     case IMGFMT_RGB12:
157         convert(mpi,dmpi,0,0x0fff,2);
158         break;
159     case IMGFMT_BGR15:
160     case IMGFMT_RGB15:
161 	convert(mpi,dmpi,0,0x7fff,2);
162 	break;
163     case IMGFMT_BGR16:
164     case IMGFMT_RGB16:
165 	convert(mpi,dmpi,0,0xffff,2);
166 	break;
167     case IMGFMT_BGR32:
168     case IMGFMT_RGB32:
169 	convert(mpi,dmpi,0,0x00ffffff,4);
170 	break;
171     default:
172 	mp_msg(MSGT_VFILTER,MSGL_ERR,"Unhandled format: 0x%X\n",dmpi->imgfmt);
173 	return 0;
174     }
175 
176     return vf_next_put_image(vf,dmpi, pts, endpts);
177 }
178 
179 //===========================================================================//
180 
query_format(struct vf_instance * vf,unsigned int fmt)181 static int query_format(struct vf_instance *vf, unsigned int fmt){
182     int best;
183     if(fmt!=IMGFMT_RGB1 && fmt!=IMGFMT_BGR1) return 0;
184     best=find_best(vf);
185     if(!best) return 0; // no match
186     return vf->next->query_format(vf->next,best);
187 }
188 
vf_open(vf_instance_t * vf,char * args)189 static int vf_open(vf_instance_t *vf, char *args){
190     vf->config=config;
191     vf->put_image=put_image;
192     vf->query_format=query_format;
193     vf->priv=malloc(sizeof(struct vf_priv_s));
194     memset(vf->priv, 0, sizeof(struct vf_priv_s));
195     return 1;
196 }
197 
198 const vf_info_t vf_info_1bpp = {
199     "1bpp bitmap -> YUV/BGR 8/15/16/32 conversion",
200     "1bpp",
201     "A'rpi",
202     "",
203     vf_open,
204     NULL
205 };
206 
207 //===========================================================================//
208