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); } }
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); } }
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; }