[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