Exemplo n.º 1
0
static inline int retry_transfer_wrapper(URLContext *h, unsigned char *buf, int size, int size_min,
                                         int (*transfer_func)(URLContext *h, unsigned char *buf, int size))
{
    int ret, len;
    int64_t timeouttime = av_gettime()+10*(1000*1000);/*10*1S.*/
    int retry=0;
    len = 0;
    while (len < size_min) {
        ret = transfer_func(h, buf+len, size-len);/*low level retry 1S*/
        if (url_interrupt_cb())
            return AVERROR_EXIT;
        if (ret == AVERROR(EINTR))
            continue;
        if (h->flags & AVIO_FLAG_NONBLOCK)
            return ret;
        if (ret == AVERROR(EAGAIN)) { 
			if(av_gettime()>=timeouttime)
				return AVERROR(EAGAIN);
			av_log(NULL,AV_LOG_INFO,"retry_transfer_wrapper,retry=%d\n",retry++);
        } else if (ret < 1){
            return ret < 0 ? ret : len;
        }else{
        	len+=ret;
        }
        if (url_interrupt_cb()) /*at least try several times for some teardown cmd finished.*/
            return AVERROR_EXIT;
    }
    return len;
}
Exemplo n.º 2
0
static int applehttp_read(URLContext *h, uint8_t *buf, int size)
{
    AppleHTTPContext *s = h->priv_data;
    const char *url;
    int ret;

start:
    if (s->seg_hd) {
        ret = ffurl_read(s->seg_hd, buf, size);
        if (ret > 0)
            return ret;
    }
    if (s->seg_hd) {
        ffurl_close(s->seg_hd);
        s->seg_hd = NULL;
        s->cur_seq_no++;
    }
retry:
    if (!s->finished) {
        int64_t now = av_gettime();
        if (now - s->last_load_time >= s->target_duration*1000000)
            if ((ret = parse_playlist(h, s->playlisturl)) < 0)
                return ret;
    }
    if (s->cur_seq_no < s->start_seq_no) {
        av_log(h, AV_LOG_WARNING,
               "skipping %d segments ahead, expired from playlist\n",
               s->start_seq_no - s->cur_seq_no);
        s->cur_seq_no = s->start_seq_no;
    }
    if (s->cur_seq_no - s->start_seq_no >= s->n_segments) {
        if (s->finished)
            return AVERROR_EOF;
        while (av_gettime() - s->last_load_time < s->target_duration*1000000) {
            if (url_interrupt_cb())
                return AVERROR_EXIT;
            usleep(100*1000);
        }
        goto retry;
    }
    url = s->segments[s->cur_seq_no - s->start_seq_no]->url,
    av_log(h, AV_LOG_DEBUG, "opening %s\n", url);
    ret = ffurl_open(&s->seg_hd, url, AVIO_FLAG_READ);
    if (ret < 0) {
        if (url_interrupt_cb())
            return AVERROR_EXIT;
        av_log(h, AV_LOG_WARNING, "Unable to open %s\n", url);
        s->cur_seq_no++;
        goto retry;
    }
    goto start;
}
Exemplo n.º 3
0
int ffurl_read_complete(URLContext *h, unsigned char *buf, int size)
{
#define MAX_RETRY (6*60) //10S*6*60=60MIN;
    int maxretry=MAX_RETRY;
    int toread=size;
    int readedlen=0;
    if (!(h->flags & AVIO_FLAG_READ))
        return AVERROR(EIO);
    while(toread>0 && maxretry-->0){
		int ret;
     		ret=retry_transfer_wrapper(h, buf+readedlen, toread, toread, h->prot->url_read);
		if(ret>0){
			toread-=ret;
			readedlen+=ret;
		}else if(ret!=AVERROR(EAGAIN)){
			return ret;/*error of EOF*/
		}
		if(url_interrupt_cb())
			return AVERROR_EXIT;
    }
    if((size-toread)!=0)
		return (size-toread);
 	else
		return AVERROR(ETIMEDOUT);/*retry too long time,//time out...*/
}
Exemplo n.º 4
0
Arquivo: tcp.c Projeto: AWilco/xbmc
static int tcp_write(URLContext *h, const uint8_t *buf, int size)
{
    TCPContext *s = h->priv_data;
    int ret, size1, len;
    struct pollfd p = {s->fd, POLLOUT, 0};

    size1 = size;
    while (size > 0) {
        if (url_interrupt_cb())
            return AVERROR(EINTR);
        ret = poll(&p, 1, 100);
        if (ret == 1 && p.revents & POLLOUT) {
            len = send(s->fd, buf, size, 0);
            if (len < 0) {
                if (ff_neterrno() != FF_NETERROR(EINTR) &&
                    ff_neterrno() != FF_NETERROR(EAGAIN))
                    return ff_neterrno();
                continue;
            }
            size -= len;
            buf += len;
        } else if (ret < 0) {
            if (ff_neterrno() == FF_NETERROR(EINTR))
                continue;
            return -1;
        }
    }
    return size1 - size;
}
Exemplo n.º 5
0
static int list_read(URLContext *h, unsigned char *buf, int size)
{
    struct list_mgt *mgt = h->priv_data;
    int len = AVERROR(EIO);
    int counts = 200;
    do {
        if (url_interrupt_cb()) {
            //av_log(NULL, AV_LOG_ERROR, " url_interrupt_cb\n");
            len = AVERROR(EINTR);
            break;
        }
        len = CacheHttp_Read(mgt->cache_http_handle, buf, size);
        /*
        if (len == AVERROR(EAGAIN)) {
            usleep(1000 * 10);
            break;
        }*/
        if (len <0) {
            usleep(1000 * 10);
        }
        if (len >= 0) {
            break;
        }
    } while (counts-- > 0);
    return len;
}
Exemplo n.º 6
0
Arquivo: avio.c Projeto: andoma/libav
static inline int retry_transfer_wrapper(URLContext *h, unsigned char *buf, int size, int size_min,
                                         int (*transfer_func)(URLContext *h, unsigned char *buf, int size))
{
    int ret, len;
    int fast_retries = 5;

    len = 0;
    while (len < size_min) {
        ret = transfer_func(h, buf+len, size-len);
        if (ret == AVERROR(EINTR))
            continue;
        if (h->flags & AVIO_FLAG_NONBLOCK)
            return ret;
        if (ret == AVERROR(EAGAIN)) {
            ret = 0;
            if (fast_retries)
                fast_retries--;
            else
                usleep(1000);
        } else if (ret < 1)
            return ret < 0 ? ret : len;
        if (ret)
           fast_retries = FFMAX(fast_retries, 2);
        len += ret;
        if (url_interrupt_cb())
            return AVERROR_EXIT;
    }
    return len;
}
Exemplo n.º 7
0
Arquivo: tcp.c Projeto: CarlHuff/kgui
static int tcp_read(URLContext *h, uint8_t *buf, int size)
{
    TCPContext *s = h->priv_data;
    int len, fd_max, ret;
    fd_set rfds;
    struct timeval tv;

    for (;;) {
        if (url_interrupt_cb())
            return AVERROR(EINTR);
        fd_max = s->fd;
        FD_ZERO(&rfds);
        FD_SET(s->fd, &rfds);
        tv.tv_sec = 0;
        tv.tv_usec = 100 * 1000;
        ret = select(fd_max + 1, &rfds, NULL, NULL, &tv);
        if (ret > 0 && FD_ISSET(s->fd, &rfds)) {
            len = recv(s->fd, buf, size, 0);
            if (len < 0) {
                if (ff_neterrno() != FF_NETERROR(EINTR) &&
                    ff_neterrno() != FF_NETERROR(EAGAIN))
                    return AVERROR(errno);
            } else return len;
        } else if (ret < 0) {
            return -1;
        }
    }
}
static int ffmpeg_hls_read(URLContext *h, unsigned char *buf, int size){
    if(h == NULL||h->priv_data == NULL||size<=0){
        RLOG("failed to read data\n");
        return -1;
    }
    FFMPEG_HLS_CONTEXT* ctx = (FFMPEG_HLS_CONTEXT*)h->priv_data;
    void * hSession = ctx->hls_ctx;
    int len = AVERROR(EIO);
    int counts = 10;
    
    do {
        if (url_interrupt_cb()>0) {
            RLOG("url_interrupt_cb\n");
            len = 0;
            break;
        }
        len = m3u_session_read_data(hSession, buf,size);

        if (len <0) {
            if(len == AVERROR(EAGAIN)){
                usleep(1000*100);
            }else{
                break;
            }
        }
        if (len >= 0) {
            break;
        }
    } while (counts-- > 0);
    if(ctx->debug_level>5){
        RLOG("%s,want:%d,got:%d\n",__FUNCTION__,size,len);
    }
    return len;
}
Exemplo n.º 9
0
static int rtmp_read(URLContext *s, uint8_t *buf, int size)
{
    RTMP *r = s->priv_data;
    int nRead = 0;
    int retries = 20;
    
    do {
        if (url_interrupt_cb()>0) {
            nRead = 0;
            break;
        }
        nRead = RTMP_Read(r, buf, size);
        if (nRead > 0) {
            break;
        } else {
            if (r->m_read.status == RTMP_READ_EOF) {
                nRead = 0;
                break;
            }
            if(nRead == 0){
                nRead = AVERROR(EAGAIN);
                usleep(1000*100);
            }else{
                break;
            }
        }    
    } while (retries-- > 0);
    
    return nRead;
}
Exemplo n.º 10
0
static int udp_read(URLContext *h, uint8_t *buf, int size)
{
    UDPContext *s = h->priv_data;
    int len;
    fd_set rfds;
    int ret;
    struct timeval tv;

    for(;;) {
        if (url_interrupt_cb())
            return AVERROR(EINTR);
        FD_ZERO(&rfds);
        FD_SET(s->udp_fd, &rfds);
        tv.tv_sec = 0;
        tv.tv_usec = 100 * 1000;
        ret = select(s->udp_fd + 1, &rfds, NULL, NULL, &tv);
        if (ret < 0)
            return AVERROR(EIO);
        if (!(ret > 0 && FD_ISSET(s->udp_fd, &rfds)))
            continue;
        len = recv(s->udp_fd, buf, size, 0);
        if (len < 0) {
            if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
                ff_neterrno() != FF_NETERROR(EINTR))
                return AVERROR(EIO);
        } else {
            break;
        }
    }
    return len;
}
Exemplo n.º 11
0
Arquivo: tcp.c Projeto: foogywoo/drone
static int tcp_read(URLContext *h, uint8_t *buf, int size)
{
    TCPContext *s = h->priv_data;
    int len, fd_max, ret;
    fd_set rfds;
    struct timeval tv;

    for (;;) {
        if (url_interrupt_cb())
            return -EINTR;
        fd_max = s->fd;
        FD_ZERO(&rfds);
        FD_SET(s->fd, &rfds);
        tv.tv_sec = 0;
        tv.tv_usec = 100 * 1000;
        ret = select(fd_max + 1, &rfds, NULL, NULL, &tv);
        if (ret > 0 && FD_ISSET(s->fd, &rfds)) {
#ifdef __BEOS__
            len = recv(s->fd, buf, size, 0);
#else
            len = read(s->fd, buf, size);
#endif
            if (len < 0) {
                if (errno != EINTR && errno != EAGAIN)
#ifdef __BEOS__
                    return errno;
#else
                    return -errno;
#endif
            } else return len;
        } else if (ret < 0) {
            return -1;
        }
    }
}
Exemplo n.º 12
0
static int file_read(URLContext *h, unsigned char *buf, int size)
{
    int fd = (intptr_t) h->priv_data;
    int rv;
    do
    {
        rv = read(fd, buf, size);
        if (rv <= 0 && ((h->flags & URL_ACTIVEFILE) == URL_ACTIVEFILE))
        {
#ifdef __MINGW32__
            usleep(20000);
#else
            struct timespec ts;
            ts.tv_sec = 0;
            ts.tv_nsec = 20000000;
            nanosleep(&ts, NULL);
#endif
            if (url_interrupt_cb())
                return -EINTR;
        }
        else
            break;
    } while (1);
    return rv;
}
Exemplo n.º 13
0
static int udp_read(URLContext *h, uint8_t *buf, int size)
{
    UDPContext *s = h->priv_data;
    struct pollfd p = {s->udp_fd, POLLIN, 0};
    int len;
    int ret;

    for(;;) {
        if (url_interrupt_cb())
            return AVERROR(EINTR);
        ret = poll(&p, 1, 100);
        if (ret < 0) {
            if (ff_neterrno() == FF_NETERROR(EINTR))
                continue;
            return AVERROR(EIO);
        }
        if (!(ret == 1 && p.revents & POLLIN))
            continue;
        len = recv(s->udp_fd, buf, size, 0);
        if (len < 0) {
            if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
                ff_neterrno() != FF_NETERROR(EINTR))
                return AVERROR(EIO);
        } else {
            break;
        }
    }
    return len;
}
Exemplo n.º 14
0
Arquivo: tcp.c Projeto: CarlHuff/kgui
static int tcp_write(URLContext *h, uint8_t *buf, int size)
{
    TCPContext *s = h->priv_data;
    int ret, size1, fd_max, len;
    fd_set wfds;
    struct timeval tv;

    size1 = size;
    while (size > 0) {
        if (url_interrupt_cb())
            return AVERROR(EINTR);
        fd_max = s->fd;
        FD_ZERO(&wfds);
        FD_SET(s->fd, &wfds);
        tv.tv_sec = 0;
        tv.tv_usec = 100 * 1000;
        ret = select(fd_max + 1, NULL, &wfds, NULL, &tv);
        if (ret > 0 && FD_ISSET(s->fd, &wfds)) {
            len = send(s->fd, buf, size, 0);
            if (len < 0) {
                if (ff_neterrno() != FF_NETERROR(EINTR) &&
                    ff_neterrno() != FF_NETERROR(EAGAIN))
                    return AVERROR(errno);
                continue;
            }
            size -= len;
            buf += len;
        } else if (ret < 0) {
            return -1;
        }
    }
    return size1 - size;
}
Exemplo n.º 15
0
static void *circular_buffer_task( void *_URLContext)
{
    URLContext *h = _URLContext;
    UDPContext *s = h->priv_data;
    fd_set rfds;
    struct timeval tv;

    for(;;) {
        int left;
        int ret;
        int len;

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

        FD_ZERO(&rfds);
        FD_SET(s->udp_fd, &rfds);
        tv.tv_sec = 1;
        tv.tv_usec = 0;
        ret = select(s->udp_fd + 1, &rfds, NULL, NULL, &tv);
        if (ret < 0) {
            if (ff_neterrno() == AVERROR(EINTR))
                continue;
            s->circular_buffer_error = EIO;
            return NULL;
        }

        if (!(ret > 0 && FD_ISSET(s->udp_fd, &rfds)))
            continue;

        /* How much do we have left to the end of the buffer */
        /* Whats the minimum we can read so that we dont comletely fill the buffer */
        left = av_fifo_space(s->fifo);
        left = FFMIN(left, s->fifo->end - s->fifo->wptr);

        /* No Space left, error, what do we do now */
        if( !left) {
            av_log(h, AV_LOG_ERROR, "circular_buffer: OVERRUN\n");
            s->circular_buffer_error = EIO;
            return NULL;
        }

        len = recv(s->udp_fd, s->fifo->wptr, left, 0);
        if (len < 0) {
            if (ff_neterrno() != AVERROR(EAGAIN) && ff_neterrno() != AVERROR(EINTR)) {
                s->circular_buffer_error = EIO;
                return NULL;
            }
        }
        s->fifo->wptr += len;
        if (s->fifo->wptr >= s->fifo->end)
            s->fifo->wptr = s->fifo->buffer;
        s->fifo->wndx += len;
    }

    return NULL;
}
Exemplo n.º 16
0
static int interrupt_call_cb(void){
    if (url_interrupt_cb()) {
        RLOG("[%s]:url_interrupt_cb\n",__FUNCTION__);        
        return 1;
    }
    return 0;
    
}
Exemplo n.º 17
0
static int rtp_read(URLContext *h, uint8_t *buf, int size)
{
    RTPContext *s = h->priv_data;
    struct sockaddr_storage from;
    socklen_t from_len;
    int len, n;
    struct pollfd p[2] = {{s->rtp_fd, POLLIN, 0}, {s->rtcp_fd, POLLIN, 0}};

    for(;;) {
        if (url_interrupt_cb())
            return AVERROR_EXIT;
        /* build fdset to listen to RTP and RTCP packets */
        n = poll(p, 2, 100);
        if (n > 0) {
            /* first try RTCP */
            if (p[1].revents & POLLIN) {
                from_len = sizeof(from);
                len = recvfrom (s->rtcp_fd, buf, size, 0,
                                (struct sockaddr *)&from, &from_len);
                if (len < 0) {
                    if (ff_neterrno() == AVERROR(EAGAIN) ||
                            ff_neterrno() == AVERROR(EINTR))
                        continue;
                    return AVERROR(EIO);
                }
                break;
            }
            /* then RTP */
            if (p[0].revents & POLLIN) {
                from_len = sizeof(from);
                len = recvfrom (s->rtp_fd, buf, size, 0,
                                (struct sockaddr *)&from, &from_len);
                if (len < 0) {
                    if (ff_neterrno() == AVERROR(EAGAIN) ||
                            ff_neterrno() == AVERROR(EINTR))
                        continue;
                    return AVERROR(EIO);
                }
                break;
            }
        } else if (n < 0) {
            if (ff_neterrno() == AVERROR(EINTR))
                continue;
            return AVERROR(EIO);
        }
    }
    return len;
}
Exemplo n.º 18
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;
}
Exemplo n.º 19
0
static void fresh_item_list(struct list_mgt *mgt){	
	int retries = 5;
	int reload_interval = mgt->target_duration * 500000;
	do{	
		if((switchto_next_item(mgt))!=NULL){
			av_log(NULL, AV_LOG_INFO, "refresh the Playlist,item num:%d,filename:%s\n",mgt->item_num,mgt->filename);		
			break;
		}	
		else{	
			if (url_interrupt_cb()){     
				av_log(NULL, AV_LOG_ERROR," url_interrupt_cb\n");	
				break;
			}
			usleep(reload_interval); //50ms
			av_log(NULL, AV_LOG_INFO, "no new item,wait next refresh,current item num:%d\n",mgt->item_num);	
		}

	}while(retries-->0);//50ms*5

}
Exemplo n.º 20
0
Arquivo: tcp.c Projeto: foogywoo/drone
static int tcp_write(URLContext *h, uint8_t *buf, int size)
{
    TCPContext *s = h->priv_data;
    int ret, size1, fd_max, len;
    fd_set wfds;
    struct timeval tv;

    size1 = size;
    while (size > 0) {
        if (url_interrupt_cb())
            return -EINTR;
        fd_max = s->fd;
        FD_ZERO(&wfds);
        FD_SET(s->fd, &wfds);
        tv.tv_sec = 0;
        tv.tv_usec = 100 * 1000;
        ret = select(fd_max + 1, NULL, &wfds, NULL, &tv);
        if (ret > 0 && FD_ISSET(s->fd, &wfds)) {
#ifdef __BEOS__
            len = send(s->fd, buf, size, 0);
#else
            len = write(s->fd, buf, size);
#endif
            if (len < 0) {
                if (errno != EINTR && errno != EAGAIN) {
#ifdef __BEOS__
                    return errno;
#else
                    return -errno;
#endif
                }
                continue;
            }
            size -= len;
            buf += len;
        } else if (ret < 0) {
            return -1;
        }
    }
    return size1 - size;
}
Exemplo n.º 21
0
static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
                           uint8_t *buf, int buf_size)
{
    RTSPState *rt = s->priv_data;
    RTSPStream *rtsp_st;
    fd_set rfds;
    int fd1, fd2, fd_max, n, i, ret;
    struct timeval tv;

    for(;;) {
        if (url_interrupt_cb())
            return -1;
        FD_ZERO(&rfds);
        fd_max = -1;
        for(i = 0; i < rt->nb_rtsp_streams; i++) {
            rtsp_st = rt->rtsp_streams[i];
            /* currently, we cannot probe RTCP handle because of blocking restrictions */
            rtp_get_file_handles(rtsp_st->rtp_handle, &fd1, &fd2);
            if (fd1 > fd_max)
                fd_max = fd1;
            FD_SET(fd1, &rfds);
        }
        tv.tv_sec = 0;
        tv.tv_usec = 100 * 1000;
        n = select(fd_max + 1, &rfds, NULL, NULL, &tv);
        if (n > 0) {
            for(i = 0; i < rt->nb_rtsp_streams; i++) {
                rtsp_st = rt->rtsp_streams[i];
                rtp_get_file_handles(rtsp_st->rtp_handle, &fd1, &fd2);
                if (FD_ISSET(fd1, &rfds)) {
                    ret = url_read(rtsp_st->rtp_handle, buf, buf_size);
                    if (ret > 0) {
                        *prtsp_st = rtsp_st;
                        return ret;
                    }
                }
            }
        }
    }
}
Exemplo n.º 22
0
static int tcp_read(URLContext *h, uint8_t *buf, int size)
{
    TCPContext *s = h->priv_data;
    int len, fd_max, ret;
    fd_set rfds;
    struct timeval tv;    
    int tout_cnt=100; //tout_cnt*time_out=10s        
    for (;;) {        
        if (url_interrupt_cb())       
            return AVERROR(EINTR);       
        fd_max = s->fd;
        FD_ZERO(&rfds);
        FD_SET(s->fd, &rfds);
        tv.tv_sec = 0;
        tv.tv_usec = 300 * 1000;       
        ret = select(fd_max + 1, &rfds, NULL, NULL, &tv);          
        if (ret > 0 && FD_ISSET(s->fd, &rfds)) {            
            len = recv(s->fd, buf, size, 0);              
            if (len < 0) {
                av_log(NULL,AV_LOG_INFO,"tcp_read recv failed: len= %d\n",len);
                if (ff_neterrno() != FF_NETERROR(EINTR) &&
                    ff_neterrno() != FF_NETERROR(EAGAIN))                
                    return AVERROR(ff_neterrno());                
            } else return len;            
        } else if (ret < 0) {  
            av_log(NULL,AV_LOG_INFO,"tcp_read select failed: ret= %d\n",ret);
            return -1;
        }
        else if(ret == 0){
            tout_cnt --;        
			av_log(NULL,AV_LOG_INFO, "tcp_read(%d): read timeout,try again\n",tout_cnt);
            if(tout_cnt == 0)
            {               
                
                return AVERROR(EAGAIN);
            }
        }        
    }
}
Exemplo n.º 23
0
Arquivo: tcp.c Projeto: foogywoo/drone
/* return non zero if error */
static int tcp_open(URLContext *h, const char *uri, int flags)
{
    struct sockaddr_in dest_addr;
    char hostname[1024], *q;
    int port, fd = -1;
    TCPContext *s;
    const char *p;
    fd_set wfds;
    int fd_max, ret;
    struct timeval tv;
    socklen_t optlen;
    char proto[1024],path[1024],tmp[1024];  // PETR: protocol and path strings

    url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname),
      &port, path, sizeof(path), uri);  // PETR: use url_split
    if (strcmp(proto,"tcp")) goto fail; // PETR: check protocol
    if ((q = strchr(hostname,'@'))) { strcpy(tmp,q+1); strcpy(hostname,tmp); } // PETR: take only the part after '@' for tcp protocol
    
    s = av_malloc(sizeof(TCPContext));
    if (!s)
        return -ENOMEM;
    h->priv_data = s;
    
    if (port <= 0 || port >= 65536)
        goto fail;
    
    dest_addr.sin_family = AF_INET;
    dest_addr.sin_port = htons(port);
    if (resolve_host(&dest_addr.sin_addr, hostname) < 0)
        goto fail;

    fd = socket(PF_INET, SOCK_STREAM, 0);
    if (fd < 0)
        goto fail;
    fcntl(fd, F_SETFL, O_NONBLOCK);
    
 redo:
    ret = connect(fd, (struct sockaddr *)&dest_addr, 
                  sizeof(dest_addr));
    if (ret < 0) {
        if (errno == EINTR)
            goto redo;
        if (errno != EINPROGRESS)
            goto fail;

        /* wait until we are connected or until abort */
        for(;;) {
            if (url_interrupt_cb()) {
                ret = -EINTR;
                goto fail1;
            }
            fd_max = fd;
            FD_ZERO(&wfds);
            FD_SET(fd, &wfds);
            tv.tv_sec = 0;
            tv.tv_usec = 100 * 1000;
            ret = select(fd_max + 1, NULL, &wfds, NULL, &tv);
            if (ret > 0 && FD_ISSET(fd, &wfds))
                break;
        }
        
        /* test error */
        optlen = sizeof(ret);
        getsockopt (fd, SOL_SOCKET, SO_ERROR, &ret, &optlen);
        if (ret != 0)
            goto fail;
    }
    s->fd = fd;
    return 0;

 fail:
    ret = AVERROR_IO;
 fail1:
    if (fd >= 0)
        close(fd);
    av_free(s);
    return ret;
}
Exemplo n.º 24
0
/* return non zero if error */
static int tcp_open(URLContext *h, const char *uri, int flags)
{
    struct addrinfo hints, *ai, *cur_ai;
    int port, fd = -1;
    TCPContext *s = NULL;
    int listen_socket = 0;
    const char *p;
    char buf[256];
    int ret;
    socklen_t optlen;
    int timeout = 500, listen_timeout = -1;
    char hostname[1024],proto[1024],path[1024];
    char portstr[10];

    av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname),
        &port, path, sizeof(path), uri);
    if (strcmp(proto, "tcp"))
        return AVERROR(EINVAL);
    if (port <= 0 || port >= 65536) {
        av_log(h, AV_LOG_ERROR, "Port missing in uri\n");
        return AVERROR(EINVAL);
    }
    p = strchr(uri, '?');
    if (p) {
        if (av_find_info_tag(buf, sizeof(buf), "listen", p))
            listen_socket = 1;
        if (av_find_info_tag(buf, sizeof(buf), "timeout", p)) {
            timeout = strtol(buf, NULL, 10);
        }
        if (av_find_info_tag(buf, sizeof(buf), "listen_timeout", p)) {
            listen_timeout = strtol(buf, NULL, 10);

        }
    }
    memset(&hints, 0, sizeof(hints));
    if(am_getconfig_bool_def("media.libplayer.ipv4only",1))	
    		hints.ai_family = AF_INET;
    else
		hints.ai_family = AF_UNSPEC;	
    hints.ai_socktype = SOCK_STREAM;
    snprintf(portstr, sizeof(portstr), "%d", port);
	av_log(h, AV_LOG_INFO,"tcp will get address from dns!\n");	
    if (listen_socket)
        hints.ai_flags |= AI_PASSIVE;
    if (!hostname[0])
        ret = getaddrinfo(NULL, portstr, &hints, &ai);
    else
    ret = getaddrinfo(hostname, portstr, &hints, &ai);
    if (ret) {
        av_log(h, AV_LOG_ERROR,
               "Failed to resolve hostname %s: %s\n",
               hostname, gai_strerror(ret));
        return AVERROR(EIO);
    }
    av_log(h, AV_LOG_INFO,"resolved %s's  ipaddress \n",hostname);
    cur_ai = ai;

 restart:
    ret = AVERROR(EIO);
    fd = socket(cur_ai->ai_family, cur_ai->ai_socktype, cur_ai->ai_protocol);
    if (fd < 0)
        goto fail;

    if (listen_socket) {
        int fd1;
        int reuse = 1;
        struct pollfd lp = { fd, POLLIN, 0 };
        setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
        ret = bind(fd, cur_ai->ai_addr, cur_ai->ai_addrlen);
        if (ret) {
            ret = ff_neterrno();
            goto fail1;
        }
        ret = listen(fd, 1);
        if (ret) {
            ret = ff_neterrno();
            goto fail1;
        }
        ret = poll(&lp, 1, listen_timeout >= 0 ? listen_timeout : -1);
        if (ret <= 0) {
            ret = AVERROR(ETIMEDOUT);
            goto fail1;
        }
        fd1 = accept(fd, NULL, NULL);
        if (fd1 < 0) {
            ret = ff_neterrno();
            goto fail1;
        }
        closesocket(fd);
        fd = fd1;
        ff_socket_nonblock(fd, 1);
    } else {
 redo:
        ff_socket_nonblock(fd, 1);
        ret = connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen);
    }

    if (ret < 0) {
        struct pollfd p = {fd, POLLOUT, 0};
        ret = ff_neterrno();
        if (ret == AVERROR(EINTR)) {
            if (url_interrupt_cb()) {
                ret = AVERROR_EXIT;
                goto fail1;
            }
            goto redo;
        }
        if (ret != AVERROR(EINPROGRESS) &&
            ret != AVERROR(EAGAIN))
            goto fail;

        /* wait until we are connected or until abort */
        while(timeout--) {
            if (url_interrupt_cb()) {
                ret = AVERROR_EXIT;
                goto fail1;
            }
            ret = poll(&p, 1, 100);
            if (ret > 0)
                break;
        }
        if (ret <= 0) {
			 av_log(h, AV_LOG_ERROR,
                   "TCP connection to %s:%d timeout failed!\n",
                   hostname, port);
            ret = AVERROR(ETIMEDOUT);
            goto fail;
        }
        /* test error */
        optlen = sizeof(ret);
        if (getsockopt (fd, SOL_SOCKET, SO_ERROR, &ret, &optlen))
            ret = AVUNERROR(ff_neterrno());
        if (ret != 0) {
            char errbuf[100];
            ret = AVERROR(ret);
            av_strerror(ret, errbuf, sizeof(errbuf));
            av_log(h, AV_LOG_ERROR,
                   "TCP connection to %s:%d failed: %s, ret = %d\n",
                   hostname, port, errbuf, ret);            
            ret = AVERROR(ret);
            if(ret>0)
                ret = AVERROR(EIO);
            goto fail;
        }
    }
    av_log(h, AV_LOG_INFO,"tcp  connect %s ok!\n",hostname);	
    s = av_malloc(sizeof(TCPContext));
    if (!s) {
        freeaddrinfo(ai);
        return AVERROR(ENOMEM);
    }
    h->priv_data = s;
    h->is_streamed = 1;
    s->fd = fd;
    freeaddrinfo(ai);
    return 0;

 fail:
    if (cur_ai->ai_next) {
        /* Retry with the next sockaddr */
        cur_ai = cur_ai->ai_next;
        if (fd >= 0)
            closesocket(fd);
        goto restart;
    }
 fail1:
    if (fd >= 0)
        closesocket(fd);
    freeaddrinfo(ai);
    return ret;
}
Exemplo n.º 25
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;
}
static int list_read(URLContext *h, unsigned char *buf, int size)
{   
	struct list_mgt *mgt = h->priv_data;
    int len=AVERROR(EIO);
	struct list_item *item=mgt->current_item;
	
retry:	
	if (url_interrupt_cb())       
            return AVERROR(EINTR); 
	av_log(NULL, AV_LOG_INFO, "list_read start buf=%x,size=%d\n",buf,size);
	if(!mgt->cur_uio )
	{
		if(item && item->file)
		{
			ByteIOContext *bio;
			av_log(NULL, AV_LOG_INFO, "list_read switch to new file=%s\n",item->file);
			len=url_fopen(&bio,item->file,O_RDONLY | URL_MINI_BUFFER | URL_NO_LP_BUFFER);
			if(len!=0)
			{
				return len;
			}
			if(url_is_file_list(bio,item->file))
			{
				/*have 32 bytes space at the end..*/
				memmove(item->file+5,item->file,strlen(item->file)+1);
				memcpy(item->file,"list:",5);
				url_fclose(bio);
				len=url_fopen(&bio,item->file,mgt->flags | URL_MINI_BUFFER | URL_NO_LP_BUFFER);
				if(len!=0)
				{
					return len;
				}
			}
			mgt->cur_uio=bio;
		}
	}
	if(mgt->cur_uio)
		len=get_buffer(mgt->cur_uio,buf,size);
	if(len==AVERROR(EAGAIN))
		 return AVERROR(EAGAIN);/*not end,bug need to*/
	else if((len<=0)&& mgt->current_item!=NULL)
	{/*end of the file*/
		av_log(NULL, AV_LOG_INFO, "try switchto_next_item buf=%x,size=%d,len=%d\n",buf,size,len);

		if(item && (item->flags & ENDLIST_FLAG))
			return 0;
		item=switchto_next_item(mgt);
		if(!item){
			 return AVERROR(EAGAIN);/*not end,but need to refresh the list later*/
		}
		if(mgt->cur_uio)
			url_fclose(mgt->cur_uio);
		mgt->cur_uio=NULL;
		mgt->current_item=item;
		if(item->flags & ENDLIST_FLAG){
			av_log(NULL, AV_LOG_INFO, "reach list end now!,item=%x\n",item);
			return 0;/*endof file*/
		}
		else if(item->flags & DISCONTINUE_FLAG){
			av_log(NULL, AV_LOG_INFO, "Discontiue item \n");
			//1 TODO:need to notify uper level stream is changed
			goto retry;
		}
		else{	
			goto retry;
		}
	}
	av_log(NULL, AV_LOG_INFO, "list_read end buf=%x,size=%d\n",buf,size);
    return len;
}
Exemplo n.º 27
0
static int list_read(URLContext *h, unsigned char *buf, int size)
{   
	struct list_mgt *mgt = h->priv_data;
    int len=AVERROR(EIO);
	struct list_item *item=mgt->current_item;
	int retries = 10;
	
retry:	
	if (url_interrupt_cb()){     
		av_log(NULL, AV_LOG_ERROR," url_interrupt_cb\n");	
            	return AVERROR(EINTR);

	}
	//av_log(NULL, AV_LOG_INFO, "list_read start buf=%x,size=%d\n",buf,size);
	if(!mgt->cur_uio )
	{
		if(item && item->file)
		{
			ByteIOContext *bio;
			av_log(NULL, AV_LOG_INFO, "list_read switch to new file=%s\n",item->file);
			len=url_fopen(&bio,item->file,AVIO_FLAG_READ | URL_MINI_BUFFER | URL_NO_LP_BUFFER);
			if(len!=0)
			{
				av_log(NULL, AV_LOG_ERROR, "list url_fopen failed =%d\n",len);
				return len;
			}			
			if(url_is_file_list(bio,item->file))
			{
				mgt->have_sub_list = 1;
				/*have 32 bytes space at the end..*/
				memmove(item->file+5,item->file,strlen(item->file)+1);
				memcpy(item->file,"list:",5);
				url_fclose(bio);
				len=url_fopen(&bio,item->file,mgt->flags | URL_MINI_BUFFER | URL_NO_LP_BUFFER);
				if(len!=0)
				{
					av_log(NULL, AV_LOG_INFO, "file list url_fopen failed =%d\n",len);
					return len;
				}
			}else{
				if(item->ktype == KEY_AES_128){	
					if(item->key_ctx&&!item->crypto){
						item->crypto = av_mallocz(sizeof(struct AESCryptoContext));
						if(!item->crypto){							
							len = AVERROR(ENOMEM);
							return len;
						}
						item->crypto->aes =  av_mallocz(av_aes_size);		
						if(!item->crypto->aes){
							len = AVERROR(ENOMEM);
							return len;
						}
						
						av_aes_init(item->crypto->aes,item->key_ctx->key, 128, 1);
						item->crypto->have_init = 1;
						
					}
					bio->is_encrypted_media =1;
				}				
			}
			mgt->cur_uio=bio;
		}
	}
	if(mgt->cur_uio){
		if(size>0&&mgt->cur_uio->is_encrypted_media>0&&mgt->current_item->key_ctx&&mgt->current_item->crypto){//codes from crypto.c			
			int blocks;
			struct AESCryptoContext* c = mgt->current_item->crypto;
readagain:			
			len = 0;
			if (c->outdata > 0) {
				size = FFMIN(size, c->outdata);
				memcpy(buf, c->outptr, size);
				c->outptr  += size;
				c->outdata -= size;
				len =size;				
			}
			// We avoid using the last block until we've found EOF,
			// since we'll remove PKCS7 padding at the end. So make
			// sure we've got at least 2 blocks, so we can decrypt
			// at least one.
			while (c->indata - c->indata_used < 2*BLOCKSIZE) {
				int n = get_buffer(mgt->cur_uio,c->inbuffer + c->indata,
				                   sizeof(c->inbuffer) - c->indata);
				if (n <= 0) {
				    c->eof = 1;
				    break;
				}
				c->indata += n;				
			}
			blocks = (c->indata - c->indata_used) / BLOCKSIZE;
			if (blocks!=0){
				if (!c->eof)
					blocks--;
				av_aes_crypt(c->aes, c->outbuffer, c->inbuffer + c->indata_used, blocks,mgt->current_item->key_ctx->iv, 1);
				c->outdata      = BLOCKSIZE * blocks;
				c->outptr       = c->outbuffer;
				c->indata_used += BLOCKSIZE * blocks;
				if (c->indata_used >= sizeof(c->inbuffer)/2) {
					memmove(c->inbuffer, c->inbuffer + c->indata_used,
						c->indata - c->indata_used);
					c->indata     -= c->indata_used;
					c->indata_used = 0;
				}
				if (c->eof) {
					// Remove PKCS7 padding at the end
					int padding = c->outbuffer[c->outdata - 1];
					c->outdata -= padding;
				}

				if(len==0){
					goto readagain;
				}
			}else{
				len  =0;
			}				
			
			
		}else{
			len=get_buffer(mgt->cur_uio,buf,size);
		}
		//av_log(NULL, AV_LOG_INFO, "list_read get_buffer=%d\n",len);
	}
	if(len==AVERROR(EAGAIN))
		 return AVERROR(EAGAIN);/*not end,bug need to*/
	else if((len<=0)&& mgt->current_item!=NULL)
	{/*end of the file*/
		av_log(NULL, AV_LOG_INFO, "try switchto_next_item buf=%x,size=%d,len=%d\n",buf,size,len);

		if(item && (item->flags & ENDLIST_FLAG)){
		    if(mgt->cur_uio)
			    url_fclose(mgt->cur_uio);
    			av_log(NULL, AV_LOG_INFO, "ENDLIST_FLAG, return 0\n");
			return 0;
		}

		
		
		item=switchto_next_item(mgt);
		if(!item){
			if(mgt->flags&REAL_STREAMING_FLAG){
				fresh_item_list(mgt);	
				if(retries>0){
					retries --;
					goto retry;
				}
			}

			av_log(NULL, AV_LOG_INFO, "Need more retry by player logic\n");
			return AVERROR(EAGAIN);/*not end,but need to refresh the list later*/
		}
		if(mgt->cur_uio)
			url_fclose(mgt->cur_uio);
		mgt->cur_uio=NULL;
		mgt->current_item=item;
		
		if(item->flags & ENDLIST_FLAG){
			av_log(NULL, AV_LOG_INFO, "reach list end now!,item=%x\n",item);
			return 0;/*endof file*/
		}
		else if(item->flags & DISCONTINUE_FLAG){
			av_log(NULL, AV_LOG_INFO, "Discontiue item \n");
			//1 TODO:need to notify uper level stream is changed
			goto retry;
		}
		else{	
			av_log(NULL, AV_LOG_INFO, "[%s]item->flags=%x \n", __FUNCTION__, item->flags);
			goto retry;
		}
		
	}
	#if 0
	if(mgt->flags&REAL_STREAMING_FLAG&&mgt->item_num<4){ //force refresh items
		fresh_item_list(mgt);	
	}
	#endif

	//av_log(NULL, AV_LOG_INFO, "list_read end buf=%x,size=%d return len=%x\n",buf,size,len);
    return len;
}
Exemplo n.º 28
0
Arquivo: tcp.c Projeto: FreeSrk/omx
/* return non zero if error */
static int tcp_open(URLContext *h, const char *uri, int flags)
{
    struct addrinfo hints, *ai, *cur_ai;
    int port, fd = -1;
    TCPContext *s = NULL;
    int listen_socket = 0;
    const char *p;
    char buf[256];
    int ret;
    socklen_t optlen;
    char hostname[1024],proto[1024],path[1024];
    char portstr[10];

    av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname),
        &port, path, sizeof(path), uri);
    if (strcmp(proto,"tcp") || port <= 0 || port >= 65536)
        return AVERROR(EINVAL);

    p = strchr(uri, '?');
    if (p) {
        if (av_find_info_tag(buf, sizeof(buf), "listen", p))
            listen_socket = 1;
    }
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    snprintf(portstr, sizeof(portstr), "%d", port);
    ret = getaddrinfo(hostname, portstr, &hints, &ai);
    if (ret) {
        av_log(NULL, AV_LOG_ERROR,
               "Failed to resolve hostname %s: %s\n",
               hostname, gai_strerror(ret));
        return AVERROR(EIO);
    }

    cur_ai = ai;

 restart:
    fd = socket(cur_ai->ai_family, cur_ai->ai_socktype, cur_ai->ai_protocol);
    if (fd < 0)
        goto fail;

    if (listen_socket) {
        int fd1;
        ret = bind(fd, cur_ai->ai_addr, cur_ai->ai_addrlen);
        listen(fd, 1);
        fd1 = accept(fd, NULL, NULL);
        closesocket(fd);
        fd = fd1;
    } else {
 redo:
        ff_socket_nonblock(fd, 1);
        //av_log (NULL, AV_LOG_INFO, "connecting....\n");
        ret = connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen);
        //av_log (NULL, AV_LOG_INFO, "connecting done.\n");
    }

    if (ret < 0) {
        int timeout = 10; //1s timeout
        struct pollfd p = {fd, POLLOUT, 0};
        if (ff_neterrno() == AVERROR(EINTR)) {
            if (url_interrupt_cb()) {
                ret = AVERROR_EXIT;
                goto fail1;
            }
            goto redo;
        }
        if (ff_neterrno() != AVERROR(EINPROGRESS) &&
            ff_neterrno() != AVERROR(EAGAIN))
            goto fail;

        /* wait until we are connected or until abort */
        for(;;) {
            if (url_interrupt_cb()) {
                ret = AVERROR_EXIT;
                goto fail1;
            }
            ret = poll(&p, 1, 100);
            if (ret > 0)
                break;
            if(!--timeout){
                av_log(NULL, AV_LOG_ERROR,
                    "TCP open %s:%d timeout\n",
                    hostname, port);
                goto fail;
            }
        }

        /* test error */
        optlen = sizeof(ret);
        getsockopt (fd, SOL_SOCKET, SO_ERROR, &ret, &optlen);
        if (ret != 0) {
            av_log(NULL, AV_LOG_ERROR,
                   "TCP connection to %s:%d failed: %s\n",
                   hostname, port, strerror(ret));
            goto fail;
        }
    }
    s = av_malloc(sizeof(TCPContext));
    if (!s) {
        ret = AVERROR(ENOMEM);
        goto fail1;
    }
    h->priv_data = s;
    h->is_streamed = 1;
    s->fd = fd;
    freeaddrinfo(ai);
    return 0;

 fail:
    if (cur_ai->ai_next) {
        /* Retry with the next sockaddr */
        cur_ai = cur_ai->ai_next;
        if (fd >= 0)
            closesocket(fd);
        goto restart;
    }
    ret = AVERROR(EIO);
 fail1:
    if (fd >= 0)
        closesocket(fd);
    freeaddrinfo(ai);
    return ret;
}
Exemplo n.º 29
0
Arquivo: tcp.c Projeto: CarlHuff/kgui
/* return non zero if error */
static int tcp_open(URLContext *h, const char *uri, int flags)
{
    struct sockaddr_in dest_addr;
    int port, fd = -1;
    TCPContext *s = NULL;
    fd_set wfds;
    int fd_max, ret;
    struct timeval tv;
    socklen_t optlen;
    char hostname[1024],proto[1024],path[1024];

    if(!ff_network_init())
        return AVERROR(EIO);

    url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname),
        &port, path, sizeof(path), uri);
    if (strcmp(proto,"tcp") || port <= 0 || port >= 65536)
        return AVERROR(EINVAL);

    dest_addr.sin_family = AF_INET;
    dest_addr.sin_port = htons(port);
    if (resolve_host(&dest_addr.sin_addr, hostname) < 0)
        return AVERROR(EIO);

    fd = socket(AF_INET, SOCK_STREAM, 0);
    if (fd < 0)
        return AVERROR(EIO);
    ff_socket_nonblock(fd, 1);

 redo:
    ret = connect(fd, (struct sockaddr *)&dest_addr,
                  sizeof(dest_addr));
    if (ret < 0) {
        if (ff_neterrno() == FF_NETERROR(EINTR))
            goto redo;
        if (ff_neterrno() != FF_NETERROR(EINPROGRESS) &&
            ff_neterrno() != FF_NETERROR(EAGAIN))
            goto fail;

        /* wait until we are connected or until abort */
        for(;;) {
            if (url_interrupt_cb()) {
                ret = AVERROR(EINTR);
                goto fail1;
            }
            fd_max = fd;
            FD_ZERO(&wfds);
            FD_SET(fd, &wfds);
            tv.tv_sec = 0;
            tv.tv_usec = 100 * 1000;
            ret = select(fd_max + 1, NULL, &wfds, NULL, &tv);
            if (ret > 0 && FD_ISSET(fd, &wfds))
                break;
        }

        /* test error */
        optlen = sizeof(ret);
        getsockopt (fd, SOL_SOCKET, SO_ERROR, &ret, &optlen);
        if (ret != 0)
            goto fail;
    }
    s = av_malloc(sizeof(TCPContext));
    if (!s)
        return AVERROR(ENOMEM);
    h->priv_data = s;
    h->is_streamed = 1;
    s->fd = fd;
    return 0;

 fail:
    ret = AVERROR(EIO);
 fail1:
    if (fd >= 0)
        closesocket(fd);
    return ret;
}
Exemplo n.º 30
0
static int _ffmpeg_cmf_getopt(URLContext *h, uint32_t  cmd, uint32_t flag, int64_t* info){
    FFMPEG_HLS_CONTEXT* ctx = (FFMPEG_HLS_CONTEXT*)h->priv_data;
	int ret=-1;    
	CmfPrivContext_t* cmf_ctx = ctx->cmf_ctx;
	RLOG("[%s]:cmd:%d,flag:%d\n",__FUNCTION__,cmd,flag);
	if(ctx == NULL||cmf_ctx == NULL){
	    RLOG("Failed call :%s\n",__FUNCTION__);
	    return -1;
	}
    if(cmd == AVCMD_TOTAL_NUM){
        *info = cmf_ctx->totol_clip_num;
        RLOG("Get total clip num:%d\n",cmf_ctx->totol_clip_num);        
    }else if(cmd == AVCMD_TOTAL_DURATION){
        *info = ctx->durationUs/1000;
        RLOG("Get duration:%lld\n",*info);
    }else if(cmd == AVCMD_SLICE_START_OFFSET){
        *info = -1;
        RLOG("Get clip start offset\n");        
    }else if(cmd == AVCMD_SLICE_INDEX){
        *info = cmf_ctx->cur_clip_index;
        RLOG("Get clip index:%d\n",cmf_ctx->cur_clip_index);        
    }else if(cmd == AVCMD_SLICE_SIZE){
        if(cmf_ctx->cur_clip_len>0){
            *info = cmf_ctx->cur_clip_len;
        }else{//ugly codes
            int64_t ret = hls_cmf_get_fsize(ctx->hls_ctx,cmf_ctx,1);
            if(ret<=0){//10s,maybe chunk stream,can't get size from server
                int counts=100;
                while(counts-->0&&ret<=0){
                    if (url_interrupt_cb()) {
                        RLOG("url_interrupt_cb,%d\n",__LINE__);
                        ret = 0;
                        break;
                    }
                    ret = hls_cmf_get_fsize(ctx->hls_ctx,cmf_ctx,2); 
                    usleep(100*1000);//100ms
                }
                if(ret<=0&&url_interrupt_cb()==0){
                    ret = hls_cmf_get_fsize(ctx->hls_ctx,cmf_ctx,3); 
                }
            }
            *info = ret;            
            
        }
        RLOG("Get clip length:%lld\n",*info);        
    }else if(cmd == AVCMD_SLICE_STARTTIME){
        if(ctx->durationUs<=0){
            *info = -1;
        }else{
            *info = cmf_ctx->cur_clip_st/1000;
        }
        RLOG("Get clip start time:%lld\n",*info);        
    }else if(cmd == AVCMD_SLICE_ENDTIME){
        if(ctx->durationUs<=0){
            *info = -1;
        }else{
            *info = cmf_ctx->cur_clip_end/1000;
        }
        RLOG("Get clip end time:%lld\n",*info);             
    }else{
        RLOG("Can't excute this case\n");
    }
    return 0;
}