Re: OSD

Alban Bedel <[email protected]>
Newsgroups gmane.comp.video.mplayer.g2.devel
Message-ID <[email protected]>
Hi Alban Bedel,

on Sat, 19 Jul 2003 15:12:32 +0200 you wrote:

> 
> Hi,
> 
> I worked a bit on OSD. Here is my current work. Comment are welcome :)
Sorry for the chitty diff, i forgot to save the file after cleanup :(
	Albeu

-- 

Everything is controlled by a small evil group
to which, unfortunately, no one we know belongs.

_______________________________________________
MPlayer-G2-dev mailing list
[email protected]
http://mplayerhq.hu/mailman/listinfo/mplayer-g2-dev
g2.osd.diff (application/octet-stream, 24.6 KB)
--- /home/alban/MP/g2/Makefile	Thu Jul 10 22:54:15 2003
+++ /home/alban/MP/g2.dev/Makefile	Fri Jul 18 18:15:06 2003
@@ -10,7 +10,7 @@
 STREAM_DEPS = demux/libmpdemux.a stream/libmpstream.a stream/mpdvdkit2/libmpdvdkit.a
 CODECS_DEPS = audio/libmpacodecs.a video/libmpvcodecs.a libavcodec/libavcodec.a libavcodec/libpostproc/libpostproc.a \
     audio/libaf/libaf.a video/libmpeg2/libmpeg2.a \
-    audio/mp3lib/libMP3.a swscale/libswscale.a
+    audio/mp3lib/libMP3.a swscale/libswscale.a osd/libmposd.a
 PLAYER_DEPS = libao2/libao2.a libvo2/libvo2.a
 
 AO_LIBS = $(ARTS_LIB) $(ESD_LIB) $(NAS_LIB) $(SGIAUDIO_LIB) $(ALSA_LIB) $(SDL_LIB)
--- /home/alban/MP/g2/cfg.h	Thu Jul 10 22:03:45 2003
+++ /home/alban/MP/g2.dev/cfg.h	Fri Jul 18 17:35:57 2003
@@ -101,7 +101,9 @@
   MODULE_TYPE_AF,
   MODULE_TYPE_AD,
   MODULE_TYPE_AE,
-  MODULE_TYPE_AO
+  MODULE_TYPE_AO,
+
+  MODULE_TYPE_OSD
 } module_type_t;
 
 typedef struct config_data_s config_data_t;
