int64_t url_lpseek(URLContext *s, int64_t offset, int whence) { int64_t pos_on_read; url_lpbuf_t *lp; int valid_data_can_seek_forward; int valid_data_can_seek_back; int64_t offset1; int ret; if(!s || !s->lpbuf) return AVERROR(EINVAL); lp=s->lpbuf; lp_lock(&lp->mutex); lp_sprint( AV_LOG_INFO, "url_lpseek:offset=%lld whence=%d,buffer=%x,rp=%x,wp=%x,end=%x,pos=%lld\n", offset,whence,lp->buffer,lp->rp,lp->wp,lp->buffer_end,lp->pos); if (whence == AVSEEK_SIZE) { int64_t size; if(!s->prot->url_seek){ lp_unlock(&lp->mutex); return -1; } size = s->prot->url_seek(s, 0, AVSEEK_SIZE); if(size<0){ if ((size = s->prot->url_seek(s, -1, SEEK_END)) < 0) { lp_unlock(&lp->mutex); return size; } size++; s->prot->url_seek(s,lp->pos, SEEK_SET); } lp_sprint(AV_LOG_INFO,"get file size=%lld\n",size); lp_unlock(&lp->mutex); return size; } else if(whence == SEEK_END) { if(!s->prot->url_seek){ lp_unlock(&lp->mutex); return -1; } if ((offset1=s->prot->url_seek(s, offset, SEEK_END)) < 0) { lp_unlock(&lp->mutex); return offset1; } lp->rp=lp->buffer; lp->wp=lp->buffer; lp->valid_data_size=0; lp->pos=offset1; lp_unlock(&lp->mutex); return offset1; } if (whence != SEEK_CUR && whence != SEEK_SET) { lp_unlock(&lp->mutex); return AVERROR(EINVAL); } if(lp->wp>=lp->rp) valid_data_can_seek_forward=lp->wp-lp->rp; else valid_data_can_seek_forward=lp->buffer_size-(lp->rp-lp->wp); pos_on_read = lp->pos-valid_data_can_seek_forward; if(whence == SEEK_CUR) { offset1 = pos_on_read; if (offset == 0) { lp_unlock(&lp->mutex); return offset1; } offset += offset1; } valid_data_can_seek_back=FFMIN(lp->valid_data_size-valid_data_can_seek_forward, lp->buffer_size-valid_data_can_seek_forward-64); if(valid_data_can_seek_back<0) valid_data_can_seek_back=0; offset1 = offset - pos_on_read;/*seek forword or back*/ lp_sprint( AV_LOG_INFO, "url_lpseek:pos_on_read=%lld,can seek forwart=%d,can seek bacd=%d,offset1=%lld\n", pos_on_read,valid_data_can_seek_forward,valid_data_can_seek_back,offset1); if(offset1>=0 && offset1<=valid_data_can_seek_forward) {/*seek forward in lp buffer*/ lp_sprint( AV_LOG_INFO, "url_lpseek:buffer seek forword offset=%lld offset1=%lld whence=%d\n",offset,offset1,whence); lp->rp+=(int)offset1; if(lp->rp>=lp->buffer_end) lp->rp-=lp->buffer_size; }else if(offset1<0 && (-offset1)<=valid_data_can_seek_back) {/*seek back in lp buffer*/ lp_sprint( AV_LOG_INFO, "url_lpseek:buffer seek back offset=%lld offset1=%lld whence=%d,(int)offset1=%d\n",offset,offset1,whence,(int)offset1); lp->rp+=(int)offset1; if(lp->rp<lp->buffer) lp->rp+=lp->buffer_size; }else if(offset1>0 && (s->is_streamed || s->is_slowmedia) && (offset1<lp->buffer_size-lp->block_read_size) && (lp->file_size<=0 || (lp->file_size>0 && offset1<lp->file_size/2)))/*if offset1>filesize/2,thendo first seek end,don't buffer*/ {/*seek to buffer end,but buffer is not full,do read seek*/ int read_offset,ret; lp_sprint( AV_LOG_INFO, "url_lpseek:buffer read seek forward offset=%lld offset1=%lld whence=%d\n",offset,offset1,whence); lp->rp+=valid_data_can_seek_forward; if(lp->rp>=lp->buffer_end) lp->rp-=lp->buffer_size; lp_unlock(&lp->mutex); read_offset=offset1-valid_data_can_seek_forward; while(read_offset>0){ ret=url_lpread(s,NULL,read_offset);/*do read seek*/ if(ret>0) read_offset-=ret; else if(ret!=AVERROR(EAGAIN)){ offset=ret;/*get error,exit now*/ break; } } lp_lock(&lp->mutex); }else {/*not support in buffer seek,do low level seek now*/ lp_sprint( AV_LOG_INFO, "url_lpseek:buffer lowlevel seek offset=%lld offset1=%lld whence=%d\n",offset,offset1,whence); if(!s->prot->url_seek){ lp_unlock(&lp->mutex); return -1; } if(lp->cache_enable && offset<lp->file_size){ /*if cache enable not need to seek here,seek on cache missed*/ ;/*do't do seek here*/ }else if ((offset1=s->prot->url_seek(s, offset, SEEK_SET)) < 0) { lp->valid_data_size=0;/*seek failed clear all old datas*/ offset1 = s->prot->url_seek(s, lp->pos, SEEK_SET);/*clear the lowlevel errors*/ lp_unlock(&lp->mutex); return offset1; } lp->rp=lp->buffer; lp->wp=lp->buffer; lp->valid_data_size=0; lp->pos=offset; } lp_sprint( AV_LOG_INFO, "url_lpseekend:offset=%lld whence=%d,buffer=%x,rp=%x,wp=%x,end=%x,pos=%lld\n", offset,whence,lp->buffer,lp->rp,lp->wp,lp->buffer_end,lp->pos); LP_ASSERT(lp->rp>=lp->buffer); LP_ASSERT(lp->rp<lp->buffer_end); lp_unlock(&lp->mutex); return offset; }
int url_lpopen(URLContext *s,int size) { url_lpbuf_t *lp; int blocksize=32*1024; int ret; float value=0.0; int bufsize=0; if(size==0){ //size=am_getconfig_float("libplayer.ffmpeg.lpbufsizemax",&value); //if(size<=0) size=IO_LP_BUFFER_SIZE; } lp_bprint( AV_LOG_INFO,"url_lpopen=%d\n",size); if(!s) return -1; lp_bprint( AV_LOG_INFO,"url_lpopen2=%d\n",size); //ret=am_getconfig_float("libplayer.ffmpeg.lpbufblocksize",&value); //if(ret>=0 && value>=32){ // blocksize=(int)value; //} lp_sprint( AV_LOG_INFO,"lpbuffer block size=%d\n",blocksize); lp=av_mallocz(sizeof(url_lpbuf_t)); if(!lp) return AVERROR(ENOMEM); lp->buffer=av_malloc(size); if(!lp->buffer) { int failedsize=size/2;/*if no memory used 1/2 size */ //ret=am_getconfig_float("libplayer.ffmpeg.lpbuffaildsize",&value); //if(ret>=0 && value>=1024){ // failedsize=(int)value; //} lp_sprint( AV_LOG_INFO,"malloc buf failed,used failed size=%d\n",failedsize); lp->buffer=av_malloc(failedsize); while(!lp->buffer){ failedsize=failedsize/2; if(failedsize<16*1024)/*do't malloc too small size failed size*/ return AVERROR(ENOMEM); lp->buffer=av_malloc(failedsize); } bufsize=failedsize; }else{ bufsize=size; } lp_sprint( AV_LOG_INFO,"url_lpopen used lp buf size=%d\n",bufsize); s->lpbuf=lp; lp->buffer_size=bufsize; lp->rp=lp->buffer; lp->wp=lp->buffer; lp->buffer_end=lp->buffer+bufsize; lp->valid_data_size=0; lp->pos=0; lp->block_read_size=FFMIN(blocksize,bufsize>>4); lp_lock_init(&lp->mutex,NULL); lp->file_size=url_lpseek(s,0,AVSEEK_SIZE); lp->cache_enable=0; lp->cache_id=aviolp_cache_open(s->filename,url_filesize(s)); lp->dbg_cnt=0; if(lp->cache_id!=0) lp->cache_enable=1; lp_bprint( AV_LOG_INFO,"url_lpopen4%d\n",bufsize); return 0; }
int url_lpopen(URLContext *s,int size) { url_lpbuf_t *lp; int blocksize=32*1024; int ret; float value=0.0; int bufsize=0; if(size==0){ ret=am_getconfig_float("libplayer.ffmpeg.lpbufsizemax",&value); if(ret<0 || value < 1024*32){ if(am_getconfig_bool_def("media.amplayer.low_ram",0)){ size=IO_LP_BUFFER_SIZE/8; }else{ size=IO_LP_BUFFER_SIZE; } }else{ size=(int)value; } } lp_bprint( AV_LOG_INFO,"url_lpopen=%d\n",size); if(!s) return -1; lp_bprint( AV_LOG_INFO,"url_lpopen2=%d\n",size); ret=am_getconfig_float("libplayer.ffmpeg.lpbufblocksize",&value); if(ret>=0 && value>=32){ blocksize=(int)value; } lp_sprint( AV_LOG_INFO,"lpbuffer block size=%d\n",blocksize); lp=av_mallocz(sizeof(url_lpbuf_t)); if(!lp) return AVERROR(ENOMEM); lp->buffer=av_malloc(size); if(!lp->buffer) { int failedsize=size/2;/*if no memory used 1/2 size */ ret=am_getconfig_float("libplayer.ffmpeg.lpbuffaildsize",&value); if(ret>=0 && value>=1024){ failedsize=(int)value; } lp_sprint( AV_LOG_INFO,"malloc buf failed,used failed size=%d\n",failedsize); lp->buffer=av_malloc(failedsize); while(!lp->buffer){ failedsize=failedsize/2; if(failedsize<16*1024){/*do't malloc too small size failed size*/ av_free(lp); return AVERROR(ENOMEM); } lp->buffer=av_malloc(failedsize); } bufsize=failedsize; }else{ bufsize=size; } lp_sprint( AV_LOG_INFO,"url_lpopen used lp buf size=%d\n",bufsize); s->lpbuf=lp; lp->buffer_size=bufsize; lp->rp=lp->buffer; lp->wp=lp->buffer; lp->buffer_end=lp->buffer+bufsize; lp->valid_data_size=0; lp->pos=0; lp->block_read_size=FFMIN(blocksize,bufsize>>4); lp_lock_init(&lp->mutex,NULL); lp->file_size=url_lpseek(s,0,AVSEEK_SIZE); lp->cache_enable=0; lp->cache_id=aviolp_cache_open(s->filename,url_lpseek(s,0,AVSEEK_SIZE)); lp->dbg_cnt=0; ret=am_getconfig_float("libplayer.ffmpeg.lpbufmaxbuflv",&value); if(ret<0) lp->max_forword_level=1; else{ lp->max_forword_level=value; } if(lp->cache_id!=0) lp->cache_enable=1; lp_bprint( AV_LOG_INFO,"url_lpopen4%d\n",bufsize); ret=am_getconfig_float("libplayer.ffmpeg.maxreadseek",&value); if(ret>=0 && value>=0) { lp->max_read_seek=value; }else { lp->max_read_seek=DEF_MAX_READ_SEEK; } return 0; }