mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-02-02 03:20:06 +00:00
Windows: Added ComSmartPtr::getInterface() and used it in a few places to simplify some COM code
This commit is contained in:
parent
99b3d85fcc
commit
54164fac3f
4 changed files with 76 additions and 90 deletions
|
|
@ -362,9 +362,8 @@ String getDeviceID (IMMDevice* device)
|
|||
static EDataFlow getDataFlow (const ComSmartPtr<IMMDevice>& device)
|
||||
{
|
||||
EDataFlow flow = eRender;
|
||||
ComSmartPtr<IMMEndpoint> endPoint;
|
||||
if (check (device.QueryInterface (endPoint)))
|
||||
(void) check (endPoint->GetDataFlow (&flow));
|
||||
if (auto endpoint = device.getInterface<IMMEndpoint>())
|
||||
(void) check (endpoint->GetDataFlow (&flow));
|
||||
|
||||
return flow;
|
||||
}
|
||||
|
|
@ -622,22 +621,12 @@ private:
|
|||
return true;
|
||||
}
|
||||
|
||||
static ComSmartPtr<IAudioClient3> getClientAsVersion3 (ComSmartPtr<IAudioClient>& clientVersion1)
|
||||
{
|
||||
ComSmartPtr<IAudioClient3> newClient;
|
||||
|
||||
if (clientVersion1 != nullptr)
|
||||
clientVersion1.QueryInterface (__uuidof (IAudioClient3), newClient);
|
||||
|
||||
return newClient;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void querySupportedBufferSizes (WAVEFORMATEXTENSIBLE format, ComSmartPtr<IAudioClient>& audioClient)
|
||||
{
|
||||
if (isLowLatencyMode (deviceMode))
|
||||
{
|
||||
if (auto audioClient3 = getClientAsVersion3 (audioClient))
|
||||
if (auto audioClient3 = audioClient.getInterface<IAudioClient3>())
|
||||
{
|
||||
UINT32 defaultPeriod = 0, fundamentalPeriod = 0, minPeriod = 0, maxPeriod = 0;
|
||||
|
||||
|
|
@ -793,7 +782,7 @@ private:
|
|||
|
||||
bool initialiseLowLatencyClient (int bufferSizeSamples, WAVEFORMATEXTENSIBLE format)
|
||||
{
|
||||
if (auto audioClient3 = getClientAsVersion3 (client))
|
||||
if (auto audioClient3 = client.getInterface<IAudioClient3>())
|
||||
return check (audioClient3->InitializeSharedAudioStream (getStreamFlags(),
|
||||
bufferSizeSamples,
|
||||
(WAVEFORMATEX*) &format,
|
||||
|
|
|
|||
|
|
@ -265,32 +265,23 @@ private:
|
|||
|
||||
void scanFileForDetails()
|
||||
{
|
||||
ComSmartPtr<IWMHeaderInfo> wmHeaderInfo;
|
||||
HRESULT hr = wmSyncReader.QueryInterface (wmHeaderInfo);
|
||||
|
||||
if (SUCCEEDED (hr))
|
||||
if (auto wmHeaderInfo = wmSyncReader.getInterface<IWMHeaderInfo>())
|
||||
{
|
||||
QWORD lengthInNanoseconds = 0;
|
||||
WORD lengthOfLength = sizeof (lengthInNanoseconds);
|
||||
WORD streamNum = 0;
|
||||
WMT_ATTR_DATATYPE wmAttrDataType;
|
||||
hr = wmHeaderInfo->GetAttributeByName (&streamNum, L"Duration", &wmAttrDataType,
|
||||
(BYTE*) &lengthInNanoseconds, &lengthOfLength);
|
||||
wmHeaderInfo->GetAttributeByName (&streamNum, L"Duration", &wmAttrDataType,
|
||||
(BYTE*) &lengthInNanoseconds, &lengthOfLength);
|
||||
|
||||
ComSmartPtr<IWMProfile> wmProfile;
|
||||
hr = wmSyncReader.QueryInterface (wmProfile);
|
||||
|
||||
if (SUCCEEDED (hr))
|
||||
if (auto wmProfile = wmSyncReader.getInterface<IWMProfile>())
|
||||
{
|
||||
ComSmartPtr<IWMStreamConfig> wmStreamConfig;
|
||||
hr = wmProfile->GetStream (0, wmStreamConfig.resetAndGetPointerAddress());
|
||||
auto hr = wmProfile->GetStream (0, wmStreamConfig.resetAndGetPointerAddress());
|
||||
|
||||
if (SUCCEEDED (hr))
|
||||
{
|
||||
ComSmartPtr<IWMMediaProps> wmMediaProperties;
|
||||
hr = wmStreamConfig.QueryInterface (wmMediaProperties);
|
||||
|
||||
if (SUCCEEDED (hr))
|
||||
if (auto wmMediaProperties = wmStreamConfig.getInterface<IWMMediaProps>())
|
||||
{
|
||||
DWORD sizeMediaType;
|
||||
hr = wmMediaProperties->GetMediaType (0, &sizeMediaType);
|
||||
|
|
|
|||
|
|
@ -134,6 +134,17 @@ public:
|
|||
return this->QueryInterface (__uuidof (OtherComClass), destObject);
|
||||
}
|
||||
|
||||
template<class OtherComClass>
|
||||
ComSmartPtr<OtherComClass> getInterface() const
|
||||
{
|
||||
ComSmartPtr<OtherComClass> destObject;
|
||||
|
||||
if (QueryInterface (destObject) == S_OK)
|
||||
return destObject;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
ComClass* p = nullptr;
|
||||
|
||||
|
|
|
|||
|
|
@ -69,8 +69,8 @@ struct CameraDevice::Pimpl : public ChangeBroadcaster
|
|||
if (FAILED (hr))
|
||||
return;
|
||||
|
||||
hr = graphBuilder.QueryInterface (mediaControl);
|
||||
if (FAILED (hr))
|
||||
mediaControl = graphBuilder.getInterface<IMediaControl>();
|
||||
if (mediaControl == nullptr)
|
||||
return;
|
||||
|
||||
{
|
||||
|
|
@ -292,13 +292,10 @@ struct CameraDevice::Pimpl : public ChangeBroadcaster
|
|||
ComSmartPtr<IPin> pin;
|
||||
if (getPin (filter, PINDIR_OUTPUT, pin))
|
||||
{
|
||||
ComSmartPtr<IAMPushSource> pushSource;
|
||||
HRESULT hr = pin.QueryInterface (pushSource);
|
||||
|
||||
if (pushSource != nullptr)
|
||||
if (auto pushSource = pin.getInterface<IAMPushSource>())
|
||||
{
|
||||
REFERENCE_TIME latency = 0;
|
||||
hr = pushSource->GetLatency (&latency);
|
||||
pushSource->GetLatency (&latency);
|
||||
|
||||
firstRecordedTime = firstRecordedTime - RelativeTime ((double) latency);
|
||||
}
|
||||
|
|
@ -364,10 +361,7 @@ struct CameraDevice::Pimpl : public ChangeBroadcaster
|
|||
|
||||
if (SUCCEEDED (hr))
|
||||
{
|
||||
ComSmartPtr<IFileSinkFilter> fileSink;
|
||||
hr = asfWriter.QueryInterface (fileSink);
|
||||
|
||||
if (SUCCEEDED (hr))
|
||||
if (auto fileSink = asfWriter.getInterface<IFileSinkFilter>())
|
||||
{
|
||||
hr = fileSink->SetFileName (file.getFullPathName().toWideCharPointer(), 0);
|
||||
|
||||
|
|
@ -377,62 +371,63 @@ struct CameraDevice::Pimpl : public ChangeBroadcaster
|
|||
|
||||
if (SUCCEEDED (hr))
|
||||
{
|
||||
ComSmartPtr<IConfigAsfWriter> asfConfig;
|
||||
hr = asfWriter.QueryInterface (asfConfig);
|
||||
asfConfig->SetIndexMode (true);
|
||||
ComSmartPtr<IWMProfileManager> profileManager;
|
||||
hr = WMCreateProfileManager (profileManager.resetAndGetPointerAddress());
|
||||
|
||||
// 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=\"$AVGTIMEPERFRAME\">"
|
||||
"<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>");
|
||||
|
||||
const int fps[] = { 10, 15, 30 };
|
||||
int maxFramesPerSecond = fps [jlimit (0, numElementsInArray (fps) - 1, quality & 0xff)];
|
||||
|
||||
if ((quality & 0xff000000) != 0) // (internal hacky way to pass explicit frame rates for testing)
|
||||
maxFramesPerSecond = (quality >> 24) & 0xff;
|
||||
|
||||
prof = prof.replace ("$WIDTH", String (width))
|
||||
.replace ("$HEIGHT", String (height))
|
||||
.replace ("$AVGTIMEPERFRAME", String (10000000 / maxFramesPerSecond));
|
||||
|
||||
ComSmartPtr<IWMProfile> currentProfile;
|
||||
hr = profileManager->LoadProfileByData (prof.toWideCharPointer(), currentProfile.resetAndGetPointerAddress());
|
||||
hr = asfConfig->ConfigureFilterUsingProfile (currentProfile);
|
||||
|
||||
if (SUCCEEDED (hr))
|
||||
if (auto asfConfig = asfWriter.getInterface<IConfigAsfWriter>())
|
||||
{
|
||||
ComSmartPtr<IPin> asfWriterInputPin;
|
||||
asfConfig->SetIndexMode (true);
|
||||
ComSmartPtr<IWMProfileManager> profileManager;
|
||||
hr = WMCreateProfileManager (profileManager.resetAndGetPointerAddress());
|
||||
|
||||
if (getPin (asfWriter, PINDIR_INPUT, asfWriterInputPin, "Video Input 01"))
|
||||
// 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=\"$AVGTIMEPERFRAME\">"
|
||||
"<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>");
|
||||
|
||||
const int fps[] = { 10, 15, 30 };
|
||||
int maxFramesPerSecond = fps[jlimit (0, numElementsInArray (fps) - 1, quality & 0xff)];
|
||||
|
||||
if ((quality & 0xff000000) != 0) // (internal hacky way to pass explicit frame rates for testing)
|
||||
maxFramesPerSecond = (quality >> 24) & 0xff;
|
||||
|
||||
prof = prof.replace ("$WIDTH", String (width))
|
||||
.replace ("$HEIGHT", String (height))
|
||||
.replace ("$AVGTIMEPERFRAME", String (10000000 / maxFramesPerSecond));
|
||||
|
||||
ComSmartPtr<IWMProfile> currentProfile;
|
||||
hr = profileManager->LoadProfileByData (prof.toWideCharPointer(), currentProfile.resetAndGetPointerAddress());
|
||||
hr = asfConfig->ConfigureFilterUsingProfile (currentProfile);
|
||||
|
||||
if (SUCCEEDED (hr))
|
||||
{
|
||||
hr = graphBuilder->Connect (smartTeeCaptureOutputPin, asfWriterInputPin);
|
||||
ComSmartPtr<IPin> asfWriterInputPin;
|
||||
|
||||
if (SUCCEEDED (hr) && openedSuccessfully && activeUsers > 0
|
||||
&& SUCCEEDED (mediaControl->Run()))
|
||||
if (getPin (asfWriter, PINDIR_INPUT, asfWriterInputPin, "Video Input 01"))
|
||||
{
|
||||
previewMaxFPS = (quality < 2) ? 15 : 25; // throttle back the preview comps to try to leave the cpu free for encoding
|
||||
hr = graphBuilder->Connect (smartTeeCaptureOutputPin, asfWriterInputPin);
|
||||
|
||||
if ((quality & 0x00ff0000) != 0) // (internal hacky way to pass explicit frame rates for testing)
|
||||
previewMaxFPS = (quality >> 16) & 0xff;
|
||||
if (SUCCEEDED (hr) && openedSuccessfully && activeUsers > 0
|
||||
&& SUCCEEDED (mediaControl->Run()))
|
||||
{
|
||||
previewMaxFPS = (quality < 2) ? 15 : 25; // throttle back the preview comps to try to leave the cpu free for encoding
|
||||
|
||||
return true;
|
||||
if ((quality & 0x00ff0000) != 0) // (internal hacky way to pass explicit frame rates for testing)
|
||||
previewMaxFPS = (quality >> 16) & 0xff;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue