Пример #1
0
static struct variant *new_variant(struct list_mgt *mgt, int bandwidth, const char *url, const char *base)
{
    struct variant *var = av_mallocz(sizeof(struct variant));
    if (!var)
        return NULL;

    var->bandwidth = bandwidth;
    char* ptr = NULL;
    int has_prefix = 0;
    if(!av_strstart(url,"https://",ptr)) {
        if(base!=NULL&&av_strstart(base,"https://",ptr)) { //change to  shttps for using android streaming framework.
            snprintf(var->url,1,"s");
            has_prefix = 1;
        }
        if(has_prefix>0) {
            ff_make_absolute_url(var->url+1, sizeof(var->url)-1, base, url);
        } else {
            ff_make_absolute_url(var->url, sizeof(var->url), base, url);
        }
    } else { //change to  shttps for using android streaming framework.
        snprintf(var->url,sizeof(var->url),"s%s",url);
    }
    //av_log(NULL,AV_LOG_INFO,"returl=%s\nbase=%s\nurl=%s\n",var->url,base,url);
    dynarray_add(&mgt->variants, &mgt->n_variants, var);
    return var;
}
Пример #2
0
static void test(const char *base, const char *rel)
{
    char buf[200], buf2[200];
    ff_make_absolute_url(buf, sizeof(buf), base, rel);
    printf("%s\n", buf);
    if (base) {
        /* Test in-buffer replacement */
        snprintf(buf2, sizeof(buf2), "%s", base);
        ff_make_absolute_url(buf2, sizeof(buf2), buf2, rel);
        if (strcmp(buf, buf2)) {
            printf("In-place handling of %s + %s failed\n", base, rel);
            exit(1);
        }
    }
}
Пример #3
0
static struct playlist *new_playlist(HLSContext *c, const char *url,
                                     const char *base)
{
    struct playlist *pls = av_mallocz(sizeof(struct playlist));
    if (!pls)
        return NULL;
    reset_packet(&pls->pkt);
    ff_make_absolute_url(pls->url, sizeof(pls->url), base, url);
    dynarray_add(&c->playlists, &c->n_playlists, pls);
    return pls;
}
Пример #4
0
static struct variant *new_variant(HLSContext *c, int bandwidth,
                                   const char *url, const char *base)
{
    struct variant *var = av_mallocz(sizeof(struct variant));
    if (!var)
        return NULL;
    reset_packet(&var->pkt);
    var->bandwidth = bandwidth;
    ff_make_absolute_url(var->url, sizeof(var->url), base, url);
    dynarray_add(&c->variants, &c->n_variants, var);
    return var;
}
Пример #5
0
static int parse_location(HTTPContext *s, const char *p)
{
    char redirected_location[MAX_URL_SIZE], *new_loc;
    ff_make_absolute_url(redirected_location, sizeof(redirected_location),
                         s->location, p);
    new_loc = av_strdup(redirected_location);
    if (!new_loc)
        return AVERROR(ENOMEM);
    av_free(s->location);
    s->location = new_loc;
    return 0;
}
Пример #6
0
static int parse_playlist(URLContext *h, const char *url)
{
    AppleHTTPContext *s = h->priv_data;
    AVIOContext *in;
    int ret = 0, duration = 0, is_segment = 0, is_variant = 0, bandwidth = 0;
    char line[1024];
    const char *ptr;

    if ((ret = avio_open(&in, url, AVIO_FLAG_READ)) < 0)
        return ret;

    read_chomp_line(in, line, sizeof(line));
    if (strcmp(line, "#EXTM3U"))
        return AVERROR_INVALIDDATA;

    free_segment_list(s);
    s->finished = 0;
    while (!in->eof_reached) {
        read_chomp_line(in, line, sizeof(line));
        if (av_strstart(line, "#EXT-X-STREAM-INF:", &ptr)) {
            struct variant_info info = {{0}};
            is_variant = 1;
            ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_variant_args,
                               &info);
            bandwidth = atoi(info.bandwidth);
        } else if (av_strstart(line, "#EXT-X-TARGETDURATION:", &ptr)) {
            s->target_duration = atoi(ptr);
        } else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) {
            s->start_seq_no = atoi(ptr);
        } else if (av_strstart(line, "#EXT-X-ENDLIST", &ptr)) {
            s->finished = 1;
        } else if (av_strstart(line, "#EXTINF:", &ptr)) {
            is_segment = 1;
            duration = atoi(ptr);
        } else if (av_strstart(line, "#", NULL)) {
            continue;
        } else if (line[0]) {
            if (is_segment) {
                struct segment *seg = av_malloc(sizeof(struct segment));
                if (!seg) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
                seg->duration = duration;
                ff_make_absolute_url(seg->url, sizeof(seg->url), url, line);
                dynarray_add(&s->segments, &s->n_segments, seg);
                is_segment = 0;
            } else if (is_variant) {
                struct variant *var = av_malloc(sizeof(struct variant));
                if (!var) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
                var->bandwidth = bandwidth;
                ff_make_absolute_url(var->url, sizeof(var->url), url, line);
                dynarray_add(&s->variants, &s->n_variants, var);
                is_variant = 0;
            }
        }
    }
    s->last_load_time = av_gettime();

