Example #1
0
int CacheHttp_Open(void ** handle,const char* headers)
{
    CacheHttpContext * s = (CacheHttpContext *)av_malloc(sizeof(CacheHttpContext));
    if(!s) {
        *handle = NULL;
        return AVERROR(EIO);
    }

    *handle = (void *)s;
    s->hd  = NULL;
    s->item_duration = 0;
    s->item_pos = 0;
    s->item_starttime = 0;
    s->finish_flag = 0;
    s->seek_flag = 0;
    s->reset_flag = -1;
    s->have_list_end = -1;
    s->is_first_read = 1;
    memset(s->headers, 0x00, sizeof(s->headers));
    s->fifo = NULL;
    float value=0.0;
    int config_ret;
    config_ret=am_getconfig_float("libplayer.ffmpeg.hlshttpbufmax",&value);
    if(config_ret<0 || value < 1024*32)
        s->fifo = av_fifo_alloc(CIRCULAR_BUFFER_SIZE);
    else {
        s->fifo = av_fifo_alloc(value);
    }
    pthread_mutex_init(&s->read_mutex,NULL);

    s->EXIT = 0;
    s->EXITED = 0;
    s->RESET = 0;
    if(headers) {
        av_strlcpy(s->headers,headers,BUFFER_SIZE);
    }
    int ret = am_getconfig_float("libplayer.hls.measured_buffer",&value);
    int  meause_unit_max = 1024*1024*10;//10M
    if(ret>=0) {
        meause_unit_max = (int)value*1024;
    }

    if(meause_unit_max/TMP_BUFFER_SIZE<100) {
        s->bandwidth_measure=bandwidth_measure_alloc(100,0);

    } else {
        s->bandwidth_measure=bandwidth_measure_alloc(meause_unit_max/TMP_BUFFER_SIZE,0);
    }
    ret = ffmpeg_pthread_create(&s->circular_buffer_thread, NULL, circular_buffer_task, s);
    av_log(NULL, AV_LOG_INFO, "----------- pthread_create ret=%d\n",ret);

    return ret;
}
static float _get_system_prop(SysPropType type){
    float value = 0.0;
    float ret = -1;    
    switch(type){
        case PROP_DEBUG_LEVEL:
            ret = am_getconfig_float("libplayer.hls.debug",&value);
            if(ret<0){
                ret = 0;
                value = 0;
            }            
            break;
        case PROP_CMF_SUPPORT:
            ret = am_getconfig_bool("libplayer.hls.cmf");
            if(ret<0){
                value = -1;
            }else{
                value= ret;
            }
            break;
        default:
            RLOG("Never see this line,type:%d\n",type);
            break;
    }
    if(ret < 0 || value <0){
        ret = -1;
    }else{
        ret = value;
    }

    return ret;
    
}
Example #3
0
static void find_best_keyframe(AVFormatContext *pFormatCtx, int video_index, int count, int64_t *time, int64_t *offset, int *maxsize)
{
    int i = 0;
    int maxFrameSize = 0;
    int64_t thumbTime = 0;
    int64_t thumbOffset = 0;
    AVPacket packet;
    int r = 0;
    int find_ok = 0;
    int keyframe_index=0;
    AVStream *st=pFormatCtx->streams[video_index];
	int havepts=0;
	int nopts=0;
	*maxsize=0;
    if(count<=0){
	   float newcnt=-0.1;
	   count=100;
	   if(am_getconfig_float("libplayer.thumbnail.scan.count",&newcnt)>=0 && newcnt>=1)
		count=(int)newcnt;
    }

    do{
	   r = av_read_next_video_frame(pFormatCtx, &packet,video_index);
	   if(r<0)
		break;
          log_debug("[find_best_keyframe][%d]read frame packet.size=%d,pts=%lld\n",i,packet.size,packet.pts);
	   havepts=(packet.pts>0||havepts);
	   nopts=(i>10)&&!havepts;
	   if (packet.size > maxFrameSize && (packet.pts>=0 || nopts)) { //packet.pts>=0 can used for seek.
		maxFrameSize = packet.size;
		thumbTime = packet.pts;
		thumbOffset = avio_tell(pFormatCtx->pb) - packet.size;
		keyframe_index=i;
		find_ok=1;
	   }
	   av_free_packet(&packet);
	   if(i>5 && find_ok && maxFrameSize>100*1024/(1+i/20))
		 break;
    }while(i++<count);

    if(find_ok){
	 log_debug("[%s]return thumbTime=%lld thumbOffset=%llx\n", __FUNCTION__, thumbTime, thumbOffset);
		if(thumbTime>=0&&thumbTime != AV_NOPTS_VALUE)
		*time = av_rescale_q(thumbTime, st->time_base, AV_TIME_BASE_Q);
		else
			*time = AV_NOPTS_VALUE;
	*offset = thumbOffset;
		*maxsize = maxFrameSize;
	r=0;
    }else{
	log_print("[%s]find_best_keyframe failed\n", __FUNCTION__);
    }
    return r;
}
Example #4
0
static float get_adaptation_ex_para(int type){
    float value = 0.0;
    float ret = -1;
    if(type==0){
        ret = am_getconfig_float("libplayer.hls.sensitivity", &value);
        if(ret<0){
            value = 1.0;
            ret = 0;
        }
    }else if(type == 1){
        ret = am_getconfig_float("libplayer.hls.upcounts", &value);
        if(ret<0){
            ret  =0;
            value = DEF_UP_COUNTS;
        }
    }else if(type == 2){
        ret = am_getconfig_float("libplayer.hls.downcounts", &value);
        if(ret<0){
            ret  =0;
            value = DEF_DOWN_COUNTS;
        }
    }else if(type == 3){
        ret = am_getconfig_float("libplayer.hls.fixed_bw", &value);       
    }else if(type == 4){
        ret = am_getconfig_float("libplayer.hls.debug", &value);
        if(ret<0){
            ret = 0;
            value = 0;
        }

    }else if(type ==5){
        ret = am_getconfig_float("libplayer.hls.initial_buffered", &value);
        if(ret<0){
            ret = 0;
            value = 0;
        }
        
    }else if(type == 6){
        ret = am_getconfig_float("libplayer.hls.measured_buffer", &value);
        if(ret<0){
            ret = 0;
            value = 0;
        }

    }
    if(ret < 0 || value <0){
        ret = -1;
    }else{
        ret = value;
    }
    //av_log(NULL, AV_LOG_INFO,"just get adaptation extend parameter(value:%d): %f\n",type,ret);
    return ret;

}
Example #5
0
static int get_adaptation_profile(){
    float value = 0.0;
    int ret = -1;
    ret = am_getconfig_float("libplayer.hls.profile", &value);
    if(ret < 0 || value <0){
        ret = ADAPTATION_PROFILE_DEFAULT;
    }else{
        ret= (int)value;
    }
    //av_log(NULL, AV_LOG_INFO,"just get adaptation profile: %d\n",ret);
    return ret;

}
Example #6
0
static void find_thumbnail_frame(AVFormatContext *pFormatCtx, int video_index, int64_t *thumb_time, int64_t *thumb_offset,int *pmaxframesize)
{
    int64_t thumbTime = 0;
    int64_t thumbOffset = 0;
    AVPacket packet;
    AVStream *st = pFormatCtx->streams[video_index];
    int duration = pFormatCtx->duration / AV_TIME_BASE;
 ///   int64_t init_seek_time = (duration > 0) ? MIN(10, duration >> 1) : 10;
    int64_t init_seek_time = 10;
    int ret = 0;
    float starttime;
	int maxframesize;
    if(am_getconfig_float("libplayer.thumbnail.starttime",&starttime)>=0 && starttime>=0)
    {
		init_seek_time=(int64_t)starttime;
		if(init_seek_time >= duration)
			init_seek_time=duration-1;
		if(init_seek_time<=0)
			init_seek_time=0;
    }else{
	if(duration > 360)
			init_seek_time=120;/*long file.don't do more seek..*/
		else if(duration>6){
			init_seek_time=duration/3;
		}else{
			init_seek_time=0;/*file is too short,try from start.*/
		}
    }
    init_seek_time *= AV_TIME_BASE;
    log_debug("[find_thumbnail_frame]duration=%lld init_seek_time=%lld\n", pFormatCtx->duration, init_seek_time);
    //init_seek_time = av_rescale_q(init_seek_time, st->time_base, AV_TIME_BASE_Q);
    //log_debug("[find_thumbnail_frame]init_seek_time=%lld timebase=%d:%d video_index=%d\n",init_seek_time,st->time_base.num,st->time_base.den, video_index);
    ret = av_seek_frame(pFormatCtx, video_index,init_seek_time, AVSEEK_FLAG_BACKWARD);
    if (ret < 0) {
        avio_seek(pFormatCtx->pb, 0, SEEK_SET);
        log_error("[%s]seek error, reset offset to 0\n", __FUNCTION__);
        return;
    }
    log_debug("[find_thumbnail_frame]offset=%llx \n", avio_tell(pFormatCtx->pb));

    find_best_keyframe(pFormatCtx, video_index, 0, &thumbTime, &thumbOffset,&maxframesize);

    if (thumbTime != AV_NOPTS_VALUE) {
        *thumb_time = thumbTime;
    }else{
	*thumb_time = AV_NOPTS_VALUE;
    }
    *thumb_offset = thumbOffset;
	*pmaxframesize=maxframesize;
    log_debug("[find_thumbnail_frame]return thumb_time=%lld thumb_offset=%lld\n", *thumb_time, *thumb_offset);
}
Example #7
0
float in_get_sys_prop_float(char* key){
    float value = 0.0;
#ifdef HAVE_ANDROID_OS
    int ret = am_getconfig_float(key,&value);
    if(ret<0){
        return -1;
    }
#else
    char * ev = getenv(key);
    if(ev==NULL){
        return -1;
    }
    value = atof(ev);
#endif    
    return value;
}
Example #8
0
int CacheHttp_Read(void * handle, uint8_t * cache, int size)
{
    if(!handle)
        return AVERROR(EIO);

    CacheHttpContext * s = (CacheHttpContext *)handle;
    pthread_mutex_lock(&s->read_mutex);

    if (s->fifo) {
        int avail;
        avail = av_fifo_size(s->fifo);
        //av_log(NULL, AV_LOG_INFO, "----------- http_read   avail=%d, size=%d ",avail,size);
        if(s->is_first_read>0) {
            float value = 0.0;
            int ret = -1;
            ret = am_getconfig_float("libplayer.hls.initial_buffered", &value);
            if(ret>=0) {
                if(avail/1024<value) {
                    //av_log(NULL, AV_LOG_INFO, "buffer data avail=%d, initial buffer buffered data size=%f  ",avail,value*1024);
                    pthread_mutex_unlock(&s->read_mutex);
                    return AVERROR(EAGAIN);
                }
            }
            s->is_first_read = 0;
        }
        if(url_interrupt_cb()) {
            pthread_mutex_unlock(&s->read_mutex);
            return 0;
        } else if(avail) {
            // Maximum amount available
            size = FFMIN( avail, size);
            av_fifo_generic_read(s->fifo, cache, size, NULL);
            pthread_mutex_unlock(&s->read_mutex);
            return size;
        } else if(s->EXITED) {
            pthread_mutex_unlock(&s->read_mutex);
            return 0;
        } else if(!s->finish_flag) {
            pthread_mutex_unlock(&s->read_mutex);
            //read just need retry
            return AVERROR(EAGAIN);
        }
    }
    pthread_mutex_unlock(&s->read_mutex);

    return 0;
}
Example #9
0
static void *circular_buffer_task( void *_handle)
{
    CacheHttpContext * s = (CacheHttpContext *)_handle;
    URLContext *h = NULL;
    float config_value = 0.0;
    void * fp = NULL;
    int config_ret = 0;

    while(!s->EXIT) {

        av_log(h, AV_LOG_ERROR, "----------circular_buffer_task  item ");
        s->reset_flag = 1;
        if (url_interrupt_cb()) {
            s->circular_buffer_error = EINTR;
            goto FAIL;
        }

        if(h) {
            CacheHttp_ffurl_close(h);
            config_ret = am_getconfig_float("libplayer.hls.dump",&config_value);
            if(config_ret >= 0 && (int)config_value == 2)
                CacheHttp_dump_close(fp);
            h = NULL;
        }

        list_item_t * item = getCurrentSegment(NULL);
        if(!item||(!item->file&&!item->flags&ENDLIST_FLAG)) {
            usleep(WAIT_TIME);
            continue;
        }

        s->reset_flag = 0;
        s->item_starttime = item->start_time;
        s->item_duration = item->duration;
        s->have_list_end = item->have_list_end;
        s->ktype = item->ktype;
        if(item->key_ctx!=NULL&& s->ktype==KEY_AES_128) {
            ff_data_to_hex(s->iv, item->key_ctx->iv, sizeof(item->key_ctx->iv), 0);
            ff_data_to_hex(s->key, item->key_ctx->key, sizeof(item->key_ctx->key), 0);
            s->iv[32] = s->key[32] = '\0';
        }
        if(item&&item->flags&ENDLIST_FLAG) {
            s->finish_flag =1;
        } else {
            s->finish_flag =0;
        }

        if(s->finish_flag) {
            av_log(NULL, AV_LOG_INFO, "ENDLIST_FLAG, return 0\n");
            //break;
            usleep(500*1000);
            continue;
        }

        int err, http_code;
        char* filename = NULL;
        if(s->ktype == KEY_NONE) {
            filename = av_strdup(item->file);

        } else {
            char url[MAX_URL_SIZE];
            if (strstr(item->file, "://"))
                snprintf(url, sizeof(url), "crypto+%s", item->file);
            else
                snprintf(url, sizeof(url), "crypto:%s", item->file);

            filename = av_strdup(url);

        }
        int retry_num = 0;
OPEN_RETRY:
        if(s->RESET)
            goto SKIP;
        err = CacheHttp_advanced_ffurl_open_h(&h, filename,AVIO_FLAG_READ|AVIO_FLAG_NONBLOCK, s->headers, &http_code,s);
        if (err) {
            if(url_interrupt_cb()) {
                if(filename) {
                    av_free(filename);
                    filename = NULL;
                }
                break;
            }
            if(1 == http_code && !s->have_list_end) {
                av_log(h, AV_LOG_ERROR, "----------CacheHttpContext : ffurl_open_h 404\n");
                if(retry_num++ < LIVE_HTTP_RETRY_TIMES) {
                    usleep(WAIT_TIME);
                    goto OPEN_RETRY;
                } else {
                    goto SKIP;
                }
            } else if(s->have_list_end || ((2 == http_code || 3 == http_code)&& !s->have_list_end)) {
                usleep(1000*20);
                goto OPEN_RETRY;
            } else if(!s->have_list_end&&err ==AVERROR(EIO)) {
                if(retry_num++ < LIVE_HTTP_RETRY_TIMES) {//if live streaming,just keep on 2s.
                    usleep(WAIT_TIME);
                    goto OPEN_RETRY;
                } else {
                    av_log(h, AV_LOG_ERROR, "----------CacheHttpContext : ffurl_open_h failed ,%d\n",err);
                    if(filename) {
                        av_free(filename);
                        filename = NULL;
                    }
                    break;
                }

            } else {
                av_log(h, AV_LOG_ERROR, "----------CacheHttpContext : ffurl_open_h failed ,%d\n",err);
                if(filename) {
                    av_free(filename);
                    filename = NULL;
                }
                break;
            }
        }

        if(h && s->seek_flag) {
            int64_t cur_pos = CacheHttp_ffurl_seek(h, 0, SEEK_CUR);
            int64_t pos_ret = CacheHttp_ffurl_seek(h, s->seek_pos-cur_pos, SEEK_CUR);
            av_log(NULL,AV_LOG_INFO,"--------------> cachehttp_seek   seek_pos=%lld, pos_ret=%lld", s->seek_pos, pos_ret);
            s->seek_flag = 0;
        }

        s->hd = h;
        s->item_pos = 0;
        s->item_size = CacheHttp_ffurl_seek(s->hd, 0, AVSEEK_SIZE);
        item->item_size = s->item_size;
        char tmpbuf[TMP_BUFFER_SIZE];
        int left = 0;
        int tmpdatasize = 0;
        config_ret = am_getconfig_float("libplayer.hls.dump",&config_value);
        if(config_ret >= 0 && config_value > 0)
            CacheHttp_dump_open(&fp, filename, (int)config_value);

        while(!s->EXIT) {

            if(s->RESET)
                break;

            if (url_interrupt_cb()) {
                s->circular_buffer_error = EINTR;
                break;
            }

            if(!s->hd)
                break;

            if(s->hd && tmpdatasize <= 0) {
                bandwidth_measure_start_read(s->bandwidth_measure);
                tmpdatasize = CacheHttp_ffurl_read(s->hd, tmpbuf, TMP_BUFFER_SIZE);
                bandwidth_measure_finish_read(s->bandwidth_measure,tmpdatasize);
            }

            //if(tmpdatasize > 0) {
            pthread_mutex_lock(&s->read_mutex);
            left = av_fifo_space(s->fifo);
            left = FFMIN(left, s->fifo->end - s->fifo->wptr);


            if( !left) {
                pthread_mutex_unlock(&s->read_mutex);
                usleep(WAIT_TIME);
                continue;
            }
            left = FFMIN(left, tmpdatasize);
            if(left >0) {
                memcpy(s->fifo->wptr, tmpbuf , left);
                tmpdatasize-=left;
            }
            if(tmpdatasize>0) {
                memmove(tmpbuf, tmpbuf+left , tmpdatasize);
            }

            if (left > 0) {
                config_ret = am_getconfig_float("libplayer.hls.dump",&config_value);
                if(config_ret >= 0 && config_value > 0)
                    CacheHttp_dump_write(fp, s->fifo->wptr, left);
                s->fifo->wptr += left;
                if (s->fifo->wptr >= s->fifo->end)
                    s->fifo->wptr = s->fifo->buffer;
                s->fifo->wndx += left;
                s->item_pos += left;
            } else if(left == AVERROR(EAGAIN) || (left < 0 && s->have_list_end&& left != AVERROR_EOF)) {
                pthread_mutex_unlock(&s->read_mutex);
                continue;
            } else {
                pthread_mutex_unlock(&s->read_mutex);
                av_log(h, AV_LOG_ERROR, "---------- circular_buffer_task read left = %d\n", left);
                break;
            }
            pthread_mutex_unlock(&s->read_mutex);
            //}

            //usleep(WAIT_TIME);

        }

SKIP:
        if(filename) {
            av_free(filename);
            filename = NULL;
        }
        if(!s->RESET)
            switchNextSegment(NULL);
    }

FAIL:

    if(h)
        CacheHttp_ffurl_close(h);
    s->hd = NULL;
    s->EXITED = 1;
    config_ret = am_getconfig_float("libplayer.hls.dump",&config_value);
    if(config_ret >= 0 && config_value > 0)
        CacheHttp_dump_close(fp);
    av_log(NULL, AV_LOG_ERROR, "---------> CacheHttp thread quit !");
    return NULL;
}
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)
			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_filesize(s));
	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;
}
Example #11
0
static int m3u_format_parser(struct list_mgt *mgt,ByteIOContext *s)
{ 
	unsigned  char line[1024];
	int ret;
	unsigned char *p; 
	int getnum=0;
	struct list_item tmpitem;
 	char prefix[1024]="";
	char prefixex[1024]="";
	int prefix_len=0,prefixex_len=0;
	int start_time=mgt->full_time;
	char *oprefix=mgt->location!=NULL?mgt->location:mgt->filename;
	
	if(oprefix){
		char *tail,*tailex,*extoptions;
		extoptions=strchr(oprefix,'?');/*ext options is start with ? ,we don't need in nested*/
		if(is_NET_URL(oprefix)){
			tail=strchr(oprefix+10,'/');/*skip Http:// and shttp:,and to first '/'*/
			if(!extoptions)// no ?
				tailex=strrchr(oprefix+10,'/');/*skip Http:// and shttp:,start to  last '/'*/
			else
				tailex=memrchr(oprefix+10,'/',extoptions-oprefix-10);/*skip Http:// and shttp:,start to  last '/',between http-->? */
		}else{
			tail=strchr(oprefix,'/'); /*first '/'*/
			if(!extoptions)//no ?
				tailex=strrchr(oprefix,'/'); /*to last '/' */
			else
				tailex=memrchr(oprefix+10,'/',extoptions-oprefix-10);/*skip Http:// and shttp:,start to  last '/',between http-->? */
		}
		
		if(tail!=NULL){
			prefix_len=tail-oprefix+1;/*left '/'..*/
			memcpy(prefix,oprefix,prefix_len);
			prefix[prefix_len]='\0';
		}

		if(tailex!=NULL){
			prefixex_len=tailex-oprefix+1;/*left '/'..*/
			memcpy(prefixex,oprefix,prefixex_len);
			prefixex[prefixex_len]='\0';
			if(NULL!=mgt->prefix){
				av_free(mgt->prefix);
				mgt->prefix = NULL;
			}
			mgt->prefix = strdup(prefixex);
		}
	}
	memset(&tmpitem,0,sizeof(tmpitem));
	av_log(NULL, AV_LOG_INFO, "m3u_format_parser get prefix=%s\n",prefix);
	av_log(NULL, AV_LOG_INFO, "m3u_format_parser get prefixex=%s\n",prefixex);
	#if 0
	if(mgt->n_variants>0){
		free_variant_list(mgt);
	}
	#endif
	while(m3u_format_get_line(s,line,1024)>=0)
	{
		ret = m3u_parser_line(mgt,line,&tmpitem);
		if(ret>0)
		{		
			struct list_item*item;
			int need_prefix=0;
			int size_file=tmpitem.file?(strlen(tmpitem.file)+32):4;
			tmpitem.start_time=start_time;
			
			if(tmpitem.file && 
				(is_NET_URL(prefix)) && /*net protocal*/
				!(is_NET_URL(tmpitem.file)))/*if item is not net protocal*/
			{/*if m3u is http,item is not http,add prefix*/
				need_prefix=1;
				size_file+=prefixex_len;
			}
			item=av_malloc(sizeof(struct list_item)+size_file);
			if(!item)
				return AVERROR(ENOMEM);
			memcpy(item,&tmpitem,sizeof(tmpitem));
			item->file=NULL;
			if(tmpitem.file)
			{
				item->file=&item[1];
				if(need_prefix){
					if(tmpitem.file[0]=='/'){/*has '/',not need the dir */
						strcpy(item->file,prefix);
						strcpy(item->file+prefix_len,tmpitem.file+1);/*don't copy two '/',we have left before*/
					}else{/*no '/', some I save the full path frefix*/
						if(!strncmp(prefixex,"shttps://",9)){
							strcpy(item->file,"http");
							strcpy(item->file+4,prefixex+6);
							strcpy(item->file+4+prefixex_len -6,tmpitem.file);
						}else{
							strcpy(item->file,prefixex);
							strcpy(item->file+prefixex_len,tmpitem.file);	
						}
						
					}
				}
				else{
					strcpy(item->file,tmpitem.file);
				}
			}

			if(mgt->flags&KEY_FLAG&&NULL!= mgt->key_tmp&&mgt->key_tmp->is_have_key_file>0){
				item->key_ctx = av_mallocz(sizeof(struct AES128KeyContext));
				if(!item->key_ctx){
					ret = AVERROR(ENOMEM);
					break;
				}				
				memcpy(item->key_ctx->key,mgt->key_tmp->key,sizeof(item->key_ctx->key));
				if(mgt->has_iv>0){
					memcpy(item->key_ctx->iv,mgt->key_tmp->iv,sizeof(item->key_ctx->iv));				
				}else{//from applehttp.c
					
					int seq = mgt->seq+mgt->item_num;
					av_log(NULL,AV_LOG_INFO,"Current item seq number:%d\n",seq);		
					AV_WB32(item->key_ctx->iv + 12, seq);
				}

				
				item->ktype = mgt->key_tmp->key_type;

			}
			if(mgt->flags&REAL_STREAMING_FLAG){			
				ret =list_test_and_add_item(mgt,item);
				if(ret==0){
					start_time+=item->duration;
				}
				
			}else{
				ret = list_add_item(mgt,item);
				start_time+=item->duration;

			}
			if(item->flags &ENDLIST_FLAG)
			{
				mgt->have_list_end=1;
				break;
			}
			else
			{
				memset(&tmpitem,0,sizeof(tmpitem));
				if(ret == 0){
					getnum++;

				}
			}
		}
		else if(ret <0){
			if(ret ==-(TRICK_LOGIC_BASE+0)&&(mgt->flags&KEY_FLAG)&&NULL!= mgt->key_tmp&&0==mgt->key_tmp->is_have_key_file){//get key from server
				 URLContext *uc;
			        if (ffurl_open(&uc, mgt->key_tmp->key_from, AVIO_FLAG_READ) == 0) {
			            if (ffurl_read_complete(uc, mgt->key_tmp->key, sizeof(mgt->key_tmp->key))
			                != sizeof(mgt->key_tmp->key)) {
			                av_log(NULL, AV_LOG_ERROR, "Unable to read key file %s\n",
			                       mgt->key_tmp->key_from);					
					
					}
					av_log(NULL,AV_LOG_INFO,"Just get aes key file from server\n");		
					mgt->key_tmp->is_have_key_file = 1;
						
					ffurl_close(uc);
			       } else {
			            	av_log(NULL, AV_LOG_ERROR, "Unable to open key file %s\n",
			                   mgt->key_tmp->key_from);
			       }
				memset(&tmpitem,0,sizeof(tmpitem));   
				continue;   
			}
			
			if(ret ==-(TRICK_LOGIC_BASE+1)||ret ==-(TRICK_LOGIC_BASE+2)){
				memset(&tmpitem,0,sizeof(tmpitem));   
				continue;
			}			
			break;
		}
		else{
			if(tmpitem.flags&ALLOW_CACHE_FLAG)
				mgt->flags|=ALLOW_CACHE_FLAG;
			if(mgt->flags&REAL_STREAMING_FLAG&&mgt->jump_item_num==INT_MAX){
				mgt->jump_item_num = 0;
				av_log(NULL, AV_LOG_INFO, "drop this list,sequence number:%ld\n",mgt->seq);
				break;
			}
		}
		
	}
	if(mgt->key_tmp){
		av_free(mgt->key_tmp);
		mgt->key_tmp = NULL;
	}
	if(mgt->n_variants>0){//just choose  middle definition;
 		float value;
		ret=am_getconfig_float("libplayer.hls.level",&value);
		if(ret==0&&value<1){
			mgt->ctype =LOW_BANDWIDTH;
		}else if(ret==0&&value>0&&value<2){
			mgt->ctype =MIDDLE_BANDWIDTH;
		}else if(ret==0&&value>1){
			mgt->ctype =HIGH_BANDWIDTH;
		}else{
			mgt->ctype =MIDDLE_BANDWIDTH;
		}
	}
	mgt->file_size=AVERROR_STREAM_SIZE_NOTVALID;
	mgt->full_time=start_time;
	mgt->last_load_time = av_gettime();
	av_log(NULL, AV_LOG_INFO, "m3u_format_parser end num =%d,fulltime=%d\n",getnum,start_time);
	return getnum;
Example #12
0
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;
}
Example #13
0
static int  fast_sort_streams(struct list_mgt * mgt){
    int key,left,middle,right;  
    struct variant *var= NULL;
    int i,j,tmp,stuff[mgt->n_variants];
    int has_bandwidth = -1;
    for (i=0; i < mgt->n_variants; i++){
        var = mgt->variants[i];
        stuff[i] = var->bandwidth;
        if(has_bandwidth<0&&stuff[i] >0){
            has_bandwidth = 1;
        }
       
    }

    if(has_bandwidth<0){
        for (i=0; i < mgt->n_variants; i++){
            var = mgt->variants[i];
            var->priority = i;           
        }
        
        mgt->playing_variant= mgt->variants[mgt->n_variants/2];
        RLOG("Invalid bandwidth streaming,choose url:%s\n",mgt->playing_variant->url);
        return 0;        
    }
    for (i=1; i < mgt->n_variants; i++){
        key = stuff[i];
        left = 0;
        right = i-1;
        while(left<=right){
            middle=(left+right)/2;             
            if (key>stuff[middle]) {//down order
                right=middle-1;
            }else{
                left=middle+1;
            }         
            
        }
        for (j=i;j>left;j--){
            stuff[j]=stuff[j-1];
        }
        stuff[left]=key; 
    }

    j = mgt->n_variants - 1;
    for (i=0; i < mgt->n_variants; i++){
        for (tmp=0; tmp <  mgt->n_variants; tmp++){
            var = mgt->variants[tmp];
            if (var->bandwidth == stuff[i]){
                var->priority = j--;    
                //av_log(NULL,AV_LOG_INFO,"===priority:%d,bandwidth:%d\n",var->priority,var->bandwidth);
                break;
            }
        }

    }

    float value = 0.0;
    int ret = -1;
    ret = am_getconfig_float("libplayer.hls.bw_max", &value);
    if(ret>=0&&value>0){
         for (i=0; i < mgt->n_variants; i++){
            var = mgt->variants[i];
            if(var->bandwidth>value){
                var->priority = -1;
            }
         }

    }
    ret = am_getconfig_float("libplayer.hls.bw_min", &value);
    if(ret>=0&&value>0){        
        for (i=0; i < mgt->n_variants; i++){
            var = mgt->variants[i];
            if(var->bandwidth<value){
                var->priority = -2;
            }
        }

    }else{
        for (i=0; i < mgt->n_variants; i++){
            var = mgt->variants[i];
            if(var->bandwidth<AUDIO_BANDWIDTH_MAX){
                var->priority = -2;
            }
        }           
    }


    ret = am_getconfig_float("libplayer.hls.bw_start", &value);
    if(ret>=0&&value>=0){
        for (i=0; i < mgt->n_variants; i++){
            var = mgt->variants[i];
            if(var->priority==(int)value){
                mgt->playing_variant= var;                
                break;
            }
        }        

    }else{
        ret =(int)get_adaptation_ex_para(3);
        for (i=0; i < mgt->n_variants; i++){
            var = mgt->variants[i];
            if(ret>=0){
                if(ret>(mgt->n_variants-1)){
                    ret = mgt->n_variants-1;
                }
               
                if(var->priority==ret){
                    
                    mgt->playing_variant= var;
                    break;
                }               
            }else{
                if(var->priority>=0){
                   
                    mgt->playing_variant= var;
                    break;
                }
            }
        }         

    }
   
    
    //av_log(NULL,AV_LOG_INFO,"Do fast sort streaming");
    return 0;
    
}