int url_lp_intelligent_buffering(URLContext *s,int size) { int forward_data,back_data; int datalen; url_lpbuf_t *lp; int ret=-1; if(!s || !s->lpbuf) return AVERROR(EINVAL); lp=s->lpbuf; lp->dbg_cnt++; if(size <=0) size=lp->block_read_size; datalen= url_lp_getbuffering_size(s,&forward_data,&back_data); if(lp->dbg_cnt%100==0) lp_print( AV_LOG_INFO, "url_lp buffering:datalen=%d,forward_datad=%d,back_data=%d,lp->buffer_size=%d,size=%d\n", datalen,forward_data,back_data,lp->buffer_size,size); if(datalen>=0 && ((forward_data/lp->buffer_size)<lp->max_forword_level) && ((datalen <lp->buffer_size-1024) || (back_data>(forward_data/2+1)) || (back_data>3*1024*1024)) ) ret=url_lpfillbuffer(s,size);/*lest 1/3 back data && < 3M back data*/ return ret; }
int64_t url_lpexseekoffset(URLContext *s, int64_t offset) { int forward_data=0; int back_data=0; lp_print( AV_LOG_INFO,"[%s:%d] doing url_lpexseekoffset\n",__FUNCTION__,__LINE__); int buffer_validdata_size=url_lp_getbuffering_size(s,&forward_data,&back_data); if(buffer_validdata_size<=0){ lp_print( AV_LOG_ERROR,"[%s:%d] LOOPBUFFER buffer is empty\n",__FUNCTION__,__LINE__); return -1; } int64_t seek_time=0; if((seek_time=s->prot->url_exseek(s, offset, AVSEEK_LOOPBUFFER_OFFSET))<0){ lp_print( AV_LOG_ERROR,"[%s:%d] LOOPBUFFER seek failed seek_time=%d\n",__FUNCTION__,__LINE__,seek_time); return -1; } int64_t seek_pos=0; if(s->priv_info>buffer_validdata_size){ lp_print( AV_LOG_ERROR,"[%s:%d] LOOPBUFFER seek out of range\n",__FUNCTION__,__LINE__); return -1; } else{ seek_pos=forward_data-s->priv_info; } if(url_lpseek(s,seek_pos,SEEK_CUR)<0){ lp_print( AV_LOG_ERROR,"[%s:%d] Failed to seek SEEK_CUR pos=%lld,time=%lld,forward_data=%d\n", __FUNCTION__,__LINE__,seek_pos,seek_time,forward_data); return -1; } lp_print( AV_LOG_INFO,"[%s:%d] seek SEEK_CUR pos=%lld,time=%lld,forward_data=%d\n", __FUNCTION__,__LINE__,seek_pos,seek_time,forward_data); return seek_time; }
t_stat lp_svc (UNIT *uptr) { uint32 cmd; uint32 st; switch (lp_cmd) { /* case on state */ case LPS_INIT: /* I/O init */ st = chan_get_cmd (lp_dib.dva, &cmd); /* get command */ if (CHS_IFERR (st)) /* channel error? */ return lp_chan_err (st); lp_inh = 0; /* clear inhibit, */ lp_run = 0; /* runaway */ lp_cmd = lp_lastcmd = cmd; /* save command */ sim_activate (uptr, chan_ctl_time); /* continue thread */ break; case LPS_FMT: case LPS_FMT|LPS_INT: /* format only */ sim_activate (uptr, uptr->wait); /* continue thread */ if ((uptr->flags & UNIT_ATT) == 0) /* not attached? */ return lp_stopioe? SCPE_UNATT: SCPE_OK; st = lp_fmt (uptr); /* format */ if (CHS_IFERR (st)) /* error? */ return lp_chan_err (st); if ((lp_model == LP_7440) && /* 7440? lnt chk */ (st != CHS_ZBC) && chan_set_chf (lp_dib.dva, CHF_LNTE)) /* not ignored? */ return lp_chan_err (SCPE_OK); /* force uend */ lp_cmd = LPS_END; /* actual print */ break; case LPS_FMTP: case LPS_FMTP|LPS_INT: /* format and print */ sim_activate (uptr, uptr->wait); /* continue thread */ if ((uptr->flags & UNIT_ATT) == 0) /* not attached? */ return lp_stopioe? SCPE_UNATT: SCPE_OK; st = lp_fmt (uptr); /* format */ if (CHS_IFERR (st)) /* error? */ return lp_chan_err (st); if (st == CHS_ZBC) { /* command done? */ if ((lp_model == LP_7440) && /* 7440? lnt err */ chan_set_chf (lp_dib.dva, CHF_LNTE)) /* not ignored? */ return lp_chan_err (SCPE_OK); } else { /* more to do */ st = lp_print (uptr); /* print */ if (CHS_IFERR (st)) /* error */ return lp_chan_err (st); } break; case LPS_PRI: case LPS_PRI|LPS_INT: /* print only */ sim_activate (uptr, uptr->wait); /* continue thread */ if ((uptr->flags & UNIT_ATT) == 0) /* not attached? */ return lp_stopioe? SCPE_UNATT: SCPE_OK; st = lp_print (uptr); /* print */ if (CHS_IFERR (st)) /* error? */ return lp_chan_err (st); break; case LPS_END: /* command done */ if ((lp_lastcmd & LPS_INT) && !lp_pass) /* int requested? */ chan_set_chi (lp_dib.dva, 0); st = chan_end (lp_dib.dva); /* set channel end */ if (CHS_IFERR (st)) /* channel error? */ return lp_chan_err (st); if (st == CHS_CCH) { /* command chain? */ lp_cmd = LPS_INIT; /* restart thread */ sim_activate (uptr, chan_ctl_time); } break; default: /* invalid cmd */ chan_uen (lp_dib.dva); /* uend */ break; } return SCPE_OK; }
int64_t url_lpexseek(URLContext *s, int64_t offset, int whence) { url_lpbuf_t *lp; int64_t ret; if(!s || !s->lpbuf || !s->prot->url_exseek) return AVERROR(EINVAL); lp=s->lpbuf; lp_lock(&lp->mutex); if (whence == AVSEEK_FULLTIME) { ret=s->prot->url_exseek(s,0, AVSEEK_FULLTIME);/*clear the lowlevel errors*/ } else if (whence == AVSEEK_BUFFERED_TIME) { ret=s->prot->url_exseek(s,0, AVSEEK_BUFFERED_TIME);/*clear the lowlevel errors*/ } else if(whence == AVSEEK_TO_TIME ){ if(s->prot->url_exseek){ if(strcmp(s->prot->name, "vhls")==0){ // hls can return the stream offset lp_print( AV_LOG_INFO,"[%s:%d] doing LOOPBUFFER seek\n",__FUNCTION__,__LINE__); lp_unlock(&lp->mutex); ret=url_lpexseekoffset(s,offset); lp_lock(&lp->mutex); if(ret>=0){ lp_print( AV_LOG_INFO,"[%s:%d] LOOPBUFFER seek deal successful\n",__FUNCTION__,__LINE__); goto seek_end; } lp_print( AV_LOG_INFO,"[%s:%d] Failed LOOPBUFFER seek\n",__FUNCTION__,__LINE__); } if((ret=s->prot->url_exseek(s, offset, AVSEEK_TO_TIME))>=0) { lp->rp=lp->buffer; lp->wp=lp->buffer; lp->valid_data_size=0; lp->pos=0; goto seek_end; } } ret= AVERROR(EPIPE); } else if(whence == AVSEEK_CMF_TS_TIME ){ if(s->prot->url_exseek){ if((ret=s->prot->url_exseek(s, offset, AVSEEK_CMF_TS_TIME))>=0) { lp->rp=lp->buffer; lp->wp=lp->buffer; lp->valid_data_size=0; lp->pos=0; goto seek_end; } } ret= AVERROR(EPIPE); } else if (whence == AVSEEK_SLICE_BYTIME) { ret= s->prot->url_seek(s, offset, AVSEEK_SLICE_BYTIME); if (ret < 0){ lp_unlock(&lp->mutex); return -1; } lp_unlock(&lp->mutex); return ret; } else if (whence == AVSEEK_ITEM_TIME) { ret= s->prot->url_seek(s, offset, AVSEEK_ITEM_TIME); if (ret < 0){ lp_unlock(&lp->mutex); return -1; } lp_unlock(&lp->mutex); return ret; } seek_end: lp_unlock(&lp->mutex); return ret; }