int stream_seek_long(stream_t *s, int64_t pos){ int res; int64_t newpos=0; // if( mp_msg_test(MSGT_STREAM,MSGL_DBG3) ) printf("seek_long to 0x%X\n",(unsigned int)pos); s->buf_pos=s->buf_len=0; if(s->mode == STREAM_WRITE) { if(!s->seek || !s->seek(s,pos)) return 0; return 1; } if(s->sector_size) newpos = (pos/s->sector_size)*s->sector_size; else newpos = pos&(~((int64_t)STREAM_BUFFER_SIZE-1)); if( mp_msg_test(MSGT_STREAM,MSGL_DBG3) ){ mp_msg(MSGT_STREAM,MSGL_DBG3, "s->pos=%"PRIX64" newpos=%"PRIX64" new_bufpos=%"PRIX64" buflen=%X \n", (int64_t)s->pos,(int64_t)newpos,(int64_t)pos,s->buf_len); } pos-=newpos; res = stream_seek_internal(s, newpos); if (res >= 0) return res; while(s->pos<newpos){ if(stream_fill_buffer(s)<=0) break; // EOF } while(stream_fill_buffer(s) > 0 && pos >= 0) { if(pos<=s->buf_len){ s->buf_pos=pos; // byte position in sector return 1; } pos -= s->buf_len; } // if(pos==s->buf_len) printf("XXX Seek to last byte of file -> EOF\n"); mp_msg(MSGT_STREAM,MSGL_V,"stream_seek: WARNING! Can't seek to 0x%"PRIX64" !\n",(int64_t)(pos+newpos)); return 0; }
int cache_stream_fill_buffer(stream_t *s){ int len; if(s->eof){ s->buf_pos=s->buf_len=0; return 0; } if(!s->cache_pid) return stream_fill_buffer(s); // cache_stats(s->cache_data); if(s->pos!=((cache_vars_t*)s->cache_data)->read_filepos) mp_msg(MSGT_CACHE,MSGL_ERR,"!!! read_filepos differs!!! report this bug...\n"); len=cache_read(s->cache_data,s->buffer, ((cache_vars_t*)s->cache_data)->sector_size); //printf("cache_stream_fill_buffer->read -> %d\n",len); if(len<=0){ s->eof=1; s->buf_pos=s->buf_len=0; return 0; } s->buf_pos=0; s->buf_len=len; s->pos+=len; // printf("[%d]",len);fflush(stdout); return len; }
void stream_dump(struct MPContext *mpctx) { struct MPOpts *opts = mpctx->opts; char *filename = opts->stream_dump; stream_t *stream = mpctx->stream; assert(stream && filename); int64_t size = 0; stream_control(stream, STREAM_CTRL_GET_SIZE, &size); stream_set_capture_file(stream, filename); while (mpctx->stop_play == KEEP_PLAYING && !stream->eof) { if (!opts->quiet && ((stream->pos / (1024 * 1024)) % 2) == 1) { uint64_t pos = stream->pos; MP_MSG(mpctx, MSGL_STATUS, "Dumping %lld/%lld...", (long long int)pos, (long long int)size); } stream_fill_buffer(stream); mp_process_input(mpctx); } }
/** * \return 1 on success, 0 if the function was interrupted and -1 on error */ int stream_enable_cache(stream_t *stream,int size,int min,int seek_limit){ int ss = stream->sector_size ? stream->sector_size : STREAM_BUFFER_SIZE; int res = -1; cache_vars_t* s; if (stream->flags & STREAM_NON_CACHEABLE) { mp_msg(MSGT_CACHE,MSGL_STATUS,"\rThis stream is non-cacheable\n"); return 1; } s=cache_init(size,ss); if(s == NULL) return -1; stream->cache_data=s; s->stream=stream; // callback s->seek_limit=seek_limit; //make sure that we won't wait from cache_fill //more data than it is alowed to fill if (s->seek_limit > s->buffer_size - s->fill_limit ){ s->seek_limit = s->buffer_size - s->fill_limit; } if (min > s->buffer_size - s->fill_limit) { min = s->buffer_size - s->fill_limit; } #if !defined(__MINGW32__) && !defined(PTHREAD_CACHE) && !defined(__OS2__) if((stream->cache_pid=fork())){ if ((pid_t)stream->cache_pid == -1) stream->cache_pid = 0; #else { stream_t* stream2=malloc(sizeof(stream_t)); memcpy(stream2,s->stream,sizeof(stream_t)); s->stream=stream2; #if defined(__MINGW32__) stream->cache_pid = _beginthread( ThreadProc, 0, s ); #elif defined(__OS2__) stream->cache_pid = _beginthread( ThreadProc, NULL, 256 * 1024, s ); #else { pthread_t tid; pthread_create(&tid, NULL, ThreadProc, s); stream->cache_pid = 1; } #endif #endif if (!stream->cache_pid) { mp_msg(MSGT_CACHE, MSGL_ERR, "Starting cache process/thread failed: %s.\n", strerror(errno)); goto err_out; } // wait until cache is filled at least prefill_init % mp_msg(MSGT_CACHE,MSGL_V,"CACHE_PRE_INIT: %"PRId64" [%"PRId64"] %"PRId64" pre:%d eof:%d \n", (int64_t)s->min_filepos,(int64_t)s->read_filepos,(int64_t)s->max_filepos,min,s->eof); while(s->read_filepos<s->min_filepos || s->max_filepos-s->read_filepos<min){ mp_msg(MSGT_CACHE,MSGL_STATUS,MSGTR_CacheFill, 100.0*(float)(s->max_filepos-s->read_filepos)/(float)(s->buffer_size), (int64_t)s->max_filepos-s->read_filepos ); if(s->eof) break; // file is smaller than prefill size if(stream_check_interrupt(PREFILL_SLEEP_TIME)) { res = 0; goto err_out; } } mp_msg(MSGT_CACHE,MSGL_STATUS,"\n"); return 1; // parent exits err_out: cache_uninit(stream); return res; } #if defined(__MINGW32__) || defined(PTHREAD_CACHE) || defined(__OS2__) } #ifdef PTHREAD_CACHE static void *ThreadProc( void *s ){ #else static void ThreadProc( void *s ){ #endif #endif #ifdef CONFIG_GUI use_gui = 0; // mp_msg may not use gui stuff in forked code #endif // cache thread mainloop: signal(SIGTERM,exit_sighandler); // kill do { if(!cache_fill(s)){ usec_sleep(FILL_USLEEP_TIME); // idle } // cache_stats(s->cache_data); } while (cache_execute_control(s)); #if defined(__MINGW32__) || defined(__OS2__) _endthread(); #elif defined(PTHREAD_CACHE) return NULL; #else // make sure forked code never leaves this function exit(0); #endif } int cache_stream_fill_buffer(stream_t *s){ int len; if(s->eof){ s->buf_pos=s->buf_len=0; return 0; } if(!s->cache_pid) return stream_fill_buffer(s); // cache_stats(s->cache_data); if(s->pos!=((cache_vars_t*)s->cache_data)->read_filepos) mp_msg(MSGT_CACHE,MSGL_ERR,"!!! read_filepos differs!!! report this bug...\n"); len=cache_read(s->cache_data,s->buffer, ((cache_vars_t*)s->cache_data)->sector_size); //printf("cache_stream_fill_buffer->read -> %d\n",len); if(len<=0){ s->eof=1; s->buf_pos=s->buf_len=0; return 0; } s->buf_pos=0; s->buf_len=len; s->pos+=len; // printf("[%d]",len);fflush(stdout); return len; }
int stream_seek_long(stream_t *s,off_t pos){ off_t newpos=0; // if( mp_msg_test(MSGT_STREAM,MSGL_DBG3) ) printf("seek_long to 0x%X\n",(unsigned int)pos); s->buf_pos=s->buf_len=0; if(s->mode == STREAM_WRITE) { if(!s->seek || !s->seek(s,pos)) return 0; return 1; } if(s->sector_size) newpos = (pos/s->sector_size)*s->sector_size; else newpos = pos&(~((off_t)STREAM_BUFFER_SIZE-1)); if( mp_msg_test(MSGT_STREAM,MSGL_DBG3) ){ mp_msg(MSGT_STREAM,MSGL_DBG3, "s->pos=%"PRIX64" newpos=%"PRIX64" new_bufpos=%"PRIX64" buflen=%X \n", (int64_t)s->pos,(int64_t)newpos,(int64_t)pos,s->buf_len); } 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 MPLAYER_NETWORK 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, pos, s->streaming_ctrl )<0 ) { mp_msg(MSGT_STREAM,MSGL_INFO,"Stream not seekable!\n"); return 1; } } #else 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 } #endif 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); } while(stream_fill_buffer(s) > 0 && pos >= 0) { if(pos<=s->buf_len){ s->buf_pos=pos; // byte position in sector return 1; } pos -= s->buf_len; } // if(pos==s->buf_len) printf("XXX Seek to last byte of file -> EOF\n"); mp_msg(MSGT_STREAM,MSGL_V,"stream_seek: WARNING! Can't seek to 0x%"PRIX64" !\n",(int64_t)(pos+newpos)); return 0; }