Browse Source

Updated win32 CameraDevice to record as wmv.

tags/2021-05-28
Julian Storer 15 years ago
parent
commit
bb524846cb
7 changed files with 100 additions and 105 deletions
  1. +4
    -0
      build/macosx/Juce.xcodeproj/project.pbxproj
  2. +45
    -50
      juce_amalgamated.cpp
  3. +2
    -1
      juce_amalgamated.h
  4. +1
    -1
      src/core/juce_StandardHeader.h
  5. +1
    -0
      src/native/windows/juce_win32_AutoLinkLibraries.h
  6. +43
    -50
      src/native/windows/juce_win32_CameraDevice.cpp
  7. +4
    -3
      src/native/windows/juce_win32_NativeIncludes.h

+ 4
- 0
build/macosx/Juce.xcodeproj/project.pbxproj View File

@@ -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;
};


+ 45
- 50
juce_amalgamated.cpp View File

@@ -396,6 +396,7 @@

#include <dshow.h>
#include <qedit.h>
#include <dshowasf.h>
#endif

#if JUCE_WASAPI
@@ -227419,11 +227420,8 @@ public:
{
ComSmartPtr <IAMStreamConfig> 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 <IFileSinkFilter> 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 <IFileSinkFilter> 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 <IConfigAsfWriter> asfConfig;
hr = asfWriter->QueryInterface (IID_IConfigAsfWriter, (void**) &asfConfig);
asfConfig->SetIndexMode (true);
ComSmartPtr <IWMProfileManager> profileManager;
hr = WMCreateProfileManager (&profileManager);

// This gibberish is the DirectShow profile for a video-only wmv file.
String prof ("<profile version=\"589824\" storageformat=\"1\" name=\"Quality\" description=\"Quality type for output.\"><streamconfig "
"majortype=\"{73646976-0000-0010-8000-00AA00389B71}\" streamnumber=\"1\" streamname=\"Video Stream\" inputname=\"Video409\" bitrate=\"894960\" "
"bufferwindow=\"0\" reliabletransport=\"1\" decodercomplexity=\"AU\" rfc1766langid=\"en-us\"><videomediaprops maxkeyframespacing=\"50000000\" quality=\"90\"/>"
"<wmmediatype subtype=\"{33564D57-0000-0010-8000-00AA00389B71}\" bfixedsizesamples=\"0\" btemporalcompression=\"1\" lsamplesize=\"0\"> <videoinfoheader "
"dwbitrate=\"894960\" dwbiterrorrate=\"0\" avgtimeperframe=\"100000\"><rcsource left=\"0\" top=\"0\" right=\"$WIDTH\" bottom=\"$HEIGHT\"/> <rctarget "
"left=\"0\" top=\"0\" right=\"$WIDTH\" bottom=\"$HEIGHT\"/> <bitmapinfoheader biwidth=\"$WIDTH\" biheight=\"$HEIGHT\" biplanes=\"1\" bibitcount=\"24\" "
"bicompression=\"WMV3\" bisizeimage=\"0\" bixpelspermeter=\"0\" biypelspermeter=\"0\" biclrused=\"0\" biclrimportant=\"0\"/> "
"</videoinfoheader></wmmediatype></streamconfig></profile>");

prof = prof.replace (T("$WIDTH"), String (width))
.replace (T("$HEIGHT"), String (height));

ComSmartPtr <IWMProfile> currentProfile;
hr = profileManager->LoadProfileByData ((const WCHAR*) prof, &currentProfile);
hr = asfConfig->ConfigureFilterUsingProfile (currentProfile);

if (SUCCEEDED (hr))
{
hr = graphBuilder->AddFilter (fileWriter, _T("File Writer"));
ComSmartPtr <IPin> asfWriterInputPin;

if (SUCCEEDED (hr))
if (getPin (asfWriter, PINDIR_INPUT, &asfWriterInputPin, "Video Input 01"))
{
ComSmartPtr <IPin> 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 <IMediaControl> mediaControl;
ComSmartPtr <IPin> smartTeePreviewOutputPin;
ComSmartPtr <IPin> smartTeeCaptureOutputPin;
ComSmartPtr <IBaseFilter> mux, fileWriter;
ComSmartPtr <IBaseFilter> asfWriter;
int activeUsers;
Array <int> 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 ***/



+ 2
- 1
juce_amalgamated.h View File

@@ -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 ***/



+ 1
- 1
src/core/juce_StandardHeader.h View File

@@ -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.


+ 1
- 0
src/native/windows/juce_win32_AutoLinkLibraries.h View File

@@ -26,4 +26,5 @@
#if JUCE_USE_CAMERA
#pragma comment (lib, "Strmiids.lib")
#pragma comment (lib, "wmvcore.lib")
#endif

+ 43
- 50
src/native/windows/juce_win32_CameraDevice.cpp View File

@@ -64,11 +64,8 @@ public:
{
ComSmartPtr <IAMStreamConfig> 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 <IFileSinkFilter> 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 <IFileSinkFilter> 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 <IConfigAsfWriter> asfConfig;
hr = asfWriter->QueryInterface (IID_IConfigAsfWriter, (void**) &asfConfig);
asfConfig->SetIndexMode (true);
ComSmartPtr <IWMProfileManager> profileManager;
hr = WMCreateProfileManager (&profileManager);
// This gibberish is the DirectShow profile for a video-only wmv file.
String prof ("<profile version=\"589824\" storageformat=\"1\" name=\"Quality\" description=\"Quality type for output.\"><streamconfig "
"majortype=\"{73646976-0000-0010-8000-00AA00389B71}\" streamnumber=\"1\" streamname=\"Video Stream\" inputname=\"Video409\" bitrate=\"894960\" "
"bufferwindow=\"0\" reliabletransport=\"1\" decodercomplexity=\"AU\" rfc1766langid=\"en-us\"><videomediaprops maxkeyframespacing=\"50000000\" quality=\"90\"/>"
"<wmmediatype subtype=\"{33564D57-0000-0010-8000-00AA00389B71}\" bfixedsizesamples=\"0\" btemporalcompression=\"1\" lsamplesize=\"0\"> <videoinfoheader "
"dwbitrate=\"894960\" dwbiterrorrate=\"0\" avgtimeperframe=\"100000\"><rcsource left=\"0\" top=\"0\" right=\"$WIDTH\" bottom=\"$HEIGHT\"/> <rctarget "
"left=\"0\" top=\"0\" right=\"$WIDTH\" bottom=\"$HEIGHT\"/> <bitmapinfoheader biwidth=\"$WIDTH\" biheight=\"$HEIGHT\" biplanes=\"1\" bibitcount=\"24\" "
"bicompression=\"WMV3\" bisizeimage=\"0\" bixpelspermeter=\"0\" biypelspermeter=\"0\" biclrused=\"0\" biclrimportant=\"0\"/> "
"</videoinfoheader></wmmediatype></streamconfig></profile>");
prof = prof.replace (T("$WIDTH"), String (width))
.replace (T("$HEIGHT"), String (height));
ComSmartPtr <IWMProfile> currentProfile;
hr = profileManager->LoadProfileByData ((const WCHAR*) prof, &currentProfile);
hr = asfConfig->ConfigureFilterUsingProfile (currentProfile);
if (SUCCEEDED (hr))
{
hr = graphBuilder->AddFilter (fileWriter, _T("File Writer"));
ComSmartPtr <IPin> asfWriterInputPin;
if (SUCCEEDED (hr))
if (getPin (asfWriter, PINDIR_INPUT, &asfWriterInputPin, "Video Input 01"))
{
ComSmartPtr <IPin> 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 <IMediaControl> mediaControl;
ComSmartPtr <IPin> smartTeePreviewOutputPin;
ComSmartPtr <IPin> smartTeeCaptureOutputPin;
ComSmartPtr <IBaseFilter> mux, fileWriter;
ComSmartPtr <IBaseFilter> asfWriter;
int activeUsers;
Array <int> 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();


+ 4
- 3
src/native/windows/juce_win32_NativeIncludes.h View File

@@ -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 <dshow.h>
#include <qedit.h>
#include <dshowasf.h>
#endif
//==============================================================================


Loading…
Cancel
Save