changeset 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 8ac4502b7b3d
children 7d6a854a5fe5
files libmpcodecs/vf.c libmpcodecs/vf.h libmpcodecs/vf_crop.c libmpcodecs/vf_expand.c libmpcodecs/vf_scale.c
diffstat 5 files changed, 93 insertions(+), 79 deletions(-) [+]
line wrap: on
line diff
--- a/libmpcodecs/vf.c	Tue May 20 17:06:00 2003 +0000
+++ b/libmpcodecs/vf.c	Tue May 20 17:42:33 2003 +0000
@@ -17,6 +17,8 @@
 #include "mp_image.h"
 #include "vf.h"
 
+#include "../libvo/fastmemcpy.h"
+
 extern vf_info_t vf_info_vo;
 extern vf_info_t vf_info_rectangle;
 #ifndef HAVE_NO_POSIX_SELECT
@@ -479,7 +481,25 @@
 }
 
 void vf_next_draw_slice(struct vf_instance_s* vf,unsigned char** src, int * stride,int w, int h, int x, int y){
-    vf->next->draw_slice(vf->next,src,stride,w,h,x,y);
+    if (vf->next->draw_slice) {
+	vf->next->draw_slice(vf->next,src,stride,w,h,x,y);
+	return;
+    }
+    if (!vf->dmpi) {
+	mp_msg(MSGT_VFILTER,MSGL_ERR,"draw_slice: dmpi not stored by vf_%s\n", vf->info->name);
+	return;
+    }
+    if (!(vf->dmpi->flags & MP_IMGFLAG_PLANAR)) {
+	memcpy_pic(vf->dmpi->planes[0]+y*vf->dmpi->stride[0]+vf->dmpi->bpp/8*x,
+	    src[0], vf->dmpi->bpp/8*w, h, vf->dmpi->stride[0], stride);
+	return;
+    }
+    memcpy_pic(vf->dmpi->planes[0]+y*vf->dmpi->stride[0]+x, src[0],
+	w, h, vf->dmpi->stride[0], stride[0]);
+    memcpy_pic(vf->dmpi->planes[1]+(y>>vf->dmpi->chroma_y_shift)*vf->dmpi->stride[1]+(x>>vf->dmpi->chroma_x_shift),
+	src[1], w>>vf->dmpi->chroma_x_shift, h>>vf->dmpi->chroma_y_shift, vf->dmpi->stride[1], stride[1]);
+    memcpy_pic(vf->dmpi->planes[2]+(y>>vf->dmpi->chroma_y_shift)*vf->dmpi->stride[2]+(x>>vf->dmpi->chroma_x_shift),
+	src[2], w>>vf->dmpi->chroma_x_shift, h>>vf->dmpi->chroma_y_shift, vf->dmpi->stride[2], stride[2]);
 }
 
 //============================================================================
--- a/libmpcodecs/vf.h	Tue May 20 17:06:00 2003 +0000
+++ b/libmpcodecs/vf.h	Tue May 20 17:42:33 2003 +0000
@@ -44,6 +44,7 @@
     // data:
     vf_image_context_t imgctx;
     struct vf_instance_s* next;
+    mp_image_t *dmpi;
     struct vf_priv_s* priv;
 } vf_instance_t;
 
