diff --git a/stream/cache2.c b/stream/cache2.c index 2b0b8d739d..d7a8005917 100644 --- a/stream/cache2.c +++ b/stream/cache2.c @@ -181,7 +181,7 @@ static int cache_fill(cache_vars_t *s) s->offset= // FIXME!? s->min_filepos=s->max_filepos=read; // drop cache content :( if(s->stream->eof) stream_reset(s->stream); - stream_seek(s->stream,read); + stream_seek_internal(s->stream,read); mp_msg(MSGT_CACHE,MSGL_DBG2,"Seek done. new pos: 0x%"PRIX64" \n",(int64_t)stream_tell(s->stream)); } } @@ -223,7 +223,7 @@ static int cache_fill(cache_vars_t *s) s->min_filepos=read-back; // avoid seeking-back to temp area... #endif - len=stream_read(s->stream,&s->buffer[pos],space); + len = stream_read_internal(s->stream, &s->buffer[pos], space); s->eof= !len; s->max_filepos+=len; diff --git a/stream/stream.c b/stream/stream.c index ca45f511e5..041b3a8c67 100644 --- a/stream/stream.c +++ b/stream/stream.c @@ -275,36 +275,43 @@ void stream_capture_do(stream_t *s) } } -int stream_fill_buffer(stream_t *s){ - int len; +int stream_read_internal(stream_t *s, void *buf, int len) +{ // we will retry even if we already reached EOF previously. switch(s->type){ case STREAMTYPE_STREAM: #ifdef CONFIG_NETWORKING if( s->streaming_ctrl!=NULL && s->streaming_ctrl->streaming_read ) { - len=s->streaming_ctrl->streaming_read(s->fd,s->buffer,STREAM_BUFFER_SIZE, s->streaming_ctrl); + len=s->streaming_ctrl->streaming_read(s->fd, buf, len, s->streaming_ctrl); } else #endif if (s->fill_buffer) - len = s->fill_buffer(s, s->buffer, STREAM_BUFFER_SIZE); + len = s->fill_buffer(s, buf, len); else - len=read(s->fd,s->buffer,STREAM_BUFFER_SIZE); + len = read(s->fd, buf, len); break; case STREAMTYPE_DS: - len = demux_read_data((demux_stream_t*)s->priv,s->buffer,STREAM_BUFFER_SIZE); + len = demux_read_data((demux_stream_t*)s->priv, buf, len); break; default: - len= s->fill_buffer ? s->fill_buffer(s,s->buffer,STREAM_BUFFER_SIZE) : 0; + len= s->fill_buffer ? s->fill_buffer(s, buf, len) : 0; } if(len<=0){ 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; + s->pos+=len; + return len; +} + +int stream_fill_buffer(stream_t *s){ + int len = stream_read_internal(s, s->buffer, STREAM_BUFFER_SIZE); + if (len <= 0) + return 0; s->buf_pos=0; s->buf_len=len; - s->pos+=len; // printf("[%d]",len);fflush(stdout); if (s->capture_file) stream_capture_do(s); @@ -322,7 +329,56 @@ int stream_write_buffer(stream_t *s, unsigned char *buf, int len) { return rd; } +int stream_seek_internal(stream_t *s, off_t newpos) +{ +if(newpos==0 || newpos!=s->pos){ + switch(s->type){ + case STREAMTYPE_STREAM: + //s->pos=newpos; // real seek + // Some streaming protocol allow to seek backward and forward + // A function call that return -1 can tell that the protocol + // doesn't support seeking. +#ifdef CONFIG_NETWORKING + if(s->seek) { // new stream seek is much cleaner than streaming_ctrl one + if(!s->seek(s,newpos)) { + mp_msg(MSGT_STREAM,MSGL_ERR, "Seek failed\n"); + return 0; + } + break; + } + + if( s->streaming_ctrl!=NULL && s->streaming_ctrl->streaming_seek ) { + if( s->streaming_ctrl->streaming_seek( s->fd, newpos, s->streaming_ctrl )<0 ) { + mp_msg(MSGT_STREAM,MSGL_INFO,"Stream not seekable!\n"); + return 1; + } + break; + } +#endif + if(newpospos){ + mp_msg(MSGT_STREAM,MSGL_INFO,"Cannot seek backward in linear streams!\n"); + return 1; + } + break; + default: + // 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 { +// putchar('%');fflush(stdout); +} + return -1; +} + int stream_seek_long(stream_t *s,off_t pos){ + int res; off_t newpos=0; // if( mp_msg_test(MSGT_STREAM,MSGL_DBG3) ) printf("seek_long to 0x%X\n",(unsigned int)pos); @@ -346,52 +402,13 @@ if( mp_msg_test(MSGT_STREAM,MSGL_DBG3) ){ } pos-=newpos; -if(newpos==0 || newpos!=s->pos){ - switch(s->type){ - case STREAMTYPE_STREAM: - //s->pos=newpos; // real seek - // Some streaming protocol allow to seek backward and forward - // A function call that return -1 can tell that the protocol - // doesn't support seeking. -#ifdef CONFIG_NETWORKING - if(s->seek) { // new stream seek is much cleaner than streaming_ctrl one - if(!s->seek(s,newpos)) { - mp_msg(MSGT_STREAM,MSGL_ERR, "Seek failed\n"); - return 0; - } - break; - } + res = stream_seek_internal(s, newpos); + if (res >= 0) + return res; - if( s->streaming_ctrl!=NULL && s->streaming_ctrl->streaming_seek ) { - if( s->streaming_ctrl->streaming_seek( s->fd, pos, s->streaming_ctrl )<0 ) { - mp_msg(MSGT_STREAM,MSGL_INFO,"Stream not seekable!\n"); - return 1; - } - break; - } -#endif - if(newpospos){ - mp_msg(MSGT_STREAM,MSGL_INFO,"Cannot seek backward in linear streams!\n"); - return 1; - } - while(s->posseek) - return 0; - // Now seek - if(!s->seek(s,newpos)) { - mp_msg(MSGT_STREAM,MSGL_ERR, "Seek failed\n"); - return 0; - } + while(s->poseof = 0; // EOF reset when seek succeeds. while (stream_fill_buffer(s) > 0) { diff --git a/stream/stream.h b/stream/stream.h index 8e4b260ffb..6d56e2adab 100644 --- a/stream/stream.h +++ b/stream/stream.h @@ -344,6 +344,10 @@ void stream_set_interrupt_callback(int (*cb)(struct input_ctx*, int), /// Call the interrupt checking callback if there is one and /// wait for time milliseconds int stream_check_interrupt(int time); +/// Internal read function bypassing the stream buffer +int stream_read_internal(stream_t *s, void *buf, int len); +/// Internal seek function bypassing the stream buffer +int stream_seek_internal(stream_t *s, off_t newpos); extern int bluray_angle; extern int bluray_chapter;