float TwoDimensionTable::Lookup(float a, float b)
{
	float arg[2];

	if(!data) return 0;

	arg[0] = a;
	arg[1] = b;

	int index1[2], index2[2];
	float fraction[2];

	int l;

	for(l=0; l<2; l++)
	{
		if(arg[l] <= axis[l].breakPoint[0])
		{
			index1[l] = index2[l] = 0;
			fraction[l] = 0;
		}
		else
		{
			if(arg[l] >= axis[l].breakPoint[axis[l].breakPointCount - 1])
			{
				index1[l] = index2[l] = axis[l].breakPointCount - 1;
				fraction[l] = 0;
			}
			else
			{
				int t;

				for(t=0; t<axis[l].breakPointCount-1; t++)
				{
					if( arg[l] >  axis[l].breakPoint[t] && 
						arg[l] <= axis[l].breakPoint[t+1] )
					{
						index1[l]   = t;
						index2[l]   = t+1;
						fraction[l] = RESCALE(arg[l],axis[l].breakPoint[t],axis[l].breakPoint[t],0,1);
					}
				}
			}
		}
	}

	float d,e;

	d = RESCALE(fraction[0], 0, 1, Data(index1[0],index1[1]), Data(index2[0],index1[1]) );
	e = RESCALE(fraction[0], 0, 1, Data(index1[0],index2[1]), Data(index2[0],index2[1]) );

	return RESCALE(fraction[1], 0, 1, d, e );


}
void ParticleNode::EvalTimedFloat(int Count, timedFloat *input, float &retval)
{
	if(life < input[0].time || Count < 2)
	{
		retval=input[0].value;
		return;
	}
	
	int l, l1;
	for(l = 0 ; l < (Count - 1) ; l++)
	{
		l1 = l + 1;
		if(life < input[l1].time)
		{
			retval = RESCALE(life, input[l].time, input[l1].time, input[l].value, input[l1].value);
			return;
		}
	}
	// assume we fell thru --- l=Count-1;
	retval=input[l].value;
}
float LookupTable::Lookup(float In)
	{
		if(In < table[0].input)
		{
			return(table[0].output);
		}

		int l,l1;
		for(l = 0 ; l < (pairs - 1) ; l++)
		{
			l1 = l + 1;
			if(In < table[l1].input)
			{
#define RESCALE(in,inmin,inmax,outmin,outmax) ( ((float)(in) - (inmin)) * ((outmax) - (outmin)) / ((inmax) - (inmin)) + (outmin))
				return(RESCALE(In, table[l].input,table[l1].input, table[l].output, table[l1].output));
			}
		}

		// assume we fell thru
		return(table[pairs-1].output);
	}
//___________________________________________________________________________
uint8_t lavMuxer::writeVideoPacket(ADMBitstream *bitstream)
{
int ret;

double p,d;
  	AVPacket pkt;
            av_init_packet(&pkt);
	    
        p=bitstream->ptsFrame+1;      // Pts           // Time p/fps1000=out/den  out=p*den*1000/fps1000
	p=(p*1000*1000*1000);
        p=p/_fps1000;                  // in us
	
        d=bitstream->dtsFrame;		// dts
	d=(d*1000*1000*1000);
	d=d/_fps1000;
	
	
	_curDTS=(int64_t)floor(d);	
        
        // Rescale
#define RESCALE(x) x=x*video_st->codec->time_base.den*1000.;\
                   x=x/_fps1000;
        
        p=bitstream->ptsFrame+1;
        RESCALE(p);
        
        d=bitstream->dtsFrame;
        RESCALE(d);
        
	pkt.dts=(int64_t)floor(d);
	pkt.pts=(int64_t)floor(p);
        
       // printf("Lavformat : Pts :%u dts:%u",displayframe,frameno);
	aprintf("Lavformat : Pts :%llu dts:%llu",pkt.pts,pkt.dts);
	pkt.stream_index=0;
           
        pkt.data= bitstream->data;
        pkt.size= bitstream->len;
	// Look if it is a gop start or seq start
        if(_type==MUXER_MP4)
        {
            if(bitstream->flags & AVI_KEY_FRAME) 
                        pkt.flags |= PKT_FLAG_KEY;
        }else
            if(!bitstream->data[0] &&  !bitstream->data[1] && bitstream->data[2]==1)
	{
            if(bitstream->data[3]==0xb3 || bitstream->data[3]==0xb8 ) // Seq start or gop start
		pkt.flags |= PKT_FLAG_KEY;
		//printf("Intra\n"); 
	}
           
	ret =av_write_frame(oc, &pkt);
	if(ret) 
	{
		printf("Error writing video packet\n");
		return 0;
	}
        aprintf("V: frame %lu pts%d\n",bitstream->dtsFrame,pkt.pts);
	
	return 1;
}