[MPlayer-dev-eng] IBP protocol support

Lukas Hejtmanek xhejtman at mail.muni.cz
Tue Nov 18 17:25:00 CET 2003


Hello,

I did patch for IBP/LORS protocol to mplayer. I have patch for libmpdemux. I'm
not sure how to change toplevel configure to:
add to config.h
#define HAVE_IBP 1
and to config.mak
IBP_STREAM = yes
IBP_INCLUDES = -I/usr/include/libxml2
IBP_LIBS = -llors -llbone -lend2end -lexnode -lfdr -libp -lmd5 -laes -ldes -lxml
2 -lz
MPLAYER_NETWORK_LIB = -lnsl $(LIVE_LIBS) $(IBP_LIBS)
(also check for lors.h header)


I'm sending patch for libmpdemux, can someone to do the rest? Will my patch be
accepted?

-- 
Lukáš Hejtmánek
-------------- next part --------------
diff -rNu old/libmpdemux/Makefile newm/libmpdemux/Makefile
--- old/libmpdemux/Makefile	2003-08-17 22:56:40.000000000 +0200
+++ newm/libmpdemux/Makefile	2003-11-17 17:46:36.000000000 +0100
@@ -7,6 +7,9 @@
 ifeq ($(XMMS_PLUGINS),yes)
 SRCS += demux_xmms.c
 endif 
+ifeq ($(IBP_STREAM),yes)
+SRCS += stream_ibp.c
+endif
 ifeq ($(MPLAYER_NETWORK),yes)
 SRCS += asf_streaming.c http.c network.c asf_mmst_streaming.c pnm.c
 SRCS += realrtsp/asmrp.c realrtsp/real.c realrtsp/rmff.c realrtsp/rtsp.c realrtsp/rtsp_session.c realrtsp/sdpplin.c realrtsp/xbuffer.c
@@ -33,7 +36,7 @@
 
 OBJS	= $(SRCS:.c=.o)
 OBJS   += $(CPLUSPLUSSRCS:.cpp=.o)
-INCLUDE = -I../loader $(CSS_INC) $(EXTRA_INC)
+INCLUDE = -I../loader $(CSS_INC) $(EXTRA_INC) $(IBP_INCLUDES)
 CFLAGS  = $(OPTFLAGS) $(INCLUDE) $(XMMS_CFLAGS) $(CDPARANOIA_INC) $(DVB_INC)
 CPLUSPLUSFLAGS  = $(CFLAGS) $(CPLUSPLUSINCLUDE)
 CPLUSPLUS = $(CC)
@@ -53,7 +56,7 @@
 	$(AR) r $(LIBNAME) $(OBJS)
 
 test:	$(LIBNAME) test.c