fail:
    avio_close(in);
    return ret;
}
Пример #7
0
static int parse_playlist(HLSContext *c, const char *url,
                          struct variant *var, AVIOContext *in)
{
    int ret = 0, duration = 0, is_segment = 0, is_variant = 0, bandwidth = 0;
    enum KeyType key_type = KEY_NONE;
    uint8_t iv[16] = "";
    int has_iv = 0;
    char key[MAX_URL_SIZE] = "";
    char line[1024];
    const char *ptr;
    int close_in = 0;

    if (!in) {
        int is_redirected = 0;
        URLContext *h = NULL;
        AVDictionary *opts = NULL;
        close_in = 1;
        /* Some HLS servers dont like being sent the range header */
        av_dict_set(&opts, "seekable", "0", 0);
        ret = avio_open2(&in, url, AVIO_FLAG_READ,
                         c->interrupt_callback, &opts);
        av_dict_free(&opts);
        if (ret < 0)
            return ret;

        h = (URLContext *) in->opaque;
        ff_http_get_location_changed(h, &is_redirected);
        if ( is_redirected ) {
           ff_http_get_new_location(h, var->url);
           av_log(NULL, AV_LOG_WARNING, "the var url changed to %s \n", var->url);
        }
    }

    read_chomp_line(in, line, sizeof(line));
    if (strcmp(line, "#EXTM3U")) {
        ret = AVERROR_INVALIDDATA;
        goto fail;
    }

    if (var) {
        free_segment_list(var);
        var->finished = 0;
    }
    while (!url_feof(in)) {
        read_chomp_line(in, line, sizeof(line));
        if (av_strstart(line, "#EXT-X-STREAM-INF:", &ptr)) {
            struct variant_info info = {{0}};
            is_variant = 1;
            ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_variant_args,
                               &info);
            bandwidth = atoi(info.bandwidth);
        } else if (av_strstart(line, "#EXT-X-KEY:", &ptr)) {
            struct key_info info = {{0}};
            ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_key_args,
                               &info);
            key_type = KEY_NONE;
            has_iv = 0;
            if (!strcmp(info.method, "AES-128"))
                key_type = KEY_AES_128;
            if (!strncmp(info.iv, "0x", 2) || !strncmp(info.iv, "0X", 2)) {
                ff_hex_to_data(iv, info.iv + 2);
                has_iv = 1;
            }
            av_strlcpy(key, info.uri, sizeof(key));
        } else if (av_strstart(line, "#EXT-X-TARGETDURATION:", &ptr)) {
            if (!var) {
                var = new_variant(c, 0, url, NULL);
                if (!var) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
            }
            var->target_duration = atoi(ptr);
        } else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) {
            if (!var) {
                var = new_variant(c, 0, url, NULL);
                if (!var) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
            }
            var->start_seq_no = atoi(ptr);
        } else if (av_strstart(line, "#EXT-X-ENDLIST", &ptr)) {
            if (var)
                var->finished = 1;
        } else if (av_strstart(line, "#EXTINF:", &ptr)) {
            is_segment = 1;
            duration   = atoi(ptr);
        } else if (av_strstart(line, "#", NULL)) {
            continue;
        } else if (line[0]) {
            if (is_variant) {
                if (!new_variant(c, bandwidth, line, url)) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
                is_variant = 0;
                bandwidth  = 0;
            }
            if (is_segment) {
                struct segment *seg;
                if (!var) {
                    var = new_variant(c, 0, url, NULL);
                    if (!var) {
                        ret = AVERROR(ENOMEM);
                        goto fail;
                    }
                }
                seg = av_malloc(sizeof(struct segment));
                if (!seg) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
                seg->duration = duration;
                seg->key_type = key_type;
                if (has_iv) {
                    memcpy(seg->iv, iv, sizeof(iv));
                } else {
                    int seq = var->start_seq_no + var->n_segments;
                    memset(seg->iv, 0, sizeof(seg->iv));
                    AV_WB32(seg->iv + 12, seq);
                }
                ff_make_absolute_url(seg->key, sizeof(seg->key), url, key);
                ff_make_absolute_url(seg->url, sizeof(seg->url), url, line);
                dynarray_add(&var->segments, &var->n_segments, seg);
                is_segment = 0;
            }
        }
    }
    if (var)
        var->last_load_time = av_gettime();

fail:
    if (close_in)
        avio_close(in);
    return ret;
}
Пример #8
0
static int parse_playlist(HLSContext *c, const char *url,
                          struct variant *var, AVIOContext *in)
{
    int ret = 0, is_segment = 0, is_variant = 0, bandwidth = 0;
    int64_t duration = 0;
    enum KeyType key_type = KEY_NONE;
    uint8_t iv[16] = "";
    int has_iv = 0;
    char key[MAX_URL_SIZE] = "";
    char line[1024];
    const char *ptr;
    int close_in = 0;
    uint8_t *new_url = NULL;

    if (!in) {
        ret = open_in(c, &in, url);
        if (ret < 0)
            return ret;
        close_in = 1;
    }

    if (av_opt_get(in, "location", AV_OPT_SEARCH_CHILDREN, &new_url) >= 0)
        url = new_url;

    read_chomp_line(in, line, sizeof(line));
    if (strcmp(line, "#EXTM3U")) {
        ret = AVERROR_INVALIDDATA;
        goto fail;
    }

    if (var) {
        free_segment_list(var);
        var->finished = 0;
    }
    while (!in->eof_reached) {
        read_chomp_line(in, line, sizeof(line));
        if (av_strstart(line, "#EXT-X-STREAM-INF:", &ptr)) {
            struct variant_info info = {{0}};
            is_variant = 1;
            ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_variant_args,
                               &info);
            bandwidth = atoi(info.bandwidth);
        } else if (av_strstart(line, "#EXT-X-KEY:", &ptr)) {
            struct key_info info = {{0}};
            ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_key_args,
                               &info);
            key_type = KEY_NONE;
            has_iv = 0;
            if (!strcmp(info.method, "AES-128"))
                key_type = KEY_AES_128;
            if (!strncmp(info.iv, "0x", 2) || !strncmp(info.iv, "0X", 2)) {
                ff_hex_to_data(iv, info.iv + 2);
                has_iv = 1;
            }
            av_strlcpy(key, info.uri, sizeof(key));
        } else if (av_strstart(line, "#EXT-X-TARGETDURATION:", &ptr)) {
            if (!var) {
                var = new_variant(c, 0, url, NULL);
                if (!var) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
            }
            var->target_duration = atoi(ptr) * AV_TIME_BASE;
        } else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) {
            if (!var) {
                var = new_variant(c, 0, url, NULL);
                if (!var) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
            }
            var->start_seq_no = atoi(ptr);
        } else if (av_strstart(line, "#EXT-X-ENDLIST", &ptr)) {
            if (var)
                var->finished = 1;
        } else if (av_strstart(line, "#EXTINF:", &ptr)) {
            is_segment = 1;
            duration   = atof(ptr) * AV_TIME_BASE;
        } else if (av_strstart(line, "#", NULL)) {
            continue;
        } else if (line[0]) {
            if (is_variant) {
                if (!new_variant(c, bandwidth, line, url)) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
                is_variant = 0;
                bandwidth  = 0;
            }
            if (is_segment) {
                struct segment *seg;
                if (!var) {
                    var = new_variant(c, 0, url, NULL);
                    if (!var) {
                        ret = AVERROR(ENOMEM);
                        goto fail;
                    }
                }
                seg = av_malloc(sizeof(struct segment));
                if (!seg) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
                seg->duration = duration;
                seg->key_type = key_type;
                if (has_iv) {
                    memcpy(seg->iv, iv, sizeof(iv));
                } else {
                    int seq = var->start_seq_no + var->n_segments;
                    memset(seg->iv, 0, sizeof(seg->iv));
                    AV_WB32(seg->iv + 12, seq);
                }
                ff_make_absolute_url(seg->key, sizeof(seg->key), url, key);
                ff_make_absolute_url(seg->url, sizeof(seg->url), url, line);
                dynarray_add(&var->segments, &var->n_segments, seg);
                is_segment = 0;
            }
        }
    }
    if (var)
        var->last_load_time = av_gettime_relative();

