Add WASAPI audio capture
- Add WASAPI audio capture for windows, input and output - Check for null pointer in os_dlopen - Add exception-safe 'WinHandle' and 'CoTaskMemPtr' helper classes that will automatically call CloseHandle on handles and call CoTaskMemFree on certain types of memory returned from windows functions - Changed the wide <-> MBS/UTF8 conversion functions so that you use buffers (like these functions are *supposed* to behave), and changed the ones that allocate to a different naming scheme to be safe
This commit is contained in:
@@ -585,13 +585,13 @@ void dstr_right(struct dstr *dst, const struct dstr *str, const size_t pos)
|
||||
void dstr_from_mbs(struct dstr *dst, const char *mbstr)
|
||||
{
|
||||
dstr_free(dst);
|
||||
dst->len = os_mbs_to_utf8(mbstr, 0, &dst->array);
|
||||
dst->len = os_mbs_to_utf8_ptr(mbstr, 0, &dst->array);
|
||||
}
|
||||
|
||||
char *dstr_to_mbs(const struct dstr *str)
|
||||
{
|
||||
char *dst;
|
||||
os_mbs_to_utf8(str->array, str->len, &dst);
|
||||
os_mbs_to_utf8_ptr(str->array, str->len, &dst);
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
@@ -33,6 +33,10 @@
|
||||
void *os_dlopen(const char *path)
|
||||
{
|
||||
struct dstr dylib_name;
|
||||
|
||||
if (!path)
|
||||
return NULL;
|
||||
|
||||
dstr_init_copy(&dylib_name, path);
|
||||
if (!dstr_find(&dylib_name, ".so"))
|
||||
dstr_cat(&dylib_name, ".so");
|
||||
|
@@ -28,6 +28,10 @@
|
||||
void *os_dlopen(const char *path)
|
||||
{
|
||||
struct dstr dylib_name;
|
||||
|
||||
if (!path)
|
||||
return NULL;
|
||||
|
||||
dstr_init_copy(&dylib_name, path);
|
||||
if (!dstr_find(&dylib_name, ".so"))
|
||||
dstr_cat(&dylib_name, ".so");
|
||||
|
@@ -52,11 +52,14 @@ void *os_dlopen(const char *path)
|
||||
wchar_t *wpath;
|
||||
HMODULE h_library = NULL;
|
||||
|
||||
if (!path)
|
||||
return NULL;
|
||||
|
||||
dstr_init_copy(&dll_name, path);
|
||||
if (!dstr_find(&dll_name, ".dll"))
|
||||
dstr_cat(&dll_name, ".dll");
|
||||
|
||||
os_utf8_to_wcs(dll_name.array, 0, &wpath);
|
||||
os_utf8_to_wcs_ptr(dll_name.array, 0, &wpath);
|
||||
h_library = LoadLibraryW(wpath);
|
||||
bfree(wpath);
|
||||
dstr_free(&dll_name);
|
||||
@@ -139,7 +142,7 @@ char *os_get_config_path(const char *name)
|
||||
SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT,
|
||||
path_utf16);
|
||||
|
||||
os_wcs_to_utf8(path_utf16, 0, &ptr);
|
||||
os_wcs_to_utf8_ptr(path_utf16, 0, &ptr);
|
||||
dstr_init_move_array(&path, ptr);
|
||||
dstr_cat(&path, "\\");
|
||||
dstr_cat(&path, name);
|
||||
@@ -152,7 +155,7 @@ bool os_file_exists(const char *path)
|
||||
HANDLE hFind;
|
||||
wchar_t *path_utf16;
|
||||
|
||||
if (!os_utf8_to_wcs(path, 0, &path_utf16))
|
||||
if (!os_utf8_to_wcs_ptr(path, 0, &path_utf16))
|
||||
return false;
|
||||
|
||||
hFind = FindFirstFileW(path_utf16, &wfd);
|
||||
@@ -168,7 +171,7 @@ int os_mkdir(const char *path)
|
||||
wchar_t *path_utf16;
|
||||
BOOL success;
|
||||
|
||||
if (!os_utf8_to_wcs(path, 0, &path_utf16))
|
||||
if (!os_utf8_to_wcs_ptr(path, 0, &path_utf16))
|
||||
return MKDIR_ERROR;
|
||||
|
||||
success = CreateDirectory(path_utf16, NULL);
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Hugh Bailey <obs.jim@gmail.com>
|
||||
* Copyright (c) 2013-2014 Hugh Bailey <obs.jim@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@@ -28,13 +28,13 @@ FILE *os_wfopen(const wchar_t *path, const char *mode)
|
||||
#ifdef _MSC_VER
|
||||
wchar_t *wcs_mode;
|
||||
|
||||
os_utf8_to_wcs(mode, 0, &wcs_mode);
|
||||
os_utf8_to_wcs_ptr(mode, 0, &wcs_mode);
|
||||
file = _wfopen(path, wcs_mode);
|
||||
bfree(wcs_mode);
|
||||
#else
|
||||
char *mbs_path;
|
||||
|
||||
os_wcs_to_utf8(path, 0, &mbs_path);
|
||||
os_wcs_to_utf8_ptr(path, 0, &mbs_path);
|
||||
file = fopen(mbs_path, mode);
|
||||
bfree(mbs_path);
|
||||
#endif
|
||||
@@ -46,7 +46,7 @@ FILE *os_fopen(const char *path, const char *mode)
|
||||
#ifdef _WIN32
|
||||
wchar_t *wpath = NULL;
|
||||
FILE *file = NULL;
|
||||
os_utf8_to_wcs(path, 0, &wpath);
|
||||
os_utf8_to_wcs_ptr(path, 0, &wpath);
|
||||
file = os_wfopen(wpath, mode);
|
||||
bfree(wpath);
|
||||
|
||||
@@ -95,7 +95,7 @@ size_t os_fread_mbs(FILE *file, char **pstr)
|
||||
}
|
||||
|
||||
mbstr[size] = 0;
|
||||
len = os_mbs_to_utf8(mbstr, size, pstr);
|
||||
len = os_mbs_to_utf8_ptr(mbstr, size, pstr);
|
||||
bfree(mbstr);
|
||||
}
|
||||
|
||||
@@ -180,7 +180,7 @@ bool os_quick_write_mbs_file(const char *path, const char *str, size_t len)
|
||||
if (!f)
|
||||
return false;
|
||||
|
||||
mbs_len = os_utf8_to_mbs(str, len, &mbs);
|
||||
mbs_len = os_utf8_to_mbs_ptr(str, len, &mbs);
|
||||
if (mbs_len)
|
||||
fwrite(mbs, 1, mbs_len, f);
|
||||
bfree(mbs);
|
||||
@@ -205,74 +205,93 @@ bool os_quick_write_utf8_file(const char *path, const char *str, size_t len,
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t os_mbs_to_wcs(const char *str, size_t len, wchar_t **pstr)
|
||||
size_t os_mbs_to_wcs(const char *str, size_t len, wchar_t *dst)
|
||||
{
|
||||
size_t out_len = mbstowcs(NULL, str, len);
|
||||
wchar_t *dst = NULL;
|
||||
size_t out_len = dst ? len : mbstowcs(NULL, str, len);
|
||||
|
||||
if (len) {
|
||||
dst = bmalloc((out_len+1) * sizeof(wchar_t));
|
||||
if (len && dst) {
|
||||
mbstowcs(dst, str, out_len+1);
|
||||
dst[out_len] = 0;
|
||||
}
|
||||
|
||||
*pstr = dst;
|
||||
return out_len;
|
||||
}
|
||||
|
||||
size_t os_utf8_to_wcs(const char *str, size_t len, wchar_t **pstr)
|
||||
size_t os_utf8_to_wcs(const char *str, size_t len, wchar_t *dst)
|
||||
{
|
||||
size_t in_len = len ? len : strlen(str);
|
||||
size_t out_len = utf8_to_wchar(str, in_len, NULL, 0, 0);
|
||||
wchar_t *dst = NULL;
|
||||
size_t out_len = dst ? len : utf8_to_wchar(str, in_len, NULL, 0, 0);
|
||||
|
||||
if (out_len) {
|
||||
dst = bmalloc((out_len+1) * sizeof(wchar_t));
|
||||
if (out_len && dst) {
|
||||
utf8_to_wchar(str, in_len, dst, out_len+1, 0);
|
||||
dst[out_len] = 0;
|
||||
}
|
||||
|
||||
*pstr = dst;
|
||||
return out_len;
|
||||
}
|
||||
|
||||
size_t os_wcs_to_mbs(const wchar_t *str, size_t len, char **pstr)
|
||||
size_t os_wcs_to_mbs(const wchar_t *str, size_t len, char *dst)
|
||||
{
|
||||
size_t out_len = wcstombs(NULL, str, len);
|
||||
char *dst = NULL;
|
||||
size_t out_len = dst ? len : wcstombs(NULL, str, len);
|
||||
|
||||
if (len) {
|
||||
dst = bmalloc(out_len+1);
|
||||
if (len && dst) {
|
||||
wcstombs(dst, str, out_len+1);
|
||||
dst[out_len] = 0;
|
||||
}
|
||||
|
||||
*pstr = dst;
|
||||
return out_len;
|
||||
}
|
||||
|
||||
size_t os_wcs_to_utf8(const wchar_t *str, size_t len, char **pstr)
|
||||
size_t os_wcs_to_utf8(const wchar_t *str, size_t len, char *dst)
|
||||
{
|
||||
size_t in_len = (len != 0) ? len : wcslen(str);
|
||||
size_t out_len = wchar_to_utf8(str, in_len, NULL, 0, 0);
|
||||
char *dst = NULL;
|
||||
size_t out_len = dst ? len : wchar_to_utf8(str, in_len, NULL, 0, 0);
|
||||
|
||||
if (out_len) {
|
||||
dst = bmalloc(out_len+1);
|
||||
if (out_len && dst) {
|
||||
wchar_to_utf8(str, in_len, dst, out_len+1, 0);
|
||||
dst[out_len] = 0;
|
||||
}
|
||||
|
||||
*pstr = dst;
|
||||
return out_len;
|
||||
}
|
||||
|
||||
size_t os_utf8_to_mbs(const char *str, size_t len, char **pstr)
|
||||
size_t os_mbs_to_wcs_ptr(const char *str, size_t len, wchar_t **pstr)
|
||||
{
|
||||
size_t out_len = os_mbs_to_wcs(str, len, NULL);
|
||||
|
||||
*pstr = bmalloc((out_len+1) * sizeof(wchar_t));
|
||||
return os_mbs_to_wcs(str, out_len, *pstr);
|
||||
}
|
||||
|
||||
size_t os_utf8_to_wcs_ptr(const char *str, size_t len, wchar_t **pstr)
|
||||
{
|
||||
size_t out_len = os_utf8_to_wcs(str, len, NULL);
|
||||
*pstr = bmalloc((out_len+1) * sizeof(wchar_t));
|
||||
return os_utf8_to_wcs(str, out_len, *pstr);
|
||||
}
|
||||
|
||||
size_t os_wcs_to_mbs_ptr(const wchar_t *str, size_t len, char **pstr)
|
||||
{
|
||||
size_t out_len = os_wcs_to_mbs(str, len, NULL);
|
||||
|
||||
*pstr = bmalloc((out_len+1) * sizeof(char));
|
||||
return os_wcs_to_mbs(str, out_len, *pstr);
|
||||
}
|
||||
|
||||
size_t os_wcs_to_utf8_ptr(const wchar_t *str, size_t len, char **pstr)
|
||||
{
|
||||
size_t out_len = os_wcs_to_utf8(str, len, NULL);
|
||||
|
||||
*pstr = bmalloc((out_len+1) * sizeof(char));
|
||||
return os_wcs_to_utf8(str, out_len, *pstr);
|
||||
}
|
||||
|
||||
size_t os_utf8_to_mbs_ptr(const char *str, size_t len, char **pstr)
|
||||
{
|
||||
wchar_t *wstr = NULL;
|
||||
char *dst = NULL;
|
||||
size_t wlen = os_utf8_to_wcs(str, len, &wstr);
|
||||
size_t out_len = os_wcs_to_mbs(wstr, wlen, &dst);
|
||||
size_t wlen = os_utf8_to_wcs_ptr(str, len, &wstr);
|
||||
size_t out_len = os_wcs_to_mbs_ptr(wstr, wlen, &dst);
|
||||
|
||||
bfree(wstr);
|
||||
*pstr = dst;
|
||||
@@ -280,12 +299,12 @@ size_t os_utf8_to_mbs(const char *str, size_t len, char **pstr)
|
||||
return out_len;
|
||||
}
|
||||
|
||||
size_t os_mbs_to_utf8(const char *str, size_t len, char **pstr)
|
||||
size_t os_mbs_to_utf8_ptr(const char *str, size_t len, char **pstr)
|
||||
{
|
||||
wchar_t *wstr = NULL;
|
||||
char *dst = NULL;
|
||||
size_t wlen = os_mbs_to_wcs(str, len, &wstr);
|
||||
size_t out_len = os_wcs_to_utf8(wstr, wlen, &dst);
|
||||
size_t wlen = os_mbs_to_wcs_ptr(str, len, &wstr);
|
||||
size_t out_len = os_wcs_to_utf8_ptr(wstr, wlen, &dst);
|
||||
|
||||
bfree(wstr);
|
||||
*pstr = dst;
|
||||
|
@@ -45,13 +45,18 @@ EXPORT char *os_quick_read_mbs_file(const char *path);
|
||||
EXPORT bool os_quick_write_mbs_file(const char *path, const char *str,
|
||||
size_t len);
|
||||
|
||||
EXPORT size_t os_mbs_to_wcs(const char *str, size_t len, wchar_t **pstr);
|
||||
EXPORT size_t os_utf8_to_wcs(const char *str, size_t len, wchar_t **pstr);
|
||||
EXPORT size_t os_wcs_to_mbs(const wchar_t *str, size_t len, char **pstr);
|
||||
EXPORT size_t os_wcs_to_utf8(const wchar_t *str, size_t len, char **pstr);
|
||||
EXPORT size_t os_mbs_to_wcs(const char *str, size_t len, wchar_t *dst);
|
||||
EXPORT size_t os_utf8_to_wcs(const char *str, size_t len, wchar_t *dst);
|
||||
EXPORT size_t os_wcs_to_mbs(const wchar_t *str, size_t len, char *dst);
|
||||
EXPORT size_t os_wcs_to_utf8(const wchar_t *str, size_t len, char *dst);
|
||||
|
||||
EXPORT size_t os_utf8_to_mbs(const char *str, size_t len, char **pstr);
|
||||
EXPORT size_t os_mbs_to_utf8(const char *str, size_t len, char **pstr);
|
||||
EXPORT size_t os_mbs_to_wcs_ptr(const char *str, size_t len, wchar_t **pstr);
|
||||
EXPORT size_t os_utf8_to_wcs_ptr(const char *str, size_t len, wchar_t **pstr);
|
||||
EXPORT size_t os_wcs_to_mbs_ptr(const wchar_t *str, size_t len, char **pstr);
|
||||
EXPORT size_t os_wcs_to_utf8_ptr(const wchar_t *str, size_t len, char **pstr);
|
||||
|
||||
EXPORT size_t os_utf8_to_mbs_ptr(const char *str, size_t len, char **pstr);
|
||||
EXPORT size_t os_mbs_to_utf8_ptr(const char *str, size_t len, char **pstr);
|
||||
|
||||
EXPORT void *os_dlopen(const char *path);
|
||||
EXPORT void *os_dlsym(void *module, const char *func);
|
||||
|
43
libobs/util/windows/CoTaskMemPtr.hpp
Normal file
43
libobs/util/windows/CoTaskMemPtr.hpp
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Hugh Bailey <obs.jim@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
template<typename T> class CoTaskMemPtr {
|
||||
T *ptr;
|
||||
|
||||
inline void Clear() {if (ptr) CoTaskMemFree(ptr);}
|
||||
|
||||
public:
|
||||
inline CoTaskMemPtr() : ptr(NULL) {}
|
||||
inline CoTaskMemPtr(T *ptr_) : ptr(ptr_) {}
|
||||
inline ~CoTaskMemPtr() {Clear();}
|
||||
|
||||
inline operator T*() const {return ptr;}
|
||||
|
||||
inline CoTaskMemPtr& operator=(T* val)
|
||||
{
|
||||
Clear();
|
||||
ptr = val;
|
||||
}
|
||||
|
||||
inline T** operator&()
|
||||
{
|
||||
Clear();
|
||||
ptr = NULL;
|
||||
return &ptr;
|
||||
}
|
||||
};
|
56
libobs/util/windows/WinHandle.hpp
Normal file
56
libobs/util/windows/WinHandle.hpp
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Hugh Bailey <obs.jim@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
class WinHandle {
|
||||
HANDLE handle;
|
||||
|
||||
inline void Clear()
|
||||
{
|
||||
if (handle && handle != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(handle);
|
||||
}
|
||||
|
||||
public:
|
||||
inline WinHandle() : handle(NULL) {}
|
||||
inline WinHandle(HANDLE handle_) : handle(handle_) {}
|
||||
inline ~WinHandle() {Clear();}
|
||||
|
||||
inline operator HANDLE() const {return handle;}
|
||||
|
||||
inline WinHandle& operator=(HANDLE handle_)
|
||||
{
|
||||
if (handle_ != handle) {
|
||||
Clear();
|
||||
handle = handle_;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline HANDLE* operator&()
|
||||
{
|
||||
Clear();
|
||||
handle = NULL;
|
||||
return &handle;
|
||||
}
|
||||
|
||||
inline bool Valid() const
|
||||
{
|
||||
return handle && handle != INVALID_HANDLE_VALUE;
|
||||
}
|
||||
};
|
Reference in New Issue
Block a user