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; }
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; }
/* 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; }
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 */ }
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)); }
//伽罗瓦域计算 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]; }
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; }
/* 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; }
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; }
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); }