improving framedrop code, bugfixes, got rid of tabs in source (I hate tabs), and other things

master
jim 2012-11-21 11:21:40 -07:00
parent 0b51cf7157
commit 129e068b1d
21 changed files with 1311 additions and 1252 deletions

View File

@ -68,6 +68,7 @@
LinkIncremental="2"
AdditionalLibraryDirectories="../OBSApi/Debug"
GenerateDebugInformation="true"
ProgramDatabaseFile="..\rundir\$(TargetName).pdb"
SubSystem="2"
TargetMachine="1"
/>
@ -144,6 +145,7 @@
LinkIncremental="2"
AdditionalLibraryDirectories="../OBSApi/x64/Debug"
GenerateDebugInformation="true"
ProgramDatabaseFile="..\rundir\$(TargetName).pdb"
SubSystem="2"
TargetMachine="17"
/>
@ -220,6 +222,7 @@
LinkIncremental="1"
AdditionalLibraryDirectories="../OBSApi/Release"
GenerateDebugInformation="true"
ProgramDatabaseFile="..\rundir\$(TargetName).pdb"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
@ -299,6 +302,7 @@
LinkIncremental="1"
AdditionalLibraryDirectories="../OBSApi/x64/Release"
GenerateDebugInformation="true"
ProgramDatabaseFile="..\rundir\$(TargetName).pdb"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"

View File

@ -68,6 +68,7 @@
AdditionalDependencies="dxguid.lib"
LinkIncremental="2"
GenerateDebugInformation="true"
ProgramDatabaseFile="..\rundir\$(TargetName).pdb"
SubSystem="2"
TargetMachine="1"
/>
@ -145,6 +146,7 @@
OutputFile="$(OutDir)\$(ProjectName).dll"
LinkIncremental="2"
GenerateDebugInformation="true"
ProgramDatabaseFile="..\rundir\$(TargetName).pdb"
SubSystem="2"
TargetMachine="17"
/>
@ -220,6 +222,7 @@
AdditionalDependencies="dxguid.lib"
LinkIncremental="1"
GenerateDebugInformation="true"
ProgramDatabaseFile="..\rundir\$(TargetName).pdb"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
@ -299,6 +302,7 @@
OutputFile="$(OutDir)\$(ProjectName).dll"
LinkIncremental="1"
GenerateDebugInformation="true"
ProgramDatabaseFile="..\rundir\$(TargetName).pdb"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"

View File

@ -176,9 +176,13 @@ void GraphicsCaptureSource::NewCapture(LPVOID address)
void GraphicsCaptureSource::EndCapture()
{
capture->Destroy();
delete capture;
capture = NULL;
if(capture)
{
capture->Destroy();
delete capture;
capture = NULL;
}
bErrorAcquiring = false;
bCapturing = false;
captureCheckInterval = -1.0f;

6
OBS.rc
View File

@ -402,13 +402,13 @@ BEGIN
PUSHBUTTON "Cancel",IDCANCEL,310,286,50,14
END
IDD_ENDINGDELAY DIALOGEX 0, 0, 258, 48
IDD_ENDINGDELAY DIALOGEX 0, 0, 258, 50
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "EndingDelay"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
PUSHBUTTON "MainWindow.StopStream",IDCANCEL,86,26,85,14
CTEXT "",IDC_TIMELEFT,7,8,244,8
PUSHBUTTON "Cancel",IDCANCEL,90,29,77,14
END
@ -561,7 +561,7 @@ BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 251
TOPMARGIN, 7
BOTTOMMARGIN, 41
BOTTOMMARGIN, 43
END
END
#endif // APSTUDIO_INVOKED

View File

@ -71,7 +71,7 @@
AdditionalLibraryDirectories="OBSApi/Debug;x264/libs/32bit;librtmp/debug;lame/output/32bit;libfaac/debug;libsamplerate/debug"
AdditionalManifestDependencies="type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='X86' publicKeyToken='6595b64144ccf1df' language='*'"
GenerateDebugInformation="true"
StripPrivateSymbols="rundir\$(TargetName).pdb"
ProgramDatabaseFile="rundir\$(TargetName).pdb"
SubSystem="2"
TargetMachine="1"
/>
@ -150,7 +150,7 @@
AdditionalLibraryDirectories="OBSApi/x64/Debug;x264/libs/64bit;librtmp/x64/debug;lame/output/64bit;libfaac/x64/debug;libsamplerate/x64/debug"
AdditionalManifestDependencies="type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'"
GenerateDebugInformation="true"
StripPrivateSymbols="rundir\$(TargetName).pdb"
ProgramDatabaseFile="rundir\$(TargetName).pdb"
SubSystem="2"
TargetMachine="17"
/>
@ -232,7 +232,7 @@
AdditionalLibraryDirectories="OBSApi/Release;x264/libs/32bit;librtmp/release;lame/output/32bit;libfaac/release;libsamplerate/release"
AdditionalManifestDependencies="type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='X86' publicKeyToken='6595b64144ccf1df' language='*'"
GenerateDebugInformation="true"
StripPrivateSymbols="rundir\$(TargetName).pdb"
ProgramDatabaseFile="rundir\$(TargetName).pdb"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
@ -316,7 +316,7 @@
AdditionalLibraryDirectories="OBSApi/x64/Release;x264/libs/64bit;librtmp/x64/release;lame/output/64bit;libfaac/x64/release;libsamplerate/x64/release"
AdditionalManifestDependencies="type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'"
GenerateDebugInformation="true"
StripPrivateSymbols="rundir\$(TargetName).pdb"
ProgramDatabaseFile="rundir\$(TargetName).pdb"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"

View File

@ -67,7 +67,7 @@
AdditionalDependencies="winmm.lib psapi.lib"
LinkIncremental="2"
GenerateDebugInformation="true"
StripPrivateSymbols="..\rundir\$(TargetName).pdb"
ProgramDatabaseFile="..\rundir\$(TargetName).pdb"
SubSystem="2"
TargetMachine="1"
/>
@ -142,7 +142,7 @@
AdditionalDependencies="winmm.lib psapi.lib"
LinkIncremental="2"
GenerateDebugInformation="true"
StripPrivateSymbols="..\rundir\$(TargetName).pdb"
ProgramDatabaseFile="..\rundir\$(TargetName).pdb"
SubSystem="2"
TargetMachine="17"
/>
@ -218,7 +218,7 @@
AdditionalDependencies="winmm.lib psapi.lib"
LinkIncremental="1"
GenerateDebugInformation="true"
StripPrivateSymbols="..\rundir\$(TargetName).pdb"
ProgramDatabaseFile="..\rundir\$(TargetName).pdb"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
@ -298,7 +298,7 @@
AdditionalDependencies="winmm.lib psapi.lib"
LinkIncremental="1"
GenerateDebugInformation="true"
StripPrivateSymbols="..\rundir\$(TargetName).pdb"
ProgramDatabaseFile="..\rundir\$(TargetName).pdb"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"

View File

@ -930,7 +930,7 @@ WORD StringCRC16(CTSTR lpData)
int len = slen(lpData);
for(int i=0; i<len; i++)
{
{
TCHAR val = lpData[i];
for(int j=0; j<(sizeof(TCHAR)*8); j++)
@ -943,7 +943,7 @@ WORD StringCRC16(CTSTR lpData)
}
}
return crc;
return crc;
}
WORD StringCRC16I(CTSTR lpData)
@ -952,7 +952,7 @@ WORD StringCRC16I(CTSTR lpData)
int len = slen(lpData);
for(int i=0; i<len; i++)
{
{
TCHAR val = lpData[i];
if((val >= 'A') && (val <= 'Z'))
@ -968,7 +968,7 @@ WORD StringCRC16I(CTSTR lpData)
}
}
return crc;
return crc;
}

View File

@ -34,38 +34,38 @@ BOOL CALLBACK EnumerateLoadedModulesProcInfo (PCTSTR ModuleName, DWORD64 ModuleB
LONG CALLBACK OBSExceptionHandler (PEXCEPTION_POINTERS exceptionInfo)
{
HANDLE hProcess;
HANDLE hProcess;
HMODULE hDbgHelp;
HMODULE hDbgHelp;
MINIDUMP_EXCEPTION_INFORMATION miniInfo;
STACKFRAME64 frame = {0};
CONTEXT context = *exceptionInfo->ContextRecord;
SYMBOL_INFO *symInfo;
DWORD64 fnOffset;
TCHAR logPath[MAX_PATH];
TCHAR dumpPath[MAX_PATH];
OSVERSIONINFOEX osInfo;
SYSTEMTIME timeInfo;
STACKFRAME64 frame = {0};
CONTEXT context = *exceptionInfo->ContextRecord;
SYMBOL_INFO *symInfo;
DWORD64 fnOffset;
TCHAR logPath[MAX_PATH];
TCHAR dumpPath[MAX_PATH];
OSVERSIONINFOEX osInfo;
SYSTEMTIME timeInfo;
ENUMERATELOADEDMODULES64 fnEnumerateLoadedModules64;
SYMSETOPTIONS fnSymSetOptions;
SYMINITIALIZE fnSymInitialize;
STACKWALK64 fnStackWalk64;
SYMFUNCTIONTABLEACCESS64 fnSymFunctionTableAccess64;
SYMGETMODULEBASE64 fnSymGetModuleBase64;
SYMFROMADDR fnSymFromAddr;
SYMCLEANUP fnSymCleanup;
MINIDUMPWRITEDUMP fnMiniDumpWriteDump;
SYMGETMODULEINFO64 fnSymGetModuleInfo64;
ENUMERATELOADEDMODULES64 fnEnumerateLoadedModules64;
SYMSETOPTIONS fnSymSetOptions;
SYMINITIALIZE fnSymInitialize;
STACKWALK64 fnStackWalk64;
SYMFUNCTIONTABLEACCESS64 fnSymFunctionTableAccess64;
SYMGETMODULEBASE64 fnSymGetModuleBase64;
SYMFROMADDR fnSymFromAddr;
SYMCLEANUP fnSymCleanup;
MINIDUMPWRITEDUMP fnMiniDumpWriteDump;
SYMGETMODULEINFO64 fnSymGetModuleInfo64;
DWORD i;
DWORD64 InstructionPtr;
DWORD i;
DWORD64 InstructionPtr;
BOOL wantUpload = TRUE;
BOOL wantUpload = TRUE;
TCHAR searchPath[MAX_PATH], *p;
TCHAR searchPath[MAX_PATH], *p;
static BOOL inExceptionHandler = FALSE;
@ -273,7 +273,7 @@ LONG CALLBACK OBSExceptionHandler (PEXCEPTION_POINTERS exceptionInfo)
//generate a minidump if possible
if (fnMiniDumpWriteDump)
{
HANDLE hFile;
HANDLE hFile;
tsprintf_s (dumpPath, _countof(dumpPath)-1, TEXT("%s\\crashDumps\\OBSCrashDump%.4d-%.2d-%.2d_%d.dmp"), lpAppDataPath, timeInfo.wYear, timeInfo.wMonth, timeInfo.wDay, i);

View File

@ -39,10 +39,10 @@ typedef BOOL (WINAPI *STACKWALK64) (
PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress
);
typedef PVOID (WINAPI *SYMFUNCTIONTABLEACCESS64) (HANDLE hProcess, DWORD64 AddrBase);
typedef PVOID (WINAPI *SYMFUNCTIONTABLEACCESS64) (HANDLE hProcess, DWORD64 AddrBase);
typedef DWORD64 (WINAPI *SYMGETMODULEBASE64) (HANDLE hProcess, DWORD64 dwAddr);
typedef BOOL (WINAPI *SYMFROMADDR) (HANDLE hProcess, DWORD64 Address, PDWORD64 Displacement, PSYMBOL_INFO Symbol);
typedef BOOL (WINAPI *SYMGETMODULEINFO64) (HANDLE hProcess, DWORD64 dwAddr, PIMAGEHLP_MODULE64 ModuleInfo);
typedef BOOL (WINAPI *SYMFROMADDR) (HANDLE hProcess, DWORD64 Address, PDWORD64 Displacement, PSYMBOL_INFO Symbol);
typedef BOOL (WINAPI *SYMGETMODULEINFO64) (HANDLE hProcess, DWORD64 dwAddr, PIMAGEHLP_MODULE64 ModuleInfo);
typedef DWORD64 (WINAPI *SYMLOADMODULE64) (HANDLE hProcess, HANDLE hFile, PSTR ImageName, PSTR ModuleName, DWORD64 BaseOfDll, DWORD SizeOfDll);

View File

@ -62,15 +62,26 @@ class DelayedPublisher : public NetworkStream
static INT_PTR CALLBACK EndDelayProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if(message == WM_INITDIALOG)
switch(message)
{
LocalizeWindow(hwnd);
SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR)lParam);
return TRUE;
}
else if(message == WM_COMMAND && LOWORD(wParam) == IDCANCEL)
{
DelayedPublisher *publisher = (DelayedPublisher*)GetWindowLongPtr(hwnd, DWLP_USER);
case WM_INITDIALOG:
LocalizeWindow(hwnd);
SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR)lParam);
return TRUE;
case WM_COMMAND:
if(LOWORD(wParam) == IDCANCEL)
{
DelayedPublisher *publisher = (DelayedPublisher*)GetWindowLongPtr(hwnd, DWLP_USER);
publisher->bCancelEnd = true;
}
break;
case WM_CLOSE:
{
DelayedPublisher *publisher = (DelayedPublisher*)GetWindowLongPtr(hwnd, DWLP_USER);
publisher->bCancelEnd = true;
}
}
return 0;
}
@ -127,24 +138,34 @@ public:
{
bStreamEnding = true;
HWND hwndProgressDialog = CreateDialogParam(hinstMain, MAKEINTRESOURCE(IDD_ENDINGDELAY), hwndMain, (DLGPROC)EndDelayProc, (LPARAM)this);
ProcessEvents();
ShowWindow(hwndProgressDialog, TRUE);
DWORD totalTimeLeft = delayTime;
String strTimeLeftVal = Str("EndingDelay.TimeLeft");
DWORD lastTimeLeft = -1;
DWORD firstTime = OSGetTime();
while(queuedPackets.Num() && !bCancelEnd)
{
ProcessEvents();
DWORD timeElapsed = (OSGetTime()-firstTime);
DWORD timeLeft = (totalTimeLeft-timeElapsed)/1000;
DWORD timeLeftMinutes = timeLeft/60;
DWORD timeLeftSeconds = timeLeft%60;
String strTimeLeft = strTimeLeftVal;
strTimeLeft.FindReplace(TEXT("$1"), FormattedString(TEXT("%u:%02u"), timeLeftMinutes, timeLeftSeconds));
SetWindowText(GetDlgItem(hwndProgressDialog, IDC_TIMELEFT), strTimeLeft);
if(timeLeft != lastTimeLeft)
{
String strTimeLeft = strTimeLeftVal;
strTimeLeft.FindReplace(TEXT("$1"), FormattedString(TEXT("%u:%02u"), timeLeftMinutes, timeLeftSeconds));
SetWindowText(GetDlgItem(hwndProgressDialog, IDC_TIMELEFT), strTimeLeft);
lastTimeLeft = timeLeft;
}
ProcessPackets(lastTimestamp+timeElapsed);
if(outputStream && outputStream->bStopping)

View File

@ -56,17 +56,6 @@ struct MP4AudioFrameInfo
#define USE_64BIT_MP4 1
void WINAPI ProcessEvents()
{
MSG msg;
while(PeekMessage(&msg, NULL, 0, 0, 1))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
//code annoyance rating: fairly nightmarish
class MP4FileStream : public VideoFileStream

View File

@ -276,6 +276,15 @@ void LoadGlobalIni()
}
}
void WINAPI ProcessEvents()
{
MSG msg;
while(PeekMessage(&msg, NULL, 0, 0, 1))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{

View File

@ -62,7 +62,7 @@ extern OBS *App;
extern TCHAR lpAppDataPath[MAX_PATH];
#define OBS_VERSION 0x000445
#define OBS_VERSION_STRING_ANSI "Open Broadcaster Software v0.445a [pre-release 2]"
#define OBS_VERSION_STRING_ANSI "Open Broadcaster Software v0.445a [pre-release 3]"
#define OBS_VERSION_STRING TEXT(OBS_VERSION_STRING_ANSI)
#define OBS_WINDOW_CLASS TEXT("OBSWindowClass")
@ -73,6 +73,8 @@ inline UINT ConvertMSTo100NanoSec(UINT ms)
return ms*1000*10; //1000 microseconds, then 10 "100nanosecond" segments
}
void WINAPI ProcessEvents();
//-------------------------------------------
// application headers

View File

@ -71,9 +71,9 @@ RTMPPublisher::RTMPPublisher(RTMP *rtmpIn, BOOL bUseSendBuffer, UINT sendBufferS
packetWaitType = 0;
maxBitRate = (UINT)AppConfig->GetInt(TEXT("Video Encoding"), TEXT("MaxBitrate"), 1000);
bufferSize = (UINT)AppConfig->GetInt(TEXT("Video Encoding"), TEXT("BufferSize"), 1000);
bufferTime = (UINT)(min(1.0, float(bufferSize)/float(maxBitRate))*1000);
maxBitRate = (UINT)AppConfig->GetInt(TEXT("Video Encoding"), TEXT("MaxBitrate"), 1000);
bufferSize = (UINT)AppConfig->GetInt(TEXT("Video Encoding"), TEXT("BufferSize"), 1000);
bufferTime = (UINT)(min(1.0, float(bufferSize)/float(maxBitRate))*1000);
//traceOut;
}
@ -114,31 +114,31 @@ RTMPPublisher::~RTMPPublisher()
UINT RTMPPublisher::BitsPerTime(List<BitRecord> *list)
{
// remove old bits
if (!bPacketDumpMode)
{
DWORD cutoffTime = OSGetTime()-bufferTime;
// remove old bits
if (!bPacketDumpMode)
{
DWORD cutoffTime = OSGetTime()-bufferTime;
while((list->Num() > 0) && (list->GetElement(0).timestamp < cutoffTime))
list->Remove(0);
}
while((list->Num() > 0) && (list->GetElement(0).timestamp < cutoffTime))
list->Remove(0);
}
UINT accumulator = 1;
for(UINT i = 0; i < list->Num(); i++)
{
BitRecord bitRecord = list->GetElement(i);
accumulator += bitRecord.bits;
}
UINT accumulator = 1;
for(UINT i = 0; i < list->Num(); i++)
{
BitRecord bitRecord = list->GetElement(i);
accumulator += bitRecord.bits;
}
return accumulator;
return accumulator;
}
void RTMPPublisher::AddBits(List<BitRecord> *list, UINT bits, DWORD timestamp)
{
BitRecord bitRecord;
bitRecord.bits = bits;
bitRecord.timestamp = timestamp;
list->Add(bitRecord);
BitRecord bitRecord;
bitRecord.bits = bits;
bitRecord.timestamp = timestamp;
list->Add(bitRecord);
}
void RTMPPublisher::SendPacket(BYTE *data, UINT size, DWORD timestamp, PacketType type)
@ -151,14 +151,17 @@ void RTMPPublisher::SendPacket(BYTE *data, UINT size, DWORD timestamp, PacketTyp
paddedData.SetSize(size+RTMP_MAX_HEADER_SIZE);
mcpy(paddedData.Array()+RTMP_MAX_HEADER_SIZE, data, size);
OSEnterMutex(hDataMutex);
OSEnterMutex(hDataMutex);
bitsInPerTime = BitsPerTime(&bitsIn);
bitsOutPerTime = BitsPerTime(&bitsOut);
// debug stuff // if (bPacketDumpMode)
// Log(TEXT("BitsIn: %u, BitsOut: %u"), BitsPerTime(&bitsIn, t), BitsPerTime(&bitsOut, t));
if(bPacketDumpMode && (bitsInPerTime <= bitsOutPerTime))
bitsInPerTime = BitsPerTime(&bitsIn);
bitsOutPerTime = BitsPerTime(&bitsOut);
// debug stuff // if (bPacketDumpMode)
// Log(TEXT("BitsIn: %u, BitsOut: %u"), BitsPerTime(&bitsIn, t), BitsPerTime(&bitsOut, t));
if(bPacketDumpMode && (bitsInPerTime <= bitsOutPerTime))
{
bPacketDumpMode = false;
bDroppingPFrames = false;
}
bool bAddPacket = false;
if(type >= packetWaitType)
@ -168,11 +171,10 @@ void RTMPPublisher::SendPacket(BYTE *data, UINT size, DWORD timestamp, PacketTyp
packetWaitType = (bPacketDumpMode) ? PacketType_VideoLow : PacketType_VideoDisposable;
if(type <= PacketType_VideoHigh)
{
AddBits(&bitsIn, size*8, OSGetTime());
bitsQueued += size*8;
{
AddBits(&bitsIn, size*8, OSGetTime());
numVideoPackets++;
}
}
}
bAddPacket = true;
@ -185,38 +187,46 @@ void RTMPPublisher::SendPacket(BYTE *data, UINT size, DWORD timestamp, PacketTyp
netPacket.timestamp = timestamp;
netPacket.data.TransferFrom(paddedData);
//begin dumping b frames if there's signs of lag
if (bitsQueued > sendBuffer.Num()*8 &&
//bitsQueued > maxBitRate*125 && bitsQueued > bitsInPerTime)
bitsQueued > bitsInPerTime)
{
if(bitsInPerTime > bitsOutPerTime)
{
if(!bPacketDumpMode)
{
bPacketDumpMode = true;
if(packetWaitType == PacketType_VideoDisposable)
packetWaitType = PacketType_VideoLow;
}
DumpBFrame();
}
bitsQueued += netPacket.data.Num()*8;
Log(TEXT("bitsQueued: %u"), bitsQueued);
//begin dumping p frames if b frames aren't enough
if (bitsQueued > sendBuffer.Num()*8 &&
bitsInPerTime > bitsOutPerTime*2 && numVideoPacketsBuffered) // TODO: Tweak this
UINT maxVidyaPackets = App->GetFPS()/10;
//begin dumping b frames if there's signs of lag
if (bitsQueued > sendBuffer.Num()*8 &&
bitsQueued > bitsInPerTime &&
numVideoPackets > maxVidyaPackets)
{
if(bitsInPerTime > bitsOutPerTime)
{
DoIFrameDelay();
if(!bPacketDumpMode)
{
bPacketDumpMode = true;
if(packetWaitType == PacketType_VideoDisposable)
packetWaitType = PacketType_VideoLow;
}
DumpBFrame();
if(packetWaitType >= PacketType_VideoHigh)
bDroppingPFrames = true;
}
}
//begin dumping p frames if b frames aren't enough
if (bitsInPerTime > bitsOutPerTime*13/10 && numVideoPacketsBuffered) // TODO: Tweak this
{
DoIFrameDelay();
bDroppingPFrames = true;
}
}
//-----------------
ReleaseSemaphore(hSendSempahore, 1, NULL);
}
else
{
AddBits(&bitsOut, size*8, OSGetTime());
bitsQueued -= size*8;
{
AddBits(&bitsOut, size*8, OSGetTime());
//bitsQueued -= size*8;
numBFramesDumped++;
}
@ -322,12 +332,12 @@ void RTMPPublisher::BeginPublishing()
double RTMPPublisher::GetPacketStrain() const
{
double dBitsIn = double(bitsInPerTime);
double dBitsOut = double(bitsOutPerTime);
double val = (dBitsIn-dBitsOut)/dBitsOut*100.0;
if(val < 0.0) val = 0.0;
else if(val > 1.0) val = 1.0;
return val*val;
if(bDroppingPFrames)
return 100.0f;
else if(bPacketDumpMode)
return 50.f;
return 0.0f;
}
QWORD RTMPPublisher::GetCurrentSentBytes()
@ -387,11 +397,12 @@ void RTMPPublisher::SendLoop()
Packets.Remove(0);
if(type <= PacketType_VideoHigh)
{
AddBits(&bitsOut, packetData.Num()*8, OSGetTime());
bitsQueued -= packetData.Num()*8;
{
AddBits(&bitsOut, packetData.Num()*8, OSGetTime());
numVideoPackets--;
}
}
bitsQueued -= packetData.Num()*8;
Log(TEXT("bitsQueued: %u"), bitsQueued);
OSLeaveMutex(hDataMutex);
//--------------------------------------------
@ -488,11 +499,16 @@ void RTMPPublisher::DoIFrameDelay()
{
NetworkPacket &bestPacket = Packets[bestItem];
AddBits(&bitsOut, bestPacket.data.Num()*8, OSGetTime());
bitsQueued -= bestPacket.data.Num()*8;
AddBits(&bitsOut, bestPacket.data.Num()*8, OSGetTime());
bitsQueued -= bestPacket.data.Num()*8;
Log(TEXT("bitsQueued: %u"), bitsQueued);
bestPacket.data.Clear();
Packets.Remove(bestItem);
numVideoPackets--;
if(bestPacket.type >= PacketType_VideoHigh)
numPFramesDumped++;
else
numBFramesDumped++;
//disposing P-frames will corrupt the rest of the frame group, so you have to wait until another I-frame
if(!bFoundIFrame || !bFoundFrameBeforeIFrame)
@ -522,22 +538,30 @@ void RTMPPublisher::DoIFrameDelay()
}
else //clear out following dependent packets of lower priority
{
AddBits(&bitsOut, packet.data.Num()*8, OSGetTime());
bitsQueued -= packet.data.Num()*8;
AddBits(&bitsOut, packet.data.Num()*8, OSGetTime());
bitsQueued -= packet.data.Num()*8;
Log(TEXT("bitsQueued: %u"), bitsQueued);
packet.data.Clear();
Packets.Remove(i--);
numVideoPackets--;
numPFramesDumped++;
if(packet.type >= PacketType_VideoHigh)
numPFramesDumped++;
else
numBFramesDumped++;
}
}
else if(packet.type == packetWaitType)
{
AddBits(&bitsOut, packet.data.Num()*8, OSGetTime());
bitsQueued -= packet.data.Num()*8;
AddBits(&bitsOut, packet.data.Num()*8, OSGetTime());
bitsQueued -= packet.data.Num()*8;
Log(TEXT("bitsQueued: %u"), bitsQueued);
packet.data.Clear();
Packets.Remove(i--);
numVideoPackets--;
numPFramesDumped++;
if(packet.type >= PacketType_VideoHigh)
numPFramesDumped++;
else
numBFramesDumped++;
bRemovedPacket = true;
}
@ -574,8 +598,9 @@ void RTMPPublisher::DumpBFrame()
}
else //clear out following dependent packets of lower priority
{
AddBits(&bitsOut, packet.data.Num()*8, OSGetTime());
bitsQueued -= packet.data.Num()*8;
AddBits(&bitsOut, packet.data.Num()*8, OSGetTime());
bitsQueued -= packet.data.Num()*8;
Log(TEXT("bitsQueued: %u"), bitsQueued);
packet.data.Clear();
Packets.Remove(i--);
numBFramesDumped++;
@ -584,8 +609,9 @@ void RTMPPublisher::DumpBFrame()
}
else if(packet.type == packetWaitType)
{
AddBits(&bitsOut, packet.data.Num()*8, OSGetTime());
bitsQueued -= packet.data.Num()*8;
AddBits(&bitsOut, packet.data.Num()*8, OSGetTime());
bitsQueued -= packet.data.Num()*8;
Log(TEXT("bitsQueued: %u"), bitsQueued);
packet.data.Clear();
Packets.Remove(i--);
numBFramesDumped++;

View File

@ -26,8 +26,8 @@ struct NetworkPacket
struct BitRecord
{
UINT bits;
DWORD timestamp;
UINT bits;
DWORD timestamp;
};
//max latency in milliseconds allowed when using the send buffer
@ -48,11 +48,11 @@ protected:
int packetWaitType;
List<NetworkPacket> Packets;
List<BitRecord> bitsIn, bitsOut;
UINT bitsInPerTime, bitsOutPerTime, bitsQueued;
List<BitRecord> bitsIn, bitsOut;
UINT bitsInPerTime, bitsOutPerTime, bitsQueued;
UINT numVideoPackets;
UINT maxBitRate, bufferSize, bufferTime;
UINT maxBitRate, bufferSize, bufferTime;
QWORD bytesSent;
@ -62,7 +62,7 @@ protected:
UINT numVideoPacketsBuffered;
DWORD firstBufferedVideoFrameTimestamp;
bool bPacketDumpMode;
bool bPacketDumpMode, bDroppingPFrames;
BOOL bUseSendBuffer;
@ -75,8 +75,8 @@ protected:
static DWORD SendThread(RTMPPublisher *publisher);
void DoIFrameDelay();
void DumpBFrame();
UINT BitsPerTime(List<BitRecord> *list);
void AddBits(List<BitRecord> *list, UINT bits, DWORD timestamp);
UINT BitsPerTime(List<BitRecord> *list);
void AddBits(List<BitRecord> *list, UINT bits, DWORD timestamp);
int FlushSendBuffer();
static int BufferedSend(RTMPSockBuf *sb, const char *buf, int len, RTMPPublisher *network);

View File

@ -33,7 +33,7 @@
//just so you know, I'm fairly disgusted with all this stuff.
//librtmp is a nice library, but they really need to work on making things function more.. cleanly.
#define SAVC(x) static const AVal av_##x = AVC(#x)
#define SAVC(x) static const AVal av_##x = AVC(#x)
#define STR2AVAL(av,str) av.av_val = str; av.av_len = (int)strlen(av.av_val)
SAVC(app);

View File

@ -45,9 +45,9 @@ float ToggleVolumeControlMute(HWND hwnd)
if(!control)
CrashError(TEXT("ToggleVolumeControlMute called on a control that's not a volume control"));
if(control->curVolume < EPSILON)
if(control->curVolume < 0.05f)
{
if(control->lastUnmutedVol < EPSILON)
if(control->lastUnmutedVol < 0.05f)
control->lastUnmutedVol = 1.0f;
control->curVolume = control->lastUnmutedVol;
}
@ -165,9 +165,9 @@ LRESULT CALLBACK VolumeControlProc(HWND hwnd, UINT message, WPARAM wParam, LPARA
{
if(control->cy == 32 && x >= (control->cx-32))
{
if(control->curVolume < EPSILON)
if(control->curVolume < 0.05f)
{
if(control->lastUnmutedVol < EPSILON)
if(control->lastUnmutedVol < 0.05f)
control->lastUnmutedVol = 1.0f;
control->curVolume = control->lastUnmutedVol;
}
@ -184,7 +184,7 @@ LRESULT CALLBACK VolumeControlProc(HWND hwnd, UINT message, WPARAM wParam, LPARA
SetCapture(hwnd);
control->bHasCapture = true;
if(control->curVolume > EPSILON)
if(control->curVolume > 0.05f)
control->lastUnmutedVol = control->curVolume;
int cxAdjust = control->cx;
@ -246,7 +246,7 @@ LRESULT CALLBACK VolumeControlProc(HWND hwnd, UINT message, WPARAM wParam, LPARA
if(control->bDisabled)
{
if(control->curVolume > EPSILON)
if(control->curVolume > 0.05f)
{
control->lastUnmutedVol = control->curVolume;
control->curVolume = 0.0f;
@ -255,7 +255,7 @@ LRESULT CALLBACK VolumeControlProc(HWND hwnd, UINT message, WPARAM wParam, LPARA
}
else
{
if(control->curVolume < EPSILON)
if(control->curVolume < 0.05f)
{
control->curVolume = control->lastUnmutedVol;
SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(id, VOLN_ADJUSTING), (LPARAM)hwnd);
@ -348,7 +348,7 @@ void VolumeControlData::DrawVolumeControl(HDC hDC)
}
if(bDrawIcon)
DrawIcon(hdcTemp, cx-32, 0, (visualVolume > EPSILON) ? hiconPlay : hiconMute);
DrawIcon(hdcTemp, cx-32, 0, (visualVolume > 0.05f) ? hiconPlay : hiconMute);
}
BitBlt(hDC, 0, 0, cx, cy, hdcTemp, 0, 0, SRCCOPY);

File diff suppressed because it is too large Load Diff

View File

@ -28,41 +28,41 @@ typedef int BOOL;
extern "C"
{
#endif
/* Error return values
/* Error return values
*/
typedef enum {
GIF_WORKING = 1,
GIF_OK = 0,
GIF_INSUFFICIENT_FRAME_DATA = -1,
GIF_FRAME_DATA_ERROR = -2,
GIF_INSUFFICIENT_DATA = -3,
GIF_DATA_ERROR = -4,
GIF_INSUFFICIENT_MEMORY = -5,
GIF_FRAME_NO_DISPLAY = -6,
GIF_END_OF_FRAME = -7
GIF_WORKING = 1,
GIF_OK = 0,
GIF_INSUFFICIENT_FRAME_DATA = -1,
GIF_FRAME_DATA_ERROR = -2,
GIF_INSUFFICIENT_DATA = -3,
GIF_DATA_ERROR = -4,
GIF_INSUFFICIENT_MEMORY = -5,
GIF_FRAME_NO_DISPLAY = -6,
GIF_END_OF_FRAME = -7
} gif_result;
/* The GIF frame data
/* The GIF frame data
*/
typedef struct gif_frame {
BOOL display; /**< whether the frame should be displayed/animated */
unsigned int frame_delay; /**< delay (in 100th second intervals) before animating the frame */
/** Internal members are listed below
*/
unsigned int frame_pointer; /**< offset (in bytes) to the GIF frame data */
BOOL virgin; /**< whether the frame has previously been used */
BOOL opaque; /**< whether the frame is totally opaque */
BOOL redraw_required; /**< whether a forcable screen redraw is required */
unsigned char disposal_method; /**< how the previous frame should be disposed; affects plotting */
BOOL transparency; /**< whether we acknoledge transparency */
unsigned char transparency_index; /**< the index designating a transparent pixel */
unsigned int redraw_x; /**< x co-ordinate of redraw rectangle */
unsigned int redraw_y; /**< y co-ordinate of redraw rectangle */
unsigned int redraw_width; /**< width of redraw rectangle */
unsigned int redraw_height; /**< height of redraw rectangle */
BOOL display; /**< whether the frame should be displayed/animated */
unsigned int frame_delay; /**< delay (in 100th second intervals) before animating the frame */
/** Internal members are listed below
*/
unsigned int frame_pointer; /**< offset (in bytes) to the GIF frame data */
BOOL virgin; /**< whether the frame has previously been used */
BOOL opaque; /**< whether the frame is totally opaque */
BOOL redraw_required; /**< whether a forcable screen redraw is required */
unsigned char disposal_method; /**< how the previous frame should be disposed; affects plotting */
BOOL transparency; /**< whether we acknoledge transparency */
unsigned char transparency_index; /**< the index designating a transparent pixel */
unsigned int redraw_x; /**< x co-ordinate of redraw rectangle */
unsigned int redraw_y; /**< y co-ordinate of redraw rectangle */
unsigned int redraw_width; /**< width of redraw rectangle */
unsigned int redraw_height; /**< height of redraw rectangle */
} gif_frame;
/* API for Bitmap callbacks
/* API for Bitmap callbacks
*/
typedef void* (*gif_bitmap_cb_create)(int width, int height);
typedef void (*gif_bitmap_cb_destroy)(void *bitmap);
@ -71,44 +71,44 @@ typedef void (*gif_bitmap_cb_set_opaque)(void *bitmap, BOOL opaque);
typedef BOOL (*gif_bitmap_cb_test_opaque)(void *bitmap);
typedef void (*gif_bitmap_cb_modified)(void *bitmap);
/* The Bitmap callbacks function table
/* The Bitmap callbacks function table
*/
typedef struct gif_bitmap_callback_vt {
gif_bitmap_cb_create bitmap_create; /**< Create a bitmap. */
gif_bitmap_cb_destroy bitmap_destroy; /**< Free a bitmap. */
gif_bitmap_cb_get_buffer bitmap_get_buffer; /**< Return a pointer to the pixel data in a bitmap. */
/** Members below are optional
*/
gif_bitmap_cb_set_opaque bitmap_set_opaque; /**< Sets whether a bitmap should be plotted opaque. */
gif_bitmap_cb_test_opaque bitmap_test_opaque; /**< Tests whether a bitmap has an opaque alpha channel. */
gif_bitmap_cb_modified bitmap_modified; /**< The bitmap image has changed, so flush any persistant cache. */
gif_bitmap_cb_create bitmap_create; /**< Create a bitmap. */
gif_bitmap_cb_destroy bitmap_destroy; /**< Free a bitmap. */
gif_bitmap_cb_get_buffer bitmap_get_buffer; /**< Return a pointer to the pixel data in a bitmap. */
/** Members below are optional
*/
gif_bitmap_cb_set_opaque bitmap_set_opaque; /**< Sets whether a bitmap should be plotted opaque. */
gif_bitmap_cb_test_opaque bitmap_test_opaque; /**< Tests whether a bitmap has an opaque alpha channel. */
gif_bitmap_cb_modified bitmap_modified; /**< The bitmap image has changed, so flush any persistant cache. */
} gif_bitmap_callback_vt;
/* The GIF animation data
/* The GIF animation data
*/
typedef struct gif_animation {
gif_bitmap_callback_vt bitmap_callbacks; /**< callbacks for bitmap functions */
unsigned char *gif_data; /**< pointer to GIF data */
unsigned int width; /**< width of GIF (may increase during decoding) */
unsigned int height; /**< heigth of GIF (may increase during decoding) */
unsigned int frame_count; /**< number of frames decoded */
unsigned int frame_count_partial; /**< number of frames partially decoded */
gif_frame *frames; /**< decoded frames */
int decoded_frame; /**< current frame decoded to bitmap */
void *frame_image; /**< currently decoded image; stored as bitmap from bitmap_create callback */
int loop_count; /**< number of times to loop animation */
gif_result current_error; /**< current error type, or 0 for none*/
/** Internal members are listed below
*/
unsigned int buffer_position; /**< current index into GIF data */
unsigned int buffer_size; /**< total number of bytes of GIF data available */
unsigned int frame_holders; /**< current number of frame holders */
unsigned int background_index; /**< index in the colour table for the background colour */
unsigned int aspect_ratio; /**< image aspect ratio (ignored) */
unsigned int colour_table_size; /**< size of colour table (in entries) */
BOOL global_colours; /**< whether the GIF has a global colour table */
unsigned int *global_colour_table; /**< global colour table */
unsigned int *local_colour_table; /**< local colour table */
gif_bitmap_callback_vt bitmap_callbacks; /**< callbacks for bitmap functions */
unsigned char *gif_data; /**< pointer to GIF data */
unsigned int width; /**< width of GIF (may increase during decoding) */
unsigned int height; /**< heigth of GIF (may increase during decoding) */
unsigned int frame_count; /**< number of frames decoded */
unsigned int frame_count_partial; /**< number of frames partially decoded */
gif_frame *frames; /**< decoded frames */
int decoded_frame; /**< current frame decoded to bitmap */
void *frame_image; /**< currently decoded image; stored as bitmap from bitmap_create callback */
int loop_count; /**< number of times to loop animation */
gif_result current_error; /**< current error type, or 0 for none*/
/** Internal members are listed below
*/
unsigned int buffer_position; /**< current index into GIF data */
unsigned int buffer_size; /**< total number of bytes of GIF data available */
unsigned int frame_holders; /**< current number of frame holders */
unsigned int background_index; /**< index in the colour table for the background colour */
unsigned int aspect_ratio; /**< image aspect ratio (ignored) */
unsigned int colour_table_size; /**< size of colour table (in entries) */
BOOL global_colours; /**< whether the GIF has a global colour table */
unsigned int *global_colour_table; /**< global colour table */
unsigned int *local_colour_table; /**< local colour table */
} gif_animation;
void gif_create(gif_animation *gif, gif_bitmap_callback_vt *bitmap_callbacks);

View File

@ -192,8 +192,8 @@
#define IDC_DELAY_STATIC 1126
#define IDC_ITALIC 1127
#define IDC_TIMELEFT 1127
#define IDC_CHECK3 1128
#define IDC_UNLOCKHIGHFPS 1128
#define IDC_CANCEL 1130
#define IDA_SOURCE_MOVEUP 40018
#define IDA_SOURCE_MOVEDOWN 40019
#define IDA_SOURCE_MOVETOTOP 40020
@ -224,7 +224,7 @@
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 141
#define _APS_NEXT_COMMAND_VALUE 40044
#define _APS_NEXT_CONTROL_VALUE 1129
#define _APS_NEXT_CONTROL_VALUE 1132
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@ -144,7 +144,7 @@ Settings.Publish.AutoReconnect "Auto-Reconnect:"
Settings.Publish.AutoReconnectTimeout "Auto-Reconnect Timeout:"
Settings.Publish.ChannelName "Channel Name:"
Settings.Publish.DashboardLink "Dashboard Link (if any):"
Settings.Publish.Delay "Delay:"
Settings.Publish.Delay "Delay (seconds):"
Settings.Publish.Mode "Mode:"
Settings.Publish.Password "Password (if any):"
Settings.Publish.Playpath "Play Path/Stream Key (if any):"
@ -168,18 +168,18 @@ Settings.Video.FPS "FPS:"
Settings.Video.Monitor "Monitor:"
Settings.Video.Resolution "Base Resolution:"
Sources.BitmapSource "Bitmap"
Sources.GameCaptureSource "Game Capture Source [experimental]"
Sources.BitmapSource "Image"
Sources.GameCaptureSource "Game Capture [experimental]"
Sources.GlobalSource "Global Source"
Sources.SoftwareCaptureSource "Software Capture Source"
Sources.TextSource "Text Source"
Sources.SoftwareCaptureSource "Software Capture"
Sources.TextSource "Text"
Sources.TransitionSource "Image Slide Show"
Sources.BitmapSource.Color "Color:"
Sources.BitmapSource.Empty "No bitmap entered. Please browse and select a bitmap"
Sources.BitmapSource.Opacity "Opacity:"
Sources.GameCaptureSource.Application "Applcation:"
Sources.GameCaptureSource.Application "Application:"
Sources.GameCaptureSource.PluginDescription "Captures frames directly from games and graphics applications by hooking into the application and reading the frames as they come in."
Sources.GameCaptureSource.PluginName "Game Capture Plugin"
Sources.GameCaptureSource.StretchToScreen "Stretch image to screen"