--- /dev/null	Mon Jul 18 01:46:18 1994
+++ /home/alban/MP/g2.dev/osd/Makefile	Fri Jul 18 18:24:12 2003
@@ -0,0 +1,46 @@
+
+BASE=..
+
+include $(BASE)/config.mak
+
+LIBNAME = libmposd.a
+
+SRCS=osd.c obj_test.c
+OBJS=$(SRCS:.c=.o)
+
+#CFLAGS  = $(OPTFLAGS) -I. -Inative -I.. -I../libmpdemux -I../loader $(EXTRA_INC) -D_GNU_SOURCE
+CFLAGS  = $(OPTFLAGS) -I. -I$(BASE) -I$(BASE)/video $(EXTRA_INC) -D_GNU_SOURCE
+
+.SUFFIXES: .c .o
+
+# .PHONY: all clean
+
+.c.o:
+	$(CC) -c $(CFLAGS) -o $@ $<
+
+all:    $(LIBNAME) $(LIBNAME2)
+
+$(LIBNAME):     $(OBJS)
+	$(AR) sr $(LIBNAME) $(OBJS)
+
+$(LIBNAME2):     $(OBJS2)
+	$(AR) sr $(LIBNAME2) $(OBJS2)
+
+clean:
+	rm -f *.o *.a *~
+
+distclean:
+	rm -f Makefile.bak $(OBJS) $(OBJS2) $(LIBNAME) $(LIBNAME2) *~ .depend
+
+dep:    depend
+
+depend:
+	$(CC) -MM $(CFLAGS) $(SRCS) $(SRCS2) 1>.depend
+
+#
+# include dependency files if they exist
+#
+ifneq ($(wildcard .depend),)
+include .depend
+endif
+
--- /dev/null	Mon Jul 18 01:46:18 1994
+++ /home/alban/MP/g2.dev/osd/obj_test.c	Sat Jul 19 14:48:34 2003
@@ -0,0 +1,79 @@
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "cfg.h"
+#include "img_format.h"
+#include "mp_image.h"
+#include "osd.h"
+
+
+
+static int init(osd_obj_t*obj,void* param) {
+  printf("Obj init :)\n");
+  return 1;
+}
+
+static int config(osd_obj_t* obj,int width,int height,unsigned format){
+  switch(format) {
+  case IMGFMT_YV12:
+  case IMGFMT_I420:
+    return 1;
+  default:
+    printf("Unsuported colorspace\n");
+    return 0;
+  }
+}
+
+static int draw(osd_obj_t* obj,mp_image_t* mpi){
+  int i,j;
+  char* dst;
+
+  if(!mpi) return 0;
+
+  dst = mpi->planes[0];
+  for(i = 0 ; i < mpi->height ; i++) {
+    for(j = 0 ; j < mpi->height ; j++) {
+      if(!((j+(i%2))% 4))
+	 dst[j] = 255;
+      //else
+      //dst[j] = 255;
+    }
+    dst += mpi->stride[0];
+  }
+  obj->status = OSD_OBJ_SHOWN;
+  printf("\nObject drawn %d\n",obj->draw_id);
+  return 1;
+}
+
+static int control(osd_obj_t* obj,int request,void* data){
+  return 0;
+}
+
+static void uninit(osd_obj_t* obj){
+}
+
+
+static osd_obj_driver_t driver = {
+  init,
+  config,
+  draw,
+  control,
+  uninit
+};
+
+module_info_t osd_obj_test_driver = {
+  MODULE_TYPE_OSD,0,
+  &driver,
+  "test",
+  "Testing object",
+  "Albeu",
+  "Albeu",
+  "No comment",
+  0,
+  NULL,
+  NULL,
+  0
+};
--- /dev/null	Mon Jul 18 01:46:18 1994
+++ /home/alban/MP/g2.dev/osd/osd.c	Sat Jul 19 14:50:34 2003
@@ -0,0 +1,371 @@
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "cfg.h"
+#include "img_format.h"
+#include "mp_image.h"
+#include "osd.h"
+
+extern module_info_t osd_obj_test_driver;
+
+static module_info_t* obj_drivers[] = {
+  &osd_obj_test_driver,
+  NULL
+};
+
+module_info_t* find_osd_obj(char* name) {
+  int i;
+
+  for(i = 0 ; obj_drivers[i] ; i++) {
+    if(strcmp(obj_drivers[i]->name,name)) continue;
+    return obj_drivers[i];
+  }
+  return NULL;
+}
+
+
+static int osd_obj_in(osd_obj_t* o,int buf_type) {
+  osd_display_t* disp = o->display;
+  osd_area_t* a;
+  
+  for(a = disp->areas ; a ; a = a->next) {
+    if(a->buffer_type != buf_type) {
+      // Fully contained in the wrong buffer type
+      if(o->x >= a->x && o->x+o->w <= a->x+a->w &&
+	 o->y >= a->y && o->y+o->h <= a->y+a->h)
+	return 0;
+      // FIX ME
+      // Here we should in fact check the resting parts
+      // of the object but atm it doesn't matter.
+      continue;
+    }
+    // Doesn't cross the area
+    if(o->x+o->w < a->x || o->x >= a->x+a->w ||
+       o->y+o->h < a->y || o->y >= a->y+a->h)
+      continue;
+    // Match !!!
+    return 1;
+  }
+  return (disp && buf_type == disp->buffer_type);
+}
+
+static int get_obj_mpi(osd_obj_t* o,mp_image_t* mpi,mp_image_t* dmpi) {
+  int x1,y1,x2,y2;
+  if(!mpi) return 0;
+
+  // Cut the object if needed
+  x1 = o->x < 0 ? 0 : o->x;
+  y1 = o->y < 0 ? 0 : o->y;
+  x2 = o->x + o->w > mpi->width ? mpi->width : o->x + o->w;
+  y2 = o->y + o->h > mpi->height ? mpi->height : o->y + o->h;
+ 
+  // Legal size ?
+  if(x2 - x1 <= 0 || y2 - y1 <= 0) return 0;
+
+  // Setup the format stuff and the buffers
+  dmpi->x = o->x < 0 ? -o->x : 0;
+  dmpi->y = o->y < 0 ? -o->y : 0;
+  dmpi->width = x2 - x1;
+  dmpi->height = y2 - y1;
+
+  if(dmpi->imgfmt != mpi->imgfmt)
+    mp_image_setfmt(dmpi,mpi->imgfmt);
+
+  if(mpi->flags&MP_IMGFLAG_PLANAR) {
+    dmpi->planes[0] = mpi->planes[0] +
+      y1 * mpi->stride[0] + x1;
+    dmpi->planes[1] = mpi->planes[1] +
+      (y1>>mpi->chroma_y_shift) * mpi->stride[1] + 
+      (x1>>mpi->chroma_x_shift);
+    dmpi->planes[2] = mpi->planes[2] +
+      (y1>>mpi->chroma_y_shift) * mpi->stride[2] +
+      (x1>>mpi->chroma_x_shift);
+    memcpy(dmpi->stride,mpi->stride,3*sizeof(int));
+  } else {
+    dmpi->planes[0] = mpi->planes[0] +
+      y1 * mpi->stride[0] + x1 * ((mpi->bpp+7)/8);
+    dmpi->stride[0] = mpi->stride[0];
+  }  
+  return 1;
+}
+
+int osd_object_draw(osd_obj_t* o,mp_image_t* mpi) {
+  mp_image_t* i = NULL;
+  osd_obj_status_t *rec;
+  int r,drawing = (o->status == OSD_OBJ_DRAWING) ? 1 : 0;
+
+
+ if(o->status != OSD_OBJ_DRAWING &&
+     o->status != OSD_OBJ_SHOWN)
+      return 0;
+
+ // On locked area, kill it
+ if(osd_obj_in(o,OSD_BUF_LOCKED)) {
+   o->status = OSD_OBJ_HIDEN;
+   return 0;
+ }
+
+ 
+ // Try to find the buffer, in the records
+ for(rec = o->recs ; rec && rec->buffer != mpi->planes[0] ; rec = rec->next)
+   /* NOP */;
+ // Not found, allocate
+ if(!rec) {
+   rec = calloc(sizeof(osd_obj_status_t),1);
+   rec->buffer = mpi->planes[0];
+   rec->next = o->recs;
+   o->recs = rec;
+   printf("--- Allocate new object records for buffer %p\n",mpi->planes[0]);
+   
+ }
+
+
+ // Get the mpi if we need to draw:
+ // We draw if the object is not drawn on the buffer,
+ // or the object must be updated, or we the object is over
+ // some TEMP area.
+ if( !rec->draw_id || o->draw_id != rec->draw_id ||
+     drawing || osd_obj_in(o,OSD_BUF_TEMP) ) {
+  if(!get_obj_mpi(o,mpi,&rec->mpi)) return -1;
+   i = &rec->mpi;
+ }
+ 
+
+ // Call the draw function. Call with NULL mpi mean that there
+ // is nothing to draw. This let the driver a chance to set itself to
+ // OSD_OBJ_DRAWING, so he can drawn something new at the next frame.
+ r = o->driver->draw(o,i);
+ if(r > 0) { // Success
+   if(i && drawing) // We draw something new
+     o->draw_id++; // Set the new draw id
+     // We record only objects wich are over STATIC
+   rec->draw_id = osd_obj_in(o,OSD_BUF_STATIC) ? o->draw_id : 0;
+   return (i != NULL) ? 1 : 0;
+ }
+ return r;
+}
+
+int osd_object_clear(osd_obj_t* o,mp_image_t* mpi) {
+  osd_obj_status_t *rec,*last = NULL;
+  int r = 0;
+
+  for(rec = o->recs ; rec && rec->buffer != mpi->planes[0] ; rec = rec->next)
+    last = rec;
+  // Never seen this buffer
+  if(!rec) return 0;
+  // Not drawn over this buffer
+  if(!rec->draw_id) return 0;
+  // Alredy drawn, don't need to update
+  if(o->status == OSD_OBJ_SHOWN && rec->draw_id == o->draw_id) return 0;
+  
+  // Clear it
+  if(o->display->clear) r = o->display->clear(o->display,&rec->mpi);
+  // Some default clear would be nice
+  rec->draw_id = 0;
+
+  // Object must be deleted, remove this record
+  if(o->status == OSD_OBJ_DESTROY) {
+    if(last) last->next = rec->next;
+    else o->recs = rec->next;
+    free(rec);
+  }
+  
+  return r;
+}
+
+int osd_display_draw(osd_display_t* disp, mp_image_t* mpi) {
+  osd_obj_t *o;
+  osd_obj_status_t *rec;
+  int ret = 0,r;
+
+
+  for(o = disp->objs ; o ; o = o->next ) {
+    r = osd_object_draw(o,mpi);
+    if(r < 0) {
+      printf("Error while drawing osd object\n");
+      continue;
+    }
+    ret += r;
+  }
+
+  return ret;
+}
+
+int osd_display_clear(osd_display_t* disp, mp_image_t* mpi) {
+  osd_obj_t *o,*last = NULL,*next;
+  osd_obj_status_t *rec;
+  int clr = 0,r;
+
+  for(o = disp->objs ; o ; o = next ) {    
+    // Clear if needed
+    if(o->recs) {
+      r = osd_object_clear(o,mpi);
+      if(r < 0) printf("Clear failed\n");
+      else clr += r;
+    }
+    next = o->next;
+    if(o->status == OSD_OBJ_DESTROY && o->recs == NULL) {
+      if(last) last->next = o->next;
+      else disp->objs = o->next;
+      free(o);
+    } else
+      last = o;
+  }
+
+  return clr;
+}
+
+osd_display_t* osd_display_new(int width,int height,unsigned int format,
+			       int buf_type) {
+  osd_display_t* disp = calloc(1,sizeof(osd_display_t));
+
+  disp->width = width;
+  disp->height = height;
+  disp->format = format;
+  disp->buffer_type = buf_type;
+
+  return disp;
+}
+
+osd_area_t* osd_display_add_area(osd_display_t* disp,int x,int y, int w, int h,
+			 int buffer_type) {
+  osd_area_t* ret;
+
+  // TODO Check area size etc
+
+  ret = calloc(sizeof(osd_area_t),1);
+  ret->x = x;
+  ret->y = y;
+  ret->w = w;
+  ret->h = h;
+  ret->buffer_type = buffer_type;
+  
+  ret->next = disp->areas;
+  disp->areas = ret;
+  return ret;
+}
+			 
+void osd_display_del_area(osd_display_t* disp,osd_area_t* area) {
+  osd_area_t *a,*l = NULL;
+
+  for(a = disp->areas ; a ; a = a->next) {
+    if(a != area) {
+      l = a;
+      continue;
+    }
+    if(l)
+      l->next = a->next;
+    else
+      disp->areas = NULL;
+    free(a);
+    return;
+  }
+  return;
+}
+
+osd_obj_t* osd_display_add_object(osd_display_t* disp,module_info_t* module,
+			    void* cfg) {
+  osd_obj_t* obj;
+  obj = calloc(1,sizeof(osd_obj_t));
+  obj->driver = module->entry;
+  obj->display = disp;
+
+  if(!obj->driver->init(obj,cfg)) {
+    free(obj);
+    return NULL;
+  }
+
+  obj->next = disp->objs;
+  disp->objs = obj;
+  
+  return obj;
+}
+
+
+int osd_object_set_size(osd_obj_t* obj,int width, int height) {
+  
+  if(obj->status == OSD_OBJ_DESTROY) {
+    printf("Wrong object state: %d\n",obj->status);
+    return 0;
+  }
+
+  if(!obj->driver->config(obj,width,height,obj->display->format)) {
+    printf("Failed to set config %d x %d 0x%x\n",width,height,
+	   obj->display->format);
+    return 0;
+  }
+
+  if(obj->status == OSD_OBJ_DISABLED)
+    obj->status = OSD_OBJ_HIDEN;
+
+  return 1;
+}
+
+int osd_object_show(osd_obj_t* obj,int show) {
+  if(obj->status == OSD_OBJ_DESTROY || obj->status == OSD_OBJ_DISABLED) {
+    printf("Wrong object state: %d\n",obj->status);
+    return 0;
+  }
+
+  if(show)
+    obj->status = OSD_OBJ_DRAWING;
+  else
+    obj->status = OSD_OBJ_HIDEN;
+
+  return 1;
+}
+
+
+void osd_display_del_object(osd_display_t* disp,osd_obj_t* obj) {
+  osd_obj_t *o;
+
+  for(o = disp->objs ; o ; o = o->next ) {
+    if(o != obj) continue;
+    if(o->driver && o->driver->uninit)
+      o->driver->uninit(o);
+    // Set the destroy state
+    o->status = OSD_OBJ_DESTROY;
+    return;
+  }
+  return;
+}
+
+int osd_display_config(osd_display_t* disp,int width,int height,unsigned format) {
+  osd_obj_t *o;
+  int fail = 0;
+
+  disp->width = width;
+  disp->height = height;
+  disp->format = format;
+
+  for(o = disp->objs ; o ; o = o->next ) {
+    if(o->status == OSD_OBJ_DESTROY) continue;
+    if(!o->driver->config(o,o->w,o->h,format)) {
+      o->status = OSD_OBJ_DISABLED;
+      fail++;
+      continue;
+    }
+    if(o->status == OSD_OBJ_DISABLED)
+      o->status = OSD_OBJ_HIDEN;
+  }
+  return fail;
+}
+
+int osd_display_show_all(osd_display_t* disp) {
+  osd_obj_t *o;
+  int fail = 0;
+
+  for(o = disp->objs ; o ; o = o->next ) {
+    if(!osd_object_show(o,1))
+      fail++;
+  }
+  return fail;
+}
+
+void osd_display_free(osd_display_t* disp) {
+  // TODO
+  
+}
+
--- /dev/null	Mon Jul 18 01:46:18 1994
+++ /home/alban/MP/g2.dev/osd/osd.h	Sat Jul 19 12:35:30 2003
@@ -0,0 +1,120 @@
+
+// TEMP:
+//  osd need to be redraw all the time
+
+// STATIC:
+//  osd don't need to be redraw at every frames
+//  original data must be saved to clear the buffer (or call a provided
+//  clear func)
+
+// IP(B):
+//  we can't draw osd on that.
+#define OSD_BUF_TEMP   0
+#define OSD_BUF_STATIC 1
+#define OSD_BUF_LOCKED 2
+
+// Area flags
+#define OSD_AREA_UPDATED 1
+
+// Object status
+#define OSD_OBJ_DISABLED 0
+#define OSD_OBJ_HIDEN 1
+#define OSD_OBJ_DRAWING 2
+#define OSD_OBJ_SHOWN 3
+#define OSD_OBJ_DESTROY 4
+
+typedef struct osd_area_st osd_area_t;
+struct osd_area_st {
+  int x,y;
+  int w,h;
+  int buffer_type; // TEMP, STATIC, LOCKED
+  int flags; // dirty flags for static
+  osd_area_t* next;
+};
+
+typedef struct osd_obj_st osd_obj_t;
+typedef struct osd_display_st osd_display_t;
+
+typedef struct osd_obj_driver_st {
+  int (*init)(osd_obj_t*,void* param);
+  int (*config)(osd_obj_t*,int width,int height,unsigned format);
+  int (*draw)(osd_obj_t*,mp_image_t*);
+  int (*control)(osd_obj_t*,int,void*);
+  void (*uninit)(osd_obj_t*);
+} osd_obj_driver_t;
+
+
+typedef struct osd_obj_status_st osd_obj_status_t;
+
+struct osd_obj_st {
+  int x,y;
+  int w,h;
+  int status;
+  int flags;
+  unsigned int draw_id; // auto inc at each (real) draw
+  mp_image_t mpi; // Mpi we give to this object for draw
+  osd_display_t* display;
+  osd_obj_t* next;
+  osd_obj_driver_t* driver;
+  osd_obj_status_t* recs; // Per buffer records
+};
+
+typedef int (*osd_clear_func_t)(osd_display_t* disp, mp_image_t* mpi);
+
+struct osd_obj_status_st {
+  void* buffer; // Pointer to the buffer start (as id)
+  unsigned int draw_id; // Draw id
+  mp_image_t mpi;
+  osd_obj_status_t* next;
+};
+
+typedef struct osd_buffer_st osd_buffer_t;
+struct osd_buffer_st {
+  void* buffer;
+  int age;
+  osd_obj_status_t* objs;
+  osd_buffer_t* next;
+};
+
+
+struct osd_display_st {
+  int width,height;
+  float aspect_ratio;
+  unsigned int format;
+  int buffer_type; // TEMP, STATIC
+  int flags; // dirty flags for static
+  osd_area_t* areas; // desc of various sub area properties
+  // clear callback
+  osd_clear_func_t clear;
+  osd_buffer_t* bufs; // buffers record for clearing
+  
+  // objs attached to the display
+  osd_obj_t* objs;
+};
+
+
+osd_display_t* osd_display_new(int width,int height,unsigned int format,
+			       int buf_type);
+
+osd_area_t* osd_display_add_area(osd_display_t* disp,int x,int y, int w, int h,
+				 int buffer_type);
+void osd_display_del_area(osd_display_t* disp,osd_area_t* area);
+
+osd_obj_t* osd_display_add_object(osd_display_t* disp,module_info_t* module,
+				  void* cfg);
+
+int osd_display_config(osd_display_t* disp,int width,int height,unsigned format);
+
+int osd_object_set_size(osd_obj_t* obj,int width, int height);
+int osd_object_show(osd_obj_t* obj,int show);
+
+int osd_display_show_all(osd_display_t* disp);
+void osd_display_del_object(osd_display_t* disp,osd_obj_t* obj);
+
+
+int osd_display_draw(osd_display_t* disp, mp_image_t* mpi);
+int osd_display_clear(osd_display_t* disp, mp_image_t* mpi);
+
+void osd_display_free(osd_display_t* disp);
+
+module_info_t* find_osd_obj(char* name);
--- /home/alban/MP/g2/video/Makefile	Mon May 12 01:47:03 2003
+++ /home/alban/MP/g2.dev/video/Makefile	Fri Jul 18 18:13:06 2003
@@ -12,7 +12,7 @@
 VIDEO_SRCS=dec_video.c vd.c $(VIDEO_SRCS_NAT) $(VIDEO_SRCS_LIB) $(VIDEO_SRCS_OPT)
 
 # vf_vo.c 
