1
0
Fork 0
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:
ed 2020-09-07 16:01:48 +01:00
parent 99b3d85fcc
commit 54164fac3f
4 changed files with 76 additions and 90 deletions

View file

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

View file

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

View file

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

View file

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