fail:
    av_free(new_url);
    if (close_in)
        avio_close(in);
    return ret;
}
Пример #9
0
#endif
static int m3u_parser_line(struct list_mgt *mgt,unsigned char *line,struct list_item*item)
{
	unsigned char *p=line; 
	int enditem=0;
	const char* ptr = NULL;
       int isLetvFlag = 0;
	while((*p==' '||*p == '\t' )&& p!='\0' && p-line<1024) p++;
	if(*p!='#' && strlen(p)>0&&mgt->is_variant==0)
	{		
		item->file=p; 
		enditem=1;
	}else if(av_strstart(line,EXT_LETV_VER, &ptr)){
	     //av_log(NULL,AV_LOG_INFO,"Get letv version: %s\n",ptr+1);
            mgt->flags|=IGNORE_SEQUENCE_FLAG;
       }else if(is_TAG(p,EXT_X_ENDLIST)){
		item->flags|=ENDLIST_FLAG;		
		enditem=1;
	}else if(is_TAG(p,EXTINF)){
		double duration=0.00;
             parseDouble(p+8,&duration);
             //av_log(NULL,AV_LOG_INFO,"Get item duration:%.4lf\n",duration);
		//sscanf(p+8,"%d",&duration);//skip strlen("#EXTINF:")
		if(duration>0){
			item->flags|=DURATION_FLAG;
			item->duration=duration;			
		}        
	} else if (av_strstart(line, "#EXT-X-TARGETDURATION:", &ptr)) {            	
		mgt->target_duration = atoi(ptr);
		//av_log(NULL, AV_LOG_INFO, "get target duration:%ld\n",mgt->target_duration);
	}else if(is_TAG(p,EXT_X_ALLOW_CACHE)){
		item->flags|=ALLOW_CACHE_FLAG;
	}else if(is_TAG(p,EXT_X_MEDIA_SEQUENCE)&&!(mgt->flags&IGNORE_SEQUENCE_FLAG)){
		int seq = -1;
		int ret=0;
		int slen = strlen("#EXT-X-MEDIA-SEQUENCE:");
		ret=sscanf(p+slen,"%d",&seq); //skip strlen("#EXT-X-MEDIA-SEQUENCE:");	
		if(mgt->debug_level>3){
		    RLOG("Get item seq:%d,next seq:%d\n",seq,mgt->next_seq);
             }
		if(ret>0&&seq>=0&&seq>=mgt->next_seq){
			//if(mgt->start_seq<0){
			mgt->start_seq=seq;	
			
			//}
			item->seq=seq;
			mgt->next_seq=seq+1;
			
		}else{
		   if(mgt->debug_level>3){     
                    RLOG("Invalid item flag,get item seq:%d,next seq:%d\n",seq,mgt->next_seq);
                }
                item->seq = seq;
                mgt->start_seq=seq;
                item->flags |=INVALID_ITEM_FLAG;
		}
	}
	
	else if(av_strstart(p,"#EXT-X-STREAM-INF:",&ptr)){
		struct variant_info info = {{0}};           
            ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_variant_args,&info);
		mgt->bandwidth = atoi(info.bandwidth);		
            if(mgt->debug_level>3){
                RLOG("Get a stream info,bandwidth:%d\n",mgt->bandwidth);	
            }
		mgt->is_variant = 1;
		return -(TRICK_LOGIC_BASE+1);
	}
	
	else if(av_strstart(p,"#EXT-X-KEY:",&ptr)){
		
		struct key_info info = {{0}};
		uint8_t iv[16] = "";
		ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_key_args,
		                   &info);
		#if 0
		av_log(NULL,AV_LOG_INFO,"==========start dump a aes key===========\n");
		av_log(NULL,AV_LOG_INFO,"==========key location : %s\n",info.uri);
		av_log(NULL,AV_LOG_INFO,"==========key iv : %s\n",info.iv);
		av_log(NULL,AV_LOG_INFO,"==========key method : %s\n",info.method);
		av_log(NULL,AV_LOG_INFO,"==========end dump a aes key===========\n");
		
		#endif
		struct encrypt_key_priv_t* key_priv_info = av_mallocz(sizeof(struct encrypt_key_priv_t));
		
		if(NULL == key_priv_info){
			//av_log(NULL,AV_LOG_ERROR,"no memory for key_info\n");
			return -1;
		}		

		if(NULL!=mgt->key_tmp){
			//av_log(NULL,AV_LOG_INFO,"released old key info\n");
			av_free(mgt->key_tmp);
			mgt->key_tmp = NULL;
		}
		
		enum KeyType key_type = KEY_NONE;
		if (!strcmp(info.method, "AES-128")){
		    	key_type = KEY_AES_128;
			
		}
		if (!strncmp(info.iv, "0x", 2) || !strncmp(info.iv, "0X", 2)) {
			ff_hex_to_data(iv, info.iv + 2);
			mgt->has_iv = 1;
		}else{
			mgt->has_iv = 0;
		}
		if(key_type ==KEY_AES_128){
			key_priv_info->key_type = key_type;
			if(mgt->has_iv>0){
				memcpy(key_priv_info->iv,iv,sizeof(key_priv_info->iv));
			}			
                    char* ptr = NULL;
                    int has_prefix = 0;
                    if(!av_strstart(info.uri,"https://",ptr)){
                        if(mgt->prefix!=NULL&&av_strstart(mgt->prefix,"https://",ptr)){//change to  shttps for using android streaming framework.           
                            snprintf(key_priv_info->key_from,1,"s");
                            has_prefix = 1;
                        }
                        if(has_prefix>0){
                            ff_make_absolute_url(key_priv_info->key_from+1, sizeof(key_priv_info->key_from)-1, mgt->prefix, info.uri);
                        }else{
                            ff_make_absolute_url(key_priv_info->key_from, sizeof(key_priv_info->key_from), mgt->prefix, info.uri);
                        }
                    }else{//change to  shttps for using android streaming framework.       
                        snprintf(key_priv_info->key_from,sizeof(key_priv_info->key_from),"s%s",info.uri);
                    }

                  
                    //av_log(NULL,AV_LOG_INFO,"aes key location,before:%s,after:%s\n",info.uri,key_priv_info->key_from);
			key_priv_info->is_have_key_file = 0;
			mgt->key_tmp = key_priv_info;
			mgt->flags |= KEY_FLAG;
			return -(TRICK_LOGIC_BASE+0);
			
		}else{
			//av_log(NULL,AV_LOG_INFO,"just only support aes key\n");
			av_free(key_priv_info);
			key_priv_info = NULL;
		}
		
		
	}
	else{

		if(mgt->is_variant>0){
			if(av_strstart(p,"http",&ptr)){
				if (!new_variant(mgt, mgt->bandwidth, p, NULL)) {	
					free_variant_list(mgt);
				 	return -1;
				}

			}else{
				if (!new_variant(mgt, mgt->bandwidth, p, mgt->prefix)) {	
					free_variant_list(mgt);
				 	return -1;
				}
			}
			mgt->is_variant = 0;
			mgt->bandwidth  = 0;	
			
			return -(TRICK_LOGIC_BASE+2);
			
		}
		
		return 0;
	}
	return enditem;
Пример #10
0
static int parse_playlist(HLSContext *c, const char *url,
                          struct variant *var, AVIOContext *in)
{
	char* resolution;
    int ret = 0, is_segment = 0, is_variant = 0, bandwidth = 0;
    double duration = 0.0;
    enum KeyType key_type = KEY_NONE;
    uint8_t iv[16] = "";
    int has_iv = 0;
    char key[MAX_URL_SIZE] = "";
    char line[1024];
    const char *ptr;
    int close_in = 0;

    if (!in) {
        close_in = 1;
        if ((ret = avio_open2(&in, url, AVIO_FLAG_READ,
                              c->interrupt_callback, NULL)) < 0)
            return ret;
    }

    read_chomp_line(in, line, sizeof(line));
    if (strcmp(line, "#EXTM3U")) {
        ret = AVERROR_INVALIDDATA;
        goto fail;
    }

    if (var) {
        free_segment_list(var);
        var->finished = 0;
    }
    while (!url_feof(in)) {
		static int a = 0;

        read_chomp_line(in, line, sizeof(line));
        if (av_strstart(line, "#EXT-X-STREAM-INF:", &ptr)) {
            struct variant_info info = {{0}};
            is_variant = 1;
            ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_variant_args,
                               &info);
            bandwidth = atoi(info.bandwidth);
            resolution = info.resolution;
			   for(uint32_t i=0; i<20; i++) {
				if(info.resolution[i] == 'x') {
					memcpy(info.width, info.resolution, i);
					memcpy(info.height, info.resolution+i+1, 20-i);
					c->ctx->width = atoi(info.width);
					c->ctx->height = atoi(info.height);
					break;
				}
			}
			LOGI("resolution = %s, width = %s, height = %s",info.resolution, info.width, info.height);
        } else if (av_strstart(line, "#EXT-X-KEY:", &ptr)) {
            struct key_info info = {{0}};
            ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_key_args,
                               &info);
            key_type = KEY_NONE;
            has_iv = 0;
            if (!strcmp(info.method, "AES-128"))
                key_type = KEY_AES_128;
            if (!strncmp(info.iv, "0x", 2) || !strncmp(info.iv, "0X", 2)) {
                ff_hex_to_data(iv, info.iv + 2);
                has_iv = 1;
            }
            av_strlcpy(key, info.uri, sizeof(key));
        } else if (av_strstart(line, "#EXT-X-TARGETDURATION:", &ptr)) {
            if (!var) {
                var = new_variant(c, 0, url, NULL);
                if (!var) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
            }
            var->target_duration = atof(ptr);
        } else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) {
            if (!var) {
                var = new_variant(c, 0, url, NULL);
                if (!var) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
            }
            var->start_seq_no = atoi(ptr);
//            LOGV("EXT-X-MEDIA-SEQUENCE = %d", var->start_seq_no);
        } else if (av_strstart(line, "#EXT-X-ENDLIST", &ptr)) {
            if (var)
                var->finished = 1;
//            static int a = 0;
//            FILE *fp = fopen( "/mnt/sdcard/Die_Hls.txt", "wta+");
//            fprintf(fp, "Line = %d, Times = %d, recive EXT-X-ENDLIST", __LINE__, a);
//            fclose(fp);
//            a++;
        } else if (av_strstart(line, "#EXTINF:", &ptr)) {
            is_segment = 1;
            duration   = atof(ptr);
        } else if (av_strstart(line, "#", NULL)) {
            continue;
        } else if (line[0]) {
            if (is_variant) {
                if (!new_variant(c, bandwidth, line, url)) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
                is_variant = 0;
                bandwidth  = 0;
            }
            if (is_segment) {
                struct segment *seg;
                if (!var) {
                    var = new_variant(c, 0, url, NULL);
                    if (!var) {
                        ret = AVERROR(ENOMEM);
                        goto fail;
                    }
                }
                seg = av_malloc(sizeof(struct segment));
                if (!seg) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
                seg->duration = duration;
                seg->key_type = key_type;
                if (has_iv) {
                    memcpy(seg->iv, iv, sizeof(iv));
                } else {
                    int seq = var->start_seq_no + var->n_segments;
                    memset(seg->iv, 0, sizeof(seg->iv));
                    AV_WB32(seg->iv + 12, seq);
                }
                ff_make_absolute_url(seg->key, sizeof(seg->key), url, key);
                ff_make_absolute_url(seg->url, sizeof(seg->url), url, line);
                dynarray_add(&var->segments, &var->n_segments, seg);
                is_segment = 0;
            }
        }
    }
    if (var)
        var->last_load_time = av_gettime();

fail:
    if (close_in)
        avio_close(in);
    return ret;
}
Пример #11
0
static int parse_playlist(HLSContext *c, const char *url,
                          struct variant *var, AVIOContext *in)
{
    int ret = 0, duration = 0, is_segment = 0, is_variant = 0, bandwidth = 0;
    enum KeyType key_type = KEY_NONE;
    uint8_t iv[16] = "";
    int has_iv = 0;
    char key[MAX_URL_SIZE] = "";
    char line[1024];
    const char *ptr;
    int close_in = 0;
    const char *locattion=NULL;
    int totaltime=0;
    int isdiscontinued=0;
	
    if (!in) {
        close_in = 1;
#ifdef  AVIO_OPEN2	
        if ((ret = avio_open2(&in, url, AVIO_FLAG_READ | URL_NO_LP_BUFFER,c->interrupt_callback, NULL)) < 0)
            return ret;
#else
	if ((ret = avio_open(&in, url, AVIO_FLAG_READ | URL_NO_LP_BUFFER)) < 0){
		av_log(NULL, AV_LOG_ERROR, "parse_playlist :open [%s]failed=%d\n",url,ret);	 
            return ret;
	}		
#endif
    }
    if(in->reallocation)
		locattion=in->reallocation;
    else
		locattion=url;
    read_chomp_line(in, line, sizeof(line));
    if (strcmp(line, "#EXTM3U")) {
	 av_log(NULL, AV_LOG_ERROR, "not a valid m3u file,first line is [%s]\n",line);	 
        ret = AVERROR_INVALIDDATA;
        goto fail;
    }

