[prev in list] [next in list] [prev in thread] [next in thread] 

List:       mplayer-g2-dev
Subject:    [MPlayer-G2-dev] OSD
From:       Alban Bedel <albeu () free ! fr>
Date:       2003-07-19 13:12:32
Message-ID: 20030719151232.147d8a6c.albeu () free ! fr
[Download RAW message or body]

Hi,

I worked a bit on OSD. Here is my current work. Comment are welcome :)
	Albeu

-- 

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


["g2.osd.diff" (application/octet-stream)]

--- /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-l1.c	Sat Jul  5 22:27:02 2003
+++ /home/alban/MP/g2.dev/cfg-l1.c	Fri Jul 18 13:38:59 2003
@@ -12,6 +12,34 @@
 
 #define CFG_STRING_LIST_SEPARATOR ','
 
+static char* esc_strchr(char* str,char c) {
+  int esc;
+
+  if(!str) return NULL;
+
+  for(esc = 0 ; str[0] ; str++) {
+    if(str[0] == '(') esc++;
+    else if(str[0] == ')') esc--;
+    else if(esc > 0) continue;
+    else if(str[0] == c) break;
+  }
+
+  return str[0] == c ? str : NULL;
+}
+
+static char* esc_strdup(char* str) {
+  int l;
+  if(!str) return NULL;
+  l = strlen(str);
+  if(l < 2) return strdup(str);
+  if(str[0] == '(' && str[l-1] == ')') {
+    char* r = strdup(str+1);
+    r[l-2] = '\0';
+    return r;
+  }
+  return strdup(str);
+}
+
 int mpconfig_parse_param(module_info_t* mod, config_t* cd, config_data_t* cfg, char* \
param){  //    int i;
     long tmp_int;
@@ -173,10 +201,11 @@
 	    while(m){
 		module_info_t* mymod=NULL;
 		config_modinfo_t mi_func=cd->priv;
-		char* q=strchr(m,',');
+		char* q=esc_strchr(m,',');
 		char* r;
 		if(q){ *q=0; ++q; }
 		r=strchr(m,'=');
+		if(q && r > q) r = NULL;
 		if(r){ *r=0; ++r; }
 		mymod=mi_func(m); // find module
 		if(!mymod){
@@ -304,9 +333,9 @@
 	mp_msg(MSGT_CFGPARSER, MSGL_ERR, "[%s] this module have no config \
options\n",mod->name);  return CFG_ERR_INVALID;
     }
-    p=subconfig=strdup(subconfig);
+    p=subconfig=esc_strdup(subconfig);
     while(p && *p){
-	q=strchr(p,':');
+	q=esc_strchr(p,':');
 	if(q){ *q=0; ++q; };
 	r=strchr(p,'=');
 	if(r){
--- /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/test-play.c	Sun Jul 13 23:03:00 2003
+++ /home/alban/MP/g2.dev/test-play.c	Thu Jul 17 01:26:57 2003
@@ -468,16 +468,19 @@
 //		    time_frame=0;
 	    }
 	    // do sleeping!
-	    if(time_frame>0){
+	    if( !(video_out->buffer_flags & VO_BUFFER_FLAG_SLEEP)  ||
+		frame_time_remaining ) {
+	      if(time_frame>0){
 		time_frame/=playback_speed;
 		mp_msg(MSGT_AVSYNC,MSGL_DBG2,"time_frame=%5.3f\n",time_frame);
 		//usec_sleep((int)(time_frame*1000000.0));
 		time_frame=sleep_accurate(time_frame)*playback_speed;
+	      }
 	    }
 	    // display!
 	    if(!frame_time_remaining){
 		if(mpi && mpi->priv && video_out->show_frame)
-		    video_out->show_frame(video_out,(vo_buffer_t*)mpi->priv,0);
+		    video_out->show_frame(video_out,(vo_buffer_t*)mpi->priv,video_out->buffer_flags \
& VO_BUFFER_FLAG_SLEEP && time_frame > 0 ? time_frame/playback_speed : 0);  if(d_sub \
&& !d_sub->eof)  test_subs(d_sub,v_pts);
 		mpi=NULL;
@@ -509,7 +512,7 @@
 #endif
 	    sh_audio->delay+=x; c_total+=x;
 	    time_frame-=x; // for -autosync
-	    mp_msg(MSGT_AVSYNC,MSGL_STATUS,"A:%8.3f (%5.3f) V:%8.3f (%5.3f) A-V:%+7.4f \
ct:%7.4f d:%5.3f x:%+5.3f \r", +	    mp_msg(MSGT_AVSYNC,MSGL_STATUS,"A:%8.3f (%5.3f) \
V:%8.3f (%+5.3f) A-V:%+7.4f ct:%7.4f d:%5.3f x:%+5.3f \r",  (float)(a_pts-delay), \
(float)((a_pts-delay) - old_apts),  (float)v_pts, (float)(v_pts - old_vpts),
 		 AV_delay, c_total, delay, x);
--- /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)
+};



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic