added CTS padding, fixed graphics capture memory leak, fixed graphics capture crash
This commit is contained in:
parent
30fab1a6b7
commit
cb2a91d3be
23
ChangeLog
23
ChangeLog
@ -1,10 +1,31 @@
|
||||
(yyyy-mm-dd)
|
||||
|
||||
-------------------------------
|
||||
2012-11-25 - 0.448 (alpha)
|
||||
* Fixed memory leak caused by the mouse cursor data not being
|
||||
freed
|
||||
* Fixed a potential crash that can happen to both the game and
|
||||
the application in certain cases
|
||||
* Padded CTS values by 75ms to compensate for any negative CTS
|
||||
deviations
|
||||
|
||||
-------------------------------
|
||||
2012-11-23 - 0.447 (alpha)
|
||||
* Changed the game capture cursor to use a regular texture
|
||||
rather than use a GDI texture, GDI texture went screwy
|
||||
on some GPUs, so rendered it to a DIB section instead
|
||||
and just copied the results
|
||||
* More reverts and adjustments with the frame drop code to
|
||||
prevent annoying frame drops, will add new frame drop code
|
||||
later
|
||||
* Fixed a bug in the new librtmp code that would cause it to
|
||||
crash
|
||||
|
||||
-------------------------------
|
||||
2012-11-22 - 0.446 (alpha)
|
||||
* Finally just about completed game capture (wow was that a
|
||||
crazy adventure)
|
||||
* Added GIF supprot to bitmap image source
|
||||
* Added GIF support to bitmap image source
|
||||
* Added stream delay feature
|
||||
* Adde option to allow users to use up to 120 FPS (if they're
|
||||
crazy)
|
||||
|
@ -104,24 +104,31 @@ LRESULT WINAPI GraphicsCaptureSource::ReceiverWindowProc(HWND hwnd, UINT message
|
||||
|
||||
case RECEIVER_NEWCAPTURE:
|
||||
{
|
||||
GraphicsCaptureSource *source = (GraphicsCaptureSource*)GetWindowLongPtr(hwnd, 0);
|
||||
if(source)
|
||||
source->NewCapture((LPVOID)lParam);
|
||||
CaptureWindowData *data = (CaptureWindowData*)GetWindowLongPtr(hwnd, 0);
|
||||
if(data->source)
|
||||
data->source->NewCapture((LPVOID)lParam);
|
||||
}
|
||||
return API->GetMaxFPS();
|
||||
|
||||
case RECEIVER_ENDCAPTURE:
|
||||
{
|
||||
GraphicsCaptureSource *source = (GraphicsCaptureSource*)GetWindowLongPtr(hwnd, 0);
|
||||
if(source)
|
||||
CaptureWindowData *data = (CaptureWindowData*)GetWindowLongPtr(hwnd, 0);
|
||||
if(data->source)
|
||||
{
|
||||
API->EnterSceneMutex();
|
||||
source->EndCapture();
|
||||
data->source->EndCapture();
|
||||
API->LeaveSceneMutex();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_DESTROY:
|
||||
{
|
||||
CaptureWindowData *data = (CaptureWindowData*)GetWindowLongPtr(hwnd, 0);
|
||||
delete data;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return DefWindowProc(hwnd, message, wParam, lParam);
|
||||
}
|
||||
@ -236,7 +243,8 @@ void GraphicsCaptureSource::BeginScene()
|
||||
if(bCaptureMouse && data->GetInt(TEXT("invertMouse")))
|
||||
invertShader = CreatePixelShaderFromFile(TEXT("shaders\\InvertTexture.pShader"));
|
||||
|
||||
hwndReceiver = CreateWindow(RECEIVER_WINDOWCLASS, NULL, 0, 0, 0, 0, 0, 0, 0, hinstMain, this);
|
||||
windowData = new CaptureWindowData(this);
|
||||
hwndReceiver = CreateWindow(RECEIVER_WINDOWCLASS, NULL, 0, 0, 0, 0, 0, 0, 0, hinstMain, windowData);
|
||||
|
||||
AttemptCapture();
|
||||
}
|
||||
@ -326,6 +334,9 @@ void GraphicsCaptureSource::EndScene()
|
||||
hwndSender = NULL;
|
||||
}
|
||||
|
||||
if(windowData)
|
||||
windowData->source = NULL;
|
||||
|
||||
if(hwndReceiver)
|
||||
{
|
||||
DestroyWindow(hwndReceiver);
|
||||
@ -461,6 +472,7 @@ void GraphicsCaptureSource::Render(const Vect2 &pos, const Vect2 &size)
|
||||
else
|
||||
{
|
||||
HICON hIcon = CopyIcon(ci.hCursor);
|
||||
hCurrentCursor = ci.hCursor;
|
||||
|
||||
delete cursorTexture;
|
||||
cursorTexture = NULL;
|
||||
@ -480,6 +492,8 @@ void GraphicsCaptureSource::Render(const Vect2 &pos, const Vect2 &size)
|
||||
cursorTexture = CreateTexture(size, size, GS_BGRA, lpData, FALSE);
|
||||
if(cursorTexture)
|
||||
bMouseCaptured = true;
|
||||
|
||||
Free(lpData);
|
||||
}
|
||||
|
||||
DeleteObject(ii.hbmColor);
|
||||
|
@ -19,8 +19,19 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
class GraphicsCaptureSource;
|
||||
|
||||
struct CaptureWindowData
|
||||
{
|
||||
inline CaptureWindowData(GraphicsCaptureSource *source) : source(source) {}
|
||||
GraphicsCaptureSource *source;
|
||||
};
|
||||
|
||||
|
||||
class GraphicsCaptureSource : public ImageSource
|
||||
{
|
||||
CaptureWindowData *windowData;
|
||||
GraphicsCaptureMethod *capture;
|
||||
UINT cx, cy;
|
||||
|
||||
|
8
OBS.rc
8
OBS.rc
@ -617,8 +617,8 @@ END
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 0,4,4,7
|
||||
PRODUCTVERSION 0,4,4,7
|
||||
FILEVERSION 0,4,4,8
|
||||
PRODUCTVERSION 0,4,4,8
|
||||
FILEFLAGSMASK 0x17L
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@ -634,12 +634,12 @@ BEGIN
|
||||
BLOCK "041104b0"
|
||||
BEGIN
|
||||
VALUE "FileDescription", "Open Broadcaster Software"
|
||||
VALUE "FileVersion", "0, 4, 4, 7"
|
||||
VALUE "FileVersion", "0, 4, 4, 8"
|
||||
VALUE "InternalName", "OBS"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2012"
|
||||
VALUE "OriginalFilename", "OBS.exe"
|
||||
VALUE "ProductName", "Open Broadcaster Software"
|
||||
VALUE "ProductVersion", "0, 4, 4, 7"
|
||||
VALUE "ProductVersion", "0, 4, 4, 8"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
@ -208,6 +208,10 @@ public:
|
||||
int timeOffset = int(INT64(picOut.i_pts+delayTime)-INT64(outputTimestamp));
|
||||
//Log(TEXT("dts: %d, pts: %d, timestamp: %d, offset: %d"), picOut.i_dts, picOut.i_pts, outputTimestamp, timeOffset);
|
||||
|
||||
timeOffset += 75; //100 is negative CTS padding for VFR
|
||||
if(timeOffset < 0) //this is very unlikely with the padding
|
||||
timeOffset = 0;
|
||||
|
||||
timeOffset = htonl(timeOffset);
|
||||
|
||||
BYTE *timeOffsetAddr = ((BYTE*)&timeOffset)+1;
|
||||
@ -233,7 +237,7 @@ public:
|
||||
*(DWORD*)(SEIPacket+5) = htonl(newPayloadSize);
|
||||
mcpy(SEIPacket+9, nal.p_payload+skipBytes, newPayloadSize);
|
||||
}
|
||||
else if(nal.i_type == NAL_SLICE_IDR || nal.i_type == NAL_SLICE)
|
||||
else if(nal.i_type == NAL_SLICE_IDR || nal.i_type == NAL_SLICE /*|| nal.i_type == NAL_SEI*/)
|
||||
{
|
||||
VideoPacket *newPacket = CurrentPackets.CreateNew();
|
||||
|
||||
@ -244,7 +248,7 @@ public:
|
||||
int newPayloadSize = (nal.i_payload-skipBytes);
|
||||
newPacket->Packet.SetSize(9+newPayloadSize);
|
||||
|
||||
newPacket->Packet[0] = ((nal.i_type == NAL_SLICE_IDR) ? 0x17 : 0x27);
|
||||
newPacket->Packet[0] = ((nal.i_type == NAL_SLICE_IDR || nal.i_type == NAL_SEI) ? 0x17 : 0x27);
|
||||
newPacket->Packet[1] = 1;
|
||||
mcpy(newPacket->Packet+2, timeOffsetAddr, 3);
|
||||
*(DWORD*)(newPacket->Packet+5) = htonl(newPayloadSize);
|
||||
@ -302,6 +306,9 @@ public:
|
||||
|
||||
x264_encoder_headers(x264, &nalOut, &nalNum);
|
||||
|
||||
int timeOffset = 0;//htonl(200);
|
||||
BYTE *timeOffsetAddr = ((BYTE*)&timeOffset)+1;
|
||||
|
||||
for(int i=0; i<nalNum; i++)
|
||||
{
|
||||
x264_nal_t &nal = nalOut[i];
|
||||
@ -312,6 +319,7 @@ public:
|
||||
|
||||
headerOut.OutputByte(0x17);
|
||||
headerOut.OutputByte(0);
|
||||
//headerOut.Serialize(timeOffsetAddr, 3);
|
||||
headerOut.OutputByte(0);
|
||||
headerOut.OutputByte(0);
|
||||
headerOut.OutputByte(0);
|
||||
|
@ -481,7 +481,7 @@ public:
|
||||
output.Serialize(IFrameIDs.Array(), IFrameIDs.Num()*sizeof(UINT));
|
||||
PopBox(); //stss
|
||||
PushBox(output, DWORD_BE('ctts')); //list of composition time offsets
|
||||
output.OutputDword(DWORD_BE(0x01000000)); //version (1) and flags (none)
|
||||
output.OutputDword(0); //version (0) and flags (none)
|
||||
output.OutputDword(fastHtonl(compositionOffsets.Num()));
|
||||
for(UINT i=0; i<compositionOffsets.Num(); i++)
|
||||
{
|
||||
|
@ -61,8 +61,8 @@ extern ConfigFile *AppConfig;
|
||||
extern OBS *App;
|
||||
extern TCHAR lpAppDataPath[MAX_PATH];
|
||||
|
||||
#define OBS_VERSION 0x000447
|
||||
#define OBS_VERSION_STRING_ANSI "Open Broadcaster Software v0.447a"
|
||||
#define OBS_VERSION 0x000448
|
||||
#define OBS_VERSION_STRING_ANSI "Open Broadcaster Software v0.448a"
|
||||
#define OBS_VERSION_STRING TEXT(OBS_VERSION_STRING_ANSI)
|
||||
|
||||
#define OBS_WINDOW_CLASS TEXT("OBSWindowClass")
|
||||
|
@ -2255,15 +2255,15 @@ void OBS::MainCaptureLoop()
|
||||
if(pendingAudioFrames.Num())
|
||||
{
|
||||
//Log(TEXT("pending frames %u, (in milliseconds): %u"), pendingAudioFrames.Num(), pendingAudioFrames.Last().timestamp-pendingAudioFrames[0].timestamp);
|
||||
while(pendingAudioFrames.Num() && pendingAudioFrames[0].timestamp < curTimeStamp)
|
||||
while(pendingAudioFrames.Num() && pendingAudioFrames[0].timestamp+75 < curTimeStamp)
|
||||
{
|
||||
List<BYTE> &audioData = pendingAudioFrames[0].audioData;
|
||||
|
||||
if(audioData.Num())
|
||||
{
|
||||
network->SendPacket(audioData.Array(), audioData.Num(), pendingAudioFrames[0].timestamp, PacketType_Audio);
|
||||
network->SendPacket(audioData.Array(), audioData.Num(), pendingAudioFrames[0].timestamp+75, PacketType_Audio);
|
||||
if(fileStream)
|
||||
fileStream->AddPacket(audioData.Array(), audioData.Num(), pendingAudioFrames[0].timestamp, PacketType_Audio);
|
||||
fileStream->AddPacket(audioData.Array(), audioData.Num(), pendingAudioFrames[0].timestamp+75, PacketType_Audio);
|
||||
|
||||
audioData.Clear();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user