217 lines
6.3 KiB
C++
217 lines
6.3 KiB
C++
// LOG.C
|
||
// low overhead logging routines
|
||
// can be used in time-critical situations
|
||
// LogInit should be called once to create the memory mapped file
|
||
// use LOGVIEW.EXE to view the log.
|
||
|
||
#include "precomp.h"
|
||
|
||
#ifdef LOGGING
|
||
// storage in log.c
|
||
// Strings corresponding to LOGMSG_XXX
|
||
// Note: cant use %s in format string
|
||
char LogStringTable [][MAX_STRING_SIZE] = {
|
||
// dont exceed the size of the string below!
|
||
// "123456789012345678901234567890123456789012345678901234567890123"
|
||
"Sent at %d\n",
|
||
"NetRecv ts = %d, seq = %d at %d\n",
|
||
"AP::Send (%d), %d bytes, ts =%d\n",
|
||
"AP::Silent (%d) %d\n",
|
||
"AP::Record (%d)\n",
|
||
"AP::Recv (%d) seq = %d len=%d\n",
|
||
"Rx::Reset1 MaxT=%d PlayT=%d PlayPos=%d\n",
|
||
"Rx::Reset2 MaxT=%d PlayT=%d PlayPos=%d\n",
|
||
"AP::Encoded(%d)\n",
|
||
"AP::Decoded(%d)\n",
|
||
"AP::Playing(%d) at %d\n",
|
||
"AP::PlaySil(%d)\n",
|
||
"RcrdTh:: try to open audio dev\n",
|
||
"PlayTh: too many missings and Yield\n",
|
||
"RcrdTh:: too many silence and Yield\n",
|
||
"AP::Recycle(%d)\n",
|
||
"AutoSilence: strength=%d,threshold=%d,avgSilence=%d\n",
|
||
"Tx -Presend(%d)\n",
|
||
"Rx-Skipping(%d)\n",
|
||
"Tx::Reset FreePos=%d SendPos=%d\n",
|
||
"Rx::VarDelay=%d samples, avgVarDelay=%d, delayPos=%d\n",
|
||
"AP::PlayInterpolated(%d)\n",
|
||
"AP::Interpolated (%d) %d\n",
|
||
"VP::Send (%d), %d bytes, ts =%d\n",
|
||
"VP::Recv (%d) seq = %d len=%d\n",
|
||
"VP::Recycle(%d)\n",
|
||
"VP::Record (%d)\n",
|
||
"VP::Playing(%d) at %d\n",
|
||
"VP::PlaySil(%d)\n",
|
||
"VP::PlayInterpolated(%d)\n",
|
||
"VP::Interpolated (%d) %d\n",
|
||
"VP::Encoded(%d)\n",
|
||
"VP::Decoded(%d)\n",
|
||
"Vid::Trying to open Capture\n",
|
||
"Vid:GetSendFrame (%d)\n",
|
||
"Vid:GetRecvFrame (%d)\n",
|
||
"Vid:ReleaseSendFrame(%d)\n",
|
||
"Vid:ReleaseRecvFrame(%d)\n",
|
||
"Vid:Playing back TS %d aud sync %d\n",
|
||
"DGSOCK:->OnRead (%d)\n",
|
||
"DGSOCK:<-OnRead (%d)\n",
|
||
"DGSOCK:->OnReadDone (%d)\n",
|
||
"DGSOCK:<-OnReadDone (%d)\n",
|
||
"DGSOCK:->RecvFrom (%d)\n",
|
||
"DGSOCK:<-RecvFrom (%d)\n",
|
||
"DGSOCK:ReadWouldBlock (%d)\n",
|
||
"VidSend: VP::Queue %d bytes, ts =%d at %d\n",
|
||
"VidSend: AP::Queue %d bytes, ts =%d at %d\n",
|
||
"VidSend: VP::Send %d bytes, ts =%d at %d\n",
|
||
"VidSend: AP::Send %d bytes, ts =%d at %d\n",
|
||
"VidSend: VP::!Send %d bytes, ts =%d\n",
|
||
"VidSend: AP::!Send %d bytes, ts =%d\n",
|
||
"VidSend: IO Pending\n",
|
||
"VidSend: Audio queue is empty\n",
|
||
"VidSend: Video queue is empty\n",
|
||
"AudSend: VP::Queue %d bytes, ts =%d\n",
|
||
"AudSend: AP::Queue %d bytes, ts =%d at %d\n",
|
||
"AudSend: VP::Send %d bytes, ts =%d\n",
|
||
"AudSend: AP::Send %d bytes, ts =%d at %d\n",
|
||
"AudSend: VP::!Send %d bytes, ts =%d\n",
|
||
"AudSend: AP::!Send %d bytes, ts =%d\n",
|
||
"AudSend: IO Pending\n",
|
||
"AudSend: Audio queue is empty\n",
|
||
"AudSend: Video queue is empty\n",
|
||
"Send blocked for %d ms\n",
|
||
|
||
"DS PlayBuf: Play=%d, Write=%d, len=%d\n",
|
||
"DS Empty : Play=%d, lastPlay=%d, nextWrite=%d\n",
|
||
"DS Timeout: Play=%d, nextWrite=%d at %d\n",
|
||
"DS PlayBuf Overflow! SetPlayPosition to %d (hr=%d)\n",
|
||
"DS Create: (hr = %d)\n",
|
||
"DS Release: (uref = %d)\n",
|
||
"DS PlayBuf: Dropped out of sequence packet\n",
|
||
"DS PlayBuf: timestamp=%d, seq=%d, fMark=%d\n",
|
||
"DS PlayBuf: GetTickCount=%d\n",
|
||
"DS PlayBuf: PlayPos=%d, WritePos=%d\n",
|
||
"DS PlayBuf: Dropping packet due to overflow\n",
|
||
"m_Next=%d, curDelay=%d, bufSize=%d\n",
|
||
|
||
"Send Audio Config took %ld ms\r\n",
|
||
"Send Audio UnConfig took %ld ms\r\n",
|
||
"Send Video Config took %ld ms\r\n",
|
||
"Send Video UnConfig took %ld ms\r\n",
|
||
"Recv Audio Config took %ld ms\r\n",
|
||
"Recv Audio UnConfig took %ld ms\r\n",
|
||
"Recv Video Config took %ld ms\r\n",
|
||
"Recv Video UnConfig took %ld ms\r\n",
|
||
|
||
|
||
"DSC Timestamp: %d\r\n",
|
||
"DSC GetCurrentPos: capPos=%d ReadPos=%d\r\n",
|
||
"DSC Timeout: A timeout has occured\r\n",
|
||
"DSC Lagging condition: Lag=%d NextExpect=%d\r\n",
|
||
"DSC Sending: Num=%d, dwFirstPos=%d, dwLastPos=%d\r\n",
|
||
"DSC Stats: BufferSize=%d, FrameSize=%d\r\n",
|
||
"DSC Early condition detected\r\n"
|
||
};
|
||
|
||
#define MAX_LOG_ENTRIES 2048
|
||
|
||
// IMPORTANT: should be identical to definition in viewer app.
|
||
typedef struct {
|
||
int locked; // set to TRUE while viewer is accessing log
|
||
int cdwEntrySize;
|
||
int cMaxEntries;
|
||
int cbOffsetBase; // from start of this struct
|
||
int cbOffsetStringTable; // from start of this struct
|
||
int cStrings; // number of strings
|
||
int cCurrent; // index of current log position
|
||
} LOG_HEADER;
|
||
|
||
struct LogEntry {
|
||
DWORD dw[4];
|
||
} *pLogBase;
|
||
|
||
#define MAX_LOG_SIZE (sizeof(LOG_HEADER)+sizeof(struct LogEntry)*MAX_LOG_ENTRIES + sizeof(LogStringTable))
|
||
|
||
HANDLE hMapFile = NULL;
|
||
char szLogViewMap[] = "LogViewMap";
|
||
LOG_HEADER *pLog=NULL;
|
||
CRITICAL_SECTION logCritSect; // not used
|
||
|
||
|
||
void Log (UINT n, UINT arg1, UINT arg2, UINT arg3)
|
||
{
|
||
struct LogEntry *pCurEntry;
|
||
if (pLog == NULL || pLog->locked)
|
||
return;
|
||
|
||
|
||
//EnterCriticalSection(&logCritSect);
|
||
// sideeffect of multiple access are not serious so
|
||
// dont bother with synchronization.
|
||
pLog->cCurrent++;
|
||
if (pLog->cCurrent >= pLog->cMaxEntries) {
|
||
pLog->cCurrent = 0; //wraparound
|
||
}
|
||
pCurEntry = pLogBase + pLog->cCurrent;
|
||
pCurEntry->dw[0] = n;
|
||
pCurEntry->dw[1] = arg1;
|
||
pCurEntry->dw[2] = arg2;
|
||
pCurEntry->dw[3] = arg3;
|
||
//LeaveCriticalSection(&logCritSect);
|
||
}
|
||
|
||
int LogInit()
|
||
{
|
||
int fSuccess;
|
||
hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE,
|
||
NULL,
|
||
PAGE_READWRITE,
|
||
0,
|
||
MAX_LOG_SIZE,
|
||
szLogViewMap);
|
||
if (hMapFile == NULL) {
|
||
//printf("Couldnt open Map: %s\n",szLogViewMap);
|
||
fSuccess = FALSE;
|
||
goto Exit;
|
||
}
|
||
pLog = (LOG_HEADER *)MapViewOfFile(hMapFile,
|
||
FILE_MAP_ALL_ACCESS,
|
||
0,
|
||
0,
|
||
0); // entire file starting from offset 0
|
||
if (pLog == NULL) {
|
||
//printf("Couldnt map view %s\n",szLogViewMap);
|
||
fSuccess = FALSE;
|
||
goto Exit;
|
||
}
|
||
InitializeCriticalSection(&logCritSect);
|
||
// initialize log
|
||
pLog->locked = 0;
|
||
pLog->cdwEntrySize = sizeof(struct LogEntry)/sizeof(DWORD); // size in dwords
|
||
pLog->cMaxEntries = MAX_LOG_ENTRIES;
|
||
pLog->cbOffsetBase = sizeof(LOG_HEADER)+sizeof(LogStringTable);
|
||
pLog->cbOffsetStringTable = sizeof(LOG_HEADER);
|
||
pLog->cStrings = sizeof(LogStringTable)/MAX_STRING_SIZE;
|
||
pLog->cCurrent = 0; // current position
|
||
|
||
pLogBase = (struct LogEntry *)((PBYTE)pLog + pLog->cbOffsetBase);
|
||
|
||
memcpy((PBYTE)pLog + pLog->cbOffsetStringTable, LogStringTable, sizeof(LogStringTable));
|
||
memset((PBYTE)pLogBase,0,MAX_LOG_ENTRIES*pLog->cdwEntrySize*4);
|
||
fSuccess = TRUE;
|
||
Exit:
|
||
return fSuccess;
|
||
}
|
||
|
||
LogClose()
|
||
{
|
||
if (pLog)
|
||
{
|
||
DeleteCriticalSection(&logCritSect);
|
||
UnmapViewOfFile(pLog);
|
||
pLog = NULL;
|
||
CloseHandle(hMapFile);
|
||
hMapFile = NULL;
|
||
}
|
||
return TRUE;
|
||
}
|
||
#endif // LOGGING enabled
|
||
|