Пример #1
0
HRESULT WINAPI QualityControlImpl_Notify(IQualityControl *iface, IBaseFilter *sender, Quality qm)
{
    QualityControlImpl *This = impl_from_IQualityControl(iface);
    HRESULT hr = S_FALSE;

    TRACE("%p %p { 0x%x %u " XTIME_FMT " " XTIME_FMT " }\n",
            This, sender, qm.Type, qm.Proportion,
            XTIME(qm.Late), XTIME(qm.TimeStamp));

    if (This->tonotify)
        return IQualityControl_Notify(This->tonotify, This->self, qm);

    if (This->input) {
        IPin *to = NULL;
        IPin_ConnectedTo(This->input, &to);
        if (to) {
            IQualityControl *qc = NULL;
            IPin_QueryInterface(to, &IID_IQualityControl, (void**)&qc);
            if (qc) {
                hr = IQualityControl_Notify(qc, This->self, qm);
                IQualityControl_Release(qc);
            }
            IPin_Release(to);
        }
    }

    return hr;
}
Пример #2
0
static BOOL QualityControlRender_IsLate(QualityControlImpl *This, REFERENCE_TIME jitter,
                                        REFERENCE_TIME start, REFERENCE_TIME stop)
{
    REFERENCE_TIME max_lateness = 200000;

    TRACE("%p " XTIME_FMT " " XTIME_FMT " " XTIME_FMT "\n",
            This, XTIME(jitter), XTIME(start), XTIME(stop));

    /* we can add a valid stop time */
    if (stop >= start)
        max_lateness += stop;
    else
        max_lateness += start;

    /* if the jitter bigger than duration and lateness we are too late */
    if (start + jitter > max_lateness) {
        WARN("buffer is too late %i > %i\n", (int)((start + jitter)/10000),  (int)(max_lateness/10000));
        /* !!emergency!!, if we did not receive anything valid for more than a
         * second, render it anyway so the user sees something */
        if (This->last_in_time < 0 ||
            start - This->last_in_time < 10000000)
            return TRUE;
        FIXME("A lot of buffers are being dropped.\n");
        FIXME("There may be a timestamping problem, or this computer is too slow.\n");
    }
    This->last_in_time = start;
    return FALSE;
}
Пример #3
0
/* GF_MULTIPLY
 *
 * multiply two bytes represented in GF(2**8), mod (x**4 + 1)
 */
PRUint8 gfm(PRUint8 a, PRUint8 b)
{
    PRUint8 res = 0;
    while (b > 0) {
	res = (b & 0x01) ? res ^ a : res;
	a = XTIME(a);
	b >>= 1;
    }
    return res;
}
Пример #4
0
void QualityControlRender_Start(QualityControlImpl *This, REFERENCE_TIME tStart)
{
    TRACE("%p " XTIME_FMT "\n", This, XTIME(tStart));
    This->avg_render = This->last_in_time = This->last_left = This->avg_duration = This->avg_pt = -1;
    This->clockstart = tStart;
    This->avg_rate = -1.0;
    This->rendered = This->dropped = 0;
    This->is_dropped = FALSE;
    This->qos_handled = TRUE; /* Lie that will be corrected on first adjustment */
}
Пример #5
0
void QualityControlRender_BeginRender(QualityControlImpl *This)
{
    TRACE("%p\n", This);

    This->start = -1;

    if (!This->clock)
        return;

    IReferenceClock_GetTime(This->clock, &This->start);
    TRACE("at: " XTIME_FMT "\n", XTIME(This->start));
}
Пример #6
0
//伽罗瓦域计算
void MixColumnStr(RijndaelContextPtr context,unsigned char* r)
{
	//r的拷贝
	unsigned char a[4];
	//r * 0x2的伽罗瓦域计算
	unsigned char b[4];
	unsigned char c;
	//unsigned char h;
	
	//a[n] ^ b[n] is element n multiplied by 3 in Rijndael's Galois field */ 
	for(c=0; c<4; c++) 
	{
		a[c] = r[c];
		//这行代码代替下面所有的代码
		//依据的规则是任何数与0异或其值不变
		b[c] = XTIME(r[c]);
		/*
		h = r[c] & 0x80;
		b[c] = r[c] << 1;
		if(h == 0x80) 
		{
			b[c] ^= 0x1b;
		}*/
	}
	//0x01、0x02、0x03、0x09、0x0b、0x0d 和 0x0e 来相乘
	//由于GF(256)域的值永远在0-255之间,所以获取2,3,9,b,d,e的
	//GF域值时可以通过查表法的
	//其实是一个矩阵c(x) = x^4 + 1 = 3*x^3 + 2*x^2 + x + 1
	//他的逆运算为c^-1(x)=11*x^3 + 13*x^2 + 9*x + 14
	//换成矩阵则是
	/*
	 * [2 3 1 1] [a0]   
	 * [1 2 3 1] [a1]
	 * [1 1 2 3] [a2]
	 * [3 1 1 2] [a3]
	 * b0 = 2 * a0 + a3 + a2 + 3 * a1
	 * b1 = 2 * a1 + a0 + a3 + 3 * a2
	 * b2 = 2 * a2 + a1 + a0 + 3 * a3
	 * b3 = 2 * a3 + a2 + a1 + 3 * a0
	 * 这里最高只有乘以3,即(x+1)=(2+1)因此b[]只要保存r[]*2的值即可
	 * b[1] ^ a[1] = 3 * a[1]
	 */
	/* 2 * a0 + a3 + a2 + 3 * a1 */
	r[0] = b[0] ^ a[3] ^ a[2] ^ b[1] ^ a[1]; 
	/* 2 * a1 + a0 + a3 + 3 * a2 */
	r[1] = b[1] ^ a[0] ^ a[3] ^ b[2] ^ a[2];
	/* 2 * a2 + a1 + a0 + 3 * a3 */
	r[2] = b[2] ^ a[1] ^ a[0] ^ b[3] ^ a[3];
	/* 2 * a3 + a2 + a1 + 3 * a0 */
	r[3] = b[3] ^ a[2] ^ a[1] ^ b[0] ^ a[0];
}
Пример #7
0
static PRStatus 
init_rijndael_tables(void)
{
    PRUint32 i;
    PRUint8 si01, si02, si03, si04, si08, si09, si0B, si0D, si0E;
    struct rijndael_tables_str *rts;
    rts = (struct rijndael_tables_str *)
                   PORT_Alloc(sizeof(struct rijndael_tables_str));
    if (!rts) return PR_FAILURE;
    for (i=0; i<256; i++) {
	/* The forward values */
	si01 = SBOX(i);
	si02 = XTIME(si01);
	si03 = si02 ^ si01;
	rts->T0[i] = WORD4(si02, si01, si01, si03);
	rts->T1[i] = WORD4(si03, si02, si01, si01);
	rts->T2[i] = WORD4(si01, si03, si02, si01);
	rts->T3[i] = WORD4(si01, si01, si03, si02);
	/* The inverse values */
	si01 = SINV(i);
	si02 = XTIME(si01);
	si04 = XTIME(si02);
	si08 = XTIME(si04);
	si03 = si02 ^ si01;
	si09 = si08 ^ si01;
	si0B = si08 ^ si03;
	si0D = si09 ^ si04;
	si0E = si08 ^ si04 ^ si02;
	rts->TInv0[i] = WORD4(si0E, si09, si0D, si0B);
	rts->TInv1[i] = WORD4(si0B, si0E, si09, si0D);
	rts->TInv2[i] = WORD4(si0D, si0B, si0E, si09);
	rts->TInv3[i] = WORD4(si09, si0D, si0B, si0E);
    }
    /* wait until all the values are in to set */
    rijndaelTables = rts;
    return PR_SUCCESS;
}
Пример #8
0
/* generate values for the tables with a function*/
static PRUint32 gen_TInvXi(PRUint8 tx, PRUint8 i)
{
    PRUint8 si01, si02, si03, si04, si08, si09, si0B, si0D, si0E;
    si01 = SINV(i);
    si02 = XTIME(si01);
    si04 = XTIME(si02);
    si08 = XTIME(si04);
    si03 = si02 ^ si01;
    si09 = si08 ^ si01;
    si0B = si08 ^ si03;
    si0D = si09 ^ si04;
    si0E = si08 ^ si04 ^ si02;
    switch (tx) {
    case 0:
	return WORD4(si0E, si09, si0D, si0B);
    case 1:
	return WORD4(si0B, si0E, si09, si0D);
    case 2:
	return WORD4(si0D, si0B, si0E, si09);
    case 3:
	return WORD4(si09, si0D, si0B, si0E);
    }
    return -1;
}
Пример #9
0
void QualityControlRender_DoQOS(QualityControlImpl *priv)
{
    REFERENCE_TIME start, stop, jitter, pt, entered, left, duration;
    double rate;

    if (!priv->clock || priv->current_rstart < 0)
        return;

    start = priv->current_rstart;
    stop = priv->current_rstop;
    jitter = priv->current_jitter;

    if (jitter < 0) {
        /* this is the time the buffer entered the sink */
        if (start < -jitter)
            entered = 0;
        else
            entered = start + jitter;
        left = start;
    } else {
        /* this is the time the buffer entered the sink */
        entered = start + jitter;
        /* this is the time the buffer left the sink */
        left = start + jitter;
    }

    /* calculate duration of the buffer */
    if (stop >= start)
        duration = stop - start;
    else
        duration = 0;

    /* if we have the time when the last buffer left us, calculate
     * processing time */
    if (priv->last_left >= 0) {
        if (entered > priv->last_left) {
            pt = entered - priv->last_left;
        } else {
            pt = 0;
        }
    } else {
        pt = priv->avg_pt;
    }

#define XTIME(u) (int)(u/10000000), (int)((u / 10000)%1000)
    TRACE("start: %u.%03u, entered %u.%03u, left %u.%03u, pt: %u.%03u, "
          "duration %u.%03u, jitter %u.%03u\n", XTIME(start), XTIME(entered),
          XTIME(left), XTIME(pt), XTIME(duration), XTIME(jitter));

    TRACE("avg_duration: %u.%03u, avg_pt: %u.%03u, avg_rate: %g\n",
      XTIME(priv->avg_duration), XTIME(priv->avg_pt), priv->avg_rate);
#undef XTIME

    /* collect running averages. for first observations, we copy the
    * values */
    if (priv->avg_duration < 0)
        priv->avg_duration = duration;
    else
        priv->avg_duration = UPDATE_RUNNING_AVG (priv->avg_duration, duration);

    if (priv->avg_pt < 0)
        priv->avg_pt = pt;
    else
        priv->avg_pt = UPDATE_RUNNING_AVG (priv->avg_pt, pt);

    if (priv->avg_duration != 0)
        rate =
            (double)priv->avg_pt /
            (double)priv->avg_duration;
    else
        rate = 0.0;

    if (priv->last_left >= 0) {
        if (priv->is_dropped || priv->avg_rate < 0.0) {
            priv->avg_rate = rate;
        } else {
            if (rate > 1.0)
                priv->avg_rate = UPDATE_RUNNING_AVG_N (priv->avg_rate, rate);
            else
                priv->avg_rate = UPDATE_RUNNING_AVG_P (priv->avg_rate, rate);
        }
    }

    if (priv->avg_rate >= 0.0) {
        HRESULT hr;
        Quality q;
        /* if we have a valid rate, start sending QoS messages */
        if (priv->current_jitter < 0) {
            /* make sure we never go below 0 when adding the jitter to the
             * timestamp. */
            if (priv->current_rstart < -priv->current_jitter)
                priv->current_jitter = -priv->current_rstart;
        }
        else
            priv->current_jitter += (priv->current_rstop - priv->current_rstart);
        q.Type = (jitter > 0 ? Famine : Flood);
        q.Proportion = (LONG)(1000. / priv->avg_rate);
        if (q.Proportion < 200)
            q.Proportion = 200;
        else if (q.Proportion > 5000)
            q.Proportion = 5000;
        q.Late = priv->current_jitter;
        q.TimeStamp = priv->current_rstart;
        TRACE("Late: %i from %i, rate: %g\n", (int)(q.Late/10000), (int)(q.TimeStamp/10000), 1./priv->avg_rate);
        hr = IQualityControl_Notify((IQualityControl *)priv, priv->self, q);
        priv->qos_handled = hr == S_OK;
    }

    /* record when this buffer will leave us */
    priv->last_left = left;
}
Пример #10
0
int  stat( REG1 char *name, REG2 struct stat *buf)
{
    struct FileFindBuf findbuf;
    unsigned findcount = 1;     /* Find only 1 match */
    unsigned findhandle = -1;   /* any unused handle */

    char * oldcwd;          /* Pointer to current directory */

    unsigned long dmap;     /* Valid Drive Map (ignored) */
    int drive;          /* A: = 1, B: = 2, etc. */

    /* Don't allow wildcards to be interpreted by system */

    if (strpbrk(name, "?*")) {
        errno = ENOENT;
        _doserrno = E_nofile;
        return(-1);
    }

    /* Try to get disk from name.  If none, get current disk.  */

    if (name[1] == ':'){

        drive = tolower(*name) - 'a' + 1;
    }
    else
        (void) DOSQCURDISK((unsigned far *) &drive,
        (unsigned long far *) &dmap);

    /* Call Find Match File */

    errno = ENOENT;

    if (DOSFINDFIRST((char far *)name, (unsigned far *)&findhandle, A_D|A_S|A_H,
    (struct FileFindBuf far *) &findbuf, sizeof(findbuf),
    (unsigned far *) &findcount, 0L)) {

        if ( STRPBRK(name, "./\\") ) {  /* Possible root directory? */
            if ( ! ( oldcwd = _getdcwd(drive, NULL, -1) ) )
                return( -1 );
            if ( chdir( name ) != -1 ) {
                chdir( oldcwd ); /* Must be a root directory */
                free( oldcwd );
            }
            else {
                free( oldcwd );
                return( -1 );
            }

            findbuf.attributes = A_D;
            findbuf.file_size = 0L;
            findbuf.write_date = (1 << 5) + 1; /* 1 January 1980 */
            findbuf.write_time = 0;        /* 00:00:00 */
            findbuf.access_date =
                findbuf.create_date =
                findbuf.access_time =
                findbuf.create_time = 0;
        }
        else
            return( -1 );

    }
    else
        DOSFINDCLOSE(findhandle);   /* Release Find handle */

    /* Fill in buf */

    buf->st_uid = buf->st_gid = buf->st_ino = 0;

    buf->st_rdev = buf->st_dev = drive - 1; /* A=0, B=1, etc. */

    /* now set the common fields */

    buf->st_mode = _dtoxmode(findbuf.attributes, name);
    buf->st_nlink = 1;
    buf->st_size = findbuf.file_size;
    buf->st_mtime = XTIME(findbuf.write_date, findbuf.write_time);

    /*
     * If create and access times are 0L, use modification time instead
     */
    if( findbuf.create_date || findbuf.create_time )
        buf->st_ctime = XTIME(findbuf.create_date, findbuf.create_time);
    else
        buf->st_ctime = buf->st_mtime;

    if( findbuf.access_date || findbuf.access_time )
        buf->st_atime = XTIME(findbuf.access_date, findbuf.access_time);
    else
        buf->st_atime = buf->st_mtime;

    return(0);
}