Bridge::Bridge(bool isDebug, string name, size_t ports) :current_ports(0), ttlthread(&Bridge::TTLTimer, this), DebugON(isDebug), isStopped(false)
{	
	max_ports = ports;
	lan_name = name;
	int optval = true;
	char hostname[HOST_NAME_MAX];
	sockaddr_in serv_addr = getSockAddrInfo(htons(0));
	addrinfo hints = getHints(AI_CANONNAME | AI_PASSIVE), *serv_info, *p;
	socklen_t salen = sizeof(serv_addr);
	memset(hostname, 0, HOST_NAME_MAX);
	
	if (gethostname(hostname, HOST_NAME_MAX) == FAILURE)
	{
		cerr << "Failed to get hostname" << endl;
		exit(1);
	}
	if (getaddrinfo(hostname, NULL, &hints, &serv_info) == FAILURE) {
		cerr << "Failed to get address info" << endl;
		exit(1);
	}
	for (p = serv_info; p != NULL; p = p->ai_next)
	{
		if ((main_socket = socket(AF_INET, SOCK_STREAM, 0)) == FAILURE)
		{
			continue;
		}
		if (setsockopt(main_socket, SOL_SOCKET,	SO_REUSEADDR, &optval, sizeof(int)) == FAILURE)
		{
			cerr << "Socket options failed." << endl;
			exit(1);
		}
		if (bind(main_socket, p->ai_addr, p->ai_addrlen) == FAILURE)
		{
			close(main_socket);
			continue;
		}
		break;
	}
	sockaddr_in *ipv4 = (sockaddr_in*)p->ai_addr;
	localIp = ipv4->sin_addr.s_addr;
	if (p == NULL)
	{
		cerr << "Failed to bind." << endl;
		exit(1);
	}
	freeaddrinfo(serv_info);
	if (listen(main_socket, BACKLOG) == FAILURE)
	{
		cerr << "Listen failed." << endl;
		exit(1);
	}
	if (getsockname(main_socket, (sockaddr *)&serv_addr, &salen) == FAILURE)
	{
		cerr << "No socket created!" << endl;
		exit(1);
	}
	open_port = ntohs(serv_addr.sin_port);
	GenerateInfoFiles();
}
void Bridge::checkNewConnections()
{
	if (FD_ISSET(main_socket, &readset))
	{
		int options, cd;
		addrinfo hints = getHints(AI_CANONNAME | AI_PASSIVE);
		addrinfo *serv_info;
		sockaddr_in client_addr;
		socklen_t calen = sizeof(client_addr);
		if ((cd = accept(main_socket, (sockaddr* ) &client_addr, &calen)) == FAILURE)
		{
			cerr << "Connection failed to connect" << endl;
			exit(1);
		}
		if ((options = fcntl(cd, F_GETFL)) == FAILURE)
		{
			cerr << "Failed to get new socket connection options" << endl;
			exit(1);
		}
		options |= O_NONBLOCK;
		if (fcntl(cd, F_SETFL, options) == FAILURE)
		{
			cerr << "Failed to set new socket connection options" << endl;
			exit(1);
		}
		if (getpeername(cd, (sockaddr *)&client_addr, &calen) == FAILURE)
		{
			cerr << "No socket found!" << endl;
			exit(1);
		}
		if (getaddrinfo(ipv4_2_str(client_addr.sin_addr.s_addr).c_str(), NULL, &hints, &serv_info) == FAILURE)
		{
			cerr << "Failed to get address info " << endl;
			exit(1);
		}
		if (current_ports < max_ports)
		{
			current_ports++;
			if (DebugON) cout <<"PORTS AVAILABLE: " << max_ports - current_ports << endl;
			cout << "connect from '" + string(serv_info->ai_canonname) + "' at '" + to_string(ntohs(client_addr.sin_port)) + "'" << endl;	
			connected_ifaces[to_string(ntohs(client_addr.sin_port))] = cd;
			if (DebugON) printConnections();
			string response("accept");
			write(cd, response.c_str(), response.length());	
		}
		else
		{
			string response("reject");
			write(cd, response.c_str(), response.length());		
			close(cd);
		}
	
		freeaddrinfo(serv_info);
	}
}
Beispiel #3
0
void OMXReader::addStream(int id)
{
    if(id > MAX_STREAMS || !avFormatContext)
        return;
    
    AVStream *pStream = avFormatContext->streams[id];
    // discard PNG stream as we don't support it, and it stops mp3 files playing with album art
    if (pStream->codec->codec_type == AVMEDIA_TYPE_VIDEO && 
        (pStream->codec->codec_id == AV_CODEC_ID_PNG))
        return;
    
    switch (pStream->codec->codec_type)
    {
        case AVMEDIA_TYPE_AUDIO:
            omxStreams[id].stream      = pStream;
            omxStreams[id].type        = OMXSTREAM_AUDIO;
            omxStreams[id].index       = audioCount;
            omxStreams[id].codec_name  = getStreamCodecName(pStream);
            omxStreams[id].id          = id;
            audioCount++;
            getHints(pStream, &omxStreams[id].hints);
            break;
        case AVMEDIA_TYPE_VIDEO:
            omxStreams[id].stream      = pStream;
            omxStreams[id].type        = OMXSTREAM_VIDEO;
            omxStreams[id].index       = videoCount;
            omxStreams[id].codec_name  = getStreamCodecName(pStream);
            omxStreams[id].id          = id;
            videoCount++;
            getHints(pStream, &omxStreams[id].hints);
            break;
        case AVMEDIA_TYPE_SUBTITLE:
            omxStreams[id].stream      = pStream;
            omxStreams[id].type        = OMXSTREAM_SUBTITLE;
            omxStreams[id].index       = subtitleCount;
            omxStreams[id].codec_name  = getStreamCodecName(pStream);
            omxStreams[id].id          = id;
            subtitleCount++;
            getHints(pStream, &omxStreams[id].hints);
            break;
        default:
            return;
    }
    
#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(52,83,0)
    AVDictionaryEntry *langTag = av_dict_get(pStream->metadata, "language", NULL, 0);
    if (langTag)
        strncpy(omxStreams[id].language, langTag->value, 3);
#else
    strcpy( omxStreams[id].language, pStream->language );
#endif
    
#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(52,83,0)
    AVDictionaryEntry *titleTag = av_dict_get(pStream->metadata,"title", NULL, 0);
    if (titleTag)
        omxStreams[id].name = titleTag->value;
#else
    omxStreams[id].name = pStream->title;
#endif
    
    if( pStream->codec->extradata && pStream->codec->extradata_size > 0 )
    {
        omxStreams[id].extrasize = pStream->codec->extradata_size;
        omxStreams[id].extradata = malloc(pStream->codec->extradata_size);
        memcpy(omxStreams[id].extradata, pStream->codec->extradata, pStream->codec->extradata_size);
    }
}
Beispiel #4
0
OMXPacket* OMXReader::Read()
{
    AVPacket  pkt;
    OMXPacket* omxPacket = NULL;
    int       result = -1;
    
    if(!avFormatContext)
        return NULL;
    
    lock();
    
    // assume we are not eof
    if(avFormatContext->pb)
        avFormatContext->pb->eof_reached = 0;
    
    // keep track if ffmpeg doesn't always set these
    pkt.size = 0;
    pkt.data = NULL;
    pkt.stream_index = MAX_OMX_STREAMS;
    
    result = av_read_frame(avFormatContext, &pkt);
    if (result < 0)
    {
        isEOF = true;
        unlock();
        return NULL;
    }
    else if (pkt.size < 0 || pkt.stream_index >= MAX_OMX_STREAMS)
    {
        // XXX, in some cases ffmpeg returns a negative packet size
        if(avFormatContext->pb && !avFormatContext->pb->eof_reached)
        {
            ofLog(OF_LOG_ERROR, "OMXReader::Read no valid packet");
            //FlushRead();
        }
        
        av_free_packet(&pkt);
        
        isEOF = true;
        unlock();
        return NULL;
    }
    
    AVStream *pStream = avFormatContext->streams[pkt.stream_index];
    
    /* only read packets for active streams */
    /*
     if(!isActive(pkt.stream_index))
     {
     av_free_packet(&pkt);
     unlock();
     return NULL;
     }
     */
    
    // lavf sometimes bugs out and gives 0 dts/pts instead of no dts/pts
    // since this could only happens on initial frame under normal
    // circomstances, let's assume it is wrong all the time
#if 0
    if(pkt.dts == 0)
        pkt.dts = AV_NOPTS_VALUE;
    if(pkt.pts == 0)
        pkt.pts = AV_NOPTS_VALUE;
#endif
    if(isMatroska && pStream->codec && pStream->codec->codec_type == AVMEDIA_TYPE_VIDEO)
    { // matroska can store different timestamps
        // for different formats, for native stored
        // stuff it is pts, but for ms compatibility
        // tracks, it is really dts. sadly ffmpeg
        // sets these two timestamps equal all the
        // time, so we select it here instead
        if(pStream->codec->codec_tag == 0)
            pkt.dts = AV_NOPTS_VALUE;
        else
            pkt.pts = AV_NOPTS_VALUE;
    }
    // we need to get duration slightly different for matroska embedded text subtitels
    if(isMatroska && pStream->codec->codec_id == AV_CODEC_ID_SUBRIP && pkt.convergence_duration != 0)
        pkt.duration = pkt.convergence_duration;
    
    if(isAVI && pStream->codec && pStream->codec->codec_type == AVMEDIA_TYPE_VIDEO)
    {
        // AVI's always have borked pts, specially if avFormatContext->flags includes
        // AVFMT_FLAG_GENPTS so always use dts
        pkt.pts = AV_NOPTS_VALUE;
    }
    
    omxPacket = allocPacket(pkt.size);
    /* oom error allocation av packet */
    if(!omxPacket)
    {
        isEOF = true;
        av_free_packet(&pkt);
        unlock();
        return NULL;
    }
    
    omxPacket->codec_type = pStream->codec->codec_type;
    
    /* copy content into our own packet */
    omxPacket->size = pkt.size;
    
    if (pkt.data)
        memcpy(omxPacket->data, pkt.data, omxPacket->size);
    
    omxPacket->stream_index = pkt.stream_index;
    getHints(pStream, &omxPacket->hints);
    
    omxPacket->dts = ConvertTimestamp(pkt.dts, pStream->time_base.den, pStream->time_base.num);
    omxPacket->pts = ConvertTimestamp(pkt.pts, pStream->time_base.den, pStream->time_base.num);
    omxPacket->duration = DVD_SEC_TO_TIME((double)pkt.duration * pStream->time_base.num / pStream->time_base.den);
    
    // used to guess streamlength
    if (omxPacket->dts != DVD_NOPTS_VALUE && (omxPacket->dts > currentPTS || currentPTS == DVD_NOPTS_VALUE))
        currentPTS = omxPacket->dts;
    
    // check if stream has passed full duration, needed for live streams
    if(pkt.dts != (int64_t)AV_NOPTS_VALUE)
    {
        int64_t duration;
        duration = pkt.dts;
        if(pStream->start_time != (int64_t)AV_NOPTS_VALUE)
            duration -= pStream->start_time;
        
        if(duration > pStream->duration)
        {
            pStream->duration = duration;
            duration = av_rescale_rnd(pStream->duration, (int64_t)pStream->time_base.num * AV_TIME_BASE, 
                                      pStream->time_base.den, AV_ROUND_NEAR_INF);
            if ((avFormatContext->duration == (int64_t)AV_NOPTS_VALUE)
                ||  (avFormatContext->duration != (int64_t)AV_NOPTS_VALUE && duration > avFormatContext->duration))
                avFormatContext->duration = duration;
        }
    }
    
    av_free_packet(&pkt);
    
    unlock();
    return omxPacket;
}