    if (var) {
        free_segment_list(var);
        var->finished = 0;
    }
    while (1) {
		int sret;
		 line[0]=0;
		 if(url_interrupt_cb())
		 	break;
	        sret=read_chomp_line(in, line, sizeof(line));
		 if(sret<0){
		 	 av_log(NULL, AV_LOG_ERROR, "read_chomp_line end,ret=%d,var=%x,c->n_variants=%x\n",sret,var,c->n_variants);	 
		 	ret=(var!=NULL ||c->n_variants>0)?0:sret;
		 	break;
		 }
	    av_log(NULL, AV_LOG_INFO+1, "parse_playlist :[%s]\n",line);	 
        if (av_strstart(line, "#EXT-X-STREAM-INF:", &ptr)) {
            struct variant_info info = {{0}};
            is_variant = 1;
            ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_variant_args,
                               &info);
            bandwidth = atoi(info.bandwidth);
        } else if (av_strstart(line, "#EXT-X-KEY:", &ptr)) {
            struct key_info info = {{0}};
            ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_key_args,
                               &info);
            key_type = KEY_NONE;
            has_iv = 0;
            if (!strcmp(info.method, "AES-128"))
                key_type = KEY_AES_128;
            if (!strncmp(info.iv, "0x", 2) || !strncmp(info.iv, "0X", 2)) {
                ff_hex_to_data(iv, info.iv + 2);
                has_iv = 1;
            }
            av_strlcpy(key, info.uri, sizeof(key));
        } else if (av_strstart(line, "#EXT-X-TARGETDURATION:", &ptr)) {
            if (!var) {
                var = new_variant(c, 0, url, NULL);
                if (!var) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
            }
            var->target_duration = atoi(ptr);
        } else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) {
            if (!var) {
                var = new_variant(c, 0, url, NULL);
                if (!var) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
            }
            var->start_seq_no = atoi(ptr);
        } else if (av_strstart(line, "#EXT-X-ENDLIST", &ptr)) {
            if (var)
                var->finished = 1;
        } else if (av_strstart(line, "#EXTINF:", &ptr)) {
            is_segment = 1;
            duration   = atoi(ptr);
        }  else if (av_strstart(line, "#EXT-X-DISCONTINUITY", &ptr)) {
            isdiscontinued   = 1;
        } else if (av_strstart(line, "#", NULL)) {
            continue;
        } else if (line[0]) {
            if (is_variant) {
                if (!new_variant(c, bandwidth, line, locattion)) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
                is_variant = 0;
                bandwidth  = 0;
            }
            if (is_segment) {
                struct segment *seg;
                if (!var) {
                    var = new_variant(c, 0, url, NULL);
                    if (!var) {
                        ret = AVERROR(ENOMEM);
                        goto fail;
                    }
                }
                seg = av_malloc(sizeof(struct segment));
                if (!seg) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
                seg->duration = duration;
                seg->key_type = key_type;
		  seg->seg_starttime=totaltime;	
		  seg->flags=DISCONTINUE_FLAG;
		  totaltime+=duration;
                if (has_iv) {
                    memcpy(seg->iv, iv, sizeof(iv));
                } else {
                    int seq = var->start_seq_no + var->n_segments;
                    memset(seg->iv, 0, sizeof(seg->iv));
                    AV_WB32(seg->iv + 12, seq);
                }
                ff_make_absolute_url(seg->key, sizeof(seg->key), url, key);
                ff_make_absolute_url(seg->url, sizeof(seg->url), locattion, line);
                dynarray_add(&var->segments, &var->n_segments, seg);
                is_segment = 0;
            }
        }
    }
    if (var){
        var->last_load_time = av_gettime();
	 var->total_time_s=totaltime;	
     }
fail:
    if (close_in)
        avio_close(in);
    return ret;
}
Пример #12
0
static int parse_playlist(HLSContext *c, const char *url,
                          struct playlist *pls, AVIOContext *in)
{
    int ret = 0, is_segment = 0, is_variant = 0, bandwidth = 0;
    int64_t duration = 0;
    enum KeyType key_type = KEY_NONE;
    uint8_t iv[16] = "";
    int has_iv = 0;
    char key[MAX_URL_SIZE] = "";
    char line[MAX_URL_SIZE];
    const char *ptr;
    int close_in = 0;
    uint8_t *new_url = NULL;

    if (!in) {
        AVDictionary *opts = NULL;
        close_in = 1;
        /* Some HLS servers don't like being sent the range header */
        av_dict_set(&opts, "seekable", "0", 0);

        // broker prior HTTP options that should be consistent across requests
        av_dict_set(&opts, "user-agent", c->user_agent, 0);
        av_dict_set(&opts, "cookies", c->cookies, 0);
        av_dict_set(&opts, "headers", c->headers, 0);

        ret = avio_open2(&in, url, AVIO_FLAG_READ,
                         c->interrupt_callback, &opts);
        av_dict_free(&opts);
        if (ret < 0)
            return ret;
    }

    if (av_opt_get(in, "location", AV_OPT_SEARCH_CHILDREN, &new_url) >= 0)
        url = new_url;

    read_chomp_line(in, line, sizeof(line));
    if (strcmp(line, "#EXTM3U")) {
        ret = AVERROR_INVALIDDATA;
        goto fail;
    }

