diff --git a/ChangeLog b/ChangeLog index cca48672..a34ed7fe 100644 --- a/ChangeLog +++ b/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) diff --git a/GraphicsCapture/GraphicsCaptureSource.cpp b/GraphicsCapture/GraphicsCaptureSource.cpp index 35ad73a2..a8149573 100644 --- a/GraphicsCapture/GraphicsCaptureSource.cpp +++ b/GraphicsCapture/GraphicsCaptureSource.cpp @@ -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); diff --git a/GraphicsCapture/GraphicsCaptureSource.h b/GraphicsCapture/GraphicsCaptureSource.h index ff22a442..85e8d128 100644 --- a/GraphicsCapture/GraphicsCaptureSource.h +++ b/GraphicsCapture/GraphicsCaptureSource.h @@ -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; diff --git a/OBS.rc b/OBS.rc index 316096af..b0f7361f 100644 --- a/OBS.rc +++ b/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" diff --git a/Source/Encoder_x264.cpp b/Source/Encoder_x264.cpp index da6138fb..4a154024 100644 --- a/Source/Encoder_x264.cpp +++ b/Source/Encoder_x264.cpp @@ -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 &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(); }