1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-27 02:20:05 +00:00

Updated win32 CameraDevice to record as wmv.

This commit is contained in:
Julian Storer 2010-02-24 19:57:34 +00:00
parent 187173da62
commit bb524846cb
7 changed files with 100 additions and 105 deletions

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

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

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

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.

View file

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

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)
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)
@ -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();

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
//==============================================================================