[Mplayer-cvslog] CVS: main/libmpdemux stream_file.c,NONE,1.1 stream.c,1.53,1.54 stream.h,1.58,1.59
Alban Bedel CVS
albeu at mplayerhq.hu
Wed Apr 2 18:25:10 CEST 2003
Update of /cvsroot/mplayer/main/libmpdemux
In directory mail:/var/tmp.root/cvs-serv2358/libmpdemux
Modified Files:
stream.c stream.h
Added Files:
stream_file.c
Log Message:
Stream modularization, the first step.
Only file stream are converted atm, other will come later.
--- NEW FILE ---
#include "config.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "mp_msg.h"
#include "stream.h"
#include "help_mp.h"
#include "../m_option.h"
#include "../m_struct.h"
static struct stream_priv_s {
char* filename;
} stream_priv_dflts = {
NULL
};
#define ST_OFF(f) M_ST_OFF(struct stream_priv_s,f)
/// URL definition
static m_option_t stream_opts_fields[] = {
{"filename", ST_OFF(filename), CONF_TYPE_STRING, 0, 0 ,0, NULL},
{ NULL, NULL, 0, 0, 0, 0, NULL }
};
static struct m_struct_st stream_opts = {
"file",
sizeof(struct stream_priv_s),
&stream_priv_dflts,
stream_opts_fields
};
static int fill_buffer(stream_t *s, char* buffer, int max_len){
int r = read(s->fd,buffer,max_len);
return (r <= 0) ? -1 : r;
}
static int write_buffer(stream_t *s, char* buffer, int len) {
int r = write(s->fd,buffer,len);
return (r <= 0) ? -1 : r;
}
static int seek(stream_t *s,off_t newpos) {
s->pos = newpos;
if(lseek(s->fd,s->pos,SEEK_SET)<0) {
s->eof=1;
return 0;
}
return 1;
}
static int seek_forward(stream_t *s,off_t newpos) {
if(newpos<s->pos){
mp_msg(MSGT_STREAM,MSGL_INFO,"Cannot seek backward in linear streams!\n");
return 0;
}
while(s->pos<newpos){
if(s->fill_buffer(s,s->buffer,STREAM_BUFFER_SIZE)<=0) break; // EOF
}
return 1;
}
static int open_f(stream_t *stream,int mode, void* opts, int* file_format) {
int f;
mode_t m = 0;
off_t len;
struct stream_priv_s* p = (struct stream_priv_s*)opts;
if(mode == STREAM_READ)
m = O_RDONLY;
else if(mode == STREAM_WRITE)
m = O_WRONLY;
else {
mp_msg(MSGT_OPEN,MSGL_ERR, "[file] Unknow open mode %d\n",mode);
m_struct_free(&stream_opts,opts);
return STREAM_UNSUPORTED;
}
#if defined(__CYGWIN__)|| defined(__MINGW32__)
m |= O_BINARY;
#endif
if(!strcmp(p->filename,"-")){
if(mode == STREAM_READ) {
// read from stdin
mp_msg(MSGT_OPEN,MSGL_INFO,MSGTR_ReadSTDIN);
f=0; // 0=stdin
} else {
mp_msg(MSGT_OPEN,MSGL_INFO,"Writing to stdout\n");
f=1;
}
} else {
f=open(p->filename,m);
if(f<0) {
mp_msg(MSGT_OPEN,MSGL_ERR,MSGTR_FileNotFound,p->filename);
m_struct_free(&stream_opts,opts);
return -1;
}
}
len=lseek(f,0,SEEK_END); lseek(f,0,SEEK_SET);
if(len == -1) {
stream->seek = seek_forward;
stream->type = STREAMTYPE_STREAM; // Must be move to STREAMTYPE_FILE
stream->flags |= STREAM_SEEK_FW;
} else if(len >= 0) {
stream->seek = seek;
stream->end_pos = len;
stream->type = STREAMTYPE_FILE;
}
#ifdef _LARGEFILE_SOURCE
mp_msg(MSGT_OPEN,MSGL_V,"[file] File size is %lld bytes\n", (long long)len);
#else
mp_msg(MSGT_OPEN,MSGL_V,"[file] File size is %u bytes\n", (unsigned int)len);
#endif
stream->fd = f;
stream->fill_buffer = fill_buffer;
stream->write_buffer = write_buffer;
m_struct_free(&stream_opts,opts);
return STREAM_OK;
}
stream_info_t stream_info_file = {
"File",
"file",
"Albeu",
"based on the code from ??? (probably Arpi)",
open_f,
{ "file", "", NULL },
&stream_opts,
1 // Urls are an option string
};
Index: stream.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/stream.c,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -r1.53 -r1.54
--- stream.c 2 Apr 2003 01:46:47 -0000 1.53
+++ stream.c 2 Apr 2003 16:25:07 -0000 1.54
@@ -9,6 +9,7 @@
#include <sys/wait.h>
#include <fcntl.h>
#include <signal.h>
+#include <strings.h>
#include "config.h"
#include "mp_msg.h"
@@ -18,6 +19,10 @@
#include "stream.h"
#include "demuxer.h"
+#include "../m_option.h"
+#include "../m_struct.h"
+
+
extern int verbose; // defined in mplayer.c
#include "cue_read.h"
@@ -52,6 +57,100 @@
#include "libsmbclient.h"
#endif
+extern stream_info_t stream_info_file;
+
+stream_info_t* auto_open_streams[] = {
+ &stream_info_file,
+ NULL
+};
+
+stream_t* open_stream_plugin(stream_info_t* sinfo,char* filename,int mode,
+ char** options, int* file_format, int* ret) {
+ void* arg = NULL;
+ stream_t* s;
+ m_struct_t* desc = (m_struct_t*)sinfo->opts;
+
+ // Parse options
+ if(desc) {
+ arg = m_struct_alloc(desc);
+ if(sinfo->opts_url) {
+ m_option_t url_opt =
+ { "stream url", arg , CONF_TYPE_CUSTOM_URL, 0, 0 ,0, sinfo->opts };
+ if(m_option_parse(&url_opt,"stream url",filename,arg,M_CONFIG_FILE) < 0) {
+ mp_msg(MSGT_OPEN,MSGL_ERR, "URL parsing failed on url %s\n",filename);
+ m_struct_free(desc,arg);
+ return NULL;
+ }
+ }
+ if(options) {
+ int i;
+ for(i = 0 ; options[i] != NULL ; i += 2) {
+ mp_msg(MSGT_OPEN,MSGL_DBG2, "Set stream arg %s=%s\n",
+ options[i],options[i+1]);
+ if(!m_struct_set(desc,arg,options[i],options[i+1]))
+ mp_msg(MSGT_OPEN,MSGL_WARN, "Failed to set stream option %s=%s\n",
+ options[i],options[i+1]);
+ }
+ }
+ }
+ s = new_stream(-2,-2);
+ s->url=strdup(filename);
+ s->flags |= mode;
+ *ret = sinfo->open(s,mode,arg,file_format);
+ if((*ret) != STREAM_OK) {
+ free(s->url);
+ free(s);
+ return NULL;
+ }
+ if(s->type <= -2)
+ mp_msg(MSGT_OPEN,MSGL_WARN, "Warning streams need a type !!!!\n");
+ if(s->flags & STREAM_SEEK && !s->seek)
+ s->flags &= ~STREAM_SEEK;
+ if(s->seek && !(s->flags & STREAM_SEEK))
+ s->flags &= STREAM_SEEK;
+
+
+ mp_msg(MSGT_OPEN,MSGL_V, "STREAM: [%s] %s\n",sinfo->name,filename);
+ mp_msg(MSGT_OPEN,MSGL_V, "STREAM: Description: %s\n",sinfo->info);
+ mp_msg(MSGT_OPEN,MSGL_V, "STREAM: Author: %s\n", sinfo->author);
+ mp_msg(MSGT_OPEN,MSGL_V, "STREAM: Comment: %s\n", sinfo->comment);
+
+ return s;
+}
+
+
+stream_t* open_stream_full(char* filename,int mode, char** options, int* file_format) {
+ int i,j,l,r;
+ stream_info_t* sinfo;
+ stream_t* s;
+
+ for(i = 0 ; auto_open_streams[i] ; i++) {
+ sinfo = auto_open_streams[i];
+ if(!sinfo->protocols) {
+ mp_msg(MSGT_OPEN,MSGL_WARN, "Stream type %s have protocols == NULL, it's a bug\n");
+ continue;
+ }
+ for(j = 0 ; sinfo->protocols[j] ; j++) {
+ l = strlen(sinfo->protocols[j]);
+ // l == 0 => Don't do protocol matching (ie network and filenames)
+ if((l == 0) || ((strncmp(sinfo->protocols[j],filename,l) == 0) &&
+ (strncmp("://",filename+l,3) == 0))) {
+ *file_format = DEMUXER_TYPE_UNKNOWN;
+ s = open_stream_plugin(sinfo,filename,mode,options,file_format,&r);
+ if(s) return s;
+ if(r != STREAM_UNSUPORTED) {
+ mp_msg(MSGT_OPEN,MSGL_ERR, "Failed to open %s\n",filename);
+ return NULL;
+ }
+ break;
+ }
+ }
+ }
+
+ mp_msg(MSGT_OPEN,MSGL_ERR, "No stream found to handle url %s\n",filename);
+ return NULL;
+}
+
//=================== STREAMER =========================
int stream_fill_buffer(stream_t *s){
@@ -63,9 +162,7 @@
len=smbc_read(s->fd,s->buffer,STREAM_BUFFER_SIZE);
break;
#endif
- case STREAMTYPE_FILE:
case STREAMTYPE_STREAM:
- case STREAMTYPE_PLAYLIST:
#ifdef STREAMING
if( s->streaming_ctrl!=NULL ) {
len=s->streaming_ctrl->streaming_read(s->fd,s->buffer,STREAM_BUFFER_SIZE, s->streaming_ctrl);break;
@@ -115,7 +212,8 @@
- default: len=0;
+ default:
+ len= s->fill_buffer ? s->fill_buffer(s,s->buffer,STREAM_BUFFER_SIZE) : 0;
}
if(len<=0){ s->eof=1; s->buf_pos=s->buf_len=0; return 0; }
s->buf_pos=0;
@@ -133,7 +231,6 @@
s->buf_pos=s->buf_len=0;
switch(s->type){
- case STREAMTYPE_FILE:
case STREAMTYPE_SMB:
case STREAMTYPE_STREAM:
#ifdef _LARGEFILE_SOURCE
@@ -151,6 +248,18 @@
case STREAMTYPE_CDDA:
newpos=(pos/VCD_SECTOR_SIZE)*VCD_SECTOR_SIZE;break;
#endif
+ default:
+ // Round on sector size
+ if(s->sector_size)
+ newpos=(pos/s->sector_size)*s->sector_size;
+ else { // Otherwise on the buffer size
+#ifdef _LARGEFILE_SOURCE
+ newpos=pos&(~((long long)STREAM_BUFFER_SIZE-1));break;
+#else
+ newpos=pos&(~(STREAM_BUFFER_SIZE-1));break;
+#endif
+ }
+ break;
}
if(verbose>=3){
@@ -167,10 +276,6 @@
if(newpos==0 || newpos!=s->pos){
switch(s->type){
- case STREAMTYPE_FILE:
- s->pos=newpos; // real seek
- if(lseek(s->fd,s->pos,SEEK_SET)<0) s->eof=1;
- break;
#ifdef LIBSMBCLIENT
case STREAMTYPE_SMB:
s->pos=newpos; // real seek
@@ -236,7 +341,14 @@
#endif
break;
default:
- return 0;
+ // This should at the beginning as soon as all streams are converted
+ if(!s->seek)
+ return 0;
+ // Now seek
+ if(!s->seek(s,newpos)) {
+ mp_msg(MSGT_STREAM,MSGL_ERR, "Seek failed\n");
+ return 0;
+ }
}
// putchar('.');fflush(stdout);
//} else {
@@ -328,8 +440,13 @@
case STREAMTYPE_DVD:
dvd_close(s->priv);
#endif
- }
- if(s->priv) free(s->priv);
+ default:
+ if(s->close) s->close(s);
+ }
+ // Disabled atm, i don't like that. s->priv can be anything after all
+ // streams should destroy their priv on close
+ //if(s->priv) free(s->priv);
+ if(s->url) free(s->url);
free(s);
}
Index: stream.h
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/stream.h,v
retrieving revision 1.58
retrieving revision 1.59
diff -u -r1.58 -r1.59
--- stream.h 30 Mar 2003 17:07:31 -0000 1.58
+++ stream.h 2 Apr 2003 16:25:07 -0000 1.59
@@ -26,6 +26,26 @@
#define VCD_SECTOR_OFFS 24
#define VCD_SECTOR_DATA 2324
+/// atm it will always use mode == STREAM_READ
+/// streams that use the new api should check the mode at open
+#define STREAM_READ 0
+#define STREAM_WRITE 1
+/// Seek flags, if not mannualy set and s->seek isn't NULL
+/// STREAM_SEEK is automaticly set
+#define STREAM_SEEK_BW 2
+#define STREAM_SEEK_FW 4
+#define STREAM_SEEK (STREAM_SEEK_BW|STREAM_SEEK_FW)
+
+//////////// Open return code
+/// This can't open the requested protocol (used by stream wich have a
+/// * protocol when they don't know the requested protocol)
+#define STREAM_UNSUPORTED -1
+#define STREAM_ERROR 0
+#define STREAM_OK 1
+
+#define MAX_STREAM_PROTOCOLS 10
+
+
#ifdef STREAMING
#include "network.h"
#endif
@@ -33,9 +53,41 @@
int vcd_seek_to_track(int fd,int track);
void vcd_read_toc(int fd);
+struct stream_st;
+typedef struct stream_info_st {
+ const char *info;
+ const char *name;
+ const char *author;
+ const char *comment;
+ /// mode isn't used atm (ie always READ) but it shouldn't be ignored
+ /// opts is at least in it's defaults settings and may have been
+ /// altered by url parsing if enabled and the options string parsing.
+ int (*open)(struct stream_st* st, int mode, void* opts, int* file_format);
+ char* protocols[MAX_STREAM_PROTOCOLS];
+ void* opts;
+ int opts_url; /* If this is 1 we will parse the url as an option string
+ * too. Otherwise options are only parsed from the
+ * options string given to open_stream_plugin */
+} stream_info_t;
+
typedef struct stream_st {
+ // Read
+ int (*fill_buffer)(struct stream_st *s, char* buffer, int max_len);
+ // Write
+ int (*write_buffer)(struct stream_st *s, char* buffer, int len);
+ // Seek
+ int (*seek)(struct stream_st *s,off_t pos);
+ // Control
+ // Will be later used to let streams like dvd and cdda report
+ // their structure (ie tracks, chapters, etc)
+ int (*control)(struct stream_st *s,int cmd,void* arg);
+ // Close
+ void (*close)(struct stream_st *s);
+
int fd; // file descriptor, see man open(2)
int type; // see STREAMTYPE_*
+ int flags;
+ int sector_size; // sector size (seek will be aligned on this size if non 0)
unsigned int buf_pos,buf_len;
off_t pos,start_pos,end_pos;
int eof;
@@ -187,7 +239,8 @@
stream_t* new_stream(int fd,int type);
void free_stream(stream_t *s);
stream_t* new_memory_stream(unsigned char* data,int len);
-stream_t* open_stream(char* filename,int vcd_track,int* file_format);
+stream_t* open_stream(char* filename,char** options,int* file_format);
+stream_t* open_stream_full(char* filename,int mode, char** options, int* file_format);
//#ifdef USE_DVDREAD
struct config;
More information about the MPlayer-cvslog
mailing list