Windows plugin working, 'update' command still needs elevated privileges

but all other commands can be run as normal user.
This commit is contained in:
Gonzalo Exequiel Pedone 2020-10-08 20:07:51 -03:00
parent 7d38a15856
commit 84d630e422
No known key found for this signature in database
GPG key ID: B8B09E63E9B85BAF
28 changed files with 238 additions and 234 deletions

View file

@ -419,7 +419,7 @@ std::string AkVCam::CmdParserPrivate::basename(const std::string &path)
auto program =
rit == path.rend()?
path:
path.substr(path.size() + (path.rbegin() - rit));
path.substr(path.size() + size_t(path.rbegin() - rit));
auto it =
std::find_if(program.begin(),
@ -431,7 +431,7 @@ std::string AkVCam::CmdParserPrivate::basename(const std::string &path)
program =
it == path.end()?
program:
program.substr(0, it - program.begin());
program.substr(0, size_t(it - program.begin()));
return program;
}
@ -987,7 +987,7 @@ int AkVCam::CmdParserPrivate::addFormat(const StringMap &flags,
if (!indexStr.empty()) {
p = nullptr;
index = strtoul(indexStr.c_str(), &p, 10);
index = int(strtoul(indexStr.c_str(), &p, 10));
if (*p) {
std::cerr << "Index must be an unsigned integer." << std::endl;
@ -996,7 +996,7 @@ int AkVCam::CmdParserPrivate::addFormat(const StringMap &flags,
}
}
VideoFormat fmt(format, width, height, {fps});
VideoFormat fmt(format, int(width), int(height), {fps});
this->m_ipcBridge.addFormat(deviceId, fmt, index);
return 0;
@ -1040,7 +1040,7 @@ int AkVCam::CmdParserPrivate::removeFormat(const StringMap &flags,
return -1;
}
this->m_ipcBridge.removeFormat(deviceId, index);
this->m_ipcBridge.removeFormat(deviceId, int(index));
return 0;
}
@ -1167,7 +1167,7 @@ int AkVCam::CmdParserPrivate::stream(const AkVCam::StringMap &flags,
return -1;
}
VideoFormat fmt(format, width, height, {{30, 1}});
VideoFormat fmt(format, int(width), int(height), {{30, 1}});
if (!this->m_ipcBridge.deviceStart(deviceId, fmt)) {
std::cerr << "Can't start stream." << std::endl;
@ -1188,8 +1188,8 @@ int AkVCam::CmdParserPrivate::stream(const AkVCam::StringMap &flags,
do {
std::cin.read(reinterpret_cast<char *>(frame.data().data()
+ bufferSize),
frame.data().size() - bufferSize);
bufferSize += std::cin.gcount();
std::streamsize(frame.data().size() - bufferSize));
bufferSize += size_t(std::cin.gcount());
if (bufferSize == frame.data().size()) {
this->m_ipcBridge.write(deviceId, frame);
@ -1438,7 +1438,7 @@ int AkVCam::CmdParserPrivate::writeControls(const StringMap &flags,
return -1;
}
controls[key] = it - control.menu.begin();
controls[key] = int(it - control.menu.begin());
} else {
if (val >= control.menu.size()) {
std::cerr << "Value at argument "
@ -1449,7 +1449,7 @@ int AkVCam::CmdParserPrivate::writeControls(const StringMap &flags,
return -1;
}
controls[key] = val;
controls[key] = int(val);
}
break;

View file

@ -18,7 +18,6 @@
*/
#include <cstdlib>
#include <cwchar>
#include <sstream>
#include <string>
@ -133,7 +132,7 @@ int64_t &AkVCam::Fraction::den()
double AkVCam::Fraction::value() const
{
return double(this->d->m_num) / this->d->m_den;
return double(this->d->m_num) / double(this->d->m_den);
}
std::string AkVCam::Fraction::toString() const

View file

@ -647,12 +647,12 @@ AkVCam::VideoFrame AkVCam::VideoFrame::scaled(size_t maxArea,
AkVCam::Scaling mode,
int align) const
{
auto width = int(sqrt(maxArea
* size_t(this->d->m_format.width())
/ size_t(this->d->m_format.height())));
auto height = int(sqrt(maxArea
* size_t(this->d->m_format.height())
/ size_t(this->d->m_format.width())));
auto width = int(sqrt(double(maxArea)
* double(this->d->m_format.width())
/ double(this->d->m_format.height())));
auto height = int(sqrt(double(maxArea)
* double(this->d->m_format.height())
/ double(this->d->m_format.width())));
int owidth = align * int(width / align);
int oheight = height * owidth / width;

View file

@ -307,7 +307,7 @@ std::vector<std::string> AkVCam::Settings::valueList(const std::string &key,
auto it = std::find(value.begin() + pos, value.end(), separator);
if (size_t(it - value.begin()) < index)
index = it - value.begin();
index = size_t(it - value.begin());
}
result.push_back(trimmed(value.substr(pos, index - pos)));
@ -446,7 +446,7 @@ std::string AkVCam::SettingsPrivate::parseString(const std::string &str)
} else if (str[i + 1] == 'x' && i < str.size() - 4) {
memcpy(hex, str.c_str() + i + 2, 2);
char *p = nullptr;
c = strtol(hex, &p, 16);
c = char(strtol(hex, &p, 16));
if (*p) {
parsedStr += str[i];

View file

@ -93,6 +93,6 @@ void AkVCam::TimerPrivate::timerLoop()
if (this->m_interval)
std::this_thread::sleep_for(std::chrono::milliseconds(this->m_interval));
AKVCAM_EMIT_NOARGS(this->self, Timeout);
AKVCAM_EMIT_NOARGS(this->self, Timeout)
}
}

View file

@ -71,7 +71,7 @@ std::string AkVCam::trimmed(const std::string &str)
if (left == str.size()) {
strippedLen = 0;
} else {
for (int64_t i = str.size() - 1; i >= 0; i--)
for (auto i = int64_t(str.size() - 1); i >= 0; i--)
if (!isspace(str[size_t(i)])) {
right = uint64_t(i);

View file

@ -16,10 +16,6 @@
#
# Web-Site: http://webcamoid.github.io/
isEmpty(CMIO_PLUGINS_DAL_PATH):
CMIO_PLUGINS_DAL_PATH = /Library/CoreMediaIO/Plug-Ins/DAL
isEmpty(CMIO_DAEMONS_PATH):
CMIO_DAEMONS_PATH = /Library/LaunchAgents
isEmpty(CMIO_PLUGIN_NAME):
CMIO_PLUGIN_NAME = AkVirtualCamera
isEmpty(CMIO_PLUGIN_ASSISTANT_NAME):
@ -34,13 +30,9 @@ isEmpty(CMIO_ASSISTANT_NAME):
CMIO_ASSISTANT_NAME = "org.webcamoid.cmio.AkVCam.Assistant"
DEFINES += \
CMIO_PLUGINS_DAL_PATH=\"\\\"$$CMIO_PLUGINS_DAL_PATH\\\"\" \
CMIO_PLUGINS_DAL_PATH_L=\"L\\\"$$CMIO_PLUGINS_DAL_PATH\\\"\" \
CMIO_DAEMONS_PATH=\"\\\"$$CMIO_DAEMONS_PATH\\\"\" \
CMIO_PLUGIN_NAME=\"\\\"$$CMIO_PLUGIN_NAME\\\"\" \
CMIO_PLUGIN_NAME_L=\"L\\\"$$CMIO_PLUGIN_NAME\\\"\" \
CMIO_PLUGIN_ASSISTANT_NAME=\"\\\"$$CMIO_PLUGIN_ASSISTANT_NAME\\\"\" \
CMIO_PLUGIN_ASSISTANT_NAME_L=\"L\\\"$$CMIO_PLUGIN_ASSISTANT_NAME\\\"\" \
CMIO_PLUGIN_DEVICE_PREFIX=\"\\\"$$CMIO_PLUGIN_DEVICE_PREFIX\\\"\" \
CMIO_PLUGIN_VENDOR=\"\\\"$$CMIO_PLUGIN_VENDOR\\\"\" \
CMIO_PLUGIN_PRODUCT=\"\\\"$$CMIO_PLUGIN_PRODUCT\\\"\" \

View file

@ -410,7 +410,10 @@ std::string AkVCam::Preferences::createDevicePath()
int AkVCam::Preferences::cameraFromCLSID(const CLSID &clsid)
{
for (DWORD i = 0; i < camerasCount(); i++) {
AkLogFunction();
AkLogDebug() << "CLSID: " << stringFromIid(clsid) << std::endl;
for (size_t i = 0; i < camerasCount(); i++) {
auto cameraClsid = createClsidFromStr(cameraPath(i));
if (IsEqualCLSID(cameraClsid, clsid))
@ -512,6 +515,7 @@ void AkVCam::Preferences::cameraSetFormats(size_t cameraIndex,
if (cameraIndex >= camerasCount())
return;
deleteKey("Cameras\\" + std::to_string(cameraIndex + 1) + "\\Formats\\");
write("Cameras\\"
+ std::to_string(cameraIndex + 1)
+ "\\Formats\\size",
@ -651,9 +655,12 @@ bool AkVCam::Preferences::readValue(const std::string &key,
PVOID data,
LPDWORD dataSize)
{
AkLogFunction();
std::string subKey;
std::string val;
splitSubKey(key, subKey, val);
AkLogDebug() << "SubKey: " << subKey << std::endl;
AkLogDebug() << "Value: " << val << std::endl;
HKEY hkey = nullptr;
auto result = RegOpenKeyExA(HKEY_CURRENT_USER,
subKey.c_str(),
@ -681,9 +688,12 @@ void AkVCam::Preferences::setValue(const std::string &key,
LPCSTR data,
DWORD dataSize)
{
AkLogFunction();
std::string subKey;
std::string val;
splitSubKey(key, subKey, val);
AkLogDebug() << "SubKey: " << subKey << std::endl;
AkLogDebug() << "Value: " << val << std::endl;
HKEY hkey = nullptr;
LONG result = RegCreateKeyExA(HKEY_CURRENT_USER,
subKey.c_str(),
@ -698,10 +708,11 @@ void AkVCam::Preferences::setValue(const std::string &key,
if (result != ERROR_SUCCESS)
return;
RegSetValueA(hkey,
RegSetValueExA(hkey,
val.c_str(),
0,
dataType,
data,
reinterpret_cast<CONST BYTE *>(data),
dataSize);
RegCloseKey(hkey);
}

View file

@ -18,7 +18,6 @@
*/
#include <algorithm>
#include <cwchar>
#include <map>
#include <sstream>
#include <dshow.h>
@ -126,6 +125,8 @@ std::string AkVCam::errorToString(DWORD errorCode)
// Converts a human redable string to a CLSID using MD5 hash.
CLSID AkVCam::createClsidFromStr(const std::string &str)
{
AkLogFunction();
AkLogDebug() << "String: " << str << std::endl;
HCRYPTPROV provider = 0;
HCRYPTHASH hash = 0;
CLSID clsid;
@ -144,7 +145,7 @@ CLSID AkVCam::createClsidFromStr(const std::string &str)
if (!CryptHashData(hash,
reinterpret_cast<const BYTE *>(str.c_str()),
DWORD(str.size() * sizeof(wchar_t)),
DWORD(str.size()),
0))
goto clsidFromStr_failed;
@ -161,21 +162,14 @@ clsidFromStr_failed:
if (provider)
CryptReleaseContext(provider, 0);
AkLogDebug() << "CLSID: " << stringFromIid(clsid) << std::endl;
return clsid;
}
std::string AkVCam::createClsidStrFromStr(const std::string &str)
{
auto clsid = createClsidFromStr(str);
LPWSTR clsidWStr = nullptr;
if (StringFromCLSID(clsid, &clsidWStr) != S_OK)
return {};
auto str_ = stringFromWSTR(clsidWStr);
CoTaskMemFree(clsidWStr);
return str_;
return stringFromIid(createClsidFromStr(str));
}
std::string AkVCam::stringFromIid(const IID &iid)
@ -267,7 +261,16 @@ std::string AkVCam::stringFromWSTR(LPCWSTR wstr)
0,
nullptr,
nullptr);
CHAR *cstr = new CHAR[len];
if (len < 1)
return {};
auto cstr = new CHAR[len + 1];
if (!cstr)
return {};
memset(cstr, 0, size_t(len + 1) * sizeof(CHAR));
WideCharToMultiByte(CP_ACP,
0,
wstr,
@ -287,14 +290,24 @@ LPWSTR AkVCam::stringToWSTR(const std::string &str)
auto len = MultiByteToWideChar(CP_ACP,
0,
str.c_str(),
str.size(),
-1,
nullptr,
0);
auto wstr = reinterpret_cast<LPWSTR>(CoTaskMemAlloc(len * sizeof(WCHAR)));
if (len < 1)
return nullptr;
auto wstr = reinterpret_cast<LPWSTR>(CoTaskMemAlloc(size_t(len + 1)
* sizeof(WCHAR)));
if (!wstr)
return nullptr;
memset(wstr, 0, size_t(len + 1) * sizeof(WCHAR));
MultiByteToWideChar(CP_ACP,
0,
str.c_str(),
str.size(),
-1,
wstr,
len);
@ -434,16 +447,16 @@ AM_MEDIA_TYPE *AkVCam::mediaTypeFromFormat(const AkVCam::VideoFormat &format)
AkVCam::VideoFormat AkVCam::formatFromMediaType(const AM_MEDIA_TYPE *mediaType)
{
if (!mediaType)
return VideoFormat();
return {};
if (!IsEqualGUID(mediaType->majortype, MEDIATYPE_Video))
return VideoFormat();
return {};
if (!isSubTypeSupported(mediaType->subtype))
return VideoFormat();
return {};
if (!mediaType->pbFormat)
return VideoFormat();
return {};
if (IsEqualGUID(mediaType->formattype, FORMAT_VideoInfo)) {
auto format = reinterpret_cast<VIDEOINFOHEADER *>(mediaType->pbFormat);
@ -465,7 +478,7 @@ AkVCam::VideoFormat AkVCam::formatFromMediaType(const AM_MEDIA_TYPE *mediaType)
{fps});
}
return VideoFormat();
return {};
}
bool AkVCam::isEqualMediaType(const AM_MEDIA_TYPE *mediaType1,
@ -821,7 +834,7 @@ LSTATUS AkVCam::deleteTree(HKEY key, LPCSTR subkey, REGSAM samFlags)
i,
name,
&nameLen,
0,
nullptr,
nullptr,
nullptr,
nullptr);
@ -933,7 +946,7 @@ LSTATUS AkVCam::copyTree(HKEY src, LPCSTR subkey, HKEY dst, REGSAM samFlags)
i,
name,
&nameLen,
0,
nullptr,
&dataType,
data,
&dataSize);
@ -969,7 +982,7 @@ AkVCam::VideoFrame AkVCam::loadPicture(const std::string &fileName)
IWICImagingFactory *imagingFactory = nullptr;
auto hr = CoCreateInstance(CLSID_WICImagingFactory,
NULL,
nullptr,
CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&imagingFactory));
@ -1003,11 +1016,13 @@ AkVCam::VideoFrame AkVCam::loadPicture(const std::string &fileName)
UINT width = 0;
UINT height = 0;
formatConverter->GetSize(&width, &height);
VideoFormat videoFormat(PixelFormatRGB24, width, height);
VideoFormat videoFormat(PixelFormatRGB24,
int(width),
int(height));
frame = VideoFrame(videoFormat);
formatConverter->CopyPixels(nullptr,
3 * width,
frame.data().size(),
UINT(frame.data().size()),
frame.data().data());
}

View file

@ -559,8 +559,11 @@ void AkVCam::IpcBridge::updateDevices()
auto path = pluginPath + "\\" DSHOW_PLUGIN_NAME ".dll";
AkLogDebug() << "Plugin binary: " << path << std::endl;
if (!this->d->fileExists(path))
if (!this->d->fileExists(path)) {
AkLogError() << "Plugin binary not found: " << path << std::endl;
return;
}
if (auto hmodule = LoadLibraryA(path.c_str())) {
auto registerServer =
@ -573,9 +576,13 @@ void AkVCam::IpcBridge::updateDevices()
message.messageId = AKVCAM_ASSISTANT_MSG_DEVICE_UPDATE;
message.dataSize = 0;
this->d->m_mainServer.sendMessage(&message);
} else {
AkLogError() << "Can't locate DllRegisterServer function." << std::endl;
}
FreeLibrary(hmodule);
} else {
AkLogError() << "Error loading plugin binary: " << path << std::endl;
}
}

View file

@ -56,12 +56,12 @@ namespace AkVCam
{
public:
BaseFilter *self;
EnumPins *m_pins;
VideoProcAmp *m_videoProcAmp;
ReferenceClock *m_referenceClock;
EnumPins *m_pins {nullptr};
VideoProcAmp *m_videoProcAmp {nullptr};
ReferenceClock *m_referenceClock {nullptr};
std::string m_vendor;
std::string m_filterName;
IFilterGraph *m_filterGraph;
IFilterGraph *m_filterGraph {nullptr};
IpcBridge m_ipcBridge;
BaseFilterPrivate(BaseFilter *self,
@ -121,7 +121,7 @@ AkVCam::BaseFilter *AkVCam::BaseFilter::create(const GUID &clsid)
{
AkLogFunction();
auto camera = Preferences::cameraFromCLSID(clsid);
AkLogInfo() << "CLSID: " << stringFromClsid(clsid) << std::endl;
AkLogInfo() << "CLSID: " << stringFromIid(clsid) << std::endl;
AkLogInfo() << "ID: " << camera << std::endl;
if (camera < 0)
@ -283,11 +283,11 @@ HRESULT AkVCam::BaseFilter::QueryFilterInfo(FILTER_INFO *pInfo)
memset(pInfo->achName, 0, MAX_FILTER_NAME * sizeof(WCHAR));
if (this->d->m_filterName.size() > 0) {
if (!this->d->m_filterName.empty()) {
auto filterName = stringToWSTR(this->d->m_filterName);
memcpy(pInfo->achName,
filterName,
std::max<size_t>(this->d->m_filterName.size() * sizeof(WCHAR),
(std::min<size_t>)(wcslen(filterName) * sizeof(WCHAR),
MAX_FILTER_NAME));
CoTaskMemFree(filterName);
}
@ -337,7 +337,7 @@ void AkVCam::BaseFilter::stateChanged(FILTER_STATE state)
if (cameraIndex < 0)
return;
auto path = Preferences::cameraPath(cameraIndex);
auto path = Preferences::cameraPath(size_t(cameraIndex));
if (state == State_Running)
this->d->m_ipcBridge.addListener(path);
@ -353,8 +353,7 @@ AkVCam::BaseFilterPrivate::BaseFilterPrivate(AkVCam::BaseFilter *self,
m_videoProcAmp(new VideoProcAmp),
m_referenceClock(new ReferenceClock),
m_vendor(vendor),
m_filterName(filterName),
m_filterGraph(nullptr)
m_filterName(filterName)
{
this->m_pins->AddRef();
this->m_videoProcAmp->AddRef();
@ -392,7 +391,7 @@ IEnumPins *AkVCam::BaseFilterPrivate::pinsForDevice(const std::string &deviceId)
if (cameraIndex < 0)
return nullptr;
auto path = Preferences::cameraPath(cameraIndex);
auto path = Preferences::cameraPath(size_t(cameraIndex));
if (path.empty() || path != deviceId)
return nullptr;
@ -412,20 +411,20 @@ void AkVCam::BaseFilterPrivate::updatePins()
if (cameraIndex < 0)
return;
auto path = Preferences::cameraPath(cameraIndex);
auto path = Preferences::cameraPath(size_t(cameraIndex));
auto broadcaster = this->m_ipcBridge.broadcaster(path);
AkVCamDevicePinCall(path,
this,
setBroadcasting,
broadcaster);
broadcaster)
auto controlsList = this->m_ipcBridge.controls(path);
std::map<std::string, int> controls;
for (auto &control: controlsList)
controls[control.id] = control.value;
AkVCamDevicePinCall(path, this, setControls, controls);
AkVCamDevicePinCall(path, this, setControls, controls)
}
void AkVCam::BaseFilterPrivate::serverStateChanged(void *userData,
@ -451,7 +450,7 @@ void AkVCam::BaseFilterPrivate::frameReady(void *userData,
{
AkLogFunction();
auto self = reinterpret_cast<BaseFilterPrivate *>(userData);
AkVCamDevicePinCall(deviceId, self, frameReady, frame);
AkVCamDevicePinCall(deviceId, self, frameReady, frame)
}
void AkVCam::BaseFilterPrivate::pictureChanged(void *userData,
@ -494,7 +493,7 @@ void AkVCam::BaseFilterPrivate::setBroadcasting(void *userData,
{
AkLogFunction();
auto self = reinterpret_cast<BaseFilterPrivate *>(userData);
AkVCamDevicePinCall(deviceId, self, setBroadcasting, broadcaster);
AkVCamDevicePinCall(deviceId, self, setBroadcasting, broadcaster)
}
void AkVCam::BaseFilterPrivate::setControls(void *userData,
@ -503,5 +502,5 @@ void AkVCam::BaseFilterPrivate::setControls(void *userData,
{
AkLogFunction();
auto self = reinterpret_cast<BaseFilterPrivate *>(userData);
AkVCamDevicePinCall(deviceId, self, setControls, controls);
AkVCamDevicePinCall(deviceId, self, setControls, controls)
}

View file

@ -48,8 +48,8 @@ namespace AkVCam
class CUnknownPrivate
{
public:
std::atomic<ULONG> m_ref;
CUnknown *m_parent;
std::atomic<ULONG> m_ref {0};
CUnknown *m_parent {nullptr};
CLSID m_parentCLSID;
};
}
@ -57,7 +57,6 @@ namespace AkVCam
AkVCam::CUnknown::CUnknown(CUnknown *parent, REFIID parentCLSID)
{
this->d = new CUnknownPrivate;
this->d->m_ref = 0;
this->d->m_parent = parent;
this->d->m_parentCLSID = parentCLSID;
}

View file

@ -30,8 +30,8 @@ namespace AkVCam
{
public:
std::vector<VideoFormat> m_formats;
size_t m_position;
bool m_changed;
size_t m_position {0};
bool m_changed {false};
};
}
@ -40,8 +40,6 @@ AkVCam::EnumMediaTypes::EnumMediaTypes(const std::vector<VideoFormat> &formats):
{
this->d = new EnumMediaTypesPrivate;
this->d->m_formats = formats;
this->d->m_position = 0;
this->d->m_changed = false;
}
AkVCam::EnumMediaTypes::EnumMediaTypes(const AkVCam::EnumMediaTypes &other):

View file

@ -31,7 +31,7 @@ namespace AkVCam
class LatencyPrivate
{
public:
IAMStreamConfig *m_streamConfig;
IAMStreamConfig *m_streamConfig {nullptr};
};
}

View file

@ -31,11 +31,11 @@ namespace AkVCam
class MediaFilterPrivate
{
public:
IBaseFilter *m_baseFilter;
IReferenceClock *m_clock;
IBaseFilter *m_baseFilter {nullptr};
IReferenceClock *m_clock {nullptr};
std::vector<StateChangedCallback> m_stateChanged;
FILTER_STATE m_state;
REFERENCE_TIME m_start;
FILTER_STATE m_state {State_Stopped};
REFERENCE_TIME m_start {0};
};
}
@ -46,9 +46,6 @@ AkVCam::MediaFilter::MediaFilter(const IID &classCLSID,
this->setParent(this, &IID_IMediaFilter);
this->d = new MediaFilterPrivate;
this->d->m_baseFilter = baseFilter;
this->d->m_clock = nullptr;
this->d->m_state = State_Stopped;
this->d->m_start = 0;
}
AkVCam::MediaFilter::~MediaFilter()

View file

@ -28,20 +28,20 @@ namespace AkVCam
class MediaSamplePrivate
{
public:
IMemAllocator *m_memAllocator;
BYTE *m_buffer;
LONG m_bufferSize;
LONG m_dataLength;
LONG m_prefix;
AM_MEDIA_TYPE *m_mediaType;
REFERENCE_TIME m_sampleTimeStart;
REFERENCE_TIME m_sampleTimeEnd;
REFERENCE_TIME m_mediaTimeStart;
REFERENCE_TIME m_mediaTimeEnd;
BOOL m_syncPoint;
BOOL m_preroll;
BOOL m_discontinuity;
BOOL m_mediaTypeChanged;
IMemAllocator *m_memAllocator {nullptr};
BYTE *m_buffer {nullptr};
LONG m_bufferSize {0};
LONG m_dataLength {0};
LONG m_prefix {0};
AM_MEDIA_TYPE *m_mediaType {nullptr};
REFERENCE_TIME m_sampleTimeStart {-1};
REFERENCE_TIME m_sampleTimeEnd {-1};
REFERENCE_TIME m_mediaTimeStart {-1};
REFERENCE_TIME m_mediaTimeEnd {-1};
BOOL m_syncPoint {S_FALSE};
BOOL m_preroll {S_FALSE};
BOOL m_discontinuity {S_FALSE};
BOOL m_mediaTypeChanged {S_FALSE};
};
}
@ -58,15 +58,7 @@ AkVCam::MediaSample::MediaSample(IMemAllocator *memAllocator,
this->d->m_prefix = prefix;
auto realSize = size_t(bufferSize + prefix + align - 1) & ~size_t(align - 1);
this->d->m_buffer = new BYTE[realSize];
this->d->m_mediaType = nullptr;
this->d->m_sampleTimeStart = -1;
this->d->m_sampleTimeEnd = -1;
this->d->m_mediaTimeStart = -1;
this->d->m_mediaTimeEnd = -1;
this->d->m_syncPoint = S_FALSE;
this->d->m_preroll = S_FALSE;
this->d->m_discontinuity = S_FALSE;
this->d->m_mediaTypeChanged = S_FALSE;
memset(this->d->m_buffer, 0, realSize * sizeof(BYTE));
}
AkVCam::MediaSample::~MediaSample()

View file

@ -26,11 +26,11 @@ namespace AkVCam
class MediaSample2Private
{
public:
DWORD m_data;
DWORD m_typeSpecificFlags;
DWORD m_sampleFlags;
DWORD m_streamId;
AM_MEDIA_TYPE *m_mediaType;
DWORD m_data {0};
DWORD m_typeSpecificFlags {0};
DWORD m_sampleFlags {0};
DWORD m_streamId {0};
AM_MEDIA_TYPE *m_mediaType {nullptr};
};
}
@ -41,11 +41,6 @@ AkVCam::MediaSample2::MediaSample2(IMemAllocator *memAllocator,
MediaSample(memAllocator, bufferSize, align, prefix)
{
this->d = new MediaSample2Private;
this->d->m_data = 0;
this->d->m_typeSpecificFlags = 0;
this->d->m_sampleFlags = 0;
this->d->m_streamId = 0;
this->d->m_mediaType = nullptr;
}
AkVCam::MediaSample2::~MediaSample2()

View file

@ -37,8 +37,8 @@ namespace AkVCam
ALLOCATOR_PROPERTIES m_properties;
std::mutex m_mutex;
std::condition_variable_any m_bufferReleased;
bool m_commited;
bool m_decommiting;
bool m_commited {false};
bool m_decommiting {false};
};
}
@ -47,8 +47,6 @@ AkVCam::MemAllocator::MemAllocator():
{
this->d = new MemAllocatorPrivate;
memset(&this->d->m_properties, 0, sizeof(ALLOCATOR_PROPERTIES));
this->d->m_commited = false;
this->d->m_decommiting = false;
}
AkVCam::MemAllocator::~MemAllocator()

View file

@ -48,39 +48,39 @@ namespace AkVCam
{
public:
Pin *self;
BaseFilter *m_baseFilter;
VideoProcAmp *m_videoProcAmp;
BaseFilter *m_baseFilter {nullptr};
VideoProcAmp *m_videoProcAmp {nullptr};
std::string m_pinName;
std::string m_pinId;
EnumMediaTypes *m_mediaTypes;
IPin *m_connectedTo;
IMemInputPin *m_memInputPin;
IMemAllocator *m_memAllocator;
REFERENCE_TIME m_pts;
REFERENCE_TIME m_ptsDrift;
REFERENCE_TIME m_start;
REFERENCE_TIME m_stop;
double m_rate;
FILTER_STATE m_prevState;
DWORD_PTR m_adviseCookie;
HANDLE m_sendFrameEvent;
EnumMediaTypes *m_mediaTypes {nullptr};
IPin *m_connectedTo {nullptr};
IMemInputPin *m_memInputPin {nullptr};
IMemAllocator *m_memAllocator {nullptr};
REFERENCE_TIME m_pts {-1};
REFERENCE_TIME m_ptsDrift {0};
REFERENCE_TIME m_start {0};
REFERENCE_TIME m_stop {MAXLONGLONG};
double m_rate {1.0};
FILTER_STATE m_prevState = State_Stopped;
DWORD_PTR m_adviseCookie {0};
HANDLE m_sendFrameEvent {nullptr};
std::thread m_sendFrameThread;
std::atomic<bool> m_running;
std::atomic<bool> m_running {false};
std::mutex m_mutex;
std::mutex m_controlsMutex;
VideoFrame m_currentFrame;
VideoFrame m_testFrame;
VideoFrame m_testFrameAdapted;
std::string m_broadcaster;
bool m_horizontalFlip; // Controlled by client
bool m_verticalFlip;
bool m_horizontalFlip {false}; // Controlled by client
bool m_verticalFlip {false};
std::map<std::string, int> m_controls;
LONG m_brightness;
LONG m_contrast;
LONG m_saturation;
LONG m_gamma;
LONG m_hue;
LONG m_colorenable;
LONG m_brightness {0};
LONG m_contrast {0};
LONG m_saturation {0};
LONG m_gamma {0};
LONG m_hue {0};
LONG m_colorenable {0};
void sendFrameOneShot();
void sendFrameLoop();
@ -111,20 +111,6 @@ AkVCam::Pin::Pin(BaseFilter *baseFilter,
this->d->m_pinId = ss.str();
this->d->m_mediaTypes = new AkVCam::EnumMediaTypes(formats);
this->d->m_mediaTypes->AddRef();
this->d->m_connectedTo = nullptr;
this->d->m_memInputPin = nullptr;
this->d->m_memAllocator = nullptr;
this->d->m_ptsDrift = -1;
this->d->m_ptsDrift = 0;
this->d->m_start = 0;
this->d->m_stop = MAXLONGLONG;
this->d->m_rate = 1.0;
this->d->m_horizontalFlip = false;
this->d->m_verticalFlip = false;
this->d->m_prevState = State_Stopped;
this->d->m_adviseCookie = 0;
this->d->m_sendFrameEvent = nullptr;
this->d->m_running = false;
auto picture = Preferences::picture();
if (!picture.empty())
@ -226,9 +212,7 @@ HRESULT AkVCam::Pin::stateChanged(void *userData, FILTER_STATE state)
auto videoFormat = formatFromMediaType(mediaType);
deleteMediaType(&mediaType);
auto fps = videoFormat.minimumFrameRate();
auto period = REFERENCE_TIME(TIME_BASE
* fps.den()
/ fps.num());
auto period = REFERENCE_TIME(TIME_BASE / fps.value());
clock->AdvisePeriodic(now,
period,
@ -691,7 +675,7 @@ HRESULT AkVCam::Pin::QueryPinInfo(PIN_INFO *pInfo)
auto pinName = stringToWSTR(this->d->m_pinName);
memcpy(pInfo->achName,
pinName,
(std::min<size_t>)(this->d->m_pinName.size() * sizeof(WCHAR),
(std::min<size_t>)(wcslen(pinName) * sizeof(WCHAR),
MAX_PIN_NAME));
CoTaskMemFree(pinName);
}
@ -718,17 +702,11 @@ HRESULT AkVCam::Pin::QueryId(LPWSTR *Id)
if (!Id)
return E_POINTER;
auto wstrSize = (this->d->m_pinId.size() + 1) * sizeof(WCHAR);
*Id = reinterpret_cast<LPWSTR>(CoTaskMemAlloc(wstrSize));
*Id = stringToWSTR(this->d->m_pinId);
if (!*Id)
return E_OUTOFMEMORY;
memset(*Id, 0, wstrSize);
auto pinId = stringToWSTR(this->d->m_pinId);
memcpy(*Id, pinId, this->d->m_pinId.size() * sizeof(WCHAR));
CoTaskMemFree(pinId);
return S_OK;
}
@ -894,9 +872,7 @@ HRESULT AkVCam::PinPrivate::sendFrame()
auto format = formatFromMediaType(mediaType);
deleteMediaType(&mediaType);
auto fps = format.minimumFrameRate();
auto duration = REFERENCE_TIME(TIME_BASE
* fps.den()
/ fps.num());
auto duration = REFERENCE_TIME(TIME_BASE / fps.value());
if (this->m_pts < 0) {
this->m_pts = 0;

View file

@ -35,20 +35,8 @@ inline AkVCam::PluginInterface *pluginInterface()
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
UNUSED(lpvReserved);
pluginInterface()->initializeLogger();
AkLogFunction();
auto loglevel = AkVCam::Preferences::logLevel();
AkVCam::Logger::setLogLevel(loglevel);
if (loglevel > AKVCAM_LOGLEVEL_DEFAULT) {
// Turn on lights
freopen("CONOUT$", "a", stdout);
freopen("CONOUT$", "a", stderr);
setbuf(stdout, nullptr);
}
auto defaultLogFile = AkVCam::tempPath() + "\\" DSHOW_PLUGIN_NAME ".log";
auto logFile = AkVCam::Preferences::readString("logfile", defaultLogFile);
AkVCam::Logger::setLogFile(logFile);
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
@ -107,6 +95,7 @@ STDAPI DllCanUnloadNow()
STDAPI DllRegisterServer()
{
pluginInterface()->initializeLogger();
AkLogFunction();
DllUnregisterServer();
@ -130,6 +119,7 @@ STDAPI DllRegisterServer()
STDAPI DllUnregisterServer()
{
pluginInterface()->initializeLogger();
AkLogFunction();
auto cameras =
AkVCam::Preferences::listRegisteredCameras(pluginInterface()->pluginHinstance());

View file

@ -23,16 +23,12 @@
#include <uuids.h>
#include "plugininterface.h"
#include "PlatformUtils/src/preferences.h"
#include "PlatformUtils/src/utils.h"
#include "VCamUtils/src/utils.h"
#if 1
#define ROOT_HKEY HKEY_CURRENT_USER
#define SUBKEY_PREFIX "Software\\Classes\\CLSID"
#else
#define ROOT_HKEY HKEY_CLASSES_ROOT
#define SUBKEY_PREFIX "CLSID"
#endif
namespace AkVCam
{
@ -119,7 +115,7 @@ bool AkVCam::PluginInterface::registerServer(const std::string &deviceId,
0L,
REG_SZ,
reinterpret_cast<const BYTE *>(threadingModel.c_str()),
DWORD((threadingModel.size() + 1) * sizeof(wchar_t)));
DWORD(threadingModel.size() + 1));
ok = true;
@ -146,7 +142,7 @@ void AkVCam::PluginInterface::unregisterServer(const CLSID &clsid) const
{
AkLogFunction();
auto clsidStr = stringFromClsid(clsid);
auto clsidStr = stringFromIid(clsid);
AkLogInfo() << "CLSID: " << clsidStr << std::endl;
auto subkey = SUBKEY_PREFIX "\\" + clsidStr;
deleteTree(ROOT_HKEY, subkey.c_str(), 0);
@ -181,12 +177,15 @@ bool AkVCam::PluginInterface::registerFilter(const std::string &deviceId,
regFilter.cPins2 = ULONG(pins.size());
regFilter.rgPins2 = pins.data();
auto result = CoInitialize(nullptr);
auto result = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
bool ok = false;
LPWSTR wdescription = nullptr;
if (FAILED(result))
if (FAILED(result)) {
AkLogError() << "Failed to initialize the COM library." << std::endl;
goto registerFilter_failed;
}
result = CoCreateInstance(CLSID_FilterMapper2,
nullptr,
@ -194,8 +193,11 @@ bool AkVCam::PluginInterface::registerFilter(const std::string &deviceId,
IID_IFilterMapper2,
reinterpret_cast<void **>(&filterMapper));
if (FAILED(result))
if (FAILED(result)) {
AkLogError() << "Can't create instance for IFilterMapper2." << std::endl;
goto registerFilter_failed;
}
wdescription = stringToWSTR(description);
result = filterMapper->RegisterFilter(clsid,
@ -230,7 +232,7 @@ void AkVCam::PluginInterface::unregisterFilter(const CLSID &clsid) const
{
AkLogFunction();
IFilterMapper2 *filterMapper = nullptr;
auto result = CoInitialize(nullptr);
auto result = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
if (FAILED(result))
goto unregisterFilter_failed;
@ -284,7 +286,7 @@ bool AkVCam::PluginInterface::setDevicePath(const std::string &deviceId) const
0,
REG_SZ,
reinterpret_cast<const BYTE *>(deviceId.c_str()),
DWORD((deviceId.size() + 1) * sizeof(wchar_t)));
DWORD(deviceId.size() + 1));
if (result != ERROR_SUCCESS)
goto setDevicePath_failed;
@ -337,3 +339,27 @@ void AkVCam::PluginInterface::destroyDevice(const CLSID &clsid)
this->unregisterFilter(clsid);
this->unregisterServer(clsid);
}
void AkVCam::PluginInterface::initializeLogger() const
{
static bool loggerReady = false;
if (loggerReady)
return;
auto loglevel = AkVCam::Preferences::logLevel();
AkVCam::Logger::setLogLevel(loglevel);
if (loglevel > AKVCAM_LOGLEVEL_DEFAULT) {
// Turn on lights
freopen("CONOUT$", "a", stdout);
freopen("CONOUT$", "a", stderr);
setbuf(stdout, nullptr);
}
auto defaultLogFile = AkVCam::tempPath() + "\\" DSHOW_PLUGIN_NAME ".log";
auto logFile = AkVCam::Preferences::readString("logfile", defaultLogFile);
AkLogInfo() << "Sending debug output to " << logFile << std::endl;
AkVCam::Logger::setLogFile(logFile);
loggerReady = true;
}

View file

@ -49,6 +49,7 @@ namespace AkVCam
const std::string &description);
void destroyDevice(const std::string &deviceId);
void destroyDevice(const CLSID &clsid);
void initializeLogger() const;
private:
PluginInterfacePrivate *d;

View file

@ -206,7 +206,7 @@ void AkVCam::AdviseCookiePrivate::adviseTimeTh(REFERENCE_TIME baseTime,
auto startSleep =
REFERENCE_TIME(1e3
* (baseTime + streamTime - clockTime)
* double(baseTime + streamTime - clockTime)
/ TIME_BASE);
if (startSleep > 0) {
@ -252,7 +252,7 @@ void AkVCam::AdviseCookiePrivate::advisePeriodicTh(REFERENCE_TIME startTime,
auto startSleep =
REFERENCE_TIME(1e3
* (startTime - clockTime)
* double(startTime - clockTime)
/ TIME_BASE);
if (startSleep > 0) {
@ -262,7 +262,7 @@ void AkVCam::AdviseCookiePrivate::advisePeriodicTh(REFERENCE_TIME startTime,
this->m_mutex.unlock();
}
auto periodSleep = REFERENCE_TIME(1e3 * periodTime / TIME_BASE);
auto periodSleep = REFERENCE_TIME(1e3 * double(periodTime) / TIME_BASE);
std::chrono::milliseconds period(periodSleep);
while (this->m_run) {

View file

@ -33,7 +33,7 @@ namespace AkVCam
class SpecifyPropertyPagesPrivate
{
public:
IPin *m_pin;
IPin *m_pin {nullptr};
};
}

View file

@ -34,8 +34,8 @@ namespace AkVCam
class StreamConfigPrivate
{
public:
Pin *m_pin;
AM_MEDIA_TYPE *m_mediaType;
Pin *m_pin {nullptr};
AM_MEDIA_TYPE *m_mediaType {nullptr};
};
}
@ -44,7 +44,6 @@ AkVCam::StreamConfig::StreamConfig(Pin *pin):
{
this->d = new StreamConfigPrivate;
this->d->m_pin = pin;
this->d->m_mediaType = nullptr;
}
AkVCam::StreamConfig::~StreamConfig()

View file

@ -36,7 +36,7 @@ namespace AkVCam
class VideoControlPrivate
{
public:
IEnumPins *m_enumPins;
IEnumPins *m_enumPins {nullptr};
};
}

View file

@ -27,7 +27,7 @@ isEmpty(DSHOW_PLUGIN_DESCRIPTION):
isEmpty(DSHOW_PLUGIN_DESCRIPTION_EXT):
DSHOW_PLUGIN_DESCRIPTION_EXT = "Central service for communicating between virtual cameras clients and servers"
isEmpty(DSHOW_PLUGIN_DEVICE_PREFIX):
DSHOW_PLUGIN_DEVICE_PREFIX = /akvcam/video
DSHOW_PLUGIN_DEVICE_PREFIX = AkVCamVideoDevice
isEmpty(DSHOW_PLUGIN_VENDOR):
DSHOW_PLUGIN_VENDOR = "Webcamoid Project"

View file

@ -13,16 +13,26 @@ Component.prototype.createOperations = function()
let archs = ["x86", "x64"];
for (let i in archs) {
if (installer.isUninstaller()) {
let managerPath =
installer.value("TargetDir")
+ "/"
+ archs[i]
+ "/AkVCamManager.exe";
component.addOperation("Execute",
managerPath, "remove-devices");
component.addElevatedOperation("Execute",
managerPath, "update");
}
let assistantPath =
installer.value("TargetDir")
+ "/"
+ archs[i]
+ "/AkVCamAssistant.exe";
if (!installer.fileExists(assistantPath))
continue;
// Load assistant daemon.
if (installer.fileExists(assistantPath))
component.addElevatedOperation("Execute",
assistantPath, "--install",
"UNDOEXECUTE",