mirror of https://github.com/mpv-player/mpv
cache, stream: avoid extra memcpy when using cache
Add a stream_read_internal() function that reads directly into a given buffer instead of the stream's internal one. Use this to read directly into cache memory, avoiding a memcpy(). This requires also adding a stream_seek_internal() as the normal seek function reads into the stream's buffer. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@32559 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
c6fb4e2aa2
commit
f94717cdc4
|
@ -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;
|
||||
|
|
121
stream/stream.c
121
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(newpos<s->pos){
|
||||
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(newpos<s->pos){
|
||||
mp_msg(MSGT_STREAM,MSGL_INFO,"Cannot seek backward in linear streams!\n");
|
||||
return 1;
|
||||
}
|
||||
while(s->pos<newpos){
|
||||
if(stream_fill_buffer(s)<=0) break; // EOF
|
||||
}
|
||||
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;
|
||||
}
|
||||
while(s->pos<newpos){
|
||||
if(stream_fill_buffer(s)<=0) break; // EOF
|
||||
}
|
||||
// putchar('.');fflush(stdout);
|
||||
//} else {
|
||||
// putchar('%');fflush(stdout);
|
||||
}
|
||||
|
||||
s->eof = 0; // EOF reset when seek succeeds.
|
||||
while (stream_fill_buffer(s) > 0) {
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue