diff options
author | Uoti Urpala <uau@mplayer2.org> | 2011-05-02 00:46:03 +0300 |
---|---|---|
committer | Uoti Urpala <uau@mplayer2.org> | 2011-05-02 00:46:03 +0300 |
commit | 7e65428712beacd416dc3410c52f22ebfd3b4c53 (patch) | |
tree | 79bb2f4388be7031b5505c7745e1a59aff6cff56 /stream | |
parent | 5c4b059f1608f6d6a981b7d81a14f1c46e40ba52 (diff) | |
parent | d0376729d171a6c0b4cc15928c168f68adefbaa6 (diff) | |
download | mpv-7e65428712beacd416dc3410c52f22ebfd3b4c53.tar.bz2 mpv-7e65428712beacd416dc3410c52f22ebfd3b4c53.tar.xz |
Merge branch 'mplayer1_changes'
Diffstat (limited to 'stream')
-rw-r--r-- | stream/cache2.c | 20 | ||||
-rw-r--r-- | stream/network.c | 7 | ||||
-rw-r--r-- | stream/network.h | 2 | ||||
-rw-r--r-- | stream/stream.c | 24 | ||||
-rw-r--r-- | stream/stream_dvdnav.c | 7 | ||||
-rw-r--r-- | stream/stream_ffmpeg.c | 1 | ||||
-rw-r--r-- | stream/stream_file.c | 12 | ||||
-rw-r--r-- | stream/stream_smb.c | 12 |
8 files changed, 76 insertions, 9 deletions
diff --git a/stream/cache2.c b/stream/cache2.c index 9e4bea35b4..e930d72255 100644 --- a/stream/cache2.c +++ b/stream/cache2.c @@ -167,6 +167,7 @@ static int cache_fill(cache_vars_t *s) int back,back2,newb,space,len,pos; off_t read=s->read_filepos; int read_chunk; + int wraparound_copy = 0; if(read<s->min_filepos || read>s->max_filepos){ // seek... @@ -208,8 +209,16 @@ static int cache_fill(cache_vars_t *s) // printf("### read=0x%X back=%d newb=%d space=%d pos=%d\n",read,back,newb,space,pos); - // reduce space if needed: - if(space>s->buffer_size-pos) space=s->buffer_size-pos; + // try to avoid wrap-around. If not possible due to sector size + // do an extra copy. + if(space>s->buffer_size-pos) { + if (s->buffer_size-pos >= s->sector_size) { + space=s->buffer_size-pos; + } else { + space = s->sector_size; + wraparound_copy = 1; + } + } // limit one-time block size read_chunk = s->stream->read_chunk; @@ -224,6 +233,13 @@ static int cache_fill(cache_vars_t *s) s->min_filepos=read-back; // avoid seeking-back to temp area... #endif + if (wraparound_copy) { + int to_copy; + len = stream_read_internal(s->stream, s->stream->buffer, space); + to_copy = FFMIN(len, s->buffer_size-pos); + memcpy(s->buffer + pos, s->stream->buffer, to_copy); + memcpy(s->buffer, s->stream->buffer + to_copy, len - to_copy); + } else len = stream_read_internal(s->stream, &s->buffer[pos], space); s->eof= !len; diff --git a/stream/network.c b/stream/network.c index c6776ac29a..b722023061 100644 --- a/stream/network.c +++ b/stream/network.c @@ -58,6 +58,7 @@ int network_bandwidth=0; int network_cookies_enabled = 0; char *network_useragent=NULL; char *network_referrer=NULL; +char **network_http_header_fields=NULL; /* IPv6 options */ int network_ipv4_only_proxy = 0; @@ -250,6 +251,12 @@ http_send_request( URL_t *url, off_t pos ) { if (network_cookies_enabled) cookies_set( http_hdr, server_url->hostname, server_url->url ); + if (network_http_header_fields) { + int i=0; + while (network_http_header_fields[i]) + http_set_field(http_hdr, network_http_header_fields[i++]); + } + http_set_field( http_hdr, "Connection: close"); if (proxy) http_add_basic_proxy_authentication(http_hdr, url->username, url->password); diff --git a/stream/network.h b/stream/network.h index 1c395acc49..33b668c516 100644 --- a/stream/network.h +++ b/stream/network.h @@ -61,6 +61,8 @@ typedef struct { extern const mime_struct_t mime_type_table[]; +extern char **network_http_header_fields; + streaming_ctrl_t *streaming_ctrl_new(void); int streaming_bufferize( streaming_ctrl_t *streaming_ctrl, char *buffer, int size); diff --git a/stream/stream.c b/stream/stream.c index 86dd61389e..9a3f25f8ab 100644 --- a/stream/stream.c +++ b/stream/stream.c @@ -28,6 +28,7 @@ #endif #include <fcntl.h> #include <strings.h> +#include <assert.h> #include "talloc.h" @@ -279,6 +280,7 @@ void stream_capture_do(stream_t *s) int stream_read_internal(stream_t *s, void *buf, int len) { + int orig_len = len; // we will retry even if we already reached EOF previously. switch(s->type){ case STREAMTYPE_STREAM: @@ -300,7 +302,26 @@ int stream_read_internal(stream_t *s, void *buf, int len) default: len= s->fill_buffer ? s->fill_buffer(s, buf, len) : 0; } - if(len<=0){ s->eof=1; return 0; } + if(len<=0){ + // dvdnav has some horrible hacks to "suspend" reads, + // we need to skip this code or seeks will hang. + if (!s->eof && s->type != STREAMTYPE_DVDNAV) { + // just in case this is an error e.g. due to network + // timeout reset and retry + // Seeking is used as a hack to make network streams + // reopen the connection, ideally they would implement + // e.g. a STREAM_CTRL_RECONNECT to do this + off_t pos = s->pos; + s->eof=1; + stream_reset(s); + stream_seek_internal(s, pos); + // make sure EOF is set to ensure no endless loops + s->eof=1; + return stream_read_internal(s, buf, orig_len); + } + s->eof=1; + return 0; + } // When reading succeeded we are obviously not at eof. // This e.g. avoids issues with eof getting stuck when lavf seeks in MPEG-TS s->eof=0; @@ -328,6 +349,7 @@ int stream_write_buffer(stream_t *s, unsigned char *buf, int len) { if(rd < 0) return -1; s->pos += rd; + assert(rd == len && "stream_write_buffer(): unexpected short write"); return rd; } diff --git a/stream/stream_dvdnav.c b/stream/stream_dvdnav.c index b1c51e68e9..d5b12dc9f6 100644 --- a/stream/stream_dvdnav.c +++ b/stream/stream_dvdnav.c @@ -134,7 +134,7 @@ static dvdnav_priv_t * new_dvdnav_stream(char * filename) { mp_msg(MSGT_OPEN,MSGL_ERR,"stream_dvdnav, failed to set PGC positioning\n"); /* report the title?! */ if (dvdnav_get_title_string(priv->dvdnav,&title_str)==DVDNAV_STATUS_OK) { - mp_msg(MSGT_IDENTIFY, MSGL_INFO,"Title: '%s'\n",title_str); + mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_DVD_VOLUME_ID=%s\n", title_str); } //dvdnav_event_clear(priv); @@ -509,7 +509,9 @@ static void identify_chapters(dvdnav_t *nav, uint32_t title) if(parts) { t = duration / 90; mp_msg(MSGT_IDENTIFY, MSGL_V, "ID_DVD_TITLE_%d_LENGTH=%d.%03d\n", title, t / 1000, t % 1000); + mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_DVD_TITLE_%d_CHAPTERS=%d\n", title, n); mp_msg(MSGT_IDENTIFY, MSGL_INFO, "TITLE %u, CHAPTERS: ", title); + for(i=0; i<n; i++) { t = parts[i] / 90000; mp_msg(MSGT_IDENTIFY, MSGL_INFO, "%02d:%02d:%02d,", t/3600, (t/60)%60, t%60); @@ -524,7 +526,7 @@ static void identify(dvdnav_priv_t *priv, struct stream_priv_s *p) uint32_t titles=0, i; if(p->track <= 0) { dvdnav_get_number_of_titles(priv->dvdnav, &titles); - for(i=0; i<titles; i++) + for(i=1; i<=titles; i++) identify_chapters(priv->dvdnav, i); } else @@ -600,6 +602,7 @@ static int open_s(stream_t *stream,int mode, void* opts, int* file_format) { mp_msg(MSGT_OPEN,MSGL_FATAL,"dvdnav_stream, couldn't select title %d, error '%s'\n", p->track, dvdnav_err_to_string(priv->dvdnav)); return STREAM_UNSUPPORTED; } + mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_DVD_CURRENT_TITLE=%d\n", p->track); } else if (p->track == 0) { if(dvdnav_menu_call(priv->dvdnav, DVD_MENU_Root) != DVDNAV_STATUS_OK) dvdnav_menu_call(priv->dvdnav, DVD_MENU_Title); diff --git a/stream/stream_ffmpeg.c b/stream/stream_ffmpeg.c index e6705883fc..343381afb0 100644 --- a/stream/stream_ffmpeg.c +++ b/stream/stream_ffmpeg.c @@ -34,6 +34,7 @@ static int fill_buffer(stream_t *s, char *buffer, int max_len) static int write_buffer(stream_t *s, char *buffer, int len) { + /* url_write retries internally on short writes and EAGAIN */ int r = url_write(s->priv, buffer, len); return (r <= 0) ? -1 : r; } diff --git a/stream/stream_file.c b/stream/stream_file.c index 22be803fba..6d436cf6f5 100644 --- a/stream/stream_file.c +++ b/stream/stream_file.c @@ -56,8 +56,16 @@ static int fill_buffer(stream_t *s, char* buffer, int max_len){ } static int write_buffer(stream_t *s, char* buffer, int len) { - int r = write(s->fd,buffer,len); - return (r <= 0) ? -1 : r; + int r; + int wr = 0; + while (wr < len) { + r = write(s->fd,buffer,len); + if (r <= 0) + return -1; + wr += r; + buffer += r; + } + return len; } static int seek(stream_t *s,off_t newpos) { diff --git a/stream/stream_smb.c b/stream/stream_smb.c index 14791a2995..f176bc7518 100644 --- a/stream/stream_smb.c +++ b/stream/stream_smb.c @@ -100,8 +100,16 @@ static int fill_buffer(stream_t *s, char* buffer, int max_len){ } static int write_buffer(stream_t *s, char* buffer, int len) { - int r = smbc_write(s->fd,buffer,len); - return (r <= 0) ? -1 : r; + int r; + int wr = 0; + while (wr < len) { + r = smbc_write(s->fd,buffer,len); + if (r <= 0) + return -1; + wr += r; + buffer += r; + } + return len; } static void close_f(stream_t *s){ |