comparison libmpcodecs/vf_expand.c @ 10140:30cad6ad9dbc

fix segfaults with slices. support slice rendering into a filter even when the following filter/vo doesn't support slices. also use unified vf->dmpi rather than having vf->priv->dmpi duplicated in every filter.
author rfelker
date Tue, 20 May 2003 17:42:33 +0000
parents f9222b8a5166
children 87043624b0d8
comparison
equal deleted inserted replaced
10139:8ac4502b7b3d 10140:30cad6ad9dbc
24 #define MAX(a,b) ((a) > (b) ? (a) : (b)) 24 #define MAX(a,b) ((a) > (b) ? (a) : (b))
25 25
26 static struct vf_priv_s { 26 static struct vf_priv_s {
27 int exp_w,exp_h; 27 int exp_w,exp_h;
28 int exp_x,exp_y; 28 int exp_x,exp_y;
29 mp_image_t *dmpi;
30 int osd; 29 int osd;
31 unsigned char* fb_ptr; 30 unsigned char* fb_ptr;
32 } vf_priv_dflt = { 31 } vf_priv_dflt = {
33 -1,-1, 32 -1,-1,
34 -1,-1, 33 -1,-1,
47 static int orig_w,orig_h; 46 static int orig_w,orig_h;
48 47
49 static void remove_func_2(int x0,int y0, int w,int h){ 48 static void remove_func_2(int x0,int y0, int w,int h){
50 // TODO: let's cleanup the place 49 // TODO: let's cleanup the place
51 //printf("OSD clear: %d;%d %dx%d \n",x0,y0,w,h); 50 //printf("OSD clear: %d;%d %dx%d \n",x0,y0,w,h);
52 vf_mpi_clear(vf->priv->dmpi,x0,y0,w,h); 51 vf_mpi_clear(vf->dmpi,x0,y0,w,h);
53 } 52 }
54 53
55 static void remove_func(int x0,int y0, int w,int h){ 54 static void remove_func(int x0,int y0, int w,int h){
56 if(!vo_osd_changed_flag) return; 55 if(!vo_osd_changed_flag) return;
57 // split it to 4 parts: 56 // split it to 4 parts:
75 // TODO clear left and right side of the image if needed 74 // TODO clear left and right side of the image if needed
76 } 75 }
77 76
78 static void draw_func(int x0,int y0, int w,int h,unsigned char* src, unsigned char *srca, int stride){ 77 static void draw_func(int x0,int y0, int w,int h,unsigned char* src, unsigned char *srca, int stride){
79 unsigned char* dst; 78 unsigned char* dst;
80 if(!vo_osd_changed_flag && vf->priv->dmpi->planes[0]==vf->priv->fb_ptr){ 79 if(!vo_osd_changed_flag && vf->dmpi->planes[0]==vf->priv->fb_ptr){
81 // ok, enough to update the area inside the video, leave the black bands 80 // ok, enough to update the area inside the video, leave the black bands
82 // untouched! 81 // untouched!
83 if(x0<vf->priv->exp_x){ 82 if(x0<vf->priv->exp_x){
84 int tmp=vf->priv->exp_x-x0; 83 int tmp=vf->priv->exp_x-x0;
85 w-=tmp; src+=tmp; srca+=tmp; x0+=tmp; 84 w-=tmp; src+=tmp; srca+=tmp; x0+=tmp;
95 h=vf->priv->exp_y+orig_h-y0; 94 h=vf->priv->exp_y+orig_h-y0;
96 } 95 }
97 } 96 }
98 if(w<=0 || h<=0) return; // nothing to do... 97 if(w<=0 || h<=0) return; // nothing to do...
99 // printf("OSD redraw: %d;%d %dx%d \n",x0,y0,w,h); 98 // printf("OSD redraw: %d;%d %dx%d \n",x0,y0,w,h);
100 dst=vf->priv->dmpi->planes[0]+ 99 dst=vf->dmpi->planes[0]+
101 vf->priv->dmpi->stride[0]*y0+ 100 vf->dmpi->stride[0]*y0+
102 (vf->priv->dmpi->bpp>>3)*x0; 101 (vf->dmpi->bpp>>3)*x0;
103 switch(vf->priv->dmpi->imgfmt){ 102 switch(vf->dmpi->imgfmt){
104 case IMGFMT_BGR15: 103 case IMGFMT_BGR15:
105 case IMGFMT_RGB15: 104 case IMGFMT_RGB15:
106 vo_draw_alpha_rgb15(w,h,src,srca,stride,dst,vf->priv->dmpi->stride[0]); 105 vo_draw_alpha_rgb15(w,h,src,srca,stride,dst,vf->dmpi->stride[0]);
107 break; 106 break;
108 case IMGFMT_BGR16: 107 case IMGFMT_BGR16:
109 case IMGFMT_RGB16: 108 case IMGFMT_RGB16:
110 vo_draw_alpha_rgb16(w,h,src,srca,stride,dst,vf->priv->dmpi->stride[0]); 109 vo_draw_alpha_rgb16(w,h,src,srca,stride,dst,vf->dmpi->stride[0]);
111 break; 110 break;
112 case IMGFMT_BGR24: 111 case IMGFMT_BGR24:
113 case IMGFMT_RGB24: 112 case IMGFMT_RGB24:
114 vo_draw_alpha_rgb24(w,h,src,srca,stride,dst,vf->priv->dmpi->stride[0]); 113 vo_draw_alpha_rgb24(w,h,src,srca,stride,dst,vf->dmpi->stride[0]);
115 break; 114 break;
116 case IMGFMT_BGR32: 115 case IMGFMT_BGR32:
117 case IMGFMT_RGB32: 116 case IMGFMT_RGB32:
118 vo_draw_alpha_rgb32(w,h,src,srca,stride,dst,vf->priv->dmpi->stride[0]); 117 vo_draw_alpha_rgb32(w,h,src,srca,stride,dst,vf->dmpi->stride[0]);
119 break; 118 break;
120 case IMGFMT_YV12: 119 case IMGFMT_YV12:
121 case IMGFMT_I420: 120 case IMGFMT_I420:
122 case IMGFMT_IYUV: 121 case IMGFMT_IYUV:
123 case IMGFMT_YVU9: 122 case IMGFMT_YVU9:
124 case IMGFMT_IF09: 123 case IMGFMT_IF09:
125 case IMGFMT_Y800: 124 case IMGFMT_Y800:
126 case IMGFMT_Y8: 125 case IMGFMT_Y8:
127 vo_draw_alpha_yv12(w,h,src,srca,stride,dst,vf->priv->dmpi->stride[0]); 126 vo_draw_alpha_yv12(w,h,src,srca,stride,dst,vf->dmpi->stride[0]);
128 break; 127 break;
129 case IMGFMT_YUY2: 128 case IMGFMT_YUY2:
130 vo_draw_alpha_yuy2(w,h,src,srca,stride,dst,vf->priv->dmpi->stride[0]); 129 vo_draw_alpha_yuy2(w,h,src,srca,stride,dst,vf->dmpi->stride[0]);
131 break; 130 break;
132 case IMGFMT_UYVY: 131 case IMGFMT_UYVY:
133 vo_draw_alpha_yuy2(w,h,src,srca,stride,dst+1,vf->priv->dmpi->stride[0]); 132 vo_draw_alpha_yuy2(w,h,src,srca,stride,dst+1,vf->dmpi->stride[0]);
134 break; 133 break;
135 } 134 }
136 } 135 }
137 136
138 static void draw_osd(struct vf_instance_s* vf_,int w,int h){ 137 static void draw_osd(struct vf_instance_s* vf_,int w,int h){
139 vf=vf_;orig_w=w;orig_h=h; 138 vf=vf_;orig_w=w;orig_h=h;
140 // printf("======================================\n"); 139 // printf("======================================\n");
141 if(vf->priv->exp_w!=w || vf->priv->exp_h!=h || 140 if(vf->priv->exp_w!=w || vf->priv->exp_h!=h ||
142 vf->priv->exp_x || vf->priv->exp_y){ 141 vf->priv->exp_x || vf->priv->exp_y){
143 // yep, we're expanding image, not just copy. 142 // yep, we're expanding image, not just copy.
144 if(vf->priv->dmpi->planes[0]!=vf->priv->fb_ptr){ 143 if(vf->dmpi->planes[0]!=vf->priv->fb_ptr){
145 // double buffering, so we need full clear :( 144 // double buffering, so we need full clear :(
146 remove_func(0,0,vf->priv->exp_w,vf->priv->exp_h); 145 remove_func(0,0,vf->priv->exp_w,vf->priv->exp_h);
147 } else { 146 } else {
148 // partial clear: 147 // partial clear:
149 vo_remove_text(vf->priv->exp_w,vf->priv->exp_h,remove_func); 148 vo_remove_text(vf->priv->exp_w,vf->priv->exp_h,remove_func);
150 } 149 }
151 } 150 }
152 vo_draw_text(vf->priv->exp_w,vf->priv->exp_h,draw_func); 151 vo_draw_text(vf->priv->exp_w,vf->priv->exp_h,draw_func);
153 // save buffer pointer for double buffering detection - yes, i know it's 152 // save buffer pointer for double buffering detection - yes, i know it's
154 // ugly method, but note that codecs with DR support does the same... 153 // ugly method, but note that codecs with DR support does the same...
155 if(vf->priv->dmpi) 154 if(vf->dmpi)
156 vf->priv->fb_ptr=vf->priv->dmpi->planes[0]; 155 vf->priv->fb_ptr=vf->dmpi->planes[0];
157 } 156 }
158 157
159 #endif 158 #endif
160 //===========================================================================// 159 //===========================================================================//
161 160
203 } 202 }
204 #endif 203 #endif
205 if(vf->priv->exp_w==mpi->width || 204 if(vf->priv->exp_w==mpi->width ||
206 (mpi->flags&(MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_ACCEPT_WIDTH)) ){ 205 (mpi->flags&(MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_ACCEPT_WIDTH)) ){
207 // try full DR ! 206 // try full DR !
208 mpi->priv=vf->priv->dmpi=vf_get_image(vf->next,mpi->imgfmt, 207 mpi->priv=vf->dmpi=vf_get_image(vf->next,mpi->imgfmt,
209 mpi->type, mpi->flags, 208 mpi->type, mpi->flags,
210 MAX(vf->priv->exp_w, mpi->width +vf->priv->exp_x), 209 MAX(vf->priv->exp_w, mpi->width +vf->priv->exp_x),
211 MAX(vf->priv->exp_h, mpi->height+vf->priv->exp_y)); 210 MAX(vf->priv->exp_h, mpi->height+vf->priv->exp_y));
212 #if 1 211 #if 1
213 if((vf->priv->dmpi->flags & MP_IMGFLAG_DRAW_CALLBACK) && 212 if((vf->dmpi->flags & MP_IMGFLAG_DRAW_CALLBACK) &&
214 !(vf->priv->dmpi->flags & MP_IMGFLAG_DIRECT)){ 213 !(vf->dmpi->flags & MP_IMGFLAG_DIRECT)){
215 printf("Full DR not possible, trying SLICES instead!\n"); 214 printf("Full DR not possible, trying SLICES instead!\n");
216 return; 215 return;
217 } 216 }
218 #endif 217 #endif
219 // set up mpi as a cropped-down image of dmpi: 218 // set up mpi as a cropped-down image of dmpi:
220 if(mpi->flags&MP_IMGFLAG_PLANAR){ 219 if(mpi->flags&MP_IMGFLAG_PLANAR){
221 mpi->planes[0]=vf->priv->dmpi->planes[0]+ 220 mpi->planes[0]=vf->dmpi->planes[0]+
222 vf->priv->exp_y*vf->priv->dmpi->stride[0]+vf->priv->exp_x; 221 vf->priv->exp_y*vf->dmpi->stride[0]+vf->priv->exp_x;
223 mpi->planes[1]=vf->priv->dmpi->planes[1]+ 222 mpi->planes[1]=vf->dmpi->planes[1]+
224 (vf->priv->exp_y>>mpi->chroma_y_shift)*vf->priv->dmpi->stride[1]+(vf->priv->exp_x>>mpi->chroma_x_shift); 223 (vf->priv->exp_y>>mpi->chroma_y_shift)*vf->dmpi->stride[1]+(vf->priv->exp_x>>mpi->chroma_x_shift);
225 mpi->planes[2]=vf->priv->dmpi->planes[2]+ 224 mpi->planes[2]=vf->dmpi->planes[2]+
226 (vf->priv->exp_y>>mpi->chroma_y_shift)*vf->priv->dmpi->stride[2]+(vf->priv->exp_x>>mpi->chroma_x_shift); 225 (vf->priv->exp_y>>mpi->chroma_y_shift)*vf->dmpi->stride[2]+(vf->priv->exp_x>>mpi->chroma_x_shift);
227 mpi->stride[1]=vf->priv->dmpi->stride[1]; 226 mpi->stride[1]=vf->dmpi->stride[1];
228 mpi->stride[2]=vf->priv->dmpi->stride[2]; 227 mpi->stride[2]=vf->dmpi->stride[2];
229 } else { 228 } else {
230 mpi->planes[0]=vf->priv->dmpi->planes[0]+ 229 mpi->planes[0]=vf->dmpi->planes[0]+
231 vf->priv->exp_y*vf->priv->dmpi->stride[0]+ 230 vf->priv->exp_y*vf->dmpi->stride[0]+
232 vf->priv->exp_x*(vf->priv->dmpi->bpp/8); 231 vf->priv->exp_x*(vf->dmpi->bpp/8);
233 } 232 }
234 mpi->stride[0]=vf->priv->dmpi->stride[0]; 233 mpi->stride[0]=vf->dmpi->stride[0];
235 mpi->width=vf->priv->dmpi->width; 234 mpi->width=vf->dmpi->width;
236 mpi->flags|=MP_IMGFLAG_DIRECT; 235 mpi->flags|=MP_IMGFLAG_DIRECT;
237 mpi->flags&=~MP_IMGFLAG_DRAW_CALLBACK; 236 mpi->flags&=~MP_IMGFLAG_DRAW_CALLBACK;
238 // vf->priv->dmpi->flags&=~MP_IMGFLAG_DRAW_CALLBACK; 237 // vf->dmpi->flags&=~MP_IMGFLAG_DRAW_CALLBACK;
239 } 238 }
240 } 239 }
241 240
242 static void start_slice(struct vf_instance_s* vf, mp_image_t *mpi){ 241 static void start_slice(struct vf_instance_s* vf, mp_image_t *mpi){
243 // printf("start_slice called! flag=%d\n",mpi->flags&MP_IMGFLAG_DRAW_CALLBACK); 242 // printf("start_slice called! flag=%d\n",mpi->flags&MP_IMGFLAG_DRAW_CALLBACK);
245 mpi->flags&=~MP_IMGFLAG_DRAW_CALLBACK; 244 mpi->flags&=~MP_IMGFLAG_DRAW_CALLBACK;
246 return; 245 return;
247 } 246 }
248 // they want slices!!! allocate the buffer. 247 // they want slices!!! allocate the buffer.
249 if(!mpi->priv) 248 if(!mpi->priv)
250 mpi->priv=vf->priv->dmpi=vf_get_image(vf->next,mpi->imgfmt, 249 mpi->priv=vf->dmpi=vf_get_image(vf->next,mpi->imgfmt,
251 // MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_PREFER_ALIGNED_STRIDE, 250 // MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_PREFER_ALIGNED_STRIDE,
252 mpi->type, mpi->flags, 251 mpi->type, mpi->flags,
253 MAX(vf->priv->exp_w, mpi->width +vf->priv->exp_x), 252 MAX(vf->priv->exp_w, mpi->width +vf->priv->exp_x),
254 MAX(vf->priv->exp_h, mpi->height+vf->priv->exp_y)); 253 MAX(vf->priv->exp_h, mpi->height+vf->priv->exp_y));
255 if(!(vf->priv->dmpi->flags&MP_IMGFLAG_DRAW_CALLBACK)) 254 if(!(vf->dmpi->flags&MP_IMGFLAG_DRAW_CALLBACK))
256 printf("WARNING! next filter doesn't support SLICES, get ready for sig11...\n"); // shouldn't happen. 255 printf("WARNING! next filter doesn't support SLICES, get ready for sig11...\n"); // shouldn't happen.
257 } 256 }
258 257
259 static void draw_slice(struct vf_instance_s* vf, 258 static void draw_slice(struct vf_instance_s* vf,
260 unsigned char** src, int* stride, int w,int h, int x, int y){ 259 unsigned char** src, int* stride, int w,int h, int x, int y){
262 vf_next_draw_slice(vf,src,stride,w,h,x+vf->priv->exp_x,y+vf->priv->exp_y); 261 vf_next_draw_slice(vf,src,stride,w,h,x+vf->priv->exp_x,y+vf->priv->exp_y);
263 } 262 }
264 263
265 static int put_image(struct vf_instance_s* vf, mp_image_t *mpi){ 264 static int put_image(struct vf_instance_s* vf, mp_image_t *mpi){
266 if(mpi->flags&MP_IMGFLAG_DIRECT || mpi->flags&MP_IMGFLAG_DRAW_CALLBACK){ 265 if(mpi->flags&MP_IMGFLAG_DIRECT || mpi->flags&MP_IMGFLAG_DRAW_CALLBACK){
267 vf->priv->dmpi=mpi->priv; 266 vf->dmpi=mpi->priv;
268 if(!vf->priv->dmpi) { printf("Why do we get NULL \n"); return 0; } 267 if(!vf->dmpi) { printf("Why do we get NULL \n"); return 0; }
269 mpi->priv=NULL; 268 mpi->priv=NULL;
270 if(mpi->flags&MP_IMGFLAG_DRAW_CALLBACK){ 269 if(mpi->flags&MP_IMGFLAG_DRAW_CALLBACK){
271 if(vf->priv->exp_y>0) 270 if(vf->priv->exp_y>0)
272 vf_next_draw_slice(vf, vf->priv->dmpi->planes, vf->priv->dmpi->stride, 271 vf_next_draw_slice(vf, vf->dmpi->planes, vf->dmpi->stride,
273 vf->priv->dmpi->w,vf->priv->exp_y,0,0); 272 vf->dmpi->w,vf->priv->exp_y,0,0);
274 if(vf->priv->exp_y+mpi->h<vf->priv->dmpi->h) 273 if(vf->priv->exp_y+mpi->h<vf->dmpi->h)
275 vf_next_draw_slice(vf, vf->priv->dmpi->planes, vf->priv->dmpi->stride, 274 vf_next_draw_slice(vf, vf->dmpi->planes, vf->dmpi->stride,
276 vf->priv->dmpi->w,vf->priv->dmpi->h-(vf->priv->exp_y+mpi->h), 275 vf->dmpi->w,vf->dmpi->h-(vf->priv->exp_y+mpi->h),
277 0,vf->priv->exp_y+mpi->h); 276 0,vf->priv->exp_y+mpi->h);
278 } 277 }
279 #ifdef OSD_SUPPORT 278 #ifdef OSD_SUPPORT
280 if(vf->priv->osd) draw_osd(vf,mpi->w,mpi->h); 279 if(vf->priv->osd) draw_osd(vf,mpi->w,mpi->h);
281 #endif 280 #endif
282 // we've used DR, so we're ready... 281 // we've used DR, so we're ready...
283 if(!(mpi->flags&MP_IMGFLAG_PLANAR)) 282 if(!(mpi->flags&MP_IMGFLAG_PLANAR))
284 vf->priv->dmpi->planes[1] = mpi->planes[1]; // passthrough rgb8 palette 283 vf->dmpi->planes[1] = mpi->planes[1]; // passthrough rgb8 palette
285 return vf_next_put_image(vf,vf->priv->dmpi); 284 return vf_next_put_image(vf,vf->dmpi);
286 } 285 }
287 286
288 // hope we'll get DR buffer: 287 // hope we'll get DR buffer:
289 vf->priv->dmpi=vf_get_image(vf->next,mpi->imgfmt, 288 vf->dmpi=vf_get_image(vf->next,mpi->imgfmt,
290 MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, 289 MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
291 vf->priv->exp_w, vf->priv->exp_h); 290 vf->priv->exp_w, vf->priv->exp_h);
292 291
293 // copy mpi->dmpi... 292 // copy mpi->dmpi...
294 if(mpi->flags&MP_IMGFLAG_PLANAR){ 293 if(mpi->flags&MP_IMGFLAG_PLANAR){
295 memcpy_pic(vf->priv->dmpi->planes[0]+ 294 memcpy_pic(vf->dmpi->planes[0]+
296 vf->priv->exp_y*vf->priv->dmpi->stride[0]+vf->priv->exp_x, 295 vf->priv->exp_y*vf->dmpi->stride[0]+vf->priv->exp_x,
297 mpi->planes[0], mpi->w, mpi->h, 296 mpi->planes[0], mpi->w, mpi->h,
298 vf->priv->dmpi->stride[0],mpi->stride[0]); 297 vf->dmpi->stride[0],mpi->stride[0]);
299 memcpy_pic(vf->priv->dmpi->planes[1]+ 298 memcpy_pic(vf->dmpi->planes[1]+
300 (vf->priv->exp_y>>mpi->chroma_y_shift)*vf->priv->dmpi->stride[1]+(vf->priv->exp_x>>mpi->chroma_x_shift), 299 (vf->priv->exp_y>>mpi->chroma_y_shift)*vf->dmpi->stride[1]+(vf->priv->exp_x>>mpi->chroma_x_shift),
301 mpi->planes[1], mpi->chroma_width, mpi->chroma_height, 300 mpi->planes[1], mpi->chroma_width, mpi->chroma_height,
302 vf->priv->dmpi->stride[1],mpi->stride[1]); 301 vf->dmpi->stride[1],mpi->stride[1]);
303 memcpy_pic(vf->priv->dmpi->planes[2]+ 302 memcpy_pic(vf->dmpi->planes[2]+
304 (vf->priv->exp_y>>mpi->chroma_y_shift)*vf->priv->dmpi->stride[2]+(vf->priv->exp_x>>mpi->chroma_x_shift), 303 (vf->priv->exp_y>>mpi->chroma_y_shift)*vf->dmpi->stride[2]+(vf->priv->exp_x>>mpi->chroma_x_shift),
305 mpi->planes[2], mpi->chroma_width, mpi->chroma_height, 304 mpi->planes[2], mpi->chroma_width, mpi->chroma_height,
306 vf->priv->dmpi->stride[2],mpi->stride[2]); 305 vf->dmpi->stride[2],mpi->stride[2]);
307 } else { 306 } else {
308 memcpy_pic(vf->priv->dmpi->planes[0]+ 307 memcpy_pic(vf->dmpi->planes[0]+
309 vf->priv->exp_y*vf->priv->dmpi->stride[0]+vf->priv->exp_x*(vf->priv->dmpi->bpp/8), 308 vf->priv->exp_y*vf->dmpi->stride[0]+vf->priv->exp_x*(vf->dmpi->bpp/8),
310 mpi->planes[0], mpi->w*(vf->priv->dmpi->bpp/8), mpi->h, 309 mpi->planes[0], mpi->w*(vf->dmpi->bpp/8), mpi->h,
311 vf->priv->dmpi->stride[0],mpi->stride[0]); 310 vf->dmpi->stride[0],mpi->stride[0]);
312 vf->priv->dmpi->planes[1] = mpi->planes[1]; // passthrough rgb8 palette 311 vf->dmpi->planes[1] = mpi->planes[1]; // passthrough rgb8 palette
313 } 312 }
314 #ifdef OSD_SUPPORT 313 #ifdef OSD_SUPPORT
315 if(vf->priv->osd) draw_osd(vf,mpi->w,mpi->h); 314 if(vf->priv->osd) draw_osd(vf,mpi->w,mpi->h);
316 #endif 315 #endif
317 return vf_next_put_image(vf,vf->priv->dmpi); 316 return vf_next_put_image(vf,vf->dmpi);
318 } 317 }
319 318
320 //===========================================================================// 319 //===========================================================================//
321 320
322 static int control(struct vf_instance_s* vf, int request, void* data){ 321 static int control(struct vf_instance_s* vf, int request, void* data){