-VFILTER_SRCS=vf.c vf_scale.c vf_vo2.c vf_vd.c vf_pp.c vf_format.c vf_tfields.c # vf_crop.c vf_expand.c # vf_format.c vf_flip.c vf_rgb2bgr.c vf_rotate.c vf_mirror.c vf_palette.c vf_lavc.c vf_dvbscale.c vf_cropdetect.c vf_test.c vf_noise.c vf_rectangle.c vf_eq.c vf_eq2.c vf_halfpack.c vf_dint.c vf_1bpp.c vf_bmovl.c vf_2xsai.c vf_unsharp.c vf_swapuv.c vf_il.c vf_boxblur.c vf_sab.c vf_smartblur.c vf_perspective.c vf_down3dright.c vf_field.c vf_denoise3d.c vf_hqdn3d.c vf_detc.c vf_telecine.c vf_tfields.c 
+VFILTER_SRCS=vf.c vf_scale.c vf_vo2.c vf_vd.c vf_pp.c vf_format.c vf_tfields.c vf_osd.c # vf_crop.c vf_expand.c # vf_format.c vf_flip.c vf_rgb2bgr.c vf_rotate.c vf_mirror.c vf_palette.c vf_lavc.c vf_dvbscale.c vf_cropdetect.c vf_test.c vf_noise.c vf_rectangle.c vf_eq.c vf_eq2.c vf_halfpack.c vf_dint.c vf_1bpp.c vf_bmovl.c vf_2xsai.c vf_unsharp.c vf_swapuv.c vf_il.c vf_boxblur.c vf_sab.c vf_smartblur.c vf_perspective.c vf_down3dright.c vf_field.c vf_denoise3d.c vf_hqdn3d.c vf_detc.c vf_telecine.c vf_tfields.c 
 ENCODER_SRCS=ve.c # ve_lavc.c # ve_divx4.c ve_vfw.c ve_rawrgb.c ve_libdv.c ve_xvid.c ve_qtvideo.c ve_nuv.c
 
 # NATIVE_SRCS=native/RTjpegN.c native/cinepak.c native/fli.c native/minilzo.c native/msvidc.c native/nuppelvideo.c native/qtrle.c native/qtrpza.c native/qtsmc.c native/roqav.c native/xa_gsm.c native/svq1.c
