[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