aboutsummaryrefslogtreecommitdiffhomepage
path: root/libmpcodecs
diff options
context:
space:
mode:
Diffstat (limited to 'libmpcodecs')
-rw-r--r--libmpcodecs/vf_expand.c129
1 files changed, 125 insertions, 4 deletions
diff --git a/libmpcodecs/vf_expand.c b/libmpcodecs/vf_expand.c
index 3c5eb2904f..abf5c62457 100644
--- a/libmpcodecs/vf_expand.c
+++ b/libmpcodecs/vf_expand.c
@@ -1,3 +1,5 @@
+//#define OSD_SUPPORT
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -5,18 +7,106 @@
#include "../config.h"
#include "../mp_msg.h"
+#include "img_format.h"
#include "mp_image.h"
#include "vf.h"
#include "../libvo/fastmemcpy.h"
+#ifdef OSD_SUPPORT
+#include "../libvo/sub.h"
+#include "../libvo/osd.h"
+#endif
+
struct vf_priv_s {
int exp_w,exp_h;
int exp_x,exp_y;
mp_image_t *dmpi;
+ int osd;
};
//===========================================================================//
+#ifdef OSD_SUPPORT
+
+static struct vf_instance_s* vf=NULL; // fixme (needs sub.c changes)
+static int orig_w,orig_h;
+
+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);
+}
+
+static void remove_func(int x0,int y0, int w,int h){
+ if(!vo_osd_changed_flag) return;
+ // split it to 4 parts:
+ if(y0<vf->priv->exp_y){
+ // it has parts above the image:
+ int y=y0+h;
+ if(y>vf->priv->exp_y) y=vf->priv->exp_y;
+ remove_func_2(x0,y0,w,y-y0);
+ if(y0+h<=vf->priv->exp_y) return;
+ h-=y-y0;y0=y;
+ }
+ if(y0+h>vf->priv->exp_y+orig_h){
+ // it has parts under the image:
+ int y=y0;
+ if(y<vf->priv->exp_y+orig_h) y=vf->priv->exp_y+orig_h;
+ remove_func_2(x0,y,w,y0+h-y);
+ if(y0>=vf->priv->exp_y+orig_h) return;
+ h=y-y0;
+ }
+ if(x0>=vf->priv->exp_x || x0+w<=vf->priv->exp_x+orig_w) return;
+ // TODO clear left and right side of the image if needed
+}
+
+static void draw_func(int x0,int y0, int w,int h,unsigned char* src, unsigned char *srca, int stride){
+ unsigned char* dst=vf->priv->dmpi->planes[0]+
+ vf->priv->dmpi->stride[0]*y0+
+ (vf->priv->dmpi->bpp>>3)*x0;
+ if(!vo_osd_changed_flag) return;
+ switch(vf->priv->dmpi->imgfmt){
+ case IMGFMT_BGR15:
+ case IMGFMT_RGB15:
+ vo_draw_alpha_rgb15(w,h,src,srca,stride,dst,vf->priv->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]);
+ break;
+ case IMGFMT_BGR24:
+ case IMGFMT_RGB24:
+ vo_draw_alpha_rgb24(w,h,src,srca,stride,dst,vf->priv->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]);
+ break;
+ case IMGFMT_YV12:
+ case IMGFMT_I420:
+ case IMGFMT_IYUV:
+ vo_draw_alpha_yv12(w,h,src,srca,stride,dst,vf->priv->dmpi->stride[0]);
+ break;
+ case IMGFMT_YUY2:
+ vo_draw_alpha_yuy2(w,h,src,srca,stride,dst,vf->priv->dmpi->stride[0]);
+ break;
+ case IMGFMT_UYVY:
+ vo_draw_alpha_yuy2(w,h,src,srca,stride,dst+1,vf->priv->dmpi->stride[0]);
+ break;
+ }
+}
+
+static void draw_osd(struct vf_instance_s* vf_,int w,int h){
+ vf=vf_;orig_w=w;orig_h=h;
+ 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.
+ vo_remove_text(vf->priv->exp_w,vf->priv->exp_h,remove_func);
+ }
+ vo_draw_text(vf->priv->exp_w,vf->priv->exp_h,draw_func);
+}
+
+#endif
+//===========================================================================//
static int config(struct vf_instance_s* vf,
int width, int height, int d_width, int d_height,
@@ -41,6 +131,14 @@ static int config(struct vf_instance_s* vf,
// codec -copy-> expand -copy-> vo (worst case)
static void get_image(struct vf_instance_s* vf, mp_image_t *mpi){
+#ifdef OSD_SUPPORT
+ if(vf->priv->osd && (mpi->flags&MP_IMGFLAG_PRESERVE)){
+ // check if we have to render osd!
+ vo_update_osd(vf->priv->exp_w, vf->priv->exp_h);
+ if(vo_osd_check_range_update(vf->priv->exp_x,vf->priv->exp_y,
+ vf->priv->exp_x+mpi->w,vf->priv->exp_y+mpi->h)) return;
+ }
+#endif
if(vf->priv->exp_w==mpi->width ||
(mpi->flags&(MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_ACCEPT_WIDTH)) ){
// try full DR !
@@ -70,6 +168,9 @@ static void get_image(struct vf_instance_s* vf, mp_image_t *mpi){
static void put_image(struct vf_instance_s* vf, mp_image_t *mpi){
if(mpi->flags&MP_IMGFLAG_DIRECT){
vf_next_put_image(vf,vf->priv->dmpi);
+#ifdef OSD_SUPPORT
+ if(vf->priv->osd) draw_osd(vf,mpi->w,mpi->h);
+#endif
return; // we've used DR, so we're ready...
}
@@ -98,13 +199,27 @@ static void put_image(struct vf_instance_s* vf, mp_image_t *mpi){
mpi->planes[0], mpi->w*(vf->priv->dmpi->bpp/8), mpi->h,
vf->priv->dmpi->stride[0],mpi->stride[0]);
}
+#ifdef OSD_SUPPORT
+ if(vf->priv->osd) draw_osd(vf,mpi->w,mpi->h);
+#endif
vf_next_put_image(vf,vf->priv->dmpi);
}
//===========================================================================//
+static int control(struct vf_instance_s* vf, int request, void* data){
+#ifdef OSD_SUPPORT
+ switch(request){
+ case VFCTRL_DRAW_OSD:
+ if(vf->priv->osd) return CONTROL_TRUE;
+ }
+#endif
+ return vf_next_control(vf,request,data);
+}
+
static int open(vf_instance_t *vf, char* args){
vf->config=config;
+ vf->control=control;
vf->get_image=get_image;
vf->put_image=put_image;
vf->priv=malloc(sizeof(struct vf_priv_s));
@@ -113,21 +228,27 @@ static int open(vf_instance_t *vf, char* args){
vf->priv->exp_y=
vf->priv->exp_w=
vf->priv->exp_h=-1;
- if(args) sscanf(args, "%d:%d:%d:%d",
+ if(args) sscanf(args, "%d:%d:%d:%d:%d",
&vf->priv->exp_w,
&vf->priv->exp_h,
&vf->priv->exp_x,
- &vf->priv->exp_y);
- printf("Expand: %d x %d, %d ; %d\n",
+ &vf->priv->exp_y,
+ &vf->priv->osd);
+ printf("Expand: %d x %d, %d ; %d (-1=autodetect) osd: %d\n",
vf->priv->exp_w,
vf->priv->exp_h,
vf->priv->exp_x,
- vf->priv->exp_y);
+ vf->priv->exp_y,
+ vf->priv->osd);
return 1;
}
vf_info_t vf_info_expand = {
+#ifdef OSD_SUPPORT
+ "expanding & osd",
+#else
"expanding",
+#endif
"expand",
"A'rpi",
"",