--- /home/alban/MP/g2/video/vf.c	Sun Jul 13 23:52:25 2003
+++ /home/alban/MP/g2.dev/video/vf.c	Fri Jul 18 18:12:46 2003
@@ -60,11 +60,13 @@
 extern vf_info_t vf_info_detc;
 extern vf_info_t vf_info_telecine;
 extern vf_info_t vf_info_tfields;
+extern vf_info_t vf_info_osd;
 
 //char** vo_plugin_args=(char**) NULL;
 
 // list of available filters:
 static vf_info_t* filter_list[]={
+    &vf_info_osd,
     &vf_info_scale,
     &vf_info_vo2,
     &vf_info_vd,
--- /dev/null	Mon Jul 18 01:46:18 1994
+++ /home/alban/MP/g2.dev/video/vf_osd.c	Sat Jul 19 14:51:03 2003
@@ -0,0 +1,245 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "config.h"
+#include "mp_msg.h"
+
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+#include "fastmemcpy.h"
+
+#include "cfg.h"
+#include "osd/osd.h"
+
+
+static struct config_data_s {
+  int w,h;
+  int x,y;
+  int force_osd;
+  config_modlist_t* objs;
+} cfg_def = {
+  0,0,
+  -1,-1,
+  0,
+  NULL
+};
+
+static config_t cfg_opts[] = {
+  {"w",&cfg_def.w, CONF_TYPE_INT, CONF_MIN, 0, 0, NULL, "Expand to width"},
+  {"h",&cfg_def.h, CONF_TYPE_INT, CONF_MIN, 0, 0, NULL, "Expand to height"},
+  {"x",&cfg_def.x, CONF_TYPE_INT, CONF_MIN, -1, 0, NULL, "Expand offset"},
+  {"y",&cfg_def.y, CONF_TYPE_INT, CONF_MIN, -1, 0, NULL, "Expand offset"},
+  {"force",&cfg_def.force_osd, CONF_TYPE_FLAG,0, 0, 1, NULL, "Alway draw osd everywhere"},
+  {"objs",&cfg_def.objs, CONF_TYPE_MODLIST, 0, 0, 0, find_osd_obj, "object"},
+  {NULL, NULL, 0, 0, 0, 0, NULL, NULL}
+};
+
+
+struct vf_priv_s {
+  osd_display_t* disp;
+  osd_area_t* m_area;
+  int exp_x,exp_y,exp_w,exp_h;
+  int x,y,w,h;
+  int force_osd;
+  int n;
+};
+
+static int osd_clear_func(osd_display_t* disp, mp_image_t* mpi) {
+  printf("------- Clear ------\n");
+  vf_mpi_clear(mpi,0,0,mpi->width,mpi->height);
+  return 1;
+}
+
+int config(struct vf_instance_s* vf,
+        int width, int height, int d_width, int d_height,
+	   unsigned int flags, unsigned int outfmt) {
+  vf->priv->exp_w = vf->priv->w > width ? vf->priv->w : width;
+  vf->priv->exp_h = vf->priv->h > height ? vf->priv->h : height;
+
+  vf->priv->exp_x = vf->priv->x >= 0 ? vf->priv->x : (vf->priv->exp_w - width)/2;
+  vf->priv->exp_y = vf->priv->y >= 0 ? vf->priv->y : (vf->priv->exp_h - height)/2;
+
+  if(vf->priv->exp_x + width > vf->priv->exp_w ||
+     vf->priv->exp_y + height > vf->priv->exp_h)
+    return 0;
+
+  if(vf->priv->exp_w > width || vf->priv->exp_h > height) {
+    if(!vf->priv->m_area) {
+      vf->priv->m_area = osd_display_add_area(vf->priv->disp,
+					      vf->priv->exp_x,
+					      vf->priv->exp_y,
+					      width,height,
+					      OSD_BUF_TEMP);
+      vf->priv->disp->buffer_type = OSD_BUF_STATIC;
+    } else {
+      vf->priv->m_area->x = vf->priv->exp_x;
+      vf->priv->m_area->y = vf->priv->exp_y;
+      vf->priv->m_area->w = width;
+      vf->priv->m_area->h = height;
+    }
+  } else {
+    if(vf->priv->m_area) {
+      osd_display_del_area(vf->priv->disp,vf->priv->m_area);
+      vf->priv->m_area = NULL;
+      vf->priv->disp->buffer_type = OSD_BUF_TEMP;
+    }
+  }
+  osd_display_config(vf->priv->disp,vf->priv->exp_w,vf->priv->exp_h,outfmt);
+  //osd_display_show_all(vf->priv->disp);
+  return vf_next_config(vf,vf->priv->exp_w,vf->priv->exp_h,vf->priv->exp_w,vf->priv->exp_h,flags,outfmt);
+}
+
+void get_image(struct vf_instance_s* vf,
+	       mp_image_t *mpi) {
+  mp_image_t *dmpi = NULL;
+
+  if(vf->priv->exp_w==mpi->width ||
+     (mpi->flags&(MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_ACCEPT_WIDTH)) ){
+    // try full DR !
+    if(vf->priv->force_osd && mpi->type != MP_IMGTYPE_TEMP)
+      return;
+    mpi->priv=dmpi=vf_get_image_cloned(vf->next,mpi,mpi->imgfmt,
+				mpi->type, mpi->flags, 
+				vf->priv->exp_w,vf->priv->exp_h);
+    // set up mpi as a cropped-down image of dmpi:
+    if(mpi->flags&MP_IMGFLAG_PLANAR){
+      mpi->planes[0]=dmpi->planes[0]+
+	vf->priv->exp_y*dmpi->stride[0]+vf->priv->exp_x;
+      mpi->planes[1]=dmpi->planes[1]+
+	(vf->priv->exp_y>>mpi->chroma_y_shift)*dmpi->stride[1]+(vf->priv->exp_x>>mpi->chroma_x_shift);
+      mpi->planes[2]=dmpi->planes[2]+
+	(vf->priv->exp_y>>mpi->chroma_y_shift)*dmpi->stride[2]+(vf->priv->exp_x>>mpi->chroma_x_shift);
+      mpi->stride[1]=dmpi->stride[1];
+      mpi->stride[2]=dmpi->stride[2];
+    } else {
+      mpi->planes[0]=dmpi->planes[0]+
+	vf->priv->exp_y*dmpi->stride[0]+
+	vf->priv->exp_x*(dmpi->bpp/8);
+    }
+    mpi->stride[0]=dmpi->stride[0];
+    mpi->width=dmpi->width;
+    mpi->flags|=MP_IMGFLAG_DIRECT;
+    if(mpi->type != MP_IMGTYPE_TEMP) {
+      if(vf->priv->m_area)
+	vf->priv->m_area->buffer_type = OSD_BUF_LOCKED;
+      else
+	vf->priv->disp->buffer_type = OSD_BUF_LOCKED;
+    } else {
+      if(vf->priv->m_area)
+	vf->priv->m_area->buffer_type = OSD_BUF_TEMP;
+      else
+	vf->priv->disp->buffer_type = OSD_BUF_TEMP;
+    }
+    osd_display_clear(vf->priv->disp,dmpi);
+  }
+}
+    
+
+inline static void copy_mpi(mp_image_t *dmpi, mp_image_t *mpi, int x, int y) {
+  if(mpi->flags&MP_IMGFLAG_PLANAR){
+    memcpy_pic(dmpi->planes[0] + y*dmpi->stride[0] + x,
+	       mpi->planes[0], mpi->width, mpi->height,
+	       dmpi->stride[0],mpi->stride[0]);
+    memcpy_pic(dmpi->planes[1] + y*dmpi->stride[1] + x/2,
+	       mpi->planes[1], mpi->chroma_width, mpi->chroma_height,
+	       dmpi->stride[1],mpi->stride[1]);
+    memcpy_pic(dmpi->planes[2] + y*dmpi->stride[2] + x/2,
+	       mpi->planes[2], mpi->chroma_width, mpi->chroma_height,
+	       dmpi->stride[2],mpi->stride[2]);
+  } else {
+    memcpy_pic(dmpi->planes[0] + y*dmpi->stride[0] + x*(dmpi->bpp/8),
+	       mpi->planes[0],
+	       mpi->width*(mpi->bpp/8), mpi->height,
+	       dmpi->stride[0],mpi->stride[0]);
+  }
+}
+
+mp_image_t* process_image(struct vf_instance_s* vf, mp_image_t* mpi,int drop) {
+  mp_image_t* dmpi = mpi->priv;
+
+
+  if(!(mpi->flags&MP_IMGFLAG_DIRECT) || !dmpi) {
+    dmpi = vf_get_image_cloned(vf->next,mpi,mpi->imgfmt,
+			       MP_IMGTYPE_TEMP, 0,
+			       vf->priv->exp_w, vf->priv->exp_h);
+    if(!dmpi) return NULL;
+    osd_display_clear(vf->priv->disp,dmpi);
+    copy_mpi(dmpi,mpi,vf->priv->exp_x,vf->priv->exp_y);
+  } else
+    vf_clone_mpi(dmpi,mpi);
+
+  osd_display_draw(vf->priv->disp,dmpi);
+
+
+  if(vf->priv->disp->objs && vf->priv->n % 25 == 0) {
+    if(vf->priv->n % 50 == 0) {
+      printf("---- SHOW ---- \n");
+      osd_object_show(vf->priv->disp->objs,1);
+    } else {
+      printf("===== HIDE =====\n");
+      osd_object_show(vf->priv->disp->objs,0);
+    }
+  }
+  vf->priv->n++;
+
+  return dmpi;
+}
+
+static int open(vf_instance_t *vf, void* cfg){
+  config_data_t* opts = vf->cfg ? vf->cfg : &cfg_def;
+
+  vf->config=config;
+  vf->get_image=get_image;
+  vf->process_image=process_image;
+  vf->priv=calloc(1,sizeof(struct vf_priv_s));
+
+  
+  
+  
+  vf->priv->disp = calloc(sizeof(osd_display_t),1);
+  vf->priv->disp->clear = osd_clear_func;
+  vf->priv->disp->buffer_type = OSD_BUF_TEMP;
+
+  vf->priv->x = opts->x;
+  vf->priv->y = opts->y;
+  vf->priv->w = opts->w;
+  vf->priv->h = opts->h;
+  vf->priv->force_osd = opts->force_osd;
+
+  if(opts->objs) {
+    int i;
+    printf("\n\n ADDIDNG OSD OBJ \n\n");
+    for(i = 0 ; opts->objs[i].mod ; i++) {
+      osd_obj_t* o = osd_display_add_object(vf->priv->disp, opts->objs[i].mod,
+					    opts->objs[i].cfg);
+      if(!o)
+	printf("Failed to add object %s\n",opts->objs[i].mod->name);
+      else {
+	printf("Added osd object %s\n",opts->objs[i].mod->name);
+	o->w = o->h = 60;
+	o->x = o->y = 80;
+      }
+    }
+  }
+
+  
+
+  return 1;
+}
+  
+  
+vf_info_t vf_info_osd  = {
+  MODULE_TYPE_VF, MODULE_VERSION,
+  open,
+  "osd",
+  "on screen display",
+  "Albeu",
+  "Albeu",
+  "",
+  0,
+  cfg_opts, &cfg_def, sizeof(struct config_data_s)
+};
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.