-	$(CC) $(CFLAGS) test.c ../mp_msg.c ../osdep/shmem.c -o test ./libmpdemux.a ../libmpdvdkit2/libmpdvdkit.a ../libvo/aclib.o ../libmpcodecs/img_format.o ../libao2/afmt.o ../sub_cc.o ../m_option.o ../subreader.o $(ALSA_LIB) $(VORBIS_LIB) $(CDPARANOIA_LIB) -lz -lpthread
+	$(CC) $(CFLAGS) test.c ../mp_msg.c ../osdep/shmem.c -o test ./libmpdemux.a ../libmpdvdkit2/libmpdvdkit.a ../libvo/aclib.o ../libmpcodecs/img_format.o ../libao2/afmt.o ../sub_cc.o ../m_option.o ../subreader.o $(ALSA_LIB) $(VORBIS_LIB) $(CDPARANOIA_LIB) $(LIBXML2) $(LIBS) -lz -lpthread
 
 clean:
 	rm -f *.o *.a *~ realrtsp/*.o realrtsp/*.a realrtsp/*~
diff -rNu old/libmpdemux/open.c newm/libmpdemux/open.c
--- old/libmpdemux/open.c	2003-09-03 21:26:33.000000000 +0200
+++ newm/libmpdemux/open.c	2003-11-17 17:22:34.000000000 +0100
@@ -30,6 +30,10 @@
 static URL_t* url;
 #endif
 
+#ifdef HAVE_IBP
+stream_t* stream_open_ibp(char *filename, char **options, int *file_format);
+#endif
+
 /// We keep these 2 for the gui atm, but they will be removed.
 int dvd_title=0;
 int vcd_track=0;
@@ -475,6 +479,12 @@
   }
 #endif
 
+#ifdef HAVE_IBP
+  if(strncmp("lors://", filename, strlen("lors://")) == 0) {
+	  return stream_open_ibp(filename, options, file_format);
+  }
+#endif
+
   // FIXME: to avoid nonsense error messages...
   if (strncmp("tv://", filename, 5) && strncmp("mf://", filename, 5) &&
     strncmp("vcd://", filename, 6) && strncmp("dvb://", filename, 6) &&
diff -rNu old/libmpdemux/stream_ibp.c newm/libmpdemux/stream_ibp.c
--- old/libmpdemux/stream_ibp.c	1970-01-01 01:00:00.000000000 +0100
+++ newm/libmpdemux/stream_ibp.c	2003-11-18 16:48:11.000000000 +0100
@@ -0,0 +1,692 @@
+#undef PACKAGE
+#undef VERSION
+
+#include <lors.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/errno.h>
+#include <stdarg.h>
+#include <sys/time.h>
+#include <time.h>
+#include "stream.h"
+#include "demuxer.h"
+
+struct io_handle_t {
+
+	ssize_t (*io_read_v)(void *stream, void *buf, size_t count);
+	ssize_t (*io_write_v)(void *stream, const void *buf, size_t count);
+	int (*io_close_v)(void *stream);
+	off_t (*io_lseek_v)(void *stream, off_t offset, int whence);
+	int (*io_ftruncate_v)(void *stream, off_t length);
+	int (*io_fstat_v)(void *stream, struct stat *buf);
+	
+	void *data;
+};
+
+struct io_handle_t * _handles[256];
+int io_initialized=0;
+
+#define LBONE_PORT 6767
+#define BLOCK_SIZE 10
+#define TIME_LIMIT 3600
+#define F_REDUNDANCY 1
+#define URI "lors://"
+#define IBP_URI "lors://"
+
+int lors_threads=1;
+int lors_timeout=100;
+
+struct io_ibp_handle_t {
+	LorsDepotPool 	*dp;
+	LorsExnode	*ex;
+	off_t	        offset;
+	void		*buffer;
+	char            *hostname;
+        char            *filename;
+	off_t		b_size;
+	off_t		b_pos;
+	off_t		begin;
+	int 		mode;
+	int 		eof;
+	int 		fillbuffer;
+};
+
+void *
+ibp_open(const char *uri, int mode, int m)
+{
+	struct io_ibp_handle_t *handle;
+	int ret;
+	int pos;
+
+	if(strncmp(uri, IBP_URI, strlen(IBP_URI)) != 0) {
+		errno = EINVAL;
+		return (void *)-1;
+	}
+	handle=(struct io_ibp_handle_t*)calloc(1,sizeof(struct io_ibp_handle_t));
+	pos=strlen(IBP_URI);
+	while(pos < strlen(uri) && uri[pos] != '/')
+		pos++;
+	
+	handle->hostname = (char *)malloc(pos-strlen(IBP_URI)+1);
+	strncpy(handle->hostname, &uri[strlen(IBP_URI)], pos-strlen(IBP_URI));
+	handle->hostname[pos-strlen(IBP_URI)] = 0;
+	pos++;
+	handle->filename = (char *)malloc(strlen(&uri[pos])+1);
+	strncpy(handle->filename, &uri[pos], strlen(&uri[pos]));
+	handle->filename[strlen(&uri[pos])] = 0;
+	handle->mode = mode;
+	handle->offset = 0;
+	handle->eof = 0;
+	handle->b_pos = 0;
+	handle->begin = 0;
+	handle->fillbuffer = 1;
+
+	if(mode & O_WRONLY || mode & O_CREAT) {	
+		handle->b_size = BLOCK_SIZE*1024*1024;
+		handle->buffer = malloc(handle->b_size);
+	        if(!handle->buffer) {
+	                free(handle);
+	                errno = EIO;
+	                return (void *)-1;
+	        }
+		ret = lorsGetDepotPool(&handle->dp, handle->hostname, 
+					LBONE_PORT, NULL, 
+			       		10, NULL, BLOCK_SIZE, IBP_SOFT, 
+			       		TIME_LIMIT, lors_threads, lors_timeout, 
+					LORS_CHECKDEPOTS);
+		if(ret != LORS_SUCCESS) {
+			errno = EIO;
+			return (void *)-1;
+		}
+		ret = lorsExnodeCreate(&handle->ex);
+		if (ret != LORS_SUCCESS) {
+			errno = EIO;
+		        return (void *)-1;
+		}
+	}
+	if(mode & O_RDONLY || !mode) {
+		handle->b_size = 128*1024;
+		handle->buffer = malloc(handle->b_size);
+		ret = lorsFileDeserialize(&handle->ex, handle->filename, NULL);
+		if(ret != LORS_SUCCESS) {
+			errno = EIO;
+			return (void *)-1;
+		}
+		ret = lorsUpdateDepotPool(handle->ex, &handle->dp, NULL, 0, 
+					  NULL, lors_threads, lors_timeout, 0);
+		if(ret != LORS_SUCCESS) {
+			errno = EIO;
+                        return (void *)-1;
+                }
+		
+	}
+	return (void *)handle;
+}
+
+
+int
+ibp_flush(void *handle)
+{
+	struct io_ibp_handle_t *hdl = (struct io_ibp_handle_t *)handle;
+	int ret;
+	LorsSet *set;
+
+	if(hdl->b_pos == 0 || !hdl->mode) {
+		return 0;
+	}
+
+	ret = lorsQuery(hdl->ex, &set, hdl->begin, hdl->b_pos, 
+			LORS_QUERY_REMOVE);
+	if(ret != LORS_SUCCESS) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	if(jrb_empty(set->mapping_map)) {
+		ret = lorsSetInit(&set, hdl->b_pos/lors_threads, 1, 
+				0);
+                if(ret != LORS_SUCCESS) {
+	                errno = EIO;
+	                return -1;
+	        }
+
+		ret = lorsSetStore(set, hdl->dp, hdl->buffer, 
+				hdl->begin, hdl->b_pos, NULL, 
+				lors_threads, 
+				lors_timeout, LORS_RETRY_UNTIL_TIMEOUT);
+		
+		if(ret != LORS_SUCCESS) {
+			lorsSetFree(set,LORS_FREE_MAPPINGS);
+			errno = EIO;
+			return -1;
+		}
+	} else {
+		set->copies=1;
+                set->data_blocksize=hdl->b_pos/lors_threads;
+		ret = lorsSetUpdate(set, hdl->dp, hdl->buffer, 
+				    hdl->begin, hdl->b_pos,
+				    lors_threads,lors_timeout,
+				    LORS_RETRY_UNTIL_TIMEOUT);
+                if(ret != LORS_SUCCESS) {
+	                lorsSetFree(set,LORS_FREE_MAPPINGS);
+		        errno=EIO;
+		        return -1;
+                }
+	}
+
+	ret = lorsAppendSet(hdl->ex, set);
+        if(ret != LORS_SUCCESS) {
+	        lorsSetFree(set, LORS_FREE_MAPPINGS);
+                errno=EIO;
+                return -1;
+        }
+	
+        lorsSetFree(set,0);
+
+	hdl->begin += hdl->b_pos;
+
+	hdl->b_pos = 0;
+
+	ret = lorsFileSerialize(hdl->ex, hdl->filename, 0, 0);
+	
+        if(ret != LORS_SUCCESS) {
+	        perror("file serialize");
+	}
+	return 0;
+}
+
+ssize_t
+ibp_write(void *handle, const void *buffer, size_t size)
+{
+	struct io_ibp_handle_t *hdl = (struct io_ibp_handle_t *)handle;
+	int ret;
+	size_t rest=0;
+
+	if(!hdl || !buffer || hdl->mode == O_RDONLY || !hdl->buffer) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	hdl->offset += size;
+
+	if(hdl->b_pos + size < hdl->b_size) {
+		memcpy((char *)hdl->buffer + hdl->b_pos, buffer, size);
+		hdl->b_pos += size;
+		return size;
+	} else {
+		memcpy((char *)hdl->buffer + hdl->b_pos, buffer, 
+				hdl->b_size - hdl->b_pos);
+		rest = size + hdl->b_pos - hdl->b_size;
+		size = hdl->b_size - hdl->b_pos;
+		hdl->b_pos += size;
+	}
+
+	ibp_flush(handle);
+
+	memcpy(hdl->buffer, (char*)buffer+size, rest);
+
+	hdl->b_pos += rest;
+
+	ret = lorsFileSerialize(hdl->ex, hdl->filename, 0, 0);
+        if(ret != LORS_SUCCESS) {
+	        perror("file serialize");
+	}
+	
+	return size;
+}
+
+ssize_t
+ibp_read(void *handle, void *buffer, size_t size)
+{
+	struct io_ibp_handle_t *hdl = (struct io_ibp_handle_t *)handle;
+	int ret;
+	int m_size=size;
+	LorsSet *set;
+
+	if(hdl->mode == O_WRONLY) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	if(size > hdl->b_size - hdl->b_pos)
+		m_size = hdl->b_size - hdl->b_pos;
+
+	if(hdl->b_pos < hdl->b_size && !hdl->fillbuffer) {
+		memcpy(buffer, hdl->buffer+hdl->b_pos, m_size);
+		hdl->b_pos += m_size;
+		hdl->offset += m_size;
+		return m_size;
+	}
+	
+	hdl->fillbuffer = 0;
+	ret = lorsQuery(hdl->ex, &set, hdl->begin, hdl->b_size, 0);
+	if(ret != LORS_SUCCESS) {
+		errno = EINVAL;
+		return -1;
+	}
+	ret = lorsSetLoad(set, hdl->buffer, hdl->begin, hdl->b_size, 512*1024,
+                              NULL, lors_threads, lors_timeout, 0);
+	
+	hdl->begin += ret;
+	
+	lorsSetFree(set, 0);
+	
+	if(ret == 0)
+		hdl->eof = 1;
+	if(ret < 0) {
+		errno = EIO;
+		return -1;
+	}
+
+	if(size > ret) 
+		size = ret;
+	
+	hdl->b_pos = size;
+	
+	memcpy(buffer, hdl->buffer, size);
+	hdl->offset += size;
+	
+	return size;
+}
+
+off_t
+ibp_lseek(void *handle, off_t offs, int mode)
+{	
+	struct io_ibp_handle_t *hdl = (struct io_ibp_handle_t *)handle;
+
+	if(mode == SEEK_SET) {
+		hdl->offset = offs;
+		if(offs - hdl->begin > hdl->b_size || 
+				offs < hdl->begin) {
+			if(ibp_flush(handle)) {
+				errno = EIO;
+				return -1;
+			}
+			hdl->begin = offs;
+			hdl->fillbuffer = 1;
+		} else {
+			hdl->b_pos = hdl->offset - hdl->begin;
+		}
+	}
+	else if(mode == SEEK_CUR) {
+		hdl->offset += offs;
+		if(hdl->b_pos + offs > hdl->b_size ||
+				hdl->b_pos + offs < 0) {
+			if(ibp_flush(handle)) {
+				errno = EIO;
+				return -1;
+			}	
+			hdl->fillbuffer = 1;
+			hdl->begin = hdl->offset;
+		} else {
+			hdl->b_pos += offs;
+		}
+	} else if(mode == SEEK_END) {
+		if(ibp_flush(handle)) {
+			errno = EIO;
+			return -1;
+		}
+		hdl->fillbuffer = 1;
+		hdl->begin = hdl->offset = hdl->ex->logical_length + offs;
+	} else {
+		errno=EINVAL;
+                return(-1);
+	}
+	        
+	return hdl->offset;
+}
+
+int
+ibp_close(void *handle) 
+{
+	struct io_ibp_handle_t *hdl = (struct io_ibp_handle_t *)handle;
+	int ret;
+	
+	if(hdl->mode & O_WRONLY || hdl->mode & O_CREAT) {
+		ibp_flush(handle);
+		if(hdl->b_pos) {
+			ret = lorsFileSerialize(hdl->ex, hdl->filename, 0, 0);
+		        if(ret != LORS_SUCCESS) {
+		                perror("file serialize");
+		        }
+		}
+	}
+	if(hdl->buffer)
+		free(hdl->buffer);
+	ret = lorsExnodeFree(hdl->ex);
+	if(ret != LORS_SUCCESS) {
+		perror("exnode free");
+	}
+	if(!hdl)
+		return 0;
+	if(hdl->dp)
+		lorsFreeDepotPool(hdl->dp);
+	free(hdl);
+	return 0;
+}
+
+int
+ibp_ftruncate(void *stream, off_t length)
+{
+	struct io_ibp_handle_t* hdl = (struct io_ibp_handle_t*)stream;
+	int ret;
+	LorsSet *set;
+
+	ibp_flush(stream);
+	if(length == hdl->ex->logical_length)
+		return 0;
+	
+	ret = lorsQuery(hdl->ex, &set, length, 
+			hdl->ex->logical_length-length, 0);
+        if(ret != LORS_SUCCESS) {
+	        errno = EINVAL;
+	        return -1;
+	}
+	ret = lorsSetTrim(set, length, hdl->ex->logical_length-length, 
+			1, 20, LORS_TRIM_ALL);
+	lorsSetFree(set, 0);
+	if(ret != LORS_SUCCESS) {
+		errno = EIO;
+		return -1;
+	}
+	return 0;
+}
+
+int
+ibp_stat(const char *file_name, struct stat *buf)
+{
+	int pos;
+	LorsExnode *exnode;
+	int ret;
+	
+	
+	pos=strlen(IBP_URI);
+	while(pos < strlen(file_name) && file_name[pos] != '/')
+		pos++;
+
+	if(stat(&file_name[pos+1],buf)) {
+		return -1;
+	}
+	
+	ret = lorsFileDeserialize(&exnode, (char *)&file_name[pos+1], NULL);
+	if(ret!=0) {
+                errno=EACCES;
+                return -1;
+        }	
+  	buf->st_ino=-1;
+        buf->st_dev=-1;
+        buf->st_size=exnode->logical_length;
+        lorsExnodeFree(exnode);
+	return 0;
+}
+
+int
+ibp_lstat(const char *file_name, struct stat *buf)
+{
+	int pos;
+
+        pos=strlen(IBP_URI);
+        while(pos < strlen(file_name) && file_name[pos] != '/')
+                pos++;
+        if(lstat(&file_name[pos],buf)) {
+                return -1;
+        }
+	return 0;
+}
+
+int
+ibp_fstat(void *stream, struct stat *buf)
+{
+	struct io_ibp_handle_t *hdl = (struct io_ibp_handle_t *)stream;
+
+	return ibp_stat(hdl->filename,buf);
+}
+
+
+int
+io_init()
+{
+        int i;
+
+        for(i = 0; i < 256; i++)
+                _handles[i] = NULL;
+	
+        io_initialized = 1;
+        return 0;
+}
+
+int
+io_open(const char *pathname, int flags, ...)
+{
+	int i;
+	int ret_fd;
+	int mode=0;
+
+	if(!io_initialized && io_init() != 0) {
+		errno = EIO;
+                return -1;
+	}
+	
+	// Find free IO handle
+        i=3; // skip stdin, stdout, stderr
+        while(_handles[i] != NULL && i < 256) i++;
+        ret_fd = i;
+	if(i == 256) {
+		// no free io handle
+		errno = EIO;
+		return -1;
+	}
+	
+        _handles[ret_fd] = (struct io_handle_t*)calloc(1,
+                                    sizeof(struct io_handle_t));
+	if(!_handles[ret_fd]) {
+		// not enough free memory
+		return -1;
+	}
+
+	if(flags & O_CREAT) {
+ 		va_list arg;
+	       	va_start (arg, flags);
+		mode = va_arg (arg, int);
+		va_end (arg);
+	}
+
+	if(strncmp(pathname, IBP_URI, strlen(IBP_URI)) == 0) {
+		// IBP uri
+		
+		_handles[ret_fd]->io_read_v = &ibp_read;
+		_handles[ret_fd]->io_write_v = &ibp_write;
+		_handles[ret_fd]->io_lseek_v = &ibp_lseek;
+		_handles[ret_fd]->io_close_v = &ibp_close;
+		_handles[ret_fd]->io_ftruncate_v = &ibp_ftruncate;
+		_handles[ret_fd]->io_fstat_v = &ibp_fstat;
+		
+		_handles[ret_fd]->data = (void *)ibp_open(pathname, flags, mode);
+		if(!_handles[ret_fd]->data) {
+	                free(_handles[ret_fd]);
+	                _handles[ret_fd] = NULL;
+			errno = EIO;
+	                return -1;
+	        }
+		return ret_fd;
+	} 
+	
+	// fallback to unix io routine
+	
+	_handles[ret_fd]->io_read_v = (ssize_t(*)(void *, void *, size_t))&read;
+	_handles[ret_fd]->io_write_v = 
+		(ssize_t(*)(void *, const void *, size_t))&write;
+	_handles[ret_fd]->io_lseek_v = (off_t(*)(void *,off_t,int))&lseek;
+	_handles[ret_fd]->io_close_v = (int (*)(void *))&close;
+	_handles[ret_fd]->io_ftruncate_v = (int (*)(void *, off_t))&ftruncate;
+	_handles[ret_fd]->io_fstat_v = (int (*)(void *, struct stat *))&fstat;
+	
+	_handles[ret_fd]->data = (void *)open(pathname, flags, mode);
+	
+	if(!_handles[ret_fd]->data) {
+		free(_handles[ret_fd]);
+		_handles[ret_fd] = NULL;
+		errno = EIO;
+		return -1;
+	}
+	
+	return ret_fd;
+}
+
+ssize_t
+io_read(int fd, void *buf, size_t count)
+{
+	if(!io_initialized && io_init() != 0) {
+		errno = EIO;
+                return -1;
+	}
+	if(!_handles[fd])
+		return read(fd, buf, count);
+	return _handles[fd]->io_read_v(_handles[fd]->data, buf, count);
+}
+
+ssize_t
+io_write(int fd, const void *buf, size_t count)
+{
+	if(!io_initialized && io_init() != 0) {
+		errno = EIO;
+                return -1;
+	}
+	
+	if(!_handles[fd])
+		return write(fd, buf, count);
+	return _handles[fd]->io_write_v(_handles[fd]->data, buf, count);
+}
+
+int
+io_ftruncate(int fd, off_t length)
+{
+	if(!io_initialized && io_init() != 0) {
+		errno = EIO;
+		return -1;
+	}
+	if(!_handles[fd])
+		return ftruncate(fd, length);
+	return _handles[fd]->io_ftruncate_v(_handles[fd]->data, length);
+}
+
+off_t
+io_lseek(int fd, off_t offset, int whence)
+{
+	if(!io_initialized && io_init() != 0) {
+		errno = EIO;
+                return -1;
+	}
+	
+	if(!_handles[fd])
+		return lseek(fd, offset, whence);
+
+	return _handles[fd]->io_lseek_v(_handles[fd]->data, offset, whence);
+}
+
+int
+io_close(int fd)
+{
+	int ret;
+	if(!io_initialized && io_init() != 0) {
+		errno = EIO;
+		return -1;
+	}
+		
+	if(!_handles[fd])
+		return close(fd);
+	ret = _handles[fd]->io_close_v(_handles[fd]->data);	
+	free(_handles[fd]);
+	_handles[fd]=NULL;
+	return ret;
+}
+
+int
+io_stat(const char *file_name, struct stat *buf)
+{
+	if(!io_initialized && io_init() != 0) {
+		errno = EIO;
+                return -1;
+	}
+
+	if(strncmp(file_name, IBP_URI, strlen(IBP_URI)) == 0) {
+		return ibp_stat(file_name, buf);
+	}
+	return stat(file_name, buf);
+}
+
+int
+io_lstat(const char *file_name, struct stat *buf)
+{
+        if(!io_initialized && io_init() != 0) {
+                errno = EIO;
+                return -1;
+        }
+
+	if(strncmp(file_name, IBP_URI, strlen(IBP_URI)) == 0) {
+		return ibp_lstat(file_name, buf);
+        }
+        return lstat(file_name, buf);
+}
+
+int
+io_fstat(int fd, struct stat *buf)
+{
+        if(!io_initialized && io_init() != 0) {
+                errno = EIO;
+                return -1;
+        }
+
+        return _handles[fd]->io_fstat_v(_handles[fd]->data, buf);
+}
+
+int
+ibp_fill_buffer(struct stream_st *s, char *buffer, int max_len)
+{
+        ibp_read(s->priv, buffer, max_len);
+}
+
+int
+ibp_write_buffer(struct stream_st *s, char *buffer, int len)
+{
+        ibp_write(s->priv, buffer, len);
+}
+
+int
+ibp_seek(struct stream_st *s, off_t pos)
+{
+        s->pos = pos;
+        if(ibp_lseek(s->priv, pos, SEEK_SET) >= 0)
+                return 1;
+        else
+                return 0;
+}
+
+void
+ibp_sclose(struct stream_st *s)
+{
+        ibp_close(s->priv);
+}
+
+stream_t*
+stream_open_ibp(char *filename, char **options, int *file_format)
+{
+        stream_t *s;
+
+        s = new_stream(-2,-2);
+        s->url = strdup(filename);
+        s->type = STREAMTYPE_FILE;
+        s->seek = ibp_seek;
+        s->fill_buffer = ibp_fill_buffer;
+        s->write_buffer = ibp_write_buffer;
+        s->close = ibp_sclose;
+        s->flags = STREAM_SEEK;
+        *file_format =  DEMUXER_TYPE_UNKNOWN;
+        s->priv = ibp_open(filename, O_RDONLY, 0);
+        s->end_pos = ((struct io_ibp_handle_t*)s->priv)->ex->logical_length;
+        return s;
+}


More information about the MPlayer-dev-eng mailing list