19 #define closesocket close
26 #include "osdep/shmem.h"
35 void cache_uninit(stream_t
*s
); // defined in cache2.c
37 //#include "vcd_read_bincue.h"
40 extern stream_info_t stream_info_vcd
;
43 extern stream_info_t stream_info_cdda
;
45 #ifdef MPLAYER_NETWORK
46 extern stream_info_t stream_info_netstream
;
47 extern stream_info_t stream_info_pnm
;
48 extern stream_info_t stream_info_asf
;
49 extern stream_info_t stream_info_rtsp
;
50 extern stream_info_t stream_info_rtp_udp
;
51 extern stream_info_t stream_info_http1
;
52 extern stream_info_t stream_info_http2
;
54 #ifdef HAS_DVBIN_SUPPORT
55 extern stream_info_t stream_info_dvb
;
58 extern stream_info_t stream_info_ftp
;
61 extern stream_info_t stream_info_vstream
;
64 extern stream_info_t stream_info_dvdnav
;
67 extern stream_info_t stream_info_smb
;
69 #ifdef STREAMING_LIVE555
70 extern stream_info_t stream_info_sdp
;
71 extern stream_info_t stream_info_rtsp_sip
;
74 extern stream_info_t stream_info_cue
;
75 extern stream_info_t stream_info_null
;
76 extern stream_info_t stream_info_file
;
78 extern stream_info_t stream_info_dvd
;
81 stream_info_t
* auto_open_streams
[] = {
88 #ifdef MPLAYER_NETWORK
89 &stream_info_netstream
,
94 #ifdef STREAMING_LIVE555
96 &stream_info_rtsp_sip
,
101 #ifdef HAS_DVBIN_SUPPORT
108 &stream_info_vstream
,
126 stream_t
* open_stream_plugin(stream_info_t
* sinfo
,char* filename
,int mode
,
127 char** options
, int* file_format
, int* ret
) {
130 m_struct_t
* desc
= (m_struct_t
*)sinfo
->opts
;
134 arg
= m_struct_alloc(desc
);
135 if(sinfo
->opts_url
) {
137 { "stream url", arg
, CONF_TYPE_CUSTOM_URL
, 0, 0 ,0, sinfo
->opts
};
138 if(m_option_parse(&url_opt
,"stream url",filename
,arg
,M_CONFIG_FILE
) < 0) {
139 mp_msg(MSGT_OPEN
,MSGL_ERR
, "URL parsing failed on url %s\n",filename
);
140 m_struct_free(desc
,arg
);
146 for(i
= 0 ; options
[i
] != NULL
; i
+= 2) {
147 mp_msg(MSGT_OPEN
,MSGL_DBG2
, "Set stream arg %s=%s\n",
148 options
[i
],options
[i
+1]);
149 if(!m_struct_set(desc
,arg
,options
[i
],options
[i
+1]))
150 mp_msg(MSGT_OPEN
,MSGL_WARN
, "Failed to set stream option %s=%s\n",
151 options
[i
],options
[i
+1]);
155 s
= new_stream(-2,-2);
156 s
->url
=strdup(filename
);
158 *ret
= sinfo
->open(s
,mode
,arg
,file_format
);
159 if((*ret
) != STREAM_OK
) {
165 mp_msg(MSGT_OPEN
,MSGL_WARN
, "Warning streams need a type !!!!\n");
166 if(s
->flags
& STREAM_SEEK
&& !s
->seek
)
167 s
->flags
&= ~STREAM_SEEK
;
168 if(s
->seek
&& !(s
->flags
& STREAM_SEEK
))
169 s
->flags
|= STREAM_SEEK
;
172 mp_msg(MSGT_OPEN
,MSGL_V
, "STREAM: [%s] %s\n",sinfo
->name
,filename
);
173 mp_msg(MSGT_OPEN
,MSGL_V
, "STREAM: Description: %s\n",sinfo
->info
);
174 mp_msg(MSGT_OPEN
,MSGL_V
, "STREAM: Author: %s\n", sinfo
->author
);
175 mp_msg(MSGT_OPEN
,MSGL_V
, "STREAM: Comment: %s\n", sinfo
->comment
);
181 stream_t
* open_stream_full(char* filename
,int mode
, char** options
, int* file_format
) {
183 stream_info_t
* sinfo
;
186 for(i
= 0 ; auto_open_streams
[i
] ; i
++) {
187 sinfo
= auto_open_streams
[i
];
188 if(!sinfo
->protocols
) {
189 mp_msg(MSGT_OPEN
,MSGL_WARN
, "Stream type %s has protocols == NULL, it's a bug\n", sinfo
->name
);
192 for(j
= 0 ; sinfo
->protocols
[j
] ; j
++) {
193 l
= strlen(sinfo
->protocols
[j
]);
194 // l == 0 => Don't do protocol matching (ie network and filenames)
195 if((l
== 0) || ((strncmp(sinfo
->protocols
[j
],filename
,l
) == 0) &&
196 (strncmp("://",filename
+l
,3) == 0))) {
197 *file_format
= DEMUXER_TYPE_UNKNOWN
;
198 s
= open_stream_plugin(sinfo
,filename
,mode
,options
,file_format
,&r
);
200 if(r
!= STREAM_UNSUPORTED
) {
201 mp_msg(MSGT_OPEN
,MSGL_ERR
, MSGTR_FailedToOpen
,filename
);
209 mp_msg(MSGT_OPEN
,MSGL_ERR
, "No stream found to handle url %s\n",filename
);
213 //=================== STREAMER =========================
215 int stream_fill_buffer(stream_t
*s
){
217 if (/*s->fd == NULL ||*/ s
->eof
) { s
->buf_pos
= s
->buf_len
= 0; return 0; }
219 case STREAMTYPE_STREAM
:
220 #ifdef MPLAYER_NETWORK
221 if( s
->streaming_ctrl
!=NULL
) {
222 len
=s
->streaming_ctrl
->streaming_read(s
->fd
,s
->buffer
,STREAM_BUFFER_SIZE
, s
->streaming_ctrl
);break;
224 len
=read(s
->fd
,s
->buffer
,STREAM_BUFFER_SIZE
);break;
227 len
=read(s
->fd
,s
->buffer
,STREAM_BUFFER_SIZE
);break;
230 len
= demux_read_data((demux_stream_t
*)s
->priv
,s
->buffer
,STREAM_BUFFER_SIZE
);
235 len
= s
->fill_buffer
? s
->fill_buffer(s
,s
->buffer
,STREAM_BUFFER_SIZE
) : 0;
237 if(len
<=0){ s
->eof
=1; s
->buf_pos
=s
->buf_len
=0; return 0; }
241 // printf("[%d]",len);fflush(stdout);
245 int stream_seek_long(stream_t
*s
,off_t pos
){
248 // if( mp_msg_test(MSGT_STREAM,MSGL_DBG3) ) printf("seek_long to 0x%X\n",(unsigned int)pos);
250 s
->buf_pos
=s
->buf_len
=0;
253 case STREAMTYPE_STREAM
:
254 #ifdef _LARGEFILE_SOURCE
255 newpos
=pos
&(~((long long)STREAM_BUFFER_SIZE
-1));break;
257 newpos
=pos
&(~(STREAM_BUFFER_SIZE
-1));break;
260 // Round on sector size
262 newpos
=(pos
/s
->sector_size
)*s
->sector_size
;
263 else { // Otherwise on the buffer size
264 #ifdef _LARGEFILE_SOURCE
265 newpos
=pos
&(~((long long)STREAM_BUFFER_SIZE
-1));break;
267 newpos
=pos
&(~(STREAM_BUFFER_SIZE
-1));break;
273 if( mp_msg_test(MSGT_STREAM
,MSGL_DBG3
) ){
274 mp_msg(MSGT_STREAM
,MSGL_DBG3
, "s->pos=%"PRIX64
" newpos=%"PRIX64
" new_bufpos=%"PRIX64
" buflen=%X \n",
275 (int64_t)s
->pos
,(int64_t)newpos
,(int64_t)pos
,s
->buf_len
);
279 if(newpos
==0 || newpos
!=s
->pos
){
281 case STREAMTYPE_STREAM
:
282 //s->pos=newpos; // real seek
283 // Some streaming protocol allow to seek backward and forward
284 // A function call that return -1 can tell that the protocol
285 // doesn't support seeking.
286 #ifdef MPLAYER_NETWORK
287 if(s
->seek
) { // new stream seek is much cleaner than streaming_ctrl one
288 if(!s
->seek(s
,newpos
)) {
289 mp_msg(MSGT_STREAM
,MSGL_ERR
, "Seek failed\n");
295 if( s
->streaming_ctrl
!=NULL
&& s
->streaming_ctrl
->streaming_seek
) {
296 if( s
->streaming_ctrl
->streaming_seek( s
->fd
, pos
, s
->streaming_ctrl
)<0 ) {
297 mp_msg(MSGT_STREAM
,MSGL_INFO
,"Stream not seekable!\n");
303 mp_msg(MSGT_STREAM
,MSGL_INFO
,"Cannot seek backward in linear streams!\n");
306 while(s
->pos
<newpos
){
307 if(stream_fill_buffer(s
)<=0) break; // EOF
312 // This should at the beginning as soon as all streams are converted
316 if(!s
->seek(s
,newpos
)) {
317 mp_msg(MSGT_STREAM
,MSGL_ERR
, "Seek failed\n");
321 // putchar('.');fflush(stdout);
323 // putchar('%');fflush(stdout);
326 while(stream_fill_buffer(s
) > 0 && pos
>= 0) {
328 s
->buf_pos
=pos
; // byte position in sector
334 // if(pos==s->buf_len) printf("XXX Seek to last byte of file -> EOF\n");
336 mp_msg(MSGT_STREAM
,MSGL_V
,"stream_seek: WARNING! Can't seek to 0x%"PRIX64
" !\n",(int64_t)(pos
+newpos
));
341 void stream_reset(stream_t
*s
){
343 s
->pos
=0; //ftell(f);
344 // s->buf_pos=s->buf_len=0;
347 if(s
->control
) s
->control(s
,STREAM_CTRL_RESET
,NULL
);
351 int stream_control(stream_t
*s
, int cmd
, void *arg
){
352 if(!s
->control
) return STREAM_UNSUPORTED
;
353 return s
->control(s
, cmd
, arg
);
356 stream_t
* new_memory_stream(unsigned char* data
,int len
){
357 stream_t
*s
=malloc(sizeof(stream_t
)+len
);
358 memset(s
,0,sizeof(stream_t
));
360 s
->type
=STREAMTYPE_MEMORY
;
361 s
->buf_pos
=0; s
->buf_len
=len
;
362 s
->start_pos
=0; s
->end_pos
=len
;
365 memcpy(s
->buffer
,data
,len
);
369 stream_t
* new_stream(int fd
,int type
){
370 stream_t
*s
=malloc(sizeof(stream_t
));
371 if(s
==NULL
) return NULL
;
372 memset(s
,0,sizeof(stream_t
));
377 int temp
= WSAStartup(0x0202, &wsdata
); // there might be a better place for this (-> later)
378 mp_msg(MSGT_STREAM
,MSGL_V
,"WINSOCK2 init: %i\n", temp
);
384 s
->buf_pos
=s
->buf_len
=0;
385 s
->start_pos
=s
->end_pos
=0;
393 void free_stream(stream_t
*s
){
394 // printf("\n*** free_stream() called ***\n");
395 #ifdef USE_STREAM_CACHE
400 if(s
->close
) s
->close(s
);
402 /* on unix we define closesocket to close
403 on windows however we have to distinguish between
404 network socket and file */
405 if(s
->url
&& strstr(s
->url
,"://"))
410 mp_msg(MSGT_STREAM
,MSGL_V
,"WINSOCK2 uninit\n");
411 WSACleanup(); // there might be a better place for this (-> later)
413 // Disabled atm, i don't like that. s->priv can be anything after all
414 // streams should destroy their priv on close
415 //if(s->priv) free(s->priv);
416 if(s
->url
) free(s
->url
);
420 stream_t
* new_ds_stream(demux_stream_t
*ds
) {
421 stream_t
* s
= new_stream(-1,STREAMTYPE_DS
);