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;