Пример #1
0
// -----------------------------------
void OggVorbisSubStream::procHeaders(Channel *ch)
{
	unsigned int packPtr=0;

	for(int i=0; i<pack.numPackets; i++)
	{
		MemoryStream vin(&pack.body[packPtr],pack.packetSizes[i]);

		packPtr += pack.packetSizes[i];

		char id[8];

		vin.read(id,7);
		id[7]=0;

		switch (id[0])
		{
			case 1:	// ident
				LOG_CHANNEL("OGG Vorbis Header: Ident (%d bytes)",vin.len);
				readIdent(vin,ch->info);
				break;
			case 3: // comment
				{
					LOG_CHANNEL("OGG Vorbis Header: Comment (%d bytes)",vin.len);
					ChanInfo newInfo = ch->info;
					readComment(vin,newInfo);
					ch->updateInfo(newInfo);
				}
				break;
			case 5: // setup
				LOG_CHANNEL("OGG Vorbis Header: Setup (%d bytes)",vin.len);
				//readSetup(vin);
				break;
			default:
				throw StreamException("Unknown Vorbis packet header type");
				break;
		}
	}

}
Пример #2
0
// -----------------------------------
ASFInfo parseASFHeader(Stream & in) {
    ASFInfo asf;

    try {
        int numHeaders = in.readLong();

        in.readChar();
        in.readChar();

        LOG_CHANNEL("ASF Headers: %d", numHeaders);
        for (int i = 0; i < numHeaders; i++) {

            ASFObject obj;

            unsigned int l = obj.readHead(in);
            obj.readData(in, l);


            MemoryStream data(obj.data, obj.lenLo);


            switch (obj.type) {
                case ASFObject::T_FILE_PROP: {
                    data.skip(32);

                    unsigned int dpLo = data.readLong();
                    unsigned int dpHi = data.readLong();

                    data.skip(24);

                    data.readLong();
                    //data.writeLong(1);	// flags = broadcast, not seekable

                    int min = data.readLong();
                    int max = data.readLong();
                    int br = data.readLong();

                    if (min != max)
                        throw StreamException("ASF packetsizes (min/max) must match");

                    asf.packetSize = max;
                    asf.bitrate = br;
                    asf.numPackets = dpLo;
                    break;
                }
                case ASFObject::T_STREAM_BITRATE: {
                    int cnt = data.readShort();
                    for (int i = 0; i < cnt; i++) {
                        unsigned int id = data.readShort();
                        int bitrate = data.readLong();
                        if (id < ASFInfo::MAX_STREAMS)
                            asf.streams[id].bitrate = bitrate;
                    }
                    break;
                }
                case ASFObject::T_STREAM_PROP: {
                    ASFStream s;
                    s.read(data);
                    asf.streams[s.id].id = s.id;
                    asf.streams[s.id].type = s.type;
                    break;
                }
            }

        }
    } catch (StreamException &e) {
        LOG_ERROR("ASF: %s", e.msg);
    }

    return asf;
}
Пример #3
0
// ------------------------------------------
int PCPStream::procAtom(AtomStream &atom, ID4 id, int numc, int dlen, BroadcastState &bcs) {
    int r = 0;
    ChanHit hit;
    int rBan = 0;

    if (id == PCP_CHAN) {
        readChanAtoms(atom, numc, bcs);
    } else if (id == PCP_ROOT) {
        if (servMgr->isRoot)
            throw StreamException("Unauthorized root message");
        else
            readRootAtoms(atom, numc, bcs);

    } else if (id == PCP_HOST) {
        readHostAtoms(atom, numc, bcs, hit);
        Channel *ch = chanMgr->findChannelByID(hit.chanID);
        if (ch && (ch->isBroadcasting() || servMgr->vpDebug)) {
            if (servMgr->autoPort0Kick && (hit.numHops == 1) && (hit.firewalled || (!hit.relay && !hit.numRelays))) {
                char tmp[32];
                hit.host.IPtoStr(tmp);
                LOG_DEBUG("host that can't relay is disconnect: %s", tmp);
                rBan = PCP_ERROR_BANNED;
            }
            if (servMgr->allowOnlyVP && (hit.numHops == 1) && !hit.version_vp) {
                char tmp[32];
                hit.host.IPtoStr(tmp);
                LOG_DEBUG("host that is not VP is disconnect: %s", tmp);
                rBan = PCP_ERROR_BANNED;
            }
        }

    } else if ((id == PCP_MESG_ASCII) || (id == PCP_MESG))        // PCP_MESG_ASCII to be depreciated
    {
        String msg;
        atom.readString(msg.data, sizeof(msg.data), dlen);
        LOG_DEBUG("PCP got text: %s", msg.cstr());
    } else if (id == PCP_BCST) {
        r = readBroadcastAtoms(atom, numc, bcs);
    } else if (id == PCP_HELO) {
        atom.skip(numc, dlen);
        atom.writeParent(PCP_OLEH, 1);
        atom.writeBytes(PCP_HELO_SESSIONID, servMgr->sessionID.id, 16);
    } else if (id == PCP_PUSH) {

        readPushAtoms(atom, numc, bcs);
    } else if (id == PCP_OK) {
        atom.readInt();

    } else if (id == PCP_QUIT) {
        r = atom.readInt();
        if (!r)
            r = PCP_ERROR_QUIT;

    } else if (id == PCP_ATOM) {
        for (int i = 0; i < numc; i++) {
            int nc, nd;
            ID4 aid = atom.read(nc, nd);
            int ar = procAtom(atom, aid, nc, nd, bcs);
            if (ar)
                r = ar;
        }

    } else {
        LOG_CHANNEL("PCP skip: %s", id.getString().str());
        atom.skip(numc, dlen);
    }

    if (!r)
        r = rBan;

    return r;

}
Пример #4
0
// ------------------------------------------
void PCPStream::readPktAtoms(Channel *ch, AtomStream &atom, int numc, BroadcastState &bcs) {
    ChanPacket pack;
    ID4 type;


    for (int i = 0; i < numc; i++) {
        int c, d;
        ID4 id = atom.read(c, d);

        if (id == PCP_CHAN_PKT_TYPE) {
            type = atom.readID4();

            if (type == PCP_CHAN_PKT_HEAD)
                pack.type = ChanPacket::T_HEAD;
            else if (type == PCP_CHAN_PKT_DATA)
                pack.type = ChanPacket::T_DATA;
            else
                pack.type = ChanPacket::T_UNKNOWN;

        } else if (id == PCP_CHAN_PKT_POS) {
            pack.pos = atom.readInt();


        } else if (id == PCP_CHAN_PKT_DATA) {
            pack.len = d;
            atom.readBytes(pack.data, pack.len);
        }
        else {
            LOG_DEBUG("PCP skip: %s,%d,%d", id.getString().str(), c, d);
            atom.skip(c, d);
        }
    }

    if (ch) {

        int diff = pack.pos - ch->streamPos;
        if (diff) {
            LOG_DEBUG("PCP skipping %s%8d (%10d -> %10d) count=%2d", (diff > 0) ? "+" : "", diff, ch->streamPos, pack.pos, ch->skipCount);
            if (ch->lastSkipTime + 120 < sys->getTime()) {
                ch->skipCount = 0;
            }
            ch->lastSkipTime = sys->getTime();
            ch->skipCount++; //JP-EX
            pack.skip = true;
        }

        if (servMgr->autoBumpSkipCount) //JP-EX
        {
            if ((ch->skipCount > servMgr->autoBumpSkipCount) && !(servMgr->disableAutoBumpIfDirect && ch->sourceHost.tracker)) //JP-MOD
            {
                LOG_DEBUG("Auto bump");
                ch->bump = true;
            }
        }

        if (pack.type == ChanPacket::T_HEAD) {
            LOG_DEBUG("New head packet at %d", pack.pos);
            bool renewhead;
            if (servMgr->keepDownstreams)
                renewhead = (memcmp(ch->headPack.data, pack.data, pack.len) != 0);
            else
                renewhead = true;

            /*
            // check for stream restart
            if (pack.pos == 0)
            {
                LOG_CHANNEL("PCP resetting stream");
                ch->streamIndex++;
                ch->rawData.init();
            }
            */
            if (renewhead || ch->lastStopTime + 30 < sys->getTime()) {
                // check for stream restart
                if (pack.pos == 0) {
                    LOG_CHANNEL("PCP resetting stream");
                    ch->streamIndex++;
                    ch->rawData.init();
                }

                ch->headPack = pack;

                ch->rawData.writePacket(pack, true);
                ch->streamPos = pack.pos + pack.len;
            }

        } else if (pack.type == ChanPacket::T_DATA) {
            ch->rawData.writePacket(pack, true);
            ch->streamPos = pack.pos + pack.len;
        }

    }

    // update this parent packet stream position
    if ((pack.pos) && (!bcs.streamPos || (pack.pos < bcs.streamPos)))
        bcs.streamPos = pack.pos;

}
Пример #5
0
// ------------------------------------------
int OGGStream::readPacket(Stream &in,Channel *ch)
{
	OggPage ogg;
	ChanPacket pack;

	ogg.read(in);

	if (ogg.isBOS())
	{
		if (!vorbis.needHeader() && !theora.needHeader())
		{
			ch->headPack.len = 0;
		}

		if (ogg.detectVorbis())
			vorbis.bos(ogg.getSerialNo());
		if (ogg.detectTheora())
			theora.bos(ogg.getSerialNo());
	}

	if (ogg.isEOS())
	{

		if (ogg.getSerialNo() == vorbis.serialNo)
		{
			LOG_CHANNEL("Vorbis stream: EOS");
			vorbis.eos();
		}
		if (ogg.getSerialNo() == theora.serialNo)
		{
			LOG_CHANNEL("Theora stream: EOS");
			theora.eos();
		}
	}

	if (vorbis.needHeader() || theora.needHeader())
	{

		if (ogg.getSerialNo() == vorbis.serialNo)
			vorbis.readHeader(ch,ogg);
		else if (ogg.getSerialNo() == theora.serialNo)
			theora.readHeader(ch,ogg);
		else
			throw StreamException("Bad OGG serial no.");


		if (!vorbis.needHeader() && !theora.needHeader())
		{

			ch->info.bitrate = 0;

			if (vorbis.isActive())
				ch->info.bitrate += vorbis.bitrate;

			if (theora.isActive())
			{
				ch->info.bitrate += theora.bitrate;
				ch->info.contentType = ChanInfo::T_OGM;
			}

			
			ch->headPack.type = ChanPacket::T_HEAD;
			ch->headPack.pos = ch->streamPos;

			ch->startTime = sys->getDTime();		

			ch->streamPos += ch->headPack.len;

			ch->newPacket(ch->headPack);
			LOG_CHANNEL("Got %d bytes of headers",ch->headPack.len);
		}

	}else
	{


		pack.init(ChanPacket::T_DATA,ogg.data,ogg.headLen+ogg.bodyLen,ch->streamPos);
		ch->newPacket(pack);

		ch->streamPos+=pack.len;

		if (theora.isActive())
		{
			if (ogg.getSerialNo() == theora.serialNo)
			{
				ch->sleepUntil(theora.getTime(ogg));
			}
		}else if (vorbis.isActive())
		{
			if (ogg.getSerialNo() == vorbis.serialNo)
			{
				ch->sleepUntil(vorbis.getTime(ogg));
			}
		}

	}
	return 0;
}