static int list_open(URLContext *h, const char *filename, int flags) { struct list_mgt *mgt; int ret; ByteIOContext *bio; mgt=av_malloc(sizeof(struct list_mgt)); if(!mgt) return AVERROR(ENOMEM); memset(mgt,0,sizeof(*mgt)); mgt->filename=filename+5; mgt->flags=flags; if((ret=list_open_internet(&bio,mgt,mgt->filename,flags| URL_MINI_BUFFER | URL_NO_LP_BUFFER))!=0) { av_free(mgt); return ret; } lp_lock_init(&mgt->mutex,NULL); mgt->current_item=mgt->item_list; mgt->cur_uio=NULL; h->is_streamed=1; h->is_slowmedia=1; if(mgt->full_time>0 && mgt->have_list_end) h->support_time_seek=1; h->priv_data = mgt; url_fclose(bio); return 0; }
static struct list_item * switchto_next_item(struct list_mgt *mgt) { struct list_item *next=NULL; struct list_item *current; if(!mgt) return NULL; if(mgt->current_item==NULL || mgt->current_item->next==NULL){ /*new refresh this mgtlist now*/ ByteIOContext *bio; int ret; if((ret=list_open_internet(&bio,mgt,mgt->filename,mgt->flags| URL_MINI_BUFFER | URL_NO_LP_BUFFER))!=0) { goto switchnext; } url_fclose(bio); if(mgt->current_item && mgt->current_item->file){/*current item,switch to next*/ current=mgt->current_item; next=mgt->current_item->next; for(;next!=NULL;next=next->next){ if(next->file && strcmp(current->file,next->file)==0){ /*found the same item,switch to the next*/ current=next; break; } } while(current!=mgt->item_list){ /*del the old item,lest current,and then play current->next*/ list_del_item(mgt,mgt->item_list); } mgt->current_item=current;/*switch to new current;*/ } } switchnext: if(mgt->current_item) next=mgt->current_item->next; else next=mgt->item_list; if(next) av_log(NULL, AV_LOG_INFO, "switch to new file=%s,total=%d,start=%d,duration=%d\n", next->file,mgt->item_num,next->start_time,next->duration); else av_log(NULL, AV_LOG_INFO, "switch to new file=NULL,total=%d\n",mgt->item_num); return next; }
static int list_open(URLContext *h, const char *filename, int flags) { struct list_mgt *mgt; int ret; ByteIOContext *bio; mgt=av_malloc(sizeof(struct list_mgt)); if(!mgt) return AVERROR(ENOMEM); memset(mgt,0,sizeof(struct list_mgt)); mgt->key_tmp = NULL; mgt->seq = -1; mgt->cur_seq_no = -1; mgt->filename=filename+5; mgt->flags=flags; mgt->jump_item_num = 0; if((ret=list_open_internet(&bio,mgt,mgt->filename,flags| URL_MINI_BUFFER | URL_NO_LP_BUFFER))!=0) { av_free(mgt); return ret; } lp_lock_init(&mgt->mutex,NULL); if(!mgt->have_list_end && (!mgt->have_sub_list)&&(mgt->target_duration<5)){ struct list_item *item=mgt->item_list; int itemindex=mgt->item_num/2+1;/*for live streaming ,choose the middle item.*/ while(itemindex-->0 && item!=NULL) item=item->next; mgt->current_item=item; }else mgt->current_item=mgt->item_list; mgt->cur_uio=NULL; h->is_streamed=1; h->is_slowmedia=1; if(mgt->full_time>0 && mgt->have_list_end) h->support_time_seek=1; h->priv_data = mgt; url_fclose(bio); return 0; }
static struct list_item * switchto_next_item(struct list_mgt *mgt) { struct list_item *next=NULL; struct list_item *current = NULL; if(!mgt) return NULL; int64_t reload_interval = mgt->item_num> 0&&mgt->current_item!=NULL? mgt->current_item->duration : mgt->target_duration; int isNeedFetch = 1; if(mgt->current_item==NULL || mgt->current_item->next==NULL){ /*new refresh this mgtlist now*/ ByteIOContext *bio; int ret; char* url = NULL; if(mgt->n_variants>0&&NULL!=mgt->playing_variant){ url = mgt->playing_variant->url; av_log(NULL, AV_LOG_INFO,"list open variant url:%s,bandwidth:%d\n",url,mgt->playing_variant->bandwidth); }else{ url = mgt->filename; av_log(NULL, AV_LOG_INFO,"list open url:%s\n",url); } reload_interval *= 500000; if(!mgt->have_list_end&&(av_gettime() - mgt->last_load_time < reload_interval)){ av_log(NULL, AV_LOG_INFO,"drop fetch playlist from server\n"); isNeedFetch = 0; } if(isNeedFetch ==0||(ret=list_open_internet(&bio,mgt,url,mgt->flags| URL_MINI_BUFFER | URL_NO_LP_BUFFER))!=0) { goto switchnext; } url_fclose(bio); if(mgt->current_item && mgt->current_item->file){/*current item,switch to next*/ current=mgt->current_item; next=mgt->current_item->next; for(;next!=NULL;next=next->next){ if(next->file && strcmp(current->file,next->file)==0){ /*found the same item,switch to the next*/ current=next; break; } } #if 0 while(current!=mgt->item_list){ /*del the old item,lest current,and then play current->next*/ list_del_item(mgt,mgt->item_list); } #endif mgt->current_item=current;/*switch to new current;*/ if(!mgt->have_list_end &&mgt->item_num>LIVE_LIST_MAX){ list_shrink_live_list(mgt); } } } switchnext: if(mgt->current_item) next=mgt->current_item->next; else next=mgt->item_list; if(next) av_log(NULL, AV_LOG_INFO, "switch to new file=%s,total=%d,start=%d,duration=%d\n", next->file,mgt->item_num,next->start_time,next->duration); else av_log(NULL, AV_LOG_INFO, "switch to new file=NULL,total=%d\n",mgt->item_num); return next; }
static int list_open(URLContext *h, const char *filename, int flags) { struct list_mgt *mgt; int ret; mgt = av_malloc(sizeof(struct list_mgt)); if (!mgt) { return AVERROR(ENOMEM); } memset(mgt, 0, sizeof(struct list_mgt)); mgt->key_tmp = NULL; mgt->start_seq = -1; mgt->next_seq = -1; mgt->filename = filename + 5; mgt->flags = flags; mgt->next_index = 0; mgt->playing_item_index = 0; mgt->playing_item_seq = 0; mgt->strategy_up_counts = 0; mgt->strategy_down_counts = 0; mgt->listclose = 0; mgt->cmf_item_index = 0; mgt->cur_uio = NULL; mgt->codec_buf_level=-1; mgt->switch_down_num = 0; mgt->switch_up_num = 0; mgt->debug_level = (int)get_adaptation_ex_para(4); char headers[1024]; char sess_id[40]; memset(headers, 0, sizeof(headers)); memset(sess_id, 0, sizeof(sess_id)); generate_segment_session_id(sess_id, 37); snprintf(headers, sizeof(headers), "Connection: keep-alive\r\n" /*"Range: bytes=0- \r\n"*/ "X-Playback-Session-Id: %s\r\n%s", sess_id,h!=NULL&&h->headers!=NULL?h->headers:""); //av_log(NULL, AV_LOG_INFO, "Generate ipad http request headers,\r\n%s\n", headers); mgt->ipad_ex_headers = strndup(headers, 1024); memset(headers, 0, sizeof(headers)); generate_playback_session_id(sess_id, 37); snprintf(headers, sizeof(headers), /*"Connection: keep-alive\r\n"*/ "X-Playback-Session-Id: %s\r\n%s", sess_id,h!=NULL&&h->headers!=NULL?h->headers:""); //av_log(NULL, AV_LOG_INFO, "Generate ipad http request media headers,\r\n%s\n", headers); mgt->ipad_req_media_headers = strndup(headers, 1024); gListMgt = mgt; if ((ret = list_open_internet(&mgt->cur_uio, mgt, mgt->filename, flags | URL_MINI_BUFFER | URL_NO_LP_BUFFER)) != 0) { av_free(mgt); return ret; } lp_lock_init(&mgt->mutex, NULL); float value = 0.0; ret = am_getconfig_float("libplayer.hls.stpos", &value); if (ret < 0 || value <= 0) { if (!mgt->have_list_end) { int itemindex =0; if(mgt->item_num<10&&mgt->target_duration<5){ itemindex = mgt->item_num / 2+1; /*for live streaming ,choose the middle item.*/ }else if(mgt->item_num>=10){ itemindex = mgt->item_num-3; //last item }else if(mgt->item_num<10&&mgt->target_duration>5){ itemindex = mgt->item_num -1; } mgt->current_item = list_find_item_by_index(mgt,itemindex-1); } else { mgt->current_item = mgt->item_list; } }else{ mgt->current_item = list_find_item_by_index(mgt,(int)value-1); } h->is_streamed = 1; h->is_slowmedia = 1; if (mgt->full_time > 0 && mgt->have_list_end) { h->support_time_seek = 1; } h->priv_data = mgt; mgt->cache_http_handle = NULL; ret = CacheHttp_Open(&mgt->cache_http_handle,mgt->ipad_req_media_headers); if(mgt->debug_level>0){ hls_base_info_dump(mgt); } return 0; }
static struct list_item * switchto_next_item(struct list_mgt *mgt) { struct list_item *next = NULL; struct list_item *current = NULL; if (!mgt) { return NULL; } int isNeedFetch = 1; int64_t reload_interval = mgt->item_num > 0 && mgt->current_item != NULL ?\ mgt->current_item->duration:mgt->target_duration; if(reload_interval >0){ //to usec reload_interval *= 1000000; } if (mgt->n_variants > 0&&mgt->codec_buf_level>=0) { //vod,have mulit-bandwidth streams //av_log(NULL, AV_LOG_INFO, "current playing item index: %d,current playing seq:%d\n", mgt->playing_item_index, mgt->playing_item_seq); int is_switch = select_best_variant(mgt); if (is_switch>0) { //will remove this tricks. if (mgt->item_num > 0) { list_delall_item(mgt); } mgt->current_item = mgt->current_item->next = NULL; mgt->start_seq = -1; if(!mgt->have_list_end){ mgt->next_seq = mgt->playing_item_seq+1; }else{ mgt->next_seq = -1; } mgt->next_index = 0; mgt->item_num = 0; mgt->full_time = 0; if(mgt->cur_uio){ url_fclose(mgt->cur_uio); mgt->cur_uio = NULL; } if(mgt->debug_level==1){ hls_base_info_dump(mgt); } } if(mgt->debug_level>1){ hls_base_info_dump(mgt); } //av_log(NULL, AV_LOG_INFO, "select best variant,bandwidth: %d\n", mgt->playing_variant->bandwidth); } reload: if (mgt->current_item == NULL || mgt->current_item->next == NULL) { /*new refresh this mgtlist now*/ ByteIOContext *bio = mgt->cur_uio; int ret; char* url = NULL; if (mgt->n_variants > 0 && NULL != mgt->playing_variant) { url = mgt->playing_variant->url; //av_log(NULL, AV_LOG_INFO, "list open variant url:%s,bandwidth:%d\n", url, mgt->playing_variant->bandwidth); } else { url = mgt->filename; //av_log(NULL, AV_LOG_INFO, "list open url:%s\n", url); } if (!mgt->have_list_end && (av_gettime() - mgt->last_load_time < reload_interval)&&mgt->item_num>0) { //av_log(NULL, AV_LOG_INFO, "drop fetch playlist from server\n"); isNeedFetch = 0; } if (url_interrupt_cb()) { return NULL; } if (isNeedFetch == 0 || (ret = list_open_internet(&bio, mgt, url, mgt->flags | URL_MINI_BUFFER | URL_NO_LP_BUFFER)) != 0) { if(ret!=0&&mgt->n_variants>1){ switch_bw_level(mgt,-1); } goto switchnext; } mgt->cur_uio = bio; if (mgt->current_item && mgt->current_item->file) { /*current item,switch to next*/ current = mgt->current_item; next = mgt->current_item->next; for (; next != NULL; next = next->next) { if (next->file && strcmp(current->file, next->file) == 0) { /*found the same item,switch to the next*/ current = next; break; } } #if 0 while (current != mgt->item_list) { /*del the old item,lest current,and then play current->next*/ list_del_item(mgt, mgt->item_list); } #endif mgt->current_item = current; /*switch to new current;*/ if (!mgt->have_list_end && mgt->item_num > LIVE_LIST_MAX) { list_shrink_live_list(mgt); } } } switchnext: if (mgt->current_item) { next = mgt->current_item->next; } else { if (!mgt->have_list_end) { //live tv next = mgt->item_list; } else { next = list_find_next_item_by_index(mgt, mgt->playing_item_index); } } if (mgt->listclose){ return NULL; } if (next){ if(next->file!=NULL){ if(mgt->debug_level>1){ RLOG("Player switch to new item,url =%s,total item=%d,start=%.4lf,duration=%.4lf,index:%d,seq:%d\n", next->file, mgt->item_num, next->start_time, next->duration,next->index,next->seq); } } }else { if(mgt->debug_level>1){ RLOG("Player can't find new item,total=%d\n", mgt->item_num); } if (!mgt->have_list_end) { if (url_interrupt_cb()) { return NULL; } usleep(100 * 1000); reload_interval = mgt->target_duration * 500000; isNeedFetch = 1; goto reload; } } return next; }