From f8c32fc953320b93c5975c03d3d2f8a5febce498 Mon Sep 17 00:00:00 2001 From: ranma Date: Thu, 10 Feb 2011 21:25:38 +0000 Subject: stream: Make stream_write_buffer() check for short writes None of the calling sites to stream_write_buffer were checking the return value to see if all bytes got written (nothing in current code actually calls it any more after MEncoder was removed). This was causing (very occasionally) problems with mencoder when using output pipes AND running under a sandbox or when being straced (ptrace is the culprit). Theoretically this problem can happen without pipes or ptrace. Only stream_file, stream_smb and stream_ffmpeg implement write_buffer and ffmpeg already handles this internally. Original patch by Sang-Uok Kum. Signed-off-by: Tobias Diedrich git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@32881 b3059339-0415-0410-9bf9-f77b7e298cf2 --- stream/stream.c | 2 ++ stream/stream_ffmpeg.c | 1 + stream/stream_file.c | 12 ++++++++++-- stream/stream_smb.c | 12 ++++++++++-- 4 files changed, 23 insertions(+), 4 deletions(-) (limited to 'stream') diff --git a/stream/stream.c b/stream/stream.c index 6f35252e3d..34b6bc81f9 100644 --- a/stream/stream.c +++ b/stream/stream.c @@ -28,6 +28,7 @@ #endif #include #include +#include #include "config.h" @@ -326,6 +327,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_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 684940749f..714e80fe79 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){ -- cgit v1.2.3 From 76bc0055806ec9a0beb6f4631d072da99823094a Mon Sep 17 00:00:00 2001 From: cehoyos Date: Sun, 20 Feb 2011 18:07:48 +0000 Subject: stream_dvdnav: don't skip last title for dvdnav:// -identify Patch by Mike Castle, dalgoda+mplayer gmail git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@32944 b3059339-0415-0410-9bf9-f77b7e298cf2 --- stream/stream_dvdnav.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'stream') diff --git a/stream/stream_dvdnav.c b/stream/stream_dvdnav.c index 21522f8b6b..b6b8df4fc3 100644 --- a/stream/stream_dvdnav.c +++ b/stream/stream_dvdnav.c @@ -524,7 +524,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; idvdnav, i); } else -- cgit v1.2.3 From 67f5ef670c97a68c96351d96a8f1631d796c3bc9 Mon Sep 17 00:00:00 2001 From: reimar Date: Tue, 22 Feb 2011 22:27:01 +0000 Subject: stream: try to reset stream once if read fails When reading from a stream fails, try one more time after a reset. This should re-establish for example timed-out network connections. Fixes bug #1841. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@32954 b3059339-0415-0410-9bf9-f77b7e298cf2 100l, fix incorrect len when retrying read. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@32957 b3059339-0415-0410-9bf9-f77b7e298cf2 Improve stream reset on read error, should now fix bug #1841 in more cases, e.g. also with -cache. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@32977 b3059339-0415-0410-9bf9-f77b7e298cf2 Add ugly hack to compensate DVDNAV's ugly hacks and fix seeking. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@33122 b3059339-0415-0410-9bf9-f77b7e298cf2 --- stream/stream.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'stream') diff --git a/stream/stream.c b/stream/stream.c index 34b6bc81f9..62f6a1f171 100644 --- a/stream/stream.c +++ b/stream/stream.c @@ -278,6 +278,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: @@ -299,7 +300,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; -- cgit v1.2.3 From 85fb21f7a25fdfeaf3e8ae21ab03abe1221a6ca4 Mon Sep 17 00:00:00 2001 From: cehoyos Date: Mon, 28 Feb 2011 10:51:56 +0000 Subject: stream_dvdnav: identify: show more title information Add ID_DVD_TITLE_x_CHAPTERS and ID_DVD_CURRENT_TITLE to the output of dvdnav:// -identify. Patch by Mike Castle, dalgoda+mplayer A gmail git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@32982 b3059339-0415-0410-9bf9-f77b7e298cf2 --- stream/stream_dvdnav.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'stream') diff --git a/stream/stream_dvdnav.c b/stream/stream_dvdnav.c index b6b8df4fc3..73a2e11b6a 100644 --- a/stream/stream_dvdnav.c +++ b/stream/stream_dvdnav.c @@ -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; itrack, 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); -- cgit v1.2.3 From 4b5a86c78e67d0412c65f8d8b0830e8e450cd2ed Mon Sep 17 00:00:00 2001 From: cehoyos Date: Mon, 14 Mar 2011 00:07:11 +0000 Subject: stream_dvdnav: output ID_DVD_VOLUME_ID also for dvdnav:// Patch by Mike Castle, dalgoda+mplayer gmail git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@33081 b3059339-0415-0410-9bf9-f77b7e298cf2 --- stream/stream_dvdnav.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'stream') diff --git a/stream/stream_dvdnav.c b/stream/stream_dvdnav.c index 73a2e11b6a..ff0e715716 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); -- cgit v1.2.3 From c99d8fc8981d13203c2bbf9c12b7720cd8632ae1 Mon Sep 17 00:00:00 2001 From: cehoyos Date: Thu, 17 Mar 2011 08:58:49 +0000 Subject: stream: http: Allow setting custom http header Patch by Nikolay Nikolaev, nicknickolaev yahoo com git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@33082 b3059339-0415-0410-9bf9-f77b7e298cf2 --- stream/network.c | 7 +++++++ stream/network.h | 2 ++ 2 files changed, 9 insertions(+) (limited to 'stream') 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); -- cgit v1.2.3 From a37b71dc329b4cfc828db9c166c94d1221f2d46c Mon Sep 17 00:00:00 2001 From: reimar Date: Sat, 26 Mar 2011 20:04:47 +0000 Subject: cache: call stream read with at least sector size space Ensure we always pass a buffer of at least sector size to the read function. This is never an issue with streams that have actual sectors, as the reads will always return a multiple of sector size and the cache is always used in blocks of sector size. However the rtp protocol misuses this so it can just assume it always has a sufficiently large buffer available and thus fails without this extra hack. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@33120 b3059339-0415-0410-9bf9-f77b7e298cf2 --- stream/cache2.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'stream') 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(readmin_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; -- cgit v1.2.3