// The following function should delete rtppack if necessary
int RTPInternalSourceData::ProcessRTPPacket(RTPPacket *rtppack,const RTPTime &receivetime,bool *stored)
{
	bool accept,onprobation,applyprobation;
	double tsunit;
	
	*stored = false;
	
	if (timestampunit < 0) 
		tsunit = INF_GetEstimatedTimestampUnit();
	else
		tsunit = timestampunit;

#ifdef RTP_SUPPORT_PROBATION
	if (validated) 				// If the source is our own process, we can already be validated. No 
		applyprobation = false;		// probation should be applied in that case.
	else
	{
		if (probationtype == RTPSources::NoProbation)
			applyprobation = false;
		else
			applyprobation = true;
	}
#else
	applyprobation = false;
#endif // RTP_SUPPORT_PROBATION

	stats.ProcessPacket(rtppack,receivetime,tsunit,ownssrc,&accept,applyprobation,&onprobation);

#ifdef RTP_SUPPORT_PROBATION
	switch (probationtype)
	{
		case RTPSources::ProbationStore:
			if (!(onprobation || accept))
				return 0;
			if (accept)
				validated = true;
			break;
		case RTPSources::ProbationDiscard:
		case RTPSources::NoProbation:
			if (!accept)
				return 0;
			validated = true;
			break;
		default:
			return ERR_RTP_INTERNALSOURCEDATA_INVALIDPROBATIONTYPE;
	}
#else
	if (!accept)
		return 0;
	validated = true;
#endif // RTP_SUPPORT_PROBATION;
	
	if (validated && !ownssrc) // for own ssrc these variables depend on the outgoing packets, not on the incoming
		issender = true;
	
	// Now, we can place the packet in the queue
	
	if (packetlist.empty())
	{
		*stored = true;
		packetlist.push_back(rtppack);
		return 0;
	}
	
	if (!validated) // still on probation
	{
		// Make sure that we don't buffer too much packets to avoid wasting memory
		// on a bad source. Delete the packet in the queue with the lowest sequence
		// number.
		if (packetlist.size() == RTPINTERNALSOURCEDATA_MAXPROBATIONPACKETS)
		{
			RTPPacket *p = *(packetlist.begin());
			packetlist.pop_front();
			RTPDelete(p,GetMemoryManager());
		}
	}

	// find the right position to insert the packet
	
	std::list<RTPPacket*>::iterator it,start;
	bool done = false;
	uint32_t newseqnr = rtppack->GetExtendedSequenceNumber();
	
	it = packetlist.end();
	--it;
	start = packetlist.begin();
	
	while (!done)
	{
		RTPPacket *p;
		uint32_t seqnr;
		
		p = *it;
		seqnr = p->GetExtendedSequenceNumber();
		if (seqnr > newseqnr)
		{
			if (it != start)
				--it;
			else // we're at the start of the list
			{
				*stored = true;
				done = true;
				packetlist.push_front(rtppack);
			}
		}
		else if (seqnr < newseqnr) // insert after this packet
		{
			++it;
			packetlist.insert(it,rtppack);
			done = true;
			*stored = true;
		}
		else // they're equal !! Drop packet
		{
			done = true;
		}
	}

	return 0;
}
//called on timer
//all data is processed here
void MediaStream::timerClick()
{
//d->mutex.lock();

#ifndef TEST_AUDIO    
    int status = d->session.Poll();
    if ( status<0 ) {
        qDebug("Poll: %s", RTPGetErrorString(status).c_str() );
    }
//    printf("JStat2 %d : %d\n", d->micBuffer->size(),d->dspBuffer->size());

    //checkRtpError( status );
    // check incoming packets
    d->session.BeginDataAccess();
    if ( d->session.GotoFirstSourceWithData() ) {

        qDebug("have rtp data");
        do {
            RTPSourceData *sourceData = d->session.GetCurrentSourceInfo();

            RTPPacket *pack;
            if ((pack = d->session.GetNextPacket()) != NULL) {
                qDebug("Get packet N %ld", pack->GetExtendedSequenceNumber());


                // debug("Got  packet with payload type %d, size %d", pack->GetPayloadType(), pack->GetPayloadLength() );

                // TODO initialise decoder here using pack payload type, maybe use QIntDict of decoders
                if ( d->decoder ) {
                    short* decodedData = 0;

                    int size = d->decoder->decode((char*)pack->GetPayloadData(), pack->GetPayloadLength(), &decodedData );

                    if ( size > 0 ) {

                        // adjust the volume
                        for ( int i=0; i<size; i++ ) {
                            double val = double(decodedData[i]) * call_dlg_dsp_level / 50.0;
                            if ( val > 32700.0 )
                                val = 32700.0;
                            if ( val < -32700.0 )
                                val = -32700.0;

                            decodedData[i] = short(val);
                        }
                        
                        // write to DSP buffer
                        d->dspBuffer->lock();
                        d->dspBuffer->put( (char*)decodedData, size*2 );
                        d->dspBuffer->unlock();
                        
                        processDspData(decodedData,size);

                        delete[] decodedData;
                    }
                    qDebug("decoded data (%d byes) with payload type %d",  size*2, pack->GetPayloadType() );


                } else {
                    qDebug("can't decode data with payload type %d", pack->GetPayloadType() );
                }

                // we don't longer need the packet, so
                // we'll delete it
                delete pack;
            }
        } while ( d->session.GotoNextSourceWithData());
    }
    d->session.EndDataAccess();

    // send the packet
    // check for in data


    short *data = 0;
    int micDataSize = 0; // size of readed mic data in samples

    d->micBuffer->lock();
    micDataSize = d->micBuffer->size()/2;
    if ( micDataSize ) {
        data = new short[micDataSize];
        memcpy( data, d->micBuffer->data(), micDataSize*2 );
        d->micBuffer->fetch( micDataSize*2 );
    }
    d->micBuffer->unlock();

    // adjust mic volume
    for ( int i=0; i<micDataSize; i++ ) {
        double val = double(data[i]) * call_dlg_mic_level / 50.0;
        if ( val > 32700.0 )
            val = 32700.0;
        if ( val < -32700.0 )
            val = -32700.0;

        data[i] = short(val);
    }

    if(micDataSize == 0) {
	micDataSize = 160;
	data = new short[160];
    }

    // examine the data here, to calculate levels
    processMicData(data, micDataSize);


    if ( data ) {
        char * encodedData = 0;
        int readed = micDataSize;
        int size = 0;

        qDebug("have mic data %d", micDataSize );
        
        
        do {
            int readed = 0;
            size = d->encoder->encode( data, micDataSize, &encodedData, &readed );

            int localPayload = d->codecPayload; // TODO get local payload here

            qDebug("readed %d  encoded %d", readed, size );

            delete[] data;
            data = 0;
            micDataSize = 0;

            // TODO: for pcmu packet (payload==0) send packets of certain size
            if ( size > 0 ) {
                memcpy( d->outBuffer+d->outBufferPos, encodedData, size );
                d->outBufferPos += size;
                d->outBufferTime += readed;
                if ( d->outBufferPos ) {
                    //checkRtpError( 

                    if ( d->session.IsActive() && d->sendPacketsFlag ) {
                        int status = d->session.SendPacket( (void *)d->outBuffer, (int)d->outBufferPos, (unsigned char)localPayload , false, (long)d->outBufferTime );
                        if ( status<0 ) {
                             qDebug("can't SendPacket, %s", RTPGetErrorString(status).c_str() );
                        }
                    }
                    qDebug("sent packet");
                }

                    

                d->outBufferPos = 0;
                d->outBufferTime = 0;
            }

            if ( encodedData ) {
                delete[] encodedData;
                encodedData = 0;
            }

        } while (size > 0);
    }
    
    status = d->session.Poll();
    if ( status<0 ) {
         qDebug("Poll: %s", RTPGetErrorString(status).c_str() );
    }
#else // TEST_AUDIO

    short *data = 0;
    int micDataSize = 0; // size of readed mic data in samples

    d->micBuffer->lock();
    micDataSize = d->micBuffer->size()/2;
    if ( micDataSize ) {
        data = new short[micDataSize];
        memcpy( data, d->micBuffer->data(), micDataSize*2 );
        d->micBuffer->fetch( micDataSize*2 );
    }
    d->micBuffer->unlock();

    if (data) {
        // write to DSP buffer
        d->dspBuffer->lock();
        d->dspBuffer->put( (char*)data,micDataSize*2 );
        d->dspBuffer->unlock();

    }

    static int totalSamples = 0;
    totalSamples += micDataSize;


    if ( micDataSize )
        printf("total audio samples: %d  %d   \r", micDataSize, totalSamples);
    

#endif // TEST_AUDIO
    
//    d->mutex->unlock();
}