--- a/libmpcodecs/vf_crop.c	Tue May 20 17:06:00 2003 +0000
+++ b/libmpcodecs/vf_crop.c	Tue May 20 17:42:33 2003 +0000
@@ -15,7 +15,6 @@
 static struct vf_priv_s {
     int crop_w,crop_h;
     int crop_x,crop_y;
-    mp_image_t *dmpi;
 } vf_priv_dflt = {
   -1,-1,
   -1,-1
@@ -71,7 +70,7 @@
 static int put_image(struct vf_instance_s* vf, mp_image_t *mpi){
     mp_image_t *dmpi;
     if (mpi->flags&MP_IMGFLAG_DRAW_CALLBACK)
-	return vf_next_put_image(vf,vf->priv->dmpi);
+	return vf_next_put_image(vf,vf->dmpi);
     dmpi=vf_get_image(vf->next,mpi->imgfmt,
 	MP_IMGTYPE_EXPORT, 0,
 	vf->priv->crop_w, vf->priv->crop_h);
@@ -96,11 +95,7 @@
 }
 
 static void start_slice(struct vf_instance_s* vf, mp_image_t *mpi){
-    if(!vf->next->draw_slice){
-	mpi->flags&=~MP_IMGFLAG_DRAW_CALLBACK;
-	return;
-    }
-    vf->priv->dmpi = vf_get_image(vf->next, mpi->imgfmt, mpi->type, mpi->flags,
+    vf->dmpi = vf_get_image(vf->next, mpi->imgfmt, mpi->type, mpi->flags,
 	vf->priv->crop_w, vf->priv->crop_h);
 }
 
@@ -108,7 +103,7 @@
         unsigned char** src, int* stride, int w,int h, int x, int y){
     unsigned char *src2[3];
     src2[0] = src[0];
-    if (vf->priv->dmpi->flags & MP_IMGFLAG_PLANAR) {
+    if (vf->dmpi->flags & MP_IMGFLAG_PLANAR) {
 	    src2[1] = src[1];
 	    src2[2] = src[2];
     }
@@ -116,9 +111,9 @@
     if ((x -= vf->priv->crop_x) < 0) {
 	x = -x;
 	src2[0] += x;
-	if (vf->priv->dmpi->flags & MP_IMGFLAG_PLANAR) {
-		src2[1] += x>>vf->priv->dmpi->chroma_x_shift;
-		src2[2] += x>>vf->priv->dmpi->chroma_x_shift;
+	if (vf->dmpi->flags & MP_IMGFLAG_PLANAR) {
+		src2[1] += x>>vf->dmpi->chroma_x_shift;
+		src2[2] += x>>vf->dmpi->chroma_x_shift;
 	}
 	w -= x;
 	x = 0;
@@ -126,9 +121,9 @@
     if ((y -= vf->priv->crop_y) < 0) {
 	y = -y;
 	src2[0] += y*stride[0];
-	if (vf->priv->dmpi->flags & MP_IMGFLAG_PLANAR) {
-		src2[1] += (y>>vf->priv->dmpi->chroma_y_shift)*stride[1];
-		src2[2] += (y>>vf->priv->dmpi->chroma_y_shift)*stride[2];
+	if (vf->dmpi->flags & MP_IMGFLAG_PLANAR) {
+		src2[1] += (y>>vf->dmpi->chroma_y_shift)*stride[1];
+		src2[2] += (y>>vf->dmpi->chroma_y_shift)*stride[2];
 	}
 	h -= y;
 	y = 0;
--- a/libmpcodecs/vf_expand.c	Tue May 20 17:06:00 2003 +0000
+++ b/libmpcodecs/vf_expand.c	Tue May 20 17:42:33 2003 +0000
@@ -26,7 +26,6 @@
 static struct vf_priv_s {
     int exp_w,exp_h;
     int exp_x,exp_y;
-    mp_image_t *dmpi;
     int osd;
     unsigned char* fb_ptr;
 } vf_priv_dflt = {
@@ -49,7 +48,7 @@
 static void remove_func_2(int x0,int y0, int w,int h){
     // TODO: let's cleanup the place
     //printf("OSD clear: %d;%d %dx%d  \n",x0,y0,w,h);
-    vf_mpi_clear(vf->priv->dmpi,x0,y0,w,h);
+    vf_mpi_clear(vf->dmpi,x0,y0,w,h);
 }
 
 static void remove_func(int x0,int y0, int w,int h){
@@ -77,7 +76,7 @@
 
 static void draw_func(int x0,int y0, int w,int h,unsigned char* src, unsigned char *srca, int stride){
     unsigned char* dst;
-    if(!vo_osd_changed_flag && vf->priv->dmpi->planes[0]==vf->priv->fb_ptr){
+    if(!vo_osd_changed_flag && vf->dmpi->planes[0]==vf->priv->fb_ptr){
 	// ok, enough to update the area inside the video, leave the black bands
 	// untouched!
 	if(x0<vf->priv->exp_x){
@@ -97,25 +96,25 @@
     }
     if(w<=0 || h<=0) return; // nothing to do...
 //    printf("OSD redraw: %d;%d %dx%d  \n",x0,y0,w,h);
-    dst=vf->priv->dmpi->planes[0]+
-			vf->priv->dmpi->stride[0]*y0+
-			(vf->priv->dmpi->bpp>>3)*x0;
-    switch(vf->priv->dmpi->imgfmt){
+    dst=vf->dmpi->planes[0]+
+			vf->dmpi->stride[0]*y0+
+			(vf->dmpi->bpp>>3)*x0;
+    switch(vf->dmpi->imgfmt){
     case IMGFMT_BGR15:
     case IMGFMT_RGB15:
-	vo_draw_alpha_rgb15(w,h,src,srca,stride,dst,vf->priv->dmpi->stride[0]);
+	vo_draw_alpha_rgb15(w,h,src,srca,stride,dst,vf->dmpi->stride[0]);
 	break;
     case IMGFMT_BGR16:
     case IMGFMT_RGB16:
-	vo_draw_alpha_rgb16(w,h,src,srca,stride,dst,vf->priv->dmpi->stride[0]);
+	vo_draw_alpha_rgb16(w,h,src,srca,stride,dst,vf->dmpi->stride[0]);
 	break;
     case IMGFMT_BGR24:
     case IMGFMT_RGB24:
-	vo_draw_alpha_rgb24(w,h,src,srca,stride,dst,vf->priv->dmpi->stride[0]);
+	vo_draw_alpha_rgb24(w,h,src,srca,stride,dst,vf->dmpi->stride[0]);
 	break;
     case IMGFMT_BGR32:
     case IMGFMT_RGB32:
-	vo_draw_alpha_rgb32(w,h,src,srca,stride,dst,vf->priv->dmpi->stride[0]);
+	vo_draw_alpha_rgb32(w,h,src,srca,stride,dst,vf->dmpi->stride[0]);
 	break;
     case IMGFMT_YV12:
     case IMGFMT_I420:
@@ -124,13 +123,13 @@
     case IMGFMT_IF09:
     case IMGFMT_Y800:
     case IMGFMT_Y8:
-	vo_draw_alpha_yv12(w,h,src,srca,stride,dst,vf->priv->dmpi->stride[0]);
+	vo_draw_alpha_yv12(w,h,src,srca,stride,dst,vf->dmpi->stride[0]);
 	break;
     case IMGFMT_YUY2:
-	vo_draw_alpha_yuy2(w,h,src,srca,stride,dst,vf->priv->dmpi->stride[0]);
+	vo_draw_alpha_yuy2(w,h,src,srca,stride,dst,vf->dmpi->stride[0]);
 	break;
     case IMGFMT_UYVY:
-	vo_draw_alpha_yuy2(w,h,src,srca,stride,dst+1,vf->priv->dmpi->stride[0]);
+	vo_draw_alpha_yuy2(w,h,src,srca,stride,dst+1,vf->dmpi->stride[0]);
 	break;
     }
 }
@@ -141,7 +140,7 @@
     if(vf->priv->exp_w!=w || vf->priv->exp_h!=h ||
 	vf->priv->exp_x || vf->priv->exp_y){
 	// yep, we're expanding image, not just copy.
-	if(vf->priv->dmpi->planes[0]!=vf->priv->fb_ptr){
+	if(vf->dmpi->planes[0]!=vf->priv->fb_ptr){
 	    // double buffering, so we need full clear :(
 	    remove_func(0,0,vf->priv->exp_w,vf->priv->exp_h);
 	} else {
@@ -152,8 +151,8 @@
     vo_draw_text(vf->priv->exp_w,vf->priv->exp_h,draw_func);
     // save buffer pointer for double buffering detection - yes, i know it's
     // ugly method, but note that codecs with DR support does the same...
-    if(vf->priv->dmpi)
-      vf->priv->fb_ptr=vf->priv->dmpi->planes[0];
+    if(vf->dmpi)
+      vf->priv->fb_ptr=vf->dmpi->planes[0];
 }
 
 #endif
@@ -205,37 +204,37 @@
     if(vf->priv->exp_w==mpi->width ||
        (mpi->flags&(MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_ACCEPT_WIDTH)) ){
 	// try full DR !
-	mpi->priv=vf->priv->dmpi=vf_get_image(vf->next,mpi->imgfmt,
+	mpi->priv=vf->dmpi=vf_get_image(vf->next,mpi->imgfmt,
 	    mpi->type, mpi->flags, 
             MAX(vf->priv->exp_w, mpi->width +vf->priv->exp_x), 
             MAX(vf->priv->exp_h, mpi->height+vf->priv->exp_y));
 #if 1
-	if((vf->priv->dmpi->flags & MP_IMGFLAG_DRAW_CALLBACK) &&
-	  !(vf->priv->dmpi->flags & MP_IMGFLAG_DIRECT)){
+	if((vf->dmpi->flags & MP_IMGFLAG_DRAW_CALLBACK) &&
+	  !(vf->dmpi->flags & MP_IMGFLAG_DIRECT)){
 	    printf("Full DR not possible, trying SLICES instead!\n");
 	    return;
 	}
 #endif
 	// set up mpi as a cropped-down image of dmpi:
 	if(mpi->flags&MP_IMGFLAG_PLANAR){
-	    mpi->planes[0]=vf->priv->dmpi->planes[0]+
-		vf->priv->exp_y*vf->priv->dmpi->stride[0]+vf->priv->exp_x;
-	    mpi->planes[1]=vf->priv->dmpi->planes[1]+
-		(vf->priv->exp_y>>mpi->chroma_y_shift)*vf->priv->dmpi->stride[1]+(vf->priv->exp_x>>mpi->chroma_x_shift);
-	    mpi->planes[2]=vf->priv->dmpi->planes[2]+
-		(vf->priv->exp_y>>mpi->chroma_y_shift)*vf->priv->dmpi->stride[2]+(vf->priv->exp_x>>mpi->chroma_x_shift);
-	    mpi->stride[1]=vf->priv->dmpi->stride[1];
-	    mpi->stride[2]=vf->priv->dmpi->stride[2];
+	    mpi->planes[0]=vf->dmpi->planes[0]+
+		vf->priv->exp_y*vf->dmpi->stride[0]+vf->priv->exp_x;
+	    mpi->planes[1]=vf->dmpi->planes[1]+
+		(vf->priv->exp_y>>mpi->chroma_y_shift)*vf->dmpi->stride[1]+(vf->priv->exp_x>>mpi->chroma_x_shift);
+	    mpi->planes[2]=vf->dmpi->planes[2]+
+		(vf->priv->exp_y>>mpi->chroma_y_shift)*vf->dmpi->stride[2]+(vf->priv->exp_x>>mpi->chroma_x_shift);
+	    mpi->stride[1]=vf->dmpi->stride[1];
+	    mpi->stride[2]=vf->dmpi->stride[2];
 	} else {
-	    mpi->planes[0]=vf->priv->dmpi->planes[0]+
-		vf->priv->exp_y*vf->priv->dmpi->stride[0]+
-		vf->priv->exp_x*(vf->priv->dmpi->bpp/8);
+	    mpi->planes[0]=vf->dmpi->planes[0]+
+		vf->priv->exp_y*vf->dmpi->stride[0]+
+		vf->priv->exp_x*(vf->dmpi->bpp/8);
 	}
-	mpi->stride[0]=vf->priv->dmpi->stride[0];
-	mpi->width=vf->priv->dmpi->width;
+	mpi->stride[0]=vf->dmpi->stride[0];
+	mpi->width=vf->dmpi->width;
 	mpi->flags|=MP_IMGFLAG_DIRECT;
 	mpi->flags&=~MP_IMGFLAG_DRAW_CALLBACK;
-//	vf->priv->dmpi->flags&=~MP_IMGFLAG_DRAW_CALLBACK;
+//	vf->dmpi->flags&=~MP_IMGFLAG_DRAW_CALLBACK;
     }
 }
 
@@ -247,12 +246,12 @@
     }
     // they want slices!!! allocate the buffer.
     if(!mpi->priv)
-	mpi->priv=vf->priv->dmpi=vf_get_image(vf->next,mpi->imgfmt,
+	mpi->priv=vf->dmpi=vf_get_image(vf->next,mpi->imgfmt,
 //	MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_PREFER_ALIGNED_STRIDE,
 	    mpi->type, mpi->flags, 
             MAX(vf->priv->exp_w, mpi->width +vf->priv->exp_x), 
             MAX(vf->priv->exp_h, mpi->height+vf->priv->exp_y));
-    if(!(vf->priv->dmpi->flags&MP_IMGFLAG_DRAW_CALLBACK))
+    if(!(vf->dmpi->flags&MP_IMGFLAG_DRAW_CALLBACK))
 	printf("WARNING! next filter doesn't support SLICES, get ready for sig11...\n"); // shouldn't happen.
 }
 
@@ -264,16 +263,16 @@
 
 static int put_image(struct vf_instance_s* vf, mp_image_t *mpi){
     if(mpi->flags&MP_IMGFLAG_DIRECT || mpi->flags&MP_IMGFLAG_DRAW_CALLBACK){
-	vf->priv->dmpi=mpi->priv;
-	if(!vf->priv->dmpi) { printf("Why do we get NULL \n"); return 0; }
+	vf->dmpi=mpi->priv;
+	if(!vf->dmpi) { printf("Why do we get NULL \n"); return 0; }
 	mpi->priv=NULL;
 	if(mpi->flags&MP_IMGFLAG_DRAW_CALLBACK){
 	    if(vf->priv->exp_y>0)
-		vf_next_draw_slice(vf, vf->priv->dmpi->planes, vf->priv->dmpi->stride,
-		vf->priv->dmpi->w,vf->priv->exp_y,0,0);
-	    if(vf->priv->exp_y+mpi->h<vf->priv->dmpi->h)
-		vf_next_draw_slice(vf, vf->priv->dmpi->planes, vf->priv->dmpi->stride,
-		vf->priv->dmpi->w,vf->priv->dmpi->h-(vf->priv->exp_y+mpi->h),
+		vf_next_draw_slice(vf, vf->dmpi->planes, vf->dmpi->stride,
+		vf->dmpi->w,vf->priv->exp_y,0,0);
+	    if(vf->priv->exp_y+mpi->h<vf->dmpi->h)
+		vf_next_draw_slice(vf, vf->dmpi->planes, vf->dmpi->stride,
+		vf->dmpi->w,vf->dmpi->h-(vf->priv->exp_y+mpi->h),
 		0,vf->priv->exp_y+mpi->h);
 	}
 #ifdef OSD_SUPPORT
@@ -281,40 +280,40 @@
 #endif
 	// we've used DR, so we're ready...
 	if(!(mpi->flags&MP_IMGFLAG_PLANAR))
-	    vf->priv->dmpi->planes[1] = mpi->planes[1]; // passthrough rgb8 palette
-	return vf_next_put_image(vf,vf->priv->dmpi);
+	    vf->dmpi->planes[1] = mpi->planes[1]; // passthrough rgb8 palette
+	return vf_next_put_image(vf,vf->dmpi);
     }
 
     // hope we'll get DR buffer:
-    vf->priv->dmpi=vf_get_image(vf->next,mpi->imgfmt,
+    vf->dmpi=vf_get_image(vf->next,mpi->imgfmt,
 	MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
 	vf->priv->exp_w, vf->priv->exp_h);
     
     // copy mpi->dmpi...
     if(mpi->flags&MP_IMGFLAG_PLANAR){
-	memcpy_pic(vf->priv->dmpi->planes[0]+
-	        vf->priv->exp_y*vf->priv->dmpi->stride[0]+vf->priv->exp_x,
+	memcpy_pic(vf->dmpi->planes[0]+
+	        vf->priv->exp_y*vf->dmpi->stride[0]+vf->priv->exp_x,
 		mpi->planes[0], mpi->w, mpi->h,
-		vf->priv->dmpi->stride[0],mpi->stride[0]);
-	memcpy_pic(vf->priv->dmpi->planes[1]+
-		(vf->priv->exp_y>>mpi->chroma_y_shift)*vf->priv->dmpi->stride[1]+(vf->priv->exp_x>>mpi->chroma_x_shift),
+		vf->dmpi->stride[0],mpi->stride[0]);
+	memcpy_pic(vf->dmpi->planes[1]+
+		(vf->priv->exp_y>>mpi->chroma_y_shift)*vf->dmpi->stride[1]+(vf->priv->exp_x>>mpi->chroma_x_shift),
 		mpi->planes[1], mpi->chroma_width, mpi->chroma_height,
-		vf->priv->dmpi->stride[1],mpi->stride[1]);
-	memcpy_pic(vf->priv->dmpi->planes[2]+
-		(vf->priv->exp_y>>mpi->chroma_y_shift)*vf->priv->dmpi->stride[2]+(vf->priv->exp_x>>mpi->chroma_x_shift),
+		vf->dmpi->stride[1],mpi->stride[1]);
+	memcpy_pic(vf->dmpi->planes[2]+
+		(vf->priv->exp_y>>mpi->chroma_y_shift)*vf->dmpi->stride[2]+(vf->priv->exp_x>>mpi->chroma_x_shift),
 		mpi->planes[2], mpi->chroma_width, mpi->chroma_height,
-		vf->priv->dmpi->stride[2],mpi->stride[2]);
+		vf->dmpi->stride[2],mpi->stride[2]);
     } else {
-	memcpy_pic(vf->priv->dmpi->planes[0]+
-	        vf->priv->exp_y*vf->priv->dmpi->stride[0]+vf->priv->exp_x*(vf->priv->dmpi->bpp/8),
-		mpi->planes[0], mpi->w*(vf->priv->dmpi->bpp/8), mpi->h,
-		vf->priv->dmpi->stride[0],mpi->stride[0]);
-	vf->priv->dmpi->planes[1] = mpi->planes[1]; // passthrough rgb8 palette
+	memcpy_pic(vf->dmpi->planes[0]+
+	        vf->priv->exp_y*vf->dmpi->stride[0]+vf->priv->exp_x*(vf->dmpi->bpp/8),
+		mpi->planes[0], mpi->w*(vf->dmpi->bpp/8), mpi->h,
+		vf->dmpi->stride[0],mpi->stride[0]);
+	vf->dmpi->planes[1] = mpi->planes[1]; // passthrough rgb8 palette
     }
 #ifdef OSD_SUPPORT
     if(vf->priv->osd) draw_osd(vf,mpi->w,mpi->h);
 #endif
-    return vf_next_put_image(vf,vf->priv->dmpi);
+    return vf_next_put_image(vf,vf->dmpi);
 }
 
 //===========================================================================//
--- a/libmpcodecs/vf_scale.c	Tue May 20 17:06:00 2003 +0000
+++ b/libmpcodecs/vf_scale.c	Tue May 20 17:42:33 2003 +0000
@@ -24,7 +24,6 @@
     unsigned int fmt;
     struct SwsContext *ctx;
     unsigned char* palette;
-    mp_image_t *dmpi;
 } vf_priv_dflt = {
   -1,-1,
   0,
@@ -228,7 +227,7 @@
 //    printf("start_slice called! flag=%d\n",mpi->flags&MP_IMGFLAG_DRAW_CALLBACK);
     if(!(mpi->flags&MP_IMGFLAG_DRAW_CALLBACK)) return; // shouldn't happen
     // they want slices!!! allocate the buffer.
-    mpi->priv=vf->priv->dmpi=vf_get_image(vf->next,vf->priv->fmt,
+    mpi->priv=vf->dmpi=vf_get_image(vf->next,vf->priv->fmt,
 //	mpi->type, mpi->flags & (~MP_IMGFLAG_DRAW_CALLBACK),
 	MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_PREFER_ALIGNED_STRIDE,
 	vf->priv->w, vf->priv->h);
@@ -236,7 +235,7 @@
 
 static void draw_slice(struct vf_instance_s* vf,
         unsigned char** src, int* stride, int w,int h, int x, int y){
-    mp_image_t *dmpi=vf->priv->dmpi;
+    mp_image_t *dmpi=vf->dmpi;
     if(!dmpi){
 	mp_msg(MSGT_VFILTER,MSGL_FATAL,"vf_scale: draw_slice() called with dmpi=NULL (no get_image??)\n");
 	return;