From bb524846cb80b607ffd98b788a811258d44af5fd Mon Sep 17 00:00:00 2001 From: Julian Storer Date: Wed, 24 Feb 2010 19:57:34 +0000 Subject: [PATCH] Updated win32 CameraDevice to record as wmv. --- build/macosx/Juce.xcodeproj/project.pbxproj | 4 + juce_amalgamated.cpp | 95 +++++++++---------- juce_amalgamated.h | 3 +- src/core/juce_StandardHeader.h | 2 +- .../windows/juce_win32_AutoLinkLibraries.h | 1 + .../windows/juce_win32_CameraDevice.cpp | 93 +++++++++--------- .../windows/juce_win32_NativeIncludes.h | 7 +- 7 files changed, 100 insertions(+), 105 deletions(-) diff --git a/build/macosx/Juce.xcodeproj/project.pbxproj b/build/macosx/Juce.xcodeproj/project.pbxproj index 4432e18a88..cfca23e227 100644 --- a/build/macosx/Juce.xcodeproj/project.pbxproj +++ b/build/macosx/Juce.xcodeproj/project.pbxproj @@ -669,6 +669,8 @@ 84AF419B10F0008E0035D74F /* juce_ScopedPointer.h in Headers */ = {isa = PBXBuildFile; fileRef = 84AF3FE710EF9FF30035D74F /* juce_ScopedPointer.h */; }; 84B2053E10D535EC008B4A79 /* juce_ValueTree.h in Headers */ = {isa = PBXBuildFile; fileRef = 843D4A3A10D3C54500624BA6 /* juce_ValueTree.h */; }; 84B2053F10D535EC008B4A79 /* juce_ValueTree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 843D4A3910D3C54500624BA6 /* juce_ValueTree.cpp */; }; + 84B56D231135B010004B26F7 /* juce_MouseInputSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84751E591132EE9E00640F9A /* juce_MouseInputSource.cpp */; }; + 84B56D241135B010004B26F7 /* juce_MouseInputSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 84751E5A1132EE9E00640F9A /* juce_MouseInputSource.h */; }; 84BA604010F2017A001D9D70 /* juce_Value.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84BA603E10F2017A001D9D70 /* juce_Value.cpp */; }; 84BA604110F2017A001D9D70 /* juce_Value.h in Headers */ = {isa = PBXBuildFile; fileRef = 84BA603F10F2017A001D9D70 /* juce_Value.h */; }; 84CABF691101292D0088D64D /* juce_TemporaryFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84CABF671101292D0088D64D /* juce_TemporaryFile.cpp */; }; @@ -3258,6 +3260,7 @@ 843E5C72111394A3006F959F /* juce_DynamicObject.h in Headers */, 8473E64B11249FD800D74E02 /* juce_TextInputTarget.h in Headers */, 8473E6541125974600D74E02 /* juce_Range.h in Headers */, + 84B56D241135B010004B26F7 /* juce_MouseInputSource.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3940,6 +3943,7 @@ 84CAC0C0110478D50088D64D /* juce_TemporaryFile.cpp in Sources */, 843E5C6F1113949F006F959F /* juce_NamedValueSet.cpp in Sources */, 843E5C71111394A2006F959F /* juce_DynamicObject.cpp in Sources */, + 84B56D231135B010004B26F7 /* juce_MouseInputSource.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index cf59a0ffaf..6c3cc8b085 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -396,6 +396,7 @@ #include #include + #include #endif #if JUCE_WASAPI @@ -227419,11 +227420,8 @@ public: { ComSmartPtr streamConfig; - hr = captureGraphBuilder->FindInterface (&PIN_CATEGORY_CAPTURE, - 0, - filter, - IID_IAMStreamConfig, - (void**) &streamConfig); + hr = captureGraphBuilder->FindInterface (&PIN_CATEGORY_CAPTURE, 0, filter, + IID_IAMStreamConfig, (void**) &streamConfig); if (streamConfig != 0) { @@ -227521,8 +227519,7 @@ public: smartTee = 0; smartTeePreviewOutputPin = 0; smartTeeCaptureOutputPin = 0; - mux = 0; - fileWriter = 0; + asfWriter = 0; delete activeImage; delete loadingImage; @@ -227618,56 +227615,59 @@ public: firstRecordedTime = Time(); recordNextFrameTime = true; - HRESULT hr = mux.CoCreateInstance (CLSID_AviDest, CLSCTX_INPROC_SERVER); + HRESULT hr = asfWriter.CoCreateInstance (CLSID_WMAsfWriter, CLSCTX_INPROC_SERVER); if (SUCCEEDED (hr)) { - hr = graphBuilder->AddFilter (mux, _T("AVI Mux")); + ComSmartPtr fileSink; + hr = asfWriter->QueryInterface (IID_IFileSinkFilter, (void**) &fileSink); if (SUCCEEDED (hr)) { - hr = fileWriter.CoCreateInstance (CLSID_FileWriter, CLSCTX_INPROC_SERVER); + hr = fileSink->SetFileName (file.getFullPathName(), 0); if (SUCCEEDED (hr)) { - ComSmartPtr fileSink; - hr = fileWriter->QueryInterface (IID_IFileSinkFilter, (void**) &fileSink); + hr = graphBuilder->AddFilter (asfWriter, _T("AsfWriter")); if (SUCCEEDED (hr)) { - AM_MEDIA_TYPE mt; - zerostruct (mt); - mt.majortype = MEDIATYPE_Stream; - mt.subtype = MEDIASUBTYPE_Avi; - mt.formattype = FORMAT_VideoInfo; - hr = fileSink->SetFileName (file.getFullPathName(), &mt); + ComSmartPtr asfConfig; + hr = asfWriter->QueryInterface (IID_IConfigAsfWriter, (void**) &asfConfig); + asfConfig->SetIndexMode (true); + ComSmartPtr profileManager; + hr = WMCreateProfileManager (&profileManager); + + // This gibberish is the DirectShow profile for a video-only wmv file. + String prof ("" + " " + ""); + + prof = prof.replace (T("$WIDTH"), String (width)) + .replace (T("$HEIGHT"), String (height)); + + ComSmartPtr currentProfile; + hr = profileManager->LoadProfileByData ((const WCHAR*) prof, ¤tProfile); + hr = asfConfig->ConfigureFilterUsingProfile (currentProfile); if (SUCCEEDED (hr)) { - hr = graphBuilder->AddFilter (fileWriter, _T("File Writer")); + ComSmartPtr asfWriterInputPin; - if (SUCCEEDED (hr)) + if (getPin (asfWriter, PINDIR_INPUT, &asfWriterInputPin, "Video Input 01")) { - ComSmartPtr muxInputPin, muxOutputPin, writerInput; + hr = graphBuilder->Connect (smartTeeCaptureOutputPin, asfWriterInputPin); - if (getPin (mux, PINDIR_INPUT, &muxInputPin) - && getPin (mux, PINDIR_OUTPUT, &muxOutputPin) - && getPin (fileWriter, PINDIR_INPUT, &writerInput)) + if (SUCCEEDED (hr) + && ok && activeUsers > 0 + && SUCCEEDED (mediaControl->Run())) { - hr = graphBuilder->Connect (smartTeeCaptureOutputPin, muxInputPin); - - if (SUCCEEDED (hr)) - { - hr = graphBuilder->Connect (muxOutputPin, writerInput); - - if (SUCCEEDED (hr)) - { - if (ok && activeUsers > 0) - mediaControl->Run(); - - return true; - } - } + return true; } } } @@ -227688,16 +227688,10 @@ public: { mediaControl->Stop(); - if (mux != 0) + if (asfWriter != 0) { - graphBuilder->RemoveFilter (mux); - mux = 0; - } - - if (fileWriter != 0) - { - graphBuilder->RemoveFilter (fileWriter); - fileWriter = 0; + graphBuilder->RemoveFilter (asfWriter); + asfWriter = 0; } if (ok && activeUsers > 0) @@ -227801,7 +227795,7 @@ private: ComSmartPtr mediaControl; ComSmartPtr smartTeePreviewOutputPin; ComSmartPtr smartTeeCaptureOutputPin; - ComSmartPtr mux, fileWriter; + ComSmartPtr asfWriter; int activeUsers; Array widths, heights; DWORD graphRegistrationID; @@ -228055,10 +228049,10 @@ Component* CameraDevice::createViewerComponent() const String CameraDevice::getFileExtension() { - return ".avi"; + return ".wmv"; } -void CameraDevice::startRecordingToFile (const File& file, int /*quality*/) +void CameraDevice::startRecordingToFile (const File& file, int quality) { stopRecording(); @@ -228240,6 +228234,7 @@ CameraDevice* CameraDevice::openDevice (int index, #if JUCE_USE_CAMERA #pragma comment (lib, "Strmiids.lib") + #pragma comment (lib, "wmvcore.lib") #endif /*** End of inlined file: juce_win32_AutoLinkLibraries.h ***/ diff --git a/juce_amalgamated.h b/juce_amalgamated.h index de9ad27aef..6263e6014e 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -43,7 +43,7 @@ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 51 -#define JUCE_BUILDNUMBER 3 +#define JUCE_BUILDNUMBER 4 #define JUCE_VERSION ((JUCE_MAJOR_VERSION << 16) + (JUCE_MINOR_VERSION << 8) + JUCE_BUILDNUMBER) @@ -28339,6 +28339,7 @@ END_JUCE_NAMESPACE #if JUCE_USE_CAMERA #pragma comment (lib, "Strmiids.lib") + #pragma comment (lib, "wmvcore.lib") #endif /*** End of inlined file: juce_win32_AutoLinkLibraries.h ***/ diff --git a/src/core/juce_StandardHeader.h b/src/core/juce_StandardHeader.h index 179aeeb572..06a2fa539e 100644 --- a/src/core/juce_StandardHeader.h +++ b/src/core/juce_StandardHeader.h @@ -33,7 +33,7 @@ */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 51 -#define JUCE_BUILDNUMBER 3 +#define JUCE_BUILDNUMBER 4 /** Current Juce version number. diff --git a/src/native/windows/juce_win32_AutoLinkLibraries.h b/src/native/windows/juce_win32_AutoLinkLibraries.h index 18e6d51ab5..a2e439861b 100644 --- a/src/native/windows/juce_win32_AutoLinkLibraries.h +++ b/src/native/windows/juce_win32_AutoLinkLibraries.h @@ -26,4 +26,5 @@ #if JUCE_USE_CAMERA #pragma comment (lib, "Strmiids.lib") + #pragma comment (lib, "wmvcore.lib") #endif diff --git a/src/native/windows/juce_win32_CameraDevice.cpp b/src/native/windows/juce_win32_CameraDevice.cpp index fe1cedaf47..b7f7ada39f 100644 --- a/src/native/windows/juce_win32_CameraDevice.cpp +++ b/src/native/windows/juce_win32_CameraDevice.cpp @@ -64,11 +64,8 @@ public: { ComSmartPtr streamConfig; - hr = captureGraphBuilder->FindInterface (&PIN_CATEGORY_CAPTURE, - 0, - filter, - IID_IAMStreamConfig, - (void**) &streamConfig); + hr = captureGraphBuilder->FindInterface (&PIN_CATEGORY_CAPTURE, 0, filter, + IID_IAMStreamConfig, (void**) &streamConfig); if (streamConfig != 0) { @@ -166,8 +163,7 @@ public: smartTee = 0; smartTeePreviewOutputPin = 0; smartTeeCaptureOutputPin = 0; - mux = 0; - fileWriter = 0; + asfWriter = 0; delete activeImage; delete loadingImage; @@ -263,56 +259,59 @@ public: firstRecordedTime = Time(); recordNextFrameTime = true; - HRESULT hr = mux.CoCreateInstance (CLSID_AviDest, CLSCTX_INPROC_SERVER); + HRESULT hr = asfWriter.CoCreateInstance (CLSID_WMAsfWriter, CLSCTX_INPROC_SERVER); if (SUCCEEDED (hr)) { - hr = graphBuilder->AddFilter (mux, _T("AVI Mux")); + ComSmartPtr fileSink; + hr = asfWriter->QueryInterface (IID_IFileSinkFilter, (void**) &fileSink); if (SUCCEEDED (hr)) { - hr = fileWriter.CoCreateInstance (CLSID_FileWriter, CLSCTX_INPROC_SERVER); + hr = fileSink->SetFileName (file.getFullPathName(), 0); if (SUCCEEDED (hr)) { - ComSmartPtr fileSink; - hr = fileWriter->QueryInterface (IID_IFileSinkFilter, (void**) &fileSink); + hr = graphBuilder->AddFilter (asfWriter, _T("AsfWriter")); if (SUCCEEDED (hr)) { - AM_MEDIA_TYPE mt; - zerostruct (mt); - mt.majortype = MEDIATYPE_Stream; - mt.subtype = MEDIASUBTYPE_Avi; - mt.formattype = FORMAT_VideoInfo; - hr = fileSink->SetFileName (file.getFullPathName(), &mt); + ComSmartPtr asfConfig; + hr = asfWriter->QueryInterface (IID_IConfigAsfWriter, (void**) &asfConfig); + asfConfig->SetIndexMode (true); + ComSmartPtr profileManager; + hr = WMCreateProfileManager (&profileManager); + + // This gibberish is the DirectShow profile for a video-only wmv file. + String prof ("" + " " + ""); + + prof = prof.replace (T("$WIDTH"), String (width)) + .replace (T("$HEIGHT"), String (height)); + + ComSmartPtr currentProfile; + hr = profileManager->LoadProfileByData ((const WCHAR*) prof, ¤tProfile); + hr = asfConfig->ConfigureFilterUsingProfile (currentProfile); if (SUCCEEDED (hr)) { - hr = graphBuilder->AddFilter (fileWriter, _T("File Writer")); + ComSmartPtr asfWriterInputPin; - if (SUCCEEDED (hr)) + if (getPin (asfWriter, PINDIR_INPUT, &asfWriterInputPin, "Video Input 01")) { - ComSmartPtr muxInputPin, muxOutputPin, writerInput; + hr = graphBuilder->Connect (smartTeeCaptureOutputPin, asfWriterInputPin); - if (getPin (mux, PINDIR_INPUT, &muxInputPin) - && getPin (mux, PINDIR_OUTPUT, &muxOutputPin) - && getPin (fileWriter, PINDIR_INPUT, &writerInput)) + if (SUCCEEDED (hr) + && ok && activeUsers > 0 + && SUCCEEDED (mediaControl->Run())) { - hr = graphBuilder->Connect (smartTeeCaptureOutputPin, muxInputPin); - - if (SUCCEEDED (hr)) - { - hr = graphBuilder->Connect (muxOutputPin, writerInput); - - if (SUCCEEDED (hr)) - { - if (ok && activeUsers > 0) - mediaControl->Run(); - - return true; - } - } + return true; } } } @@ -333,16 +332,10 @@ public: { mediaControl->Stop(); - if (mux != 0) - { - graphBuilder->RemoveFilter (mux); - mux = 0; - } - - if (fileWriter != 0) + if (asfWriter != 0) { - graphBuilder->RemoveFilter (fileWriter); - fileWriter = 0; + graphBuilder->RemoveFilter (asfWriter); + asfWriter = 0; } if (ok && activeUsers > 0) @@ -450,7 +443,7 @@ private: ComSmartPtr mediaControl; ComSmartPtr smartTeePreviewOutputPin; ComSmartPtr smartTeeCaptureOutputPin; - ComSmartPtr mux, fileWriter; + ComSmartPtr asfWriter; int activeUsers; Array widths, heights; DWORD graphRegistrationID; @@ -709,10 +702,10 @@ Component* CameraDevice::createViewerComponent() const String CameraDevice::getFileExtension() { - return ".avi"; + return ".wmv"; } -void CameraDevice::startRecordingToFile (const File& file, int /*quality*/) +void CameraDevice::startRecordingToFile (const File& file, int quality) { stopRecording(); diff --git a/src/native/windows/juce_win32_NativeIncludes.h b/src/native/windows/juce_win32_NativeIncludes.h index a121da5306..d70850694b 100644 --- a/src/native/windows/juce_win32_NativeIncludes.h +++ b/src/native/windows/juce_win32_NativeIncludes.h @@ -127,14 +127,15 @@ /* If you're using the camera classes, you'll need access to a few DirectShow headers. - Both of these files are provided in the normal Windows SDK, but some Microsoft plonker - didn't realise that qedit.h doesn't actually compile without the rest of the DirectShow SDK! + These files are provided in the normal Windows SDK, but some Microsoft plonker + didn't realise that qedit.h doesn't actually compile without the rest of the DirectShow SDK.. Microsoft's suggested fix for this is to hack their qedit.h file! See: http://social.msdn.microsoft.com/Forums/en-US/windowssdk/thread/ed097d2c-3d68-4f48-8448-277eaaf68252 - .. which is a pathetic bodge, but a lot less hassle than installing the full DShow SDK. + .. which is a bit of a bodge, but a lot less hassle than installing the full DShow SDK. */ #include #include + #include #endif //==============================================================================