    if (pls) {
        free_segment_list(pls);
        pls->finished = 0;
    }
    while (!url_feof(in)) {
        read_chomp_line(in, line, sizeof(line));
        if (av_strstart(line, "#EXT-X-STREAM-INF:", &ptr)) {
            struct variant_info info = {{0}};
            is_variant = 1;
            ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_variant_args,
                               &info);
            bandwidth = atoi(info.bandwidth);
        } else if (av_strstart(line, "#EXT-X-KEY:", &ptr)) {
            struct key_info info = {{0}};
            ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_key_args,
                               &info);
            key_type = KEY_NONE;
            has_iv = 0;
            if (!strcmp(info.method, "AES-128"))
                key_type = KEY_AES_128;
            if (!strncmp(info.iv, "0x", 2) || !strncmp(info.iv, "0X", 2)) {
                ff_hex_to_data(iv, info.iv + 2);
                has_iv = 1;
            }
            av_strlcpy(key, info.uri, sizeof(key));
        } else if (av_strstart(line, "#EXT-X-TARGETDURATION:", &ptr)) {
            if (!pls) {
                if (!new_variant(c, 0, url, NULL)) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
                pls = c->playlists[c->n_playlists - 1];
            }
            pls->target_duration = atoi(ptr) * AV_TIME_BASE;
        } else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) {
            if (!pls) {
                if (!new_variant(c, 0, url, NULL)) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
                pls = c->playlists[c->n_playlists - 1];
            }
            pls->start_seq_no = atoi(ptr);
        } else if (av_strstart(line, "#EXT-X-ENDLIST", &ptr)) {
            if (pls)
                pls->finished = 1;
        } else if (av_strstart(line, "#EXTINF:", &ptr)) {
            is_segment = 1;
            duration   = atof(ptr) * AV_TIME_BASE;
        } else if (av_strstart(line, "#", NULL)) {
            continue;
        } else if (line[0]) {
            if (is_variant) {
                if (!new_variant(c, bandwidth, line, url)) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
                is_variant = 0;
                bandwidth  = 0;
            }
            if (is_segment) {
                struct segment *seg;
                if (!pls) {
                    if (!new_variant(c, 0, url, NULL)) {
                        ret = AVERROR(ENOMEM);
                        goto fail;
                    }
                    pls = c->playlists[c->n_playlists - 1];
                }
                seg = av_malloc(sizeof(struct segment));
                if (!seg) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
                seg->duration = duration;
                seg->key_type = key_type;
                if (has_iv) {
                    memcpy(seg->iv, iv, sizeof(iv));
                } else {
                    int seq = pls->start_seq_no + pls->n_segments;
                    memset(seg->iv, 0, sizeof(seg->iv));
                    AV_WB32(seg->iv + 12, seq);
                }
                ff_make_absolute_url(seg->key, sizeof(seg->key), url, key);
                ff_make_absolute_url(seg->url, sizeof(seg->url), url, line);
                dynarray_add(&pls->segments, &pls->n_segments, seg);
                is_segment = 0;
            }
        }
    }
    if (pls)
        pls->last_load_time = av_gettime();

fail:
    av_free(new_url);
    if (close_in)
        avio_close(in);
    return ret;
}
Пример #13
0
static int parse_playlist(AppleHTTPContext *c, const char *url,
                          struct variant *var, AVIOContext *in)
{
    int ret = 0, duration = 0, is_segment = 0, is_variant = 0, bandwidth = 0;
    char line[1024];
    const char *ptr;
    int close_in = 0;

    if (!in) {
        close_in = 1;
        if ((ret = avio_open(&in, url, AVIO_RDONLY)) < 0)
            return ret;
    }

    read_chomp_line(in, line, sizeof(line));
    if (strcmp(line, "#EXTM3U")) {
        ret = AVERROR_INVALIDDATA;
        goto fail;
    }

    if (var) {
        free_segment_list(var);
        var->finished = 0;
    }
    while (!url_feof(in)) {
        read_chomp_line(in, line, sizeof(line));
        if (av_strstart(line, "#EXT-X-STREAM-INF:", &ptr)) {
            struct variant_info info = {{0}};
            is_variant = 1;
            ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_variant_args,
                               &info);
            bandwidth = atoi(info.bandwidth);
        } else if (av_strstart(line, "#EXT-X-TARGETDURATION:", &ptr)) {
            if (!var) {
                var = new_variant(c, 0, url, NULL);
                if (!var) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
            }
            var->target_duration = atoi(ptr);
        } else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) {
            if (!var) {
                var = new_variant(c, 0, url, NULL);
                if (!var) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
            }
            var->start_seq_no = atoi(ptr);
        } else if (av_strstart(line, "#EXT-X-ENDLIST", &ptr)) {
            if (var)
                var->finished = 1;
        } else if (av_strstart(line, "#EXTINF:", &ptr)) {
            is_segment = 1;
            duration   = atoi(ptr);
        } else if (av_strstart(line, "#", NULL)) {
            continue;
        } else if (line[0]) {
            if (is_variant) {
                if (!new_variant(c, bandwidth, line, url)) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
                is_variant = 0;
                bandwidth  = 0;
            }
            if (is_segment) {
                struct segment *seg;
                if (!var) {
                    var = new_variant(c, 0, url, NULL);
                    if (!var) {
                        ret = AVERROR(ENOMEM);
                        goto fail;
                    }
                }
                seg = av_malloc(sizeof(struct segment));
                if (!seg) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
                seg->duration = duration;
                ff_make_absolute_url(seg->url, sizeof(seg->url), url, line);
                dynarray_add(&var->segments, &var->n_segments, seg);
                is_segment = 0;
            }
        }
    }
    if (var)
        var->last_load_time = av_gettime();

fail:
    if (close_in)
        avio_close(in);
    return ret;
}