New upstream version 25.0.3+dfsg1

This commit is contained in:
Sebastian Ramacher 2020-03-25 09:07:22 +01:00
parent 04fe0efc67
commit 8b2e5f2130
569 changed files with 62491 additions and 5875 deletions

View file

@ -174,8 +174,20 @@ elseif(UNIX)
util/pipe-posix.c
util/platform-nix.c)
set(libobs_PLATFORM_HEADERS
util/threading-posix.h)
if(NEEDS_SIMDE)
set(libobs_PLATFORM_HEADERS
util/simde/check.h
util/simde/hedley.h
util/simde/mmx.h
util/simde/simde-arch.h
util/simde/simde-common.h
util/simde/sse.h
util/simde/sse2.h
util/threading-posix.h)
else()
set(libobs_PLATFORM_HEADERS
util/threading-posix.h)
endif()
if(HAVE_PULSEAUDIO)
set(libobs_audio_monitoring_HEADERS
@ -278,6 +290,7 @@ set(libobs_graphics_SOURCES
graphics/math-extra.c
graphics/graphics-imports.c)
set(libobs_graphics_HEADERS
graphics/half.h
graphics/plane.h
graphics/quat.h
graphics/input.h
@ -337,15 +350,14 @@ set(libobs_util_SOURCES
util/cf-parser.c
util/profiler.c)
set(libobs_util_HEADERS
util/curl/curl-helper.h
util/sse-intrin.h
util/array-serializer.h
util/file-serializer.h
util/utf8.h
util/crc32.h
util/base.h
util/text-lookup.h
util/vc/vc_inttypes.h
util/vc/vc_stdbool.h
util/vc/vc_stdint.h
util/bmem.h
util/c99defs.h
util/util_uint128.h
@ -465,19 +477,9 @@ target_compile_definitions(libobs
PUBLIC
HAVE_OBSCONFIG_H)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)64le")
target_compile_options(libobs
PUBLIC
-mvsx)
add_compile_definitions(NO_WARN_X86_INTRINSICS)
elseif(NOT MSVC)
target_compile_options(libobs
PUBLIC
-mmmx
-msse
-msse2)
endif()
target_compile_options(libobs
PUBLIC
${ARCH_SIMD_FLAGS})
target_compile_options(libobs
PUBLIC

View file

@ -287,7 +287,7 @@ static void pulseaudio_source_info(pa_context *c, const pa_source_info *i,
{
UNUSED_PARAMETER(c);
PULSE_DATA(userdata);
// An error occured
// An error occurred
if (eol < 0) {
data->format = PA_SAMPLE_INVALID;
goto skip;

View file

@ -48,10 +48,16 @@ void get_default_id(char **id)
bzalloc(sizeof(struct pulseaudio_default_output));
pulseaudio_get_server_info(
(pa_server_info_cb_t)pulseaudio_default_devices, (void *)pdo);
*id = bzalloc(strlen(pdo->default_sink_name) + 9);
strcat(*id, pdo->default_sink_name);
strcat(*id, ".monitor");
bfree(pdo->default_sink_name);
if (!pdo->default_sink_name || !*pdo->default_sink_name) {
*id = NULL;
} else {
*id = bzalloc(strlen(pdo->default_sink_name) + 9);
strcat(*id, pdo->default_sink_name);
strcat(*id, ".monitor");
bfree(pdo->default_sink_name);
}
bfree(pdo);
pulseaudio_unref();
}

View file

@ -79,7 +79,7 @@ void pulseaudio_wait();
/**
* Wait for accept signal from calling thread
*
* This function tells the pulseaudio mainloop wheter the data provided to
* This function tells the pulseaudio mainloop whether the data provided to
* the callback should be retained until the calling thread executes
* pulseaudio_accept()
*

View file

@ -52,7 +52,8 @@ device_cubetexture_create(gs_device_t *device, uint32_t size,
EXPORT gs_texture_t *
device_voltexture_create(gs_device_t *device, uint32_t width, uint32_t height,
uint32_t depth, enum gs_color_format color_format,
uint32_t levels, const uint8_t **data, uint32_t flags);
uint32_t levels, const uint8_t *const *data,
uint32_t flags);
EXPORT gs_zstencil_t *device_zstencil_create(gs_device_t *device,
uint32_t width, uint32_t height,
enum gs_zstencil_format format);
@ -113,6 +114,7 @@ EXPORT void device_copy_texture_region(gs_device_t *device, gs_texture_t *dst,
uint32_t src_h);
EXPORT void device_stage_texture(gs_device_t *device, gs_stagesurf_t *dst,
gs_texture_t *src);
EXPORT void device_begin_frame(gs_device_t *device);
EXPORT void device_begin_scene(gs_device_t *device);
EXPORT void device_draw(gs_device_t *device, enum gs_draw_mode draw_mode,
uint32_t start_vert, uint32_t num_verts);

View file

@ -85,6 +85,7 @@ bool load_graphics_imports(struct gs_exports *exports, void *module,
GRAPHICS_IMPORT(device_copy_texture_region);
GRAPHICS_IMPORT(device_copy_texture);
GRAPHICS_IMPORT(device_stage_texture);
GRAPHICS_IMPORT(device_begin_frame);
GRAPHICS_IMPORT(device_begin_scene);
GRAPHICS_IMPORT(device_draw);
GRAPHICS_IMPORT(device_load_swapchain);
@ -213,6 +214,8 @@ bool load_graphics_imports(struct gs_exports *exports, void *module,
GRAPHICS_IMPORT_OPTIONAL(device_texture_release_sync);
GRAPHICS_IMPORT_OPTIONAL(device_texture_create_nv12);
GRAPHICS_IMPORT_OPTIONAL(device_stagesurface_create_nv12);
GRAPHICS_IMPORT_OPTIONAL(device_register_loss_callbacks);
GRAPHICS_IMPORT_OPTIONAL(device_unregister_loss_callbacks);
#endif
return success;

View file

@ -53,7 +53,7 @@ struct gs_exports {
gs_texture_t *(*device_voltexture_create)(
gs_device_t *device, uint32_t width, uint32_t height,
uint32_t depth, enum gs_color_format color_format,
uint32_t levels, const uint8_t **data, uint32_t flags);
uint32_t levels, const uint8_t *const *data, uint32_t flags);
gs_zstencil_t *(*device_zstencil_create)(
gs_device_t *device, uint32_t width, uint32_t height,
enum gs_zstencil_format format);
@ -115,6 +115,7 @@ struct gs_exports {
uint32_t src_w, uint32_t src_h);
void (*device_stage_texture)(gs_device_t *device, gs_stagesurf_t *dst,
gs_texture_t *src);
void (*device_begin_frame)(gs_device_t *device);
void (*device_begin_scene)(gs_device_t *device);
void (*device_draw)(gs_device_t *device, enum gs_draw_mode draw_mode,
uint32_t start_vert, uint32_t num_verts);
@ -310,6 +311,10 @@ struct gs_exports {
gs_stagesurf_t *(*device_stagesurface_create_nv12)(gs_device_t *device,
uint32_t width,
uint32_t height);
void (*device_register_loss_callbacks)(
gs_device_t *device, const struct gs_device_loss *callbacks);
void (*device_unregister_loss_callbacks)(gs_device_t *device,
void *data);
#endif
};

View file

@ -1737,6 +1737,16 @@ void gs_stage_texture(gs_stagesurf_t *dst, gs_texture_t *src)
graphics->exports.device_stage_texture(graphics->device, dst, src);
}
void gs_begin_frame(void)
{
graphics_t *graphics = thread_graphics;
if (!gs_valid("gs_begin_frame"))
return;
graphics->exports.device_begin_frame(graphics->device);
}
void gs_begin_scene(void)
{
graphics_t *graphics = thread_graphics;
@ -2952,4 +2962,28 @@ gs_stagesurf_t *gs_stagesurface_create_nv12(uint32_t width, uint32_t height)
return NULL;
}
void gs_register_loss_callbacks(const struct gs_device_loss *callbacks)
{
graphics_t *graphics = thread_graphics;
if (!gs_valid("gs_register_loss_callbacks"))
return;
if (graphics->exports.device_register_loss_callbacks)
graphics->exports.device_register_loss_callbacks(
graphics->device, callbacks);
}
void gs_unregister_loss_callbacks(void *data)
{
graphics_t *graphics = thread_graphics;
if (!gs_valid("gs_unregister_loss_callbacks"))
return;
if (graphics->exports.device_unregister_loss_callbacks)
graphics->exports.device_unregister_loss_callbacks(
graphics->device, data);
}
#endif

View file

@ -169,6 +169,12 @@ enum gs_texture_type {
GS_TEXTURE_CUBE,
};
struct gs_device_loss {
void (*device_loss_release)(void *data);
void (*device_loss_rebuild)(void *device, void *data);
void *data;
};
struct gs_monitor_info {
int rotation_degrees;
long x;
@ -668,6 +674,7 @@ EXPORT void gs_copy_texture_region(gs_texture_t *dst, uint32_t dst_x,
uint32_t src_w, uint32_t src_h);
EXPORT void gs_stage_texture(gs_stagesurf_t *dst, gs_texture_t *src);
EXPORT void gs_begin_frame(void);
EXPORT void gs_begin_scene(void);
EXPORT void gs_draw(enum gs_draw_mode draw_mode, uint32_t start_vert,
uint32_t num_verts);
@ -882,6 +889,9 @@ EXPORT bool gs_texture_create_nv12(gs_texture_t **tex_y, gs_texture_t **tex_uv,
EXPORT gs_stagesurf_t *gs_stagesurface_create_nv12(uint32_t width,
uint32_t height);
EXPORT void gs_register_loss_callbacks(const struct gs_device_loss *callbacks);
EXPORT void gs_unregister_loss_callbacks(void *data);
#endif
/* inline functions used by modules */
@ -937,10 +947,12 @@ static inline bool gs_is_compressed_format(enum gs_color_format format)
return (format == GS_DXT1 || format == GS_DXT3 || format == GS_DXT5);
}
static inline uint32_t gs_get_total_levels(uint32_t width, uint32_t height)
static inline uint32_t gs_get_total_levels(uint32_t width, uint32_t height,
uint32_t depth)
{
uint32_t size = width > height ? width : height;
uint32_t num_levels = 0;
size = size > depth ? size : depth;
uint32_t num_levels = 1;
while (size > 1) {
size /= 2;

102
libobs/graphics/half.h Normal file
View file

@ -0,0 +1,102 @@
/******************************************************************************
Copyright (C) 2020 by Hugh Bailey <obs.jim@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
/******************************************************************************
The MIT License (MIT)
Copyright (c) 2011-2019 Microsoft Corp
Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be included in all copies
or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
******************************************************************************/
#pragma once
#include "math-defs.h"
#ifdef __cplusplus
extern "C" {
#endif
struct half {
uint16_t u;
};
/* adapted from DirectXMath XMConvertFloatToHalf */
static struct half half_from_float(float f)
{
uint32_t Result;
uint32_t IValue;
memcpy(&IValue, &f, sizeof(IValue));
uint32_t Sign = (IValue & 0x80000000U) >> 16U;
IValue = IValue & 0x7FFFFFFFU; // Hack off the sign
if (IValue > 0x477FE000U) {
// The number is too large to be represented as a half. Saturate to infinity.
if (((IValue & 0x7F800000) == 0x7F800000) &&
((IValue & 0x7FFFFF) != 0)) {
Result = 0x7FFF; // NAN
} else {
Result = 0x7C00U; // INF
}
} else if (!IValue) {
Result = 0;
} else {
if (IValue < 0x38800000U) {
// The number is too small to be represented as a normalized half.
// Convert it to a denormalized value.
uint32_t Shift = 113U - (IValue >> 23U);
IValue = (0x800000U | (IValue & 0x7FFFFFU)) >> Shift;
} else {
// Rebias the exponent to represent the value as a normalized half.
IValue += 0xC8000000U;
}
Result = ((IValue + 0x0FFFU + ((IValue >> 13U) & 1U)) >> 13U) &
0x7FFFU;
}
struct half h;
h.u = (uint16_t)(Result | Sign);
return h;
}
static struct half half_from_bits(uint16_t u)
{
struct half h;
h.u = u;
return h;
}
#ifdef __cplusplus
}
#endif

View file

@ -41,7 +41,7 @@
'buffer_position' should initially be 0, and will be internally updated
as the decoding commences. The caller should then repeatedly call
gif_initialise() with the structure until the function returns 1, or
no more data is avaliable.
no more data is available.
Once the initialisation has begun, the decoder completes the variables
'frame_count' and 'frame_count_partial'. The former being the total
@ -54,7 +54,7 @@
the current 'frame_image' to reflect the desired frame. The required
'disposal_method' is also updated to reflect how the frame should be
plotted. The caller must not assume that the current 'frame_image' will
be valid between calls if initialisation is still occuring, and should
be valid between calls if initialisation is still occurring, and should
either always request that the frame is decoded (no processing will
occur if the 'decoded_frame' has not been invalidated by initialisation)
or perform the check itself.

View file

@ -51,7 +51,7 @@ typedef struct gif_frame {
bool opaque; /**< whether the frame is totally opaque */
bool redraw_required; /**< whether a forcable screen redraw is required */
unsigned char disposal_method; /**< how the previous frame should be disposed; affects plotting */
bool transparency; /**< whether we acknoledge transparency */
bool transparency; /**< whether we acknowledge transparency */
unsigned char transparency_index; /**< the index designating a transparent pixel */
unsigned int redraw_x; /**< x co-ordinate of redraw rectangle */
unsigned int redraw_y; /**< y co-ordinate of redraw rectangle */
@ -78,7 +78,7 @@ typedef struct gif_bitmap_callback_vt {
*/
gif_bitmap_cb_set_opaque bitmap_set_opaque; /**< Sets whether a bitmap should be plotted opaque. */
gif_bitmap_cb_test_opaque bitmap_test_opaque; /**< Tests whether a bitmap has an opaque alpha channel. */
gif_bitmap_cb_modified bitmap_modified; /**< The bitmap image has changed, so flush any persistant cache. */
gif_bitmap_cb_modified bitmap_modified; /**< The bitmap image has changed, so flush any persistent cache. */
} gif_bitmap_callback_vt;
/* The GIF animation data
@ -87,7 +87,7 @@ typedef struct gif_animation {
gif_bitmap_callback_vt bitmap_callbacks; /**< callbacks for bitmap functions */
unsigned char *gif_data; /**< pointer to GIF data */
unsigned int width; /**< width of GIF (may increase during decoding) */
unsigned int height; /**< heigth of GIF (may increase during decoding) */
unsigned int height; /**< height of GIF (may increase during decoding) */
unsigned int frame_count; /**< number of frames decoded */
unsigned int frame_count_partial; /**< number of frames partially decoded */
gif_frame *frames; /**< decoded frames */

View file

@ -20,7 +20,8 @@
#include "../util/c99defs.h"
#include "math-defs.h"
#include "vec3.h"
#include <xmmintrin.h>
#include "../util/sse-intrin.h"
/*
* Quaternion math

View file

@ -19,7 +19,8 @@
#include "math-defs.h"
#include "vec4.h"
#include <xmmintrin.h>
#include "../util/sse-intrin.h"
#ifdef __cplusplus
extern "C" {

View file

@ -18,7 +18,8 @@
#pragma once
#include "math-defs.h"
#include <xmmintrin.h>
#include "../util/sse-intrin.h"
#ifdef __cplusplus
extern "C" {

View file

@ -16,8 +16,8 @@
******************************************************************************/
#include "format-conversion.h"
#include <xmmintrin.h>
#include <emmintrin.h>
#include "../util/sse-intrin.h"
/* ...surprisingly, if I don't use a macro to force inlining, it causes the
* CPU usage to boost by a tremendous amount in debug builds. */

View file

@ -74,6 +74,7 @@ enum video_colorspace {
VIDEO_CS_DEFAULT,
VIDEO_CS_601,
VIDEO_CS_709,
VIDEO_CS_SRGB,
};
enum video_range_type {
@ -176,7 +177,8 @@ static inline const char *get_video_colorspace_name(enum video_colorspace cs)
case VIDEO_CS_709:
return "709";
case VIDEO_CS_601:
case VIDEO_CS_DEFAULT:;
case VIDEO_CS_DEFAULT:
case VIDEO_CS_SRGB:;
}
return "601";

View file

@ -94,9 +94,9 @@ static inline const int *get_ffmpeg_coeffs(enum video_colorspace cs)
return sws_getCoefficients(SWS_CS_ITU601);
case VIDEO_CS_709:
return sws_getCoefficients(SWS_CS_ITU709);
default:
return sws_getCoefficients(SWS_CS_ITU601);
}
return sws_getCoefficients(SWS_CS_ITU601);
}
static inline int get_ffmpeg_range_type(enum video_range_type type)

View file

@ -16,7 +16,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <math.h>
#include <xmmintrin.h>
#include "util/sse-intrin.h"
#include "util/threading.h"
#include "util/bmem.h"

View file

@ -27,7 +27,7 @@
/*
* Increment if major breaking API changes
*/
#define LIBOBS_API_MAJOR_VER 24
#define LIBOBS_API_MAJOR_VER 25
/*
* Increment if backward-compatible additions
@ -41,7 +41,7 @@
*
* Reset to zero each major or minor version
*/
#define LIBOBS_API_PATCH_VER 6
#define LIBOBS_API_PATCH_VER 3
#define MAKE_SEMANTIC_VERSION(major, minor, patch) \
((major << 24) | (minor << 16) | patch)

View file

@ -694,6 +694,14 @@ void obs_encoder_set_scaled_size(obs_encoder_t *encoder, uint32_t width,
encoder->scaled_height = height;
}
bool obs_encoder_scaling_enabled(const obs_encoder_t *encoder)
{
if (!obs_encoder_valid(encoder, "obs_encoder_scaling_enabled"))
return false;
return encoder->scaled_width || encoder->scaled_height;
}
uint32_t obs_encoder_get_width(const obs_encoder_t *encoder)
{
if (!obs_encoder_valid(encoder, "obs_encoder_get_width"))
@ -1309,12 +1317,14 @@ void obs_encoder_packet_create_instance(struct encoder_packet *dst,
memcpy(dst->data, src->data, src->size);
}
/* OBS_DEPRECATED */
void obs_duplicate_encoder_packet(struct encoder_packet *dst,
const struct encoder_packet *src)
{
obs_encoder_packet_create_instance(dst, src);
}
/* OBS_DEPRECATED */
void obs_free_encoder_packet(struct encoder_packet *packet)
{
obs_encoder_packet_release(packet);

View file

@ -32,6 +32,7 @@ extern "C" {
#define OBS_ENCODER_CAP_DEPRECATED (1 << 0)
#define OBS_ENCODER_CAP_PASS_TEXTURE (1 << 1)
#define OBS_ENCODER_CAP_DYN_BITRATE (1 << 2)
#define OBS_ENCODER_CAP_INTERNAL (1 << 3)
/** Specifies the encoder type */
enum obs_encoder_type {

View file

@ -476,3 +476,178 @@ OBS_MOUSE_BUTTON(OBS_KEY_MOUSE29)
#endif
OBS_HOTKEY(OBS_KEY_BACKSLASH_RT102)
OBS_HOTKEY(OBS_KEY_OPEN)
OBS_HOTKEY(OBS_KEY_FIND)
OBS_HOTKEY(OBS_KEY_REDO)
OBS_HOTKEY(OBS_KEY_UNDO)
OBS_HOTKEY(OBS_KEY_FRONT)
OBS_HOTKEY(OBS_KEY_PROPS)
OBS_HOTKEY(OBS_KEY_VK_CANCEL)
OBS_HOTKEY(OBS_KEY_0x07)
OBS_HOTKEY(OBS_KEY_0x0A)
OBS_HOTKEY(OBS_KEY_0x0B)
OBS_HOTKEY(OBS_KEY_0x0E)
OBS_HOTKEY(OBS_KEY_0x0F)
OBS_HOTKEY(OBS_KEY_0x16)
OBS_HOTKEY(OBS_KEY_VK_JUNJA)
OBS_HOTKEY(OBS_KEY_VK_FINAL)
OBS_HOTKEY(OBS_KEY_0x1A)
OBS_HOTKEY(OBS_KEY_VK_ACCEPT)
OBS_HOTKEY(OBS_KEY_VK_MODECHANGE)
OBS_HOTKEY(OBS_KEY_VK_SELECT)
OBS_HOTKEY(OBS_KEY_VK_PRINT)
OBS_HOTKEY(OBS_KEY_VK_EXECUTE)
OBS_HOTKEY(OBS_KEY_VK_HELP)
OBS_HOTKEY(OBS_KEY_0x30)
OBS_HOTKEY(OBS_KEY_0x31)
OBS_HOTKEY(OBS_KEY_0x32)
OBS_HOTKEY(OBS_KEY_0x33)
OBS_HOTKEY(OBS_KEY_0x34)
OBS_HOTKEY(OBS_KEY_0x35)
OBS_HOTKEY(OBS_KEY_0x36)
OBS_HOTKEY(OBS_KEY_0x37)
OBS_HOTKEY(OBS_KEY_0x38)
OBS_HOTKEY(OBS_KEY_0x39)
OBS_HOTKEY(OBS_KEY_0x3A)
OBS_HOTKEY(OBS_KEY_0x3B)
OBS_HOTKEY(OBS_KEY_0x3C)
OBS_HOTKEY(OBS_KEY_0x3D)
OBS_HOTKEY(OBS_KEY_0x3E)
OBS_HOTKEY(OBS_KEY_0x3F)
OBS_HOTKEY(OBS_KEY_0x40)
OBS_HOTKEY(OBS_KEY_0x41)
OBS_HOTKEY(OBS_KEY_0x42)
OBS_HOTKEY(OBS_KEY_0x43)
OBS_HOTKEY(OBS_KEY_0x44)
OBS_HOTKEY(OBS_KEY_0x45)
OBS_HOTKEY(OBS_KEY_0x46)
OBS_HOTKEY(OBS_KEY_0x47)
OBS_HOTKEY(OBS_KEY_0x48)
OBS_HOTKEY(OBS_KEY_0x49)
OBS_HOTKEY(OBS_KEY_0x4A)
OBS_HOTKEY(OBS_KEY_0x4B)
OBS_HOTKEY(OBS_KEY_0x4C)
OBS_HOTKEY(OBS_KEY_0x4D)
OBS_HOTKEY(OBS_KEY_0x4E)
OBS_HOTKEY(OBS_KEY_0x4F)
OBS_HOTKEY(OBS_KEY_0x50)
OBS_HOTKEY(OBS_KEY_0x51)
OBS_HOTKEY(OBS_KEY_0x52)
OBS_HOTKEY(OBS_KEY_0x53)
OBS_HOTKEY(OBS_KEY_0x54)
OBS_HOTKEY(OBS_KEY_0x55)
OBS_HOTKEY(OBS_KEY_0x56)
OBS_HOTKEY(OBS_KEY_0x57)
OBS_HOTKEY(OBS_KEY_0x58)
OBS_HOTKEY(OBS_KEY_0x59)
OBS_HOTKEY(OBS_KEY_0x5A)
OBS_HOTKEY(OBS_KEY_VK_LWIN)
OBS_HOTKEY(OBS_KEY_VK_RWIN)
OBS_HOTKEY(OBS_KEY_VK_APPS)
OBS_HOTKEY(OBS_KEY_0x5E)
OBS_HOTKEY(OBS_KEY_VK_SLEEP)
OBS_HOTKEY(OBS_KEY_VK_SEPARATOR)
OBS_HOTKEY(OBS_KEY_0x88)
OBS_HOTKEY(OBS_KEY_0x89)
OBS_HOTKEY(OBS_KEY_0x8A)
OBS_HOTKEY(OBS_KEY_0x8B)
OBS_HOTKEY(OBS_KEY_0x8C)
OBS_HOTKEY(OBS_KEY_0x8D)
OBS_HOTKEY(OBS_KEY_0x8E)
OBS_HOTKEY(OBS_KEY_0x8F)
OBS_HOTKEY(OBS_KEY_VK_OEM_FJ_JISHO)
OBS_HOTKEY(OBS_KEY_VK_OEM_FJ_LOYA)
OBS_HOTKEY(OBS_KEY_VK_OEM_FJ_ROYA)
OBS_HOTKEY(OBS_KEY_0x97)
OBS_HOTKEY(OBS_KEY_0x98)
OBS_HOTKEY(OBS_KEY_0x99)
OBS_HOTKEY(OBS_KEY_0x9A)
OBS_HOTKEY(OBS_KEY_0x9B)
OBS_HOTKEY(OBS_KEY_0x9C)
OBS_HOTKEY(OBS_KEY_0x9D)
OBS_HOTKEY(OBS_KEY_0x9E)
OBS_HOTKEY(OBS_KEY_0x9F)
OBS_HOTKEY(OBS_KEY_VK_LSHIFT)
OBS_HOTKEY(OBS_KEY_VK_RSHIFT)
OBS_HOTKEY(OBS_KEY_VK_LCONTROL)
OBS_HOTKEY(OBS_KEY_VK_RCONTROL)
OBS_HOTKEY(OBS_KEY_VK_LMENU)
OBS_HOTKEY(OBS_KEY_VK_RMENU)
OBS_HOTKEY(OBS_KEY_VK_BROWSER_BACK)
OBS_HOTKEY(OBS_KEY_VK_BROWSER_FORWARD)
OBS_HOTKEY(OBS_KEY_VK_BROWSER_REFRESH)
OBS_HOTKEY(OBS_KEY_VK_BROWSER_STOP)
OBS_HOTKEY(OBS_KEY_VK_BROWSER_SEARCH)
OBS_HOTKEY(OBS_KEY_VK_BROWSER_FAVORITES)
OBS_HOTKEY(OBS_KEY_VK_BROWSER_HOME)
OBS_HOTKEY(OBS_KEY_VK_VOLUME_MUTE)
OBS_HOTKEY(OBS_KEY_VK_VOLUME_DOWN)
OBS_HOTKEY(OBS_KEY_VK_VOLUME_UP)
OBS_HOTKEY(OBS_KEY_VK_MEDIA_NEXT_TRACK)
OBS_HOTKEY(OBS_KEY_VK_MEDIA_PREV_TRACK)
OBS_HOTKEY(OBS_KEY_VK_MEDIA_STOP)
OBS_HOTKEY(OBS_KEY_VK_MEDIA_PLAY_PAUSE)
OBS_HOTKEY(OBS_KEY_VK_LAUNCH_MAIL)
OBS_HOTKEY(OBS_KEY_VK_LAUNCH_MEDIA_SELECT)
OBS_HOTKEY(OBS_KEY_VK_LAUNCH_APP1)
OBS_HOTKEY(OBS_KEY_VK_LAUNCH_APP2)
OBS_HOTKEY(OBS_KEY_0xB8)
OBS_HOTKEY(OBS_KEY_0xB9)
OBS_HOTKEY(OBS_KEY_0xC1)
OBS_HOTKEY(OBS_KEY_0xC2)
OBS_HOTKEY(OBS_KEY_0xC3)
OBS_HOTKEY(OBS_KEY_0xC4)
OBS_HOTKEY(OBS_KEY_0xC5)
OBS_HOTKEY(OBS_KEY_0xC6)
OBS_HOTKEY(OBS_KEY_0xC7)
OBS_HOTKEY(OBS_KEY_0xC8)
OBS_HOTKEY(OBS_KEY_0xC9)
OBS_HOTKEY(OBS_KEY_0xCA)
OBS_HOTKEY(OBS_KEY_0xCB)
OBS_HOTKEY(OBS_KEY_0xCC)
OBS_HOTKEY(OBS_KEY_0xCD)
OBS_HOTKEY(OBS_KEY_0xCE)
OBS_HOTKEY(OBS_KEY_0xCF)
OBS_HOTKEY(OBS_KEY_0xD0)
OBS_HOTKEY(OBS_KEY_0xD1)
OBS_HOTKEY(OBS_KEY_0xD2)
OBS_HOTKEY(OBS_KEY_0xD3)
OBS_HOTKEY(OBS_KEY_0xD4)
OBS_HOTKEY(OBS_KEY_0xD5)
OBS_HOTKEY(OBS_KEY_0xD6)
OBS_HOTKEY(OBS_KEY_0xD7)
OBS_HOTKEY(OBS_KEY_0xD8)
OBS_HOTKEY(OBS_KEY_0xD9)
OBS_HOTKEY(OBS_KEY_0xDA)
OBS_HOTKEY(OBS_KEY_VK_OEM_8)
OBS_HOTKEY(OBS_KEY_0xE0)
OBS_HOTKEY(OBS_KEY_VK_OEM_AX)
OBS_HOTKEY(OBS_KEY_VK_ICO_HELP)
OBS_HOTKEY(OBS_KEY_VK_ICO_00)
OBS_HOTKEY(OBS_KEY_VK_PROCESSKEY)
OBS_HOTKEY(OBS_KEY_VK_ICO_CLEAR)
OBS_HOTKEY(OBS_KEY_VK_PACKET)
OBS_HOTKEY(OBS_KEY_0xE8)
OBS_HOTKEY(OBS_KEY_VK_OEM_RESET)
OBS_HOTKEY(OBS_KEY_VK_OEM_JUMP)
OBS_HOTKEY(OBS_KEY_VK_OEM_PA1)
OBS_HOTKEY(OBS_KEY_VK_OEM_PA2)
OBS_HOTKEY(OBS_KEY_VK_OEM_PA3)
OBS_HOTKEY(OBS_KEY_VK_OEM_WSCTRL)
OBS_HOTKEY(OBS_KEY_VK_OEM_CUSEL)
OBS_HOTKEY(OBS_KEY_VK_OEM_ATTN)
OBS_HOTKEY(OBS_KEY_VK_OEM_FINISH)
OBS_HOTKEY(OBS_KEY_VK_OEM_COPY)
OBS_HOTKEY(OBS_KEY_VK_OEM_AUTO)
OBS_HOTKEY(OBS_KEY_VK_OEM_ENLW)
OBS_HOTKEY(OBS_KEY_VK_ATTN)
OBS_HOTKEY(OBS_KEY_VK_CRSEL)
OBS_HOTKEY(OBS_KEY_VK_EXSEL)
OBS_HOTKEY(OBS_KEY_VK_EREOF)
OBS_HOTKEY(OBS_KEY_VK_PLAY)
OBS_HOTKEY(OBS_KEY_VK_ZOOM)
OBS_HOTKEY(OBS_KEY_VK_NONAME)
OBS_HOTKEY(OBS_KEY_VK_PA1)
OBS_HOTKEY(OBS_KEY_VK_OEM_CLEAR)

View file

@ -234,6 +234,11 @@ struct obs_tex_frame {
bool released;
};
struct obs_task_info {
obs_task_t task;
void *param;
};
struct obs_core_video {
graphics_t *graphics;
gs_stagesurf_t *copy_surfaces[NUM_TEXTURES][NUM_CHANNELS];
@ -306,6 +311,9 @@ struct obs_core_video {
gs_effect_t *deinterlace_yadif_2x_effect;
struct obs_video_info ovi;
pthread_mutex_t task_mutex;
struct circlebuf tasks;
};
struct audio_monitor;
@ -420,6 +428,8 @@ struct obs_core {
struct obs_core_audio audio;
struct obs_core_data data;
struct obs_core_hotkeys hotkeys;
obs_task_handler_t ui_task_handler;
};
extern struct obs_core *obs;
@ -641,6 +651,7 @@ struct obs_source {
bool async_cache_full_range;
enum gs_color_format async_texture_formats[MAX_AV_PLANES];
int async_channel_count;
long async_rotation;
bool async_flip;
bool async_active;
bool async_update_texture;
@ -700,6 +711,10 @@ struct obs_source {
gs_texrender_t *transition_texrender[2];
pthread_mutex_t transition_mutex;
obs_source_t *transition_sources[2];
float transition_manual_clamp;
float transition_manual_torque;
float transition_manual_target;
float transition_manual_val;
bool transitioning_video;
bool transitioning_audio;
bool transition_source_active[2];
@ -721,13 +736,15 @@ struct obs_source {
};
extern struct obs_source_info *get_source_info(const char *id);
extern struct obs_source_info *get_source_info2(const char *unversioned_id,
uint32_t ver);
extern bool obs_source_init_context(struct obs_source *source,
obs_data_t *settings, const char *name,
obs_data_t *hotkey_data, bool private);
extern bool obs_transition_init(obs_source_t *transition);
extern void obs_transition_free(obs_source_t *transition);
extern void obs_transition_tick(obs_source_t *transition);
extern void obs_transition_tick(obs_source_t *transition, float t);
extern void obs_transition_enum_sources(obs_source_t *transition,
obs_source_enum_proc_t enum_callback,
void *param);

View file

@ -581,7 +581,7 @@ void obs_register_source_s(const struct obs_source_info *info, size_t size)
goto error;
}
if (get_source_info(info->id)) {
if (get_source_info2(info->id, info->version)) {
source_warn("Source '%s' already exists! "
"Duplicate library?",
info->id);
@ -650,6 +650,17 @@ void obs_register_source_s(const struct obs_source_info *info, size_t size)
goto error;
}
/* version-related stuff */
data.unversioned_id = data.id;
if (data.version) {
struct dstr versioned_id = {0};
dstr_printf(&versioned_id, "%s_v%d", data.id,
(int)data.version);
data.id = versioned_id.array;
} else {
data.id = bstrdup(data.id);
}
if (array)
darray_push_back(sizeof(struct obs_source_info), array, &data);
da_push_back(obs->source_types, &data);

View file

@ -35,6 +35,8 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xlib-xcb.h>
#include <X11/XF86keysym.h>
#include <X11/Sunkeysym.h>
#include <inttypes.h>
const char *get_module_extension(void)
@ -501,9 +503,30 @@ static int get_keysym(obs_key_t key)
return XK_Hyper_R;
case OBS_KEY_HELP:
return XK_Help;
case OBS_KEY_CANCEL:
return XK_Cancel;
case OBS_KEY_FIND:
return XK_Find;
case OBS_KEY_REDO:
return XK_Redo;
case OBS_KEY_UNDO:
return XK_Undo;
case OBS_KEY_SPACE:
return XK_space;
case OBS_KEY_COPY:
return XF86XK_Copy;
case OBS_KEY_CUT:
return XF86XK_Cut;
case OBS_KEY_OPEN:
return XF86XK_Open;
case OBS_KEY_PASTE:
return XF86XK_Paste;
case OBS_KEY_FRONT:
return SunXK_Front;
case OBS_KEY_PROPS:
return SunXK_Props;
case OBS_KEY_EXCLAM:
return XK_exclam;
case OBS_KEY_QUOTEDBL:

View file

@ -55,6 +55,7 @@ struct path_data {
struct text_data {
enum obs_text_type type;
bool monospace;
};
struct list_data {
@ -330,9 +331,32 @@ void obs_properties_remove_by_name(obs_properties_t *props, const char *name)
while (cur) {
if (strcmp(cur->name, name) == 0) {
// Fix props->last pointer.
if (props->last == &cur->next) {
if (cur == prev) {
// If we are the last entry and there
// is no previous entry, reset.
props->last = &props->first_property;
} else {
// If we are the last entry and there
// is a previous entry, update.
props->last = &prev->next;
}
}
// Fix props->first_property.
if (props->first_property == cur)
props->first_property = cur->next;
// Update the previous element next pointer with our
// next pointer. This is an automatic no-op if both
// elements alias the same memory.
prev->next = cur->next;
cur->next = 0;
// Finally clear our own next pointer and destroy.
cur->next = NULL;
obs_property_destroy(cur);
break;
}
@ -978,6 +1002,12 @@ enum obs_text_type obs_property_text_type(obs_property_t *p)
return data ? data->type : OBS_TEXT_DEFAULT;
}
enum obs_text_type obs_property_text_monospace(obs_property_t *p)
{
struct text_data *data = get_type_data(p, OBS_PROPERTY_TEXT);
return data ? data->monospace : false;
}
enum obs_path_type obs_property_path_type(obs_property_t *p)
{
struct path_data *data = get_type_data(p, OBS_PROPERTY_PATH);
@ -1051,6 +1081,15 @@ void obs_property_float_set_suffix(obs_property_t *p, const char *suffix)
data->suffix = bstrdup(suffix);
}
void obs_property_text_set_monospace(obs_property_t *p, bool monospace)
{
struct text_data *data = get_type_data(p, OBS_PROPERTY_TEXT);
if (!data)
return;
data->monospace = monospace;
}
void obs_property_list_clear(obs_property_t *p)
{
struct list_data *data = get_list_data(p);

View file

@ -313,6 +313,7 @@ EXPORT double obs_property_float_step(obs_property_t *p);
EXPORT enum obs_number_type obs_property_float_type(obs_property_t *p);
EXPORT const char *obs_property_float_suffix(obs_property_t *p);
EXPORT enum obs_text_type obs_property_text_type(obs_property_t *p);
EXPORT enum obs_text_type obs_property_text_monospace(obs_property_t *p);
EXPORT enum obs_path_type obs_property_path_type(obs_property_t *p);
EXPORT const char *obs_property_path_filter(obs_property_t *p);
EXPORT const char *obs_property_path_default_path(obs_property_t *p);
@ -326,6 +327,7 @@ EXPORT void obs_property_float_set_limits(obs_property_t *p, double min,
EXPORT void obs_property_int_set_suffix(obs_property_t *p, const char *suffix);
EXPORT void obs_property_float_set_suffix(obs_property_t *p,
const char *suffix);
EXPORT void obs_property_text_set_monospace(obs_property_t *p, bool monospace);
EXPORT void obs_property_list_clear(obs_property_t *p);
@ -395,7 +397,7 @@ EXPORT enum obs_group_type obs_property_group_type(obs_property_t *p);
EXPORT obs_properties_t *obs_property_group_content(obs_property_t *p);
#ifndef SWIG
DEPRECATED
OBS_DEPRECATED
EXPORT enum obs_text_type obs_proprety_text_type(obs_property_t *p);
#endif

View file

@ -48,6 +48,7 @@ static const char *obs_scene_signals[] = {
"void item_add(ptr scene, ptr item)",
"void item_remove(ptr scene, ptr item)",
"void reorder(ptr scene)",
"void refresh(ptr scene)",
"void item_visible(ptr scene, ptr item, bool visible)",
"void item_select(ptr scene, ptr item)",
"void item_deselect(ptr scene, ptr item)",
@ -85,7 +86,7 @@ static void *scene_create(obs_data_t *settings, struct obs_source *source)
struct obs_scene *scene = bzalloc(sizeof(struct obs_scene));
scene->source = source;
if (source->info.id == group_info.id) {
if (strcmp(source->info.id, group_info.id) == 0) {
scene->is_group = true;
scene->custom_size = true;
scene->cx = 0;
@ -736,7 +737,7 @@ static void scene_load_item(struct obs_scene *scene, obs_data_t *item_data)
return;
}
item->is_group = source->info.id == group_info.id;
item->is_group = strcmp(source->info.id, group_info.id) == 0;
obs_data_set_default_int(item_data, "align",
OBS_ALIGN_TOP | OBS_ALIGN_LEFT);
@ -1409,7 +1410,7 @@ obs_source_t *obs_scene_get_source(const obs_scene_t *scene)
obs_scene_t *obs_scene_from_source(const obs_source_t *source)
{
if (!source || source->info.id != scene_info.id)
if (!source || strcmp(source->info.id, scene_info.id) != 0)
return NULL;
return source->context.data;
@ -1417,7 +1418,7 @@ obs_scene_t *obs_scene_from_source(const obs_source_t *source)
obs_scene_t *obs_group_from_source(const obs_source_t *source)
{
if (!source || source->info.id != group_info.id)
if (!source || strcmp(source->info.id, group_info.id) != 0)
return NULL;
return source->context.data;
@ -1445,6 +1446,39 @@ obs_sceneitem_t *obs_scene_find_source(obs_scene_t *scene, const char *name)
return item;
}
obs_sceneitem_t *obs_scene_find_source_recursive(obs_scene_t *scene,
const char *name)
{
struct obs_scene_item *item;
if (!scene)
return NULL;
full_lock(scene);
item = scene->first_item;
while (item) {
if (strcmp(item->source->context.name, name) == 0)
break;
if (item->is_group) {
obs_scene_t *group = item->source->context.data;
obs_sceneitem_t *child =
obs_scene_find_source(group, name);
if (child) {
item = child;
break;
}
}
item = item->next;
}
full_unlock(scene);
return item;
}
obs_sceneitem_t *obs_scene_find_sceneitem_by_id(obs_scene_t *scene, int64_t id)
{
struct obs_scene_item *item;
@ -1657,7 +1691,7 @@ static obs_sceneitem_t *obs_scene_add_internal(obs_scene_t *scene,
item->actions_mutex = mutex;
item->user_visible = true;
item->locked = false;
item->is_group = source->info.id == group_info.id;
item->is_group = strcmp(source->info.id, group_info.id) == 0;
item->private_settings = obs_data_create();
item->toggle_visibility = OBS_INVALID_HOTKEY_PAIR_ID;
os_atomic_set_long(&item->active_refs, 1);
@ -1719,6 +1753,9 @@ obs_sceneitem_t *obs_scene_add(obs_scene_t *scene, obs_source_t *source)
struct calldata params;
uint8_t stack[128];
if (!item)
return NULL;
calldata_init_fixed(&params, stack, sizeof(stack));
calldata_set_ptr(&params, "scene", scene);
calldata_set_ptr(&params, "item", item);
@ -1886,6 +1923,18 @@ static inline void signal_reorder(struct obs_scene_item *item)
signal_parent(item->parent, command, &params);
}
static inline void signal_refresh(obs_scene_t *scene)
{
const char *command = NULL;
struct calldata params;
uint8_t stack[128];
command = "refresh";
calldata_init_fixed(&params, stack, sizeof(stack));
signal_parent(scene, command, &params);
}
void obs_sceneitem_set_order(obs_sceneitem_t *item,
enum obs_order_movement movement)
{
@ -2525,6 +2574,12 @@ obs_sceneitem_t *obs_scene_add_group(obs_scene_t *scene, const char *name)
return obs_scene_insert_group(scene, name, NULL, 0);
}
obs_sceneitem_t *obs_scene_add_group2(obs_scene_t *scene, const char *name,
bool signal)
{
return obs_scene_insert_group2(scene, name, NULL, 0, signal);
}
obs_sceneitem_t *obs_scene_insert_group(obs_scene_t *scene, const char *name,
obs_sceneitem_t **items, size_t count)
{
@ -2582,6 +2637,17 @@ obs_sceneitem_t *obs_scene_insert_group(obs_scene_t *scene, const char *name,
return item;
}
obs_sceneitem_t *obs_scene_insert_group2(obs_scene_t *scene, const char *name,
obs_sceneitem_t **items, size_t count,
bool signal)
{
obs_sceneitem_t *item =
obs_scene_insert_group(scene, name, items, count);
if (signal && item)
signal_refresh(scene);
return item;
}
obs_sceneitem_t *obs_scene_get_group(obs_scene_t *scene, const char *name)
{
if (!scene || !name || !*name) {
@ -2662,6 +2728,14 @@ void obs_sceneitem_group_ungroup(obs_sceneitem_t *item)
obs_sceneitem_release(item);
}
void obs_sceneitem_group_ungroup2(obs_sceneitem_t *item, bool signal)
{
obs_scene_t *scene = item->parent;
obs_sceneitem_group_ungroup(item);
if (signal)
signal_refresh(scene);
}
void obs_sceneitem_group_add_item(obs_sceneitem_t *group, obs_sceneitem_t *item)
{
if (!group || !group->is_group || !item)
@ -2669,41 +2743,33 @@ void obs_sceneitem_group_add_item(obs_sceneitem_t *group, obs_sceneitem_t *item)
obs_scene_t *scene = group->parent;
obs_scene_t *groupscene = group->source->context.data;
obs_sceneitem_t *last;
if (item->parent != scene)
return;
if (item->parent == groupscene)
return;
/* ------------------------- */
full_lock(scene);
remove_group_transform(group, item);
detach_sceneitem(item);
/* ------------------------- */
full_lock(groupscene);
last = groupscene->first_item;
if (last) {
for (;;) {
if (!last->next)
break;
last = last->next;
}
last->next = item;
item->prev = last;
} else {
groupscene->first_item = item;
}
item->parent = groupscene;
item->next = NULL;
remove_group_transform(group, item);
detach_sceneitem(item);
attach_sceneitem(groupscene, item, NULL);
apply_group_transform(item, group);
resize_group(group);
full_unlock(groupscene);
full_unlock(scene);
/* ------------------------- */
full_unlock(scene);
signal_refresh(scene);
}
void obs_sceneitem_group_remove_item(obs_sceneitem_t *group,
@ -2719,27 +2785,20 @@ void obs_sceneitem_group_remove_item(obs_sceneitem_t *group,
full_lock(scene);
full_lock(groupscene);
remove_group_transform(group, item);
detach_sceneitem(item);
/* ------------------------- */
if (group->prev) {
group->prev->next = item;
item->prev = group->prev;
} else {
scene->first_item = item;
item->prev = NULL;
}
group->prev = item;
item->next = group;
item->parent = scene;
/* ------------------------- */
attach_sceneitem(scene, item, NULL);
resize_group(group);
full_unlock(groupscene);
full_unlock(scene);
/* ------------------------- */
signal_refresh(scene);
}
static void
@ -2927,7 +2986,7 @@ obs_sceneitem_t *obs_sceneitem_get_group(obs_scene_t *scene,
bool obs_source_is_group(const obs_source_t *source)
{
return source && source->info.id == group_info.id;
return source && strcmp(source->info.id, group_info.id) == 0;
}
bool obs_scene_is_group(const obs_scene_t *scene)

View file

@ -52,7 +52,7 @@ struct obs_service_info {
*
* @param data Internal service data
* @param output Output context
* @eturn true to allow the output to start up,
* @return true to allow the output to start up,
* false to prevent output from starting up
*/
bool (*initialize)(void *data, obs_output_t *output);

View file

@ -16,6 +16,7 @@
******************************************************************************/
#include "obs-internal.h"
#include "graphics/math-extra.h"
#define lock_transition(transition) \
pthread_mutex_lock(&transition->transition_mutex);
@ -203,11 +204,24 @@ static void recalculate_transition_size(obs_source_t *transition)
transition->transition_actual_cy = cy;
}
void obs_transition_tick(obs_source_t *transition)
void obs_transition_tick(obs_source_t *transition, float t)
{
recalculate_transition_size(transition);
recalculate_transition_matrices(transition);
if (transition->transition_mode == OBS_TRANSITION_MODE_MANUAL) {
if (transition->transition_manual_torque == 0.0f) {
transition->transition_manual_val =
transition->transition_manual_target;
} else {
transition->transition_manual_val = calc_torquef(
transition->transition_manual_val,
transition->transition_manual_target,
transition->transition_manual_torque,
transition->transition_manual_clamp, t);
}
}
if (trylock_textures(transition) == 0) {
gs_texrender_reset(transition->transition_texrender[0]);
gs_texrender_reset(transition->transition_texrender[1]);
@ -351,6 +365,7 @@ bool obs_transition_start(obs_source_t *transition,
bool active;
bool same_as_source;
bool same_as_dest;
bool same_mode;
if (!transition_valid(transition, "obs_transition_start"))
return false;
@ -358,11 +373,21 @@ bool obs_transition_start(obs_source_t *transition,
lock_transition(transition);
same_as_source = dest == transition->transition_sources[0];
same_as_dest = dest == transition->transition_sources[1];
same_mode = mode == transition->transition_mode;
active = transition_active(transition);
unlock_transition(transition);
if (same_as_source && !active)
return false;
if (active && mode == OBS_TRANSITION_MODE_MANUAL && same_mode &&
same_as_dest)
return true;
lock_transition(transition);
transition->transition_mode = mode;
transition->transition_manual_val = 0.0f;
transition->transition_manual_target = 0.0f;
unlock_transition(transition);
if (transition->info.transition_start)
transition->info.transition_start(transition->context.data);
@ -389,11 +414,25 @@ bool obs_transition_start(obs_source_t *transition,
recalculate_transition_size(transition);
recalculate_transition_matrices(transition);
/* TODO: Add mode */
UNUSED_PARAMETER(mode);
return true;
}
void obs_transition_set_manual_torque(obs_source_t *transition, float torque,
float clamp)
{
lock_transition(transition);
transition->transition_manual_torque = torque;
transition->transition_manual_clamp = clamp;
unlock_transition(transition);
}
void obs_transition_set_manual_time(obs_source_t *transition, float t)
{
lock_transition(transition);
transition->transition_manual_target = t;
unlock_transition(transition);
}
void obs_transition_set(obs_source_t *transition, obs_source_t *source)
{
obs_source_t *s[2];
@ -415,6 +454,8 @@ void obs_transition_set(obs_source_t *transition, obs_source_t *source)
transition->transition_sources[0] = source;
transition->transitioning_video = false;
transition->transitioning_audio = false;
transition->transition_manual_val = 0.0f;
transition->transition_manual_target = 0.0f;
unlock_transition(transition);
for (size_t i = 0; i < 2; i++) {
@ -429,6 +470,9 @@ void obs_transition_set(obs_source_t *transition, obs_source_t *source)
static float calc_time(obs_source_t *transition, uint64_t ts)
{
if (transition->transition_mode == OBS_TRANSITION_MODE_MANUAL)
return transition->transition_manual_val;
uint64_t end;
if (ts <= transition->transition_start_time)

View file

@ -51,6 +51,19 @@ struct obs_source_info *get_source_info(const char *id)
return NULL;
}
struct obs_source_info *get_source_info2(const char *unversioned_id,
uint32_t ver)
{
for (size_t i = 0; i < obs->source_types.num; i++) {
struct obs_source_info *info = &obs->source_types.array[i];
if (strcmp(info->unversioned_id, unversioned_id) == 0 &&
info->version == ver)
return info;
}
return NULL;
}
static const char *source_signals[] = {
"void destroy(ptr source)",
"void remove(ptr source)",
@ -80,6 +93,14 @@ static const char *source_signals[] = {
"void transition_start(ptr source)",
"void transition_video_stop(ptr source)",
"void transition_stop(ptr source)",
"void media_play(ptr source)",
"void media_pause(ptr source)",
"void media_restart(ptr source)",
"void media_stopped(ptr source)",
"void media_next(ptr source)",
"void media_previous(ptr source)",
"void media_started(ptr source)",
"void media_ended(ptr source)",
NULL,
};
@ -320,6 +341,7 @@ obs_source_create_internal(const char *id, const char *name,
source->info.id = bstrdup(id);
source->owns_info_id = true;
source->info.unversioned_id = bstrdup(source->info.id);
} else {
source->info = *info;
@ -470,8 +492,6 @@ void obs_source_copy_filters(obs_source_t *dst, obs_source_t *src)
duplicate_filters(dst, src, dst->context.private);
}
extern obs_scene_t *obs_group_from_source(const obs_source_t *source);
obs_source_t *obs_source_duplicate(obs_source_t *source, const char *new_name,
bool create_private)
{
@ -642,8 +662,10 @@ void obs_source_destroy(struct obs_source *source)
obs_data_release(source->private_settings);
obs_context_data_free(&source->context);
if (source->owns_info_id)
if (source->owns_info_id) {
bfree((void *)source->info.id);
bfree((void *)source->info.unversioned_id);
}
bfree(source);
}
@ -1069,7 +1091,7 @@ void obs_source_video_tick(obs_source_t *source, float seconds)
return;
if (source->info.type == OBS_SOURCE_TYPE_TRANSITION)
obs_transition_tick(source);
obs_transition_tick(source, seconds);
if ((source->info.output_flags & OBS_SOURCE_ASYNC) != 0)
async_tick(source);
@ -1090,6 +1112,18 @@ void obs_source_video_tick(obs_source_t *source, float seconds)
hide_source(source);
}
if (source->filters.num) {
for (size_t i = source->filters.num; i > 0; i--) {
obs_source_t *filter =
source->filters.array[i - 1];
if (now_showing) {
show_source(filter);
} else {
hide_source(filter);
}
}
}
source->showing = now_showing;
}
@ -1102,6 +1136,18 @@ void obs_source_video_tick(obs_source_t *source, float seconds)
deactivate_source(source);
}
if (source->filters.num) {
for (size_t i = source->filters.num; i > 0; i--) {
obs_source_t *filter =
source->filters.array[i - 1];
if (now_active) {
activate_source(filter);
} else {
deactivate_source(filter);
}
}
}
source->active = now_active;
}
@ -2004,10 +2050,41 @@ static void obs_source_update_async_video(obs_source_t *source)
}
}
static void rotate_async_video(obs_source_t *source, long rotation)
{
float x = 0;
float y = 0;
switch (rotation) {
case 90:
y = (float)source->async_width;
break;
case 270:
case -90:
x = (float)source->async_height;
break;
case 180:
x = (float)source->async_width;
y = (float)source->async_height;
}
gs_matrix_translate3f(x, y, 0);
gs_matrix_rotaa4f(0.0f, 0.0f, -1.0f, RAD((float)rotation));
}
static inline void obs_source_render_async_video(obs_source_t *source)
{
if (source->async_textures[0] && source->async_active)
if (source->async_textures[0] && source->async_active) {
long rotation = source->async_rotation;
if (rotation) {
gs_matrix_push();
rotate_async_video(source, rotation);
}
obs_source_draw_async_texture(source);
if (rotation) {
gs_matrix_pop();
}
}
}
static inline void obs_source_render_filters(obs_source_t *source)
@ -2131,6 +2208,18 @@ void obs_source_video_render(obs_source_t *source)
obs_source_release(source);
}
static inline uint32_t get_async_width(const obs_source_t *source)
{
return ((source->async_rotation % 180) == 0) ? source->async_width
: source->async_height;
}
static inline uint32_t get_async_height(const obs_source_t *source)
{
return ((source->async_rotation % 180) == 0) ? source->async_height
: source->async_width;
}
static uint32_t get_base_width(const obs_source_t *source)
{
bool is_filter = !!source->filter_parent;
@ -2146,7 +2235,7 @@ static uint32_t get_base_width(const obs_source_t *source)
return get_base_width(source->filter_target);
}
return source->async_active ? source->async_width : 0;
return source->async_active ? get_async_width(source) : 0;
}
static uint32_t get_base_height(const obs_source_t *source)
@ -2164,7 +2253,7 @@ static uint32_t get_base_height(const obs_source_t *source)
return get_base_height(source->filter_target);
}
return source->async_active ? source->async_height : 0;
return source->async_active ? get_async_height(source) : 0;
}
static uint32_t get_recurse_width(obs_source_t *source)
@ -2246,10 +2335,12 @@ obs_source_t *obs_filter_get_target(const obs_source_t *filter)
: NULL;
}
#define OBS_SOURCE_AV (OBS_SOURCE_ASYNC_VIDEO | OBS_SOURCE_AUDIO)
static bool filter_compatible(obs_source_t *source, obs_source_t *filter)
{
uint32_t s_caps = source->info.output_flags;
uint32_t f_caps = filter->info.output_flags;
uint32_t s_caps = source->info.output_flags & OBS_SOURCE_AV;
uint32_t f_caps = filter->info.output_flags & OBS_SOURCE_AV;
if ((f_caps & OBS_SOURCE_AUDIO) != 0 &&
(f_caps & OBS_SOURCE_VIDEO) == 0)
@ -2509,12 +2600,13 @@ static inline void copy_frame_data_plane(struct obs_source_frame *dst,
const struct obs_source_frame *src,
uint32_t plane, uint32_t lines)
{
if (dst->linesize[plane] != src->linesize[plane])
if (dst->linesize[plane] != src->linesize[plane]) {
for (uint32_t y = 0; y < lines; y++)
copy_frame_data_line(dst, src, plane, y);
else
} else {
memcpy(dst->data[plane], src->data[plane],
dst->linesize[plane] * lines);
(size_t)dst->linesize[plane] * (size_t)lines);
}
}
static void copy_frame_data(struct obs_source_frame *dst,
@ -2764,6 +2856,12 @@ void obs_source_output_video2(obs_source_t *source,
obs_source_output_video_internal(source, &new_frame);
}
void obs_source_set_async_rotation(obs_source_t *source, long rotation)
{
if (source)
source->async_rotation = rotation;
}
static inline bool preload_frame_changed(obs_source_t *source,
const struct obs_source_frame *in)
{
@ -3294,6 +3392,13 @@ const char *obs_source_get_id(const obs_source_t *source)
: NULL;
}
const char *obs_source_get_unversioned_id(const obs_source_t *source)
{
return obs_source_valid(source, "obs_source_get_unversioned_id")
? source->info.unversioned_id
: NULL;
}
static inline void render_filter_bypass(obs_source_t *target,
gs_effect_t *effect,
const char *tech_name)
@ -4491,6 +4596,10 @@ void obs_source_audio_render(obs_source_t *source, uint32_t mixers,
}
if (source->info.audio_render) {
if (!source->context.data) {
source->audio_pending = true;
return;
}
custom_audio_render(source, mixers, channels, sample_rate);
return;
}
@ -4712,3 +4821,135 @@ uint32_t obs_source_get_last_obs_version(const obs_source_t *source)
? source->last_obs_ver
: 0;
}
enum obs_icon_type obs_source_get_icon_type(const char *id)
{
const struct obs_source_info *info = get_source_info(id);
return (info) ? info->icon_type : OBS_ICON_TYPE_UNKNOWN;
}
void obs_source_media_play_pause(obs_source_t *source, bool pause)
{
if (!obs_source_valid(source, "obs_source_media_play_pause"))
return;
if (!source->info.media_play_pause)
return;
source->info.media_play_pause(source->context.data, pause);
if (pause)
obs_source_dosignal(source, NULL, "media_pause");
else
obs_source_dosignal(source, NULL, "media_play");
}
void obs_source_media_restart(obs_source_t *source)
{
if (!obs_source_valid(source, "obs_source_media_restart"))
return;
if (!source->info.media_restart)
return;
source->info.media_restart(source->context.data);
obs_source_dosignal(source, NULL, "media_restart");
}
void obs_source_media_stop(obs_source_t *source)
{
if (!obs_source_valid(source, "obs_source_media_stop"))
return;
if (!source->info.media_stop)
return;
source->info.media_stop(source->context.data);
obs_source_dosignal(source, NULL, "media_stopped");
}
void obs_source_media_next(obs_source_t *source)
{
if (!obs_source_valid(source, "obs_source_media_next"))
return;
if (!source->info.media_next)
return;
source->info.media_next(source->context.data);
obs_source_dosignal(source, NULL, "media_next");
}
void obs_source_media_previous(obs_source_t *source)
{
if (!obs_source_valid(source, "obs_source_media_previous"))
return;
if (!source->info.media_previous)
return;
source->info.media_previous(source->context.data);
obs_source_dosignal(source, NULL, "media_previous");
}
int64_t obs_source_media_get_duration(obs_source_t *source)
{
if (!obs_source_valid(source, "obs_source_media_get_duration"))
return 0;
if (source->info.media_get_duration)
return source->info.media_get_duration(source->context.data);
else
return 0;
}
int64_t obs_source_media_get_time(obs_source_t *source)
{
if (!obs_source_valid(source, "obs_source_media_get_time"))
return 0;
if (source->info.media_get_time)
return source->info.media_get_time(source->context.data);
else
return 0;
}
void obs_source_media_set_time(obs_source_t *source, int64_t ms)
{
if (!obs_source_valid(source, "obs_source_media_set_time"))
return;
if (source->info.media_set_time)
source->info.media_set_time(source->context.data, ms);
}
enum obs_media_state obs_source_media_get_state(obs_source_t *source)
{
if (!obs_source_valid(source, "obs_source_media_get_state"))
return OBS_MEDIA_STATE_NONE;
if (source->info.media_get_state)
return source->info.media_get_state(source->context.data);
else
return OBS_MEDIA_STATE_NONE;
}
void obs_source_media_started(obs_source_t *source)
{
if (!obs_source_valid(source, "obs_source_media_started"))
return;
obs_source_dosignal(source, NULL, "media_started");
}
void obs_source_media_ended(obs_source_t *source)
{
if (!obs_source_valid(source, "obs_source_media_ended"))
return;
obs_source_dosignal(source, NULL, "media_ended");
}

View file

@ -43,6 +43,34 @@ enum obs_balance_type {
OBS_BALANCE_TYPE_LINEAR,
};
enum obs_icon_type {
OBS_ICON_TYPE_UNKNOWN,
OBS_ICON_TYPE_IMAGE,
OBS_ICON_TYPE_COLOR,
OBS_ICON_TYPE_SLIDESHOW,
OBS_ICON_TYPE_AUDIO_INPUT,
OBS_ICON_TYPE_AUDIO_OUTPUT,
OBS_ICON_TYPE_DESKTOP_CAPTURE,
OBS_ICON_TYPE_WINDOW_CAPTURE,
OBS_ICON_TYPE_GAME_CAPTURE,
OBS_ICON_TYPE_CAMERA,
OBS_ICON_TYPE_TEXT,
OBS_ICON_TYPE_MEDIA,
OBS_ICON_TYPE_BROWSER,
OBS_ICON_TYPE_CUSTOM,
};
enum obs_media_state {
OBS_MEDIA_STATE_NONE,
OBS_MEDIA_STATE_PLAYING,
OBS_MEDIA_STATE_OPENING,
OBS_MEDIA_STATE_BUFFERING,
OBS_MEDIA_STATE_PAUSED,
OBS_MEDIA_STATE_STOPPED,
OBS_MEDIA_STATE_ENDED,
OBS_MEDIA_STATE_ERROR,
};
/**
* @name Source output flags
*
@ -139,6 +167,11 @@ enum obs_balance_type {
*/
#define OBS_SOURCE_CAP_DISABLED (1 << 10)
/**
* Source type is obsolete (has been updated with new defaults/properties/etc)
*/
#define OBS_SOURCE_CAP_OBSOLETE OBS_SOURCE_CAP_DISABLED
/**
* Source should enable monitoring by default. Monitoring should be set by the
* frontend if this flag is set.
@ -148,6 +181,11 @@ enum obs_balance_type {
/** Used internally for audio submixing */
#define OBS_SOURCE_SUBMIX (1 << 12)
/**
* Source type can be controlled by media controls
*/
#define OBS_SOURCE_CONTROLLABLE_MEDIA (1 << 13)
/** @} */
typedef void (*obs_source_enum_proc_t)(obs_source_t *parent,
@ -471,6 +509,24 @@ struct obs_source_info {
bool (*audio_mix)(void *data, uint64_t *ts_out,
struct audio_output_data *audio_output,
size_t channels, size_t sample_rate);
/** Icon type for the source */
enum obs_icon_type icon_type;
/** Media controls */
void (*media_play_pause)(void *data, bool pause);
void (*media_restart)(void *data);
void (*media_stop)(void *data);
void (*media_next)(void *data);
void (*media_previous)(void *data);
int64_t (*media_get_duration)(void *data);
int64_t (*media_get_time)(void *data);
void (*media_set_time)(void *data, int64_t miliseconds);
enum obs_media_state (*media_get_state)(void *data);
/* version-related stuff */
uint32_t version; /* increment if needed to specify a new version */
const char *unversioned_id; /* set internally, don't set manually */
};
EXPORT void obs_register_source_s(const struct obs_source_info *info,

View file

@ -46,7 +46,7 @@ struct obs_modal_ui {
* Callback to execute modal interface.
*
* The @b object variable points to the input/output/encoder/etc. The
* @b ui_data varaible points to the UI parent or UI-specific data to
* @b ui_data variable points to the UI parent or UI-specific data to
* be used with the custom user interface.
*
* What @b ui_data points to differs depending on the target, and you

View file

@ -24,6 +24,11 @@
#include "media-io/format-conversion.h"
#include "media-io/video-frame.h"
#ifdef _WIN32
#define WIN32_MEAN_AND_LEAN
#include <windows.h>
#endif
static uint64_t tick_sources(uint64_t cur_time, uint64_t last_time)
{
struct obs_core_data *data = &obs->data;
@ -811,6 +816,25 @@ static void clear_gpu_frame_data(void)
}
#endif
extern THREAD_LOCAL bool is_graphics_thread;
static void execute_graphics_tasks(void)
{
struct obs_core_video *video = &obs->video;
bool tasks_remaining = true;
while (tasks_remaining) {
pthread_mutex_lock(&video->task_mutex);
if (video->tasks.size) {
struct obs_task_info info;
circlebuf_pop_front(&video->tasks, &info, sizeof(info));
info.task(info.param);
}
tasks_remaining = !!video->tasks.size;
pthread_mutex_unlock(&video->task_mutex);
}
}
static const char *tick_sources_name = "tick_sources";
static const char *render_displays_name = "render_displays";
static const char *output_frame_name = "output_frame";
@ -827,6 +851,8 @@ void *obs_graphics_thread(void *param)
bool raw_was_active = false;
bool was_active = false;
is_graphics_thread = true;
obs->video.video_time = os_gettime_ns();
obs->video.video_frame_interval_ns = interval;
@ -839,7 +865,11 @@ void *obs_graphics_thread(void *param)
srand((unsigned int)time(NULL));
while (!video_output_stopped(obs->video.video)) {
for (;;) {
/* defer loop break to clean up sources */
const bool stop_requested =
video_output_stopped(obs->video.video);
uint64_t frame_start = os_gettime_ns();
uint64_t frame_time_ns;
bool raw_active = obs->video.raw_active > 0;
@ -866,10 +896,24 @@ void *obs_graphics_thread(void *param)
profile_start(video_thread_name);
gs_enter_context(obs->video.graphics);
gs_begin_frame();
gs_leave_context();
profile_start(tick_sources_name);
last_time = tick_sources(obs->video.video_time, last_time);
profile_end(tick_sources_name);
execute_graphics_tasks();
#ifdef _WIN32
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
#endif
profile_start(output_frame_name);
output_frame(raw_active, gpu_active);
profile_end(output_frame_name);
@ -903,6 +947,9 @@ void *obs_graphics_thread(void *param)
fps_total_ns = 0;
fps_total_frames = 0;
}
if (stop_requested)
break;
}
UNUSED_PARAMETER(param);

View file

@ -40,12 +40,10 @@ const char *get_module_extension(void)
#endif
static const char *module_bin[] = {
"obs-plugins/" BIT_STRING,
"../../obs-plugins/" BIT_STRING,
};
static const char *module_data[] = {"data/%module%",
"../../data/obs-plugins/%module%"};
static const char *module_data[] = {"../../data/obs-plugins/%module%"};
static const int module_patterns_size =
sizeof(module_bin) / sizeof(module_bin[0]);
@ -62,9 +60,6 @@ char *find_libobs_data_file(const char *file)
struct dstr path;
dstr_init(&path);
if (check_path(file, "data/libobs/", &path))
return path.array;
if (check_path(file, "../../data/libobs/", &path))
return path.array;
@ -130,16 +125,22 @@ static void log_available_memory(void)
(DWORD)(ms.ullAvailPhys / 1048576), note);
}
extern const char *get_win_release_id();
static void log_windows_version(void)
{
struct win_version_info ver;
get_win_ver(&ver);
const char *release_id = get_win_release_id();
bool b64 = is_64_bit_windows();
const char *windows_bitness = b64 ? "64" : "32";
blog(LOG_INFO, "Windows Version: %d.%d Build %d (revision: %d; %s-bit)",
ver.major, ver.minor, ver.build, ver.revis, windows_bitness);
blog(LOG_INFO,
"Windows Version: %d.%d Build %d (release: %s; revision: %d; %s-bit)",
ver.major, ver.minor, ver.build, release_id, ver.revis,
windows_bitness);
}
static void log_admin_status(void)
@ -654,6 +655,341 @@ static int get_virtual_key(obs_key_t key)
case OBS_KEY_MOUSE5:
return VK_XBUTTON2;
case OBS_KEY_VK_CANCEL:
return VK_CANCEL;
case OBS_KEY_0x07:
return 0x07;
case OBS_KEY_0x0A:
return 0x0A;
case OBS_KEY_0x0B:
return 0x0B;
case OBS_KEY_0x0E:
return 0x0E;
case OBS_KEY_0x0F:
return 0x0F;
case OBS_KEY_0x16:
return 0x16;
case OBS_KEY_VK_JUNJA:
return VK_JUNJA;
case OBS_KEY_VK_FINAL:
return VK_FINAL;
case OBS_KEY_0x1A:
return 0x1A;
case OBS_KEY_VK_ACCEPT:
return VK_ACCEPT;
case OBS_KEY_VK_MODECHANGE:
return VK_MODECHANGE;
case OBS_KEY_VK_SELECT:
return VK_SELECT;
case OBS_KEY_VK_PRINT:
return VK_PRINT;
case OBS_KEY_VK_EXECUTE:
return VK_EXECUTE;
case OBS_KEY_VK_HELP:
return VK_HELP;
case OBS_KEY_0x30:
return 0x30;
case OBS_KEY_0x31:
return 0x31;
case OBS_KEY_0x32:
return 0x32;
case OBS_KEY_0x33:
return 0x33;
case OBS_KEY_0x34:
return 0x34;
case OBS_KEY_0x35:
return 0x35;
case OBS_KEY_0x36:
return 0x36;
case OBS_KEY_0x37:
return 0x37;
case OBS_KEY_0x38:
return 0x38;
case OBS_KEY_0x39:
return 0x39;
case OBS_KEY_0x3A:
return 0x3A;
case OBS_KEY_0x3B:
return 0x3B;
case OBS_KEY_0x3C:
return 0x3C;
case OBS_KEY_0x3D:
return 0x3D;
case OBS_KEY_0x3E:
return 0x3E;
case OBS_KEY_0x3F:
return 0x3F;
case OBS_KEY_0x40:
return 0x40;
case OBS_KEY_0x41:
return 0x41;
case OBS_KEY_0x42:
return 0x42;
case OBS_KEY_0x43:
return 0x43;
case OBS_KEY_0x44:
return 0x44;
case OBS_KEY_0x45:
return 0x45;
case OBS_KEY_0x46:
return 0x46;
case OBS_KEY_0x47:
return 0x47;
case OBS_KEY_0x48:
return 0x48;
case OBS_KEY_0x49:
return 0x49;
case OBS_KEY_0x4A:
return 0x4A;
case OBS_KEY_0x4B:
return 0x4B;
case OBS_KEY_0x4C:
return 0x4C;
case OBS_KEY_0x4D:
return 0x4D;
case OBS_KEY_0x4E:
return 0x4E;
case OBS_KEY_0x4F:
return 0x4F;
case OBS_KEY_0x50:
return 0x50;
case OBS_KEY_0x51:
return 0x51;
case OBS_KEY_0x52:
return 0x52;
case OBS_KEY_0x53:
return 0x53;
case OBS_KEY_0x54:
return 0x54;
case OBS_KEY_0x55:
return 0x55;
case OBS_KEY_0x56:
return 0x56;
case OBS_KEY_0x57:
return 0x57;
case OBS_KEY_0x58:
return 0x58;
case OBS_KEY_0x59:
return 0x59;
case OBS_KEY_0x5A:
return 0x5A;
case OBS_KEY_VK_LWIN:
return VK_LWIN;
case OBS_KEY_VK_RWIN:
return VK_RWIN;
case OBS_KEY_VK_APPS:
return VK_APPS;
case OBS_KEY_0x5E:
return 0x5E;
case OBS_KEY_VK_SLEEP:
return VK_SLEEP;
case OBS_KEY_VK_SEPARATOR:
return VK_SEPARATOR;
case OBS_KEY_0x88:
return 0x88;
case OBS_KEY_0x89:
return 0x89;
case OBS_KEY_0x8A:
return 0x8A;
case OBS_KEY_0x8B:
return 0x8B;
case OBS_KEY_0x8C:
return 0x8C;
case OBS_KEY_0x8D:
return 0x8D;
case OBS_KEY_0x8E:
return 0x8E;
case OBS_KEY_0x8F:
return 0x8F;
case OBS_KEY_VK_OEM_FJ_JISHO:
return VK_OEM_FJ_JISHO;
case OBS_KEY_VK_OEM_FJ_LOYA:
return VK_OEM_FJ_LOYA;
case OBS_KEY_VK_OEM_FJ_ROYA:
return VK_OEM_FJ_ROYA;
case OBS_KEY_0x97:
return 0x97;
case OBS_KEY_0x98:
return 0x98;
case OBS_KEY_0x99:
return 0x99;
case OBS_KEY_0x9A:
return 0x9A;
case OBS_KEY_0x9B:
return 0x9B;
case OBS_KEY_0x9C:
return 0x9C;
case OBS_KEY_0x9D:
return 0x9D;
case OBS_KEY_0x9E:
return 0x9E;
case OBS_KEY_0x9F:
return 0x9F;
case OBS_KEY_VK_LSHIFT:
return VK_LSHIFT;
case OBS_KEY_VK_RSHIFT:
return VK_RSHIFT;
case OBS_KEY_VK_LCONTROL:
return VK_LCONTROL;
case OBS_KEY_VK_RCONTROL:
return VK_RCONTROL;
case OBS_KEY_VK_LMENU:
return VK_LMENU;
case OBS_KEY_VK_RMENU:
return VK_RMENU;
case OBS_KEY_VK_BROWSER_BACK:
return VK_BROWSER_BACK;
case OBS_KEY_VK_BROWSER_FORWARD:
return VK_BROWSER_FORWARD;
case OBS_KEY_VK_BROWSER_REFRESH:
return VK_BROWSER_REFRESH;
case OBS_KEY_VK_BROWSER_STOP:
return VK_BROWSER_STOP;
case OBS_KEY_VK_BROWSER_SEARCH:
return VK_BROWSER_SEARCH;
case OBS_KEY_VK_BROWSER_FAVORITES:
return VK_BROWSER_FAVORITES;
case OBS_KEY_VK_BROWSER_HOME:
return VK_BROWSER_HOME;
case OBS_KEY_VK_VOLUME_MUTE:
return VK_VOLUME_MUTE;
case OBS_KEY_VK_VOLUME_DOWN:
return VK_VOLUME_DOWN;
case OBS_KEY_VK_VOLUME_UP:
return VK_VOLUME_UP;
case OBS_KEY_VK_MEDIA_NEXT_TRACK:
return VK_MEDIA_NEXT_TRACK;
case OBS_KEY_VK_MEDIA_PREV_TRACK:
return VK_MEDIA_PREV_TRACK;
case OBS_KEY_VK_MEDIA_STOP:
return VK_MEDIA_STOP;
case OBS_KEY_VK_MEDIA_PLAY_PAUSE:
return VK_MEDIA_PLAY_PAUSE;
case OBS_KEY_VK_LAUNCH_MAIL:
return VK_LAUNCH_MAIL;
case OBS_KEY_VK_LAUNCH_MEDIA_SELECT:
return VK_LAUNCH_MEDIA_SELECT;
case OBS_KEY_VK_LAUNCH_APP1:
return VK_LAUNCH_APP1;
case OBS_KEY_VK_LAUNCH_APP2:
return VK_LAUNCH_APP2;
case OBS_KEY_0xB8:
return 0xB8;
case OBS_KEY_0xB9:
return 0xB9;
case OBS_KEY_0xC1:
return 0xC1;
case OBS_KEY_0xC2:
return 0xC2;
case OBS_KEY_0xC3:
return 0xC3;
case OBS_KEY_0xC4:
return 0xC4;
case OBS_KEY_0xC5:
return 0xC5;
case OBS_KEY_0xC6:
return 0xC6;
case OBS_KEY_0xC7:
return 0xC7;
case OBS_KEY_0xC8:
return 0xC8;
case OBS_KEY_0xC9:
return 0xC9;
case OBS_KEY_0xCA:
return 0xCA;
case OBS_KEY_0xCB:
return 0xCB;
case OBS_KEY_0xCC:
return 0xCC;
case OBS_KEY_0xCD:
return 0xCD;
case OBS_KEY_0xCE:
return 0xCE;
case OBS_KEY_0xCF:
return 0xCF;
case OBS_KEY_0xD0:
return 0xD0;
case OBS_KEY_0xD1:
return 0xD1;
case OBS_KEY_0xD2:
return 0xD2;
case OBS_KEY_0xD3:
return 0xD3;
case OBS_KEY_0xD4:
return 0xD4;
case OBS_KEY_0xD5:
return 0xD5;
case OBS_KEY_0xD6:
return 0xD6;
case OBS_KEY_0xD7:
return 0xD7;
case OBS_KEY_0xD8:
return 0xD8;
case OBS_KEY_0xD9:
return 0xD9;
case OBS_KEY_0xDA:
return 0xDA;
case OBS_KEY_VK_OEM_8:
return VK_OEM_8;
case OBS_KEY_0xE0:
return 0xE0;
case OBS_KEY_VK_OEM_AX:
return VK_OEM_AX;
case OBS_KEY_VK_ICO_HELP:
return VK_ICO_HELP;
case OBS_KEY_VK_ICO_00:
return VK_ICO_00;
case OBS_KEY_VK_PROCESSKEY:
return VK_PROCESSKEY;
case OBS_KEY_VK_ICO_CLEAR:
return VK_ICO_CLEAR;
case OBS_KEY_VK_PACKET:
return VK_PACKET;
case OBS_KEY_0xE8:
return 0xE8;
case OBS_KEY_VK_OEM_RESET:
return VK_OEM_RESET;
case OBS_KEY_VK_OEM_JUMP:
return VK_OEM_JUMP;
case OBS_KEY_VK_OEM_PA1:
return VK_OEM_PA1;
case OBS_KEY_VK_OEM_PA2:
return VK_OEM_PA2;
case OBS_KEY_VK_OEM_PA3:
return VK_OEM_PA3;
case OBS_KEY_VK_OEM_WSCTRL:
return VK_OEM_WSCTRL;
case OBS_KEY_VK_OEM_CUSEL:
return VK_OEM_CUSEL;
case OBS_KEY_VK_OEM_ATTN:
return VK_OEM_ATTN;
case OBS_KEY_VK_OEM_FINISH:
return VK_OEM_FINISH;
case OBS_KEY_VK_OEM_COPY:
return VK_OEM_COPY;
case OBS_KEY_VK_OEM_AUTO:
return VK_OEM_AUTO;
case OBS_KEY_VK_OEM_ENLW:
return VK_OEM_ENLW;
case OBS_KEY_VK_ATTN:
return VK_ATTN;
case OBS_KEY_VK_CRSEL:
return VK_CRSEL;
case OBS_KEY_VK_EXSEL:
return VK_EXSEL;
case OBS_KEY_VK_EREOF:
return VK_EREOF;
case OBS_KEY_VK_PLAY:
return VK_PLAY;
case OBS_KEY_VK_ZOOM:
return VK_ZOOM;
case OBS_KEY_VK_NONAME:
return VK_NONAME;
case OBS_KEY_VK_PA1:
return VK_PA1;
case OBS_KEY_VK_OEM_CLEAR:
return VK_OEM_CLEAR;
/* TODO: Implement keys for non-US keyboards */
default:;
}
@ -740,7 +1076,8 @@ void obs_key_to_str(obs_key_t key, struct dstr *str)
scan_code |= 0x01000000;
}
if (scan_code != 0 && GetKeyNameTextW(scan_code, name, 128) != 0) {
if ((key < OBS_KEY_VK_CANCEL || key > OBS_KEY_VK_OEM_CLEAR) &&
scan_code != 0 && GetKeyNameTextW(scan_code, name, 128) != 0) {
dstr_from_wcs(str, name);
} else if (key != OBS_KEY_NONE) {
dstr_copy(str, obs_key_to_name(key));
@ -923,9 +1260,15 @@ void obs_init_win32_crash_handler(void)
initialize_crash_handler();
}
void initialize_com(void)
bool initialize_com(void)
{
CoInitializeEx(0, COINIT_MULTITHREADED);
const HRESULT hr = CoInitializeEx(0, COINIT_APARTMENTTHREADED);
const bool success = SUCCEEDED(hr);
if (success)
blog(LOG_INFO, "CoInitializeEx succeeded: 0x%08X", hr);
else
blog(LOG_ERROR, "CoInitializeEx failed: 0x%08X", hr);
return success;
}
void uninitialize_com(void)

View file

@ -426,6 +426,8 @@ static int obs_init_video(struct obs_video_info *ovi)
return OBS_VIDEO_FAIL;
if (pthread_mutex_init(&video->gpu_encoder_mutex, NULL) < 0)
return OBS_VIDEO_FAIL;
if (pthread_mutex_init(&video->task_mutex, NULL) < 0)
return OBS_VIDEO_FAIL;
errorcode = pthread_create(&video->video_thread, NULL,
obs_graphics_thread, obs);
@ -511,16 +513,18 @@ static void obs_free_video(void)
circlebuf_free(&video->vframe_info_buffer_gpu);
video->texture_rendered = false;
;
memset(video->textures_copied, 0,
sizeof(video->textures_copied));
video->texture_converted = false;
;
pthread_mutex_destroy(&video->gpu_encoder_mutex);
pthread_mutex_init_value(&video->gpu_encoder_mutex);
da_free(video->gpu_encoders);
pthread_mutex_destroy(&video->task_mutex);
pthread_mutex_init_value(&video->task_mutex);
circlebuf_free(&video->tasks);
video->gpu_encoder_active = 0;
video->cur_texture = 0;
}
@ -843,6 +847,7 @@ static bool obs_init(const char *locale, const char *module_config_path,
pthread_mutex_init_value(&obs->audio.monitoring_mutex);
pthread_mutex_init_value(&obs->video.gpu_encoder_mutex);
pthread_mutex_init_value(&obs->video.task_mutex);
obs->name_store_owned = !store;
obs->name_store = store ? store : profiler_name_store_create();
@ -871,8 +876,9 @@ static bool obs_init(const char *locale, const char *module_config_path,
}
#ifdef _WIN32
extern void initialize_com(void);
extern bool initialize_com(void);
extern void uninitialize_com(void);
static bool com_initialized = false;
#endif
/* Separate from actual context initialization
@ -933,7 +939,7 @@ bool obs_startup(const char *locale, const char *module_config_path,
}
#ifdef _WIN32
initialize_com();
com_initialized = initialize_com();
#endif
success = obs_init(locale, module_config_path, store);
@ -988,6 +994,15 @@ void obs_shutdown(void)
if (!obs)
return;
for (size_t i = 0; i < obs->source_types.num; i++) {
struct obs_source_info *item = &obs->source_types.array[i];
if (item->type_data && item->free_type_data)
item->free_type_data(item->type_data);
if (item->id)
bfree((void *)item->id);
}
da_free(obs->source_types);
#define FREE_REGISTERED_TYPES(structure, list) \
do { \
for (size_t i = 0; i < list.num; i++) { \
@ -998,7 +1013,6 @@ void obs_shutdown(void)
da_free(list); \
} while (false)
FREE_REGISTERED_TYPES(obs_source_info, obs->source_types);
FREE_REGISTERED_TYPES(obs_output_info, obs->output_types);
FREE_REGISTERED_TYPES(obs_encoder_info, obs->encoder_types);
FREE_REGISTERED_TYPES(obs_service_info, obs->service_types);
@ -1048,7 +1062,8 @@ void obs_shutdown(void)
bfree(cmdline_args.argv);
#ifdef _WIN32
uninitialize_com();
if (com_initialized)
uninitialize_com();
#endif
}
@ -1253,6 +1268,47 @@ bool obs_enum_input_types(size_t idx, const char **id)
return true;
}
bool obs_enum_input_types2(size_t idx, const char **id,
const char **unversioned_id)
{
if (!obs)
return false;
if (idx >= obs->input_types.num)
return false;
if (id)
*id = obs->input_types.array[idx].id;
if (unversioned_id)
*unversioned_id = obs->input_types.array[idx].unversioned_id;
return true;
}
const char *obs_get_latest_input_type_id(const char *unversioned_id)
{
struct obs_source_info *latest = NULL;
int version = -1;
if (!obs)
return NULL;
if (!unversioned_id)
return NULL;
for (size_t i = 0; i < obs->source_types.num; i++) {
struct obs_source_info *info = &obs->source_types.array[i];
if (strcmp(info->unversioned_id, unversioned_id) == 0 &&
(int)info->version > version) {
latest = info;
version = info->version;
}
}
assert(!!latest);
if (!latest)
return NULL;
return latest->id;
}
bool obs_enum_filter_types(size_t idx, const char **id)
{
if (!obs)
@ -1453,7 +1509,7 @@ void obs_enum_sources(bool (*enum_proc)(void *, obs_source_t *), void *param)
obs_source_t *next_source =
(obs_source_t *)source->context.next;
if (source->info.id == group_info.id &&
if (strcmp(source->info.id, group_info.id) == 0 &&
!enum_proc(param, source)) {
break;
} else if (source->info.type == OBS_SOURCE_TYPE_INPUT &&
@ -1654,7 +1710,7 @@ gs_effect_t *obs_get_base_effect(enum obs_base_effect effect)
return NULL;
}
/* DEPRECATED */
/* OBS_DEPRECATED */
gs_effect_t *obs_get_default_rect_effect(void)
{
if (!obs)
@ -1676,6 +1732,7 @@ proc_handler_t *obs_get_proc_handler(void)
return obs->procs;
}
/* OBS_DEPRECATED */
void obs_render_main_view(void)
{
if (!obs)
@ -1766,6 +1823,7 @@ static obs_source_t *obs_load_source_type(obs_data_t *source_data)
obs_source_t *source;
const char *name = obs_data_get_string(source_data, "name");
const char *id = obs_data_get_string(source_data, "id");
const char *v_id = obs_data_get_string(source_data, "versioned_id");
obs_data_t *settings = obs_data_get_obj(source_data, "settings");
obs_data_t *hotkeys = obs_data_get_obj(source_data, "hotkeys");
double volume;
@ -1781,8 +1839,15 @@ static obs_source_t *obs_load_source_type(obs_data_t *source_data)
prev_ver = (uint32_t)obs_data_get_int(source_data, "prev_ver");
source = obs_source_create_set_last_ver(id, name, settings, hotkeys,
if (!*v_id)
v_id = id;
source = obs_source_create_set_last_ver(v_id, name, settings, hotkeys,
prev_ver);
if (source->owns_info_id) {
bfree((void *)source->info.unversioned_id);
source->info.unversioned_id = bstrdup(id);
}
obs_data_release(hotkeys);
@ -1955,7 +2020,8 @@ obs_data_t *obs_save_source(obs_source_t *source)
int64_t sync = obs_source_get_sync_offset(source);
uint32_t flags = obs_source_get_flags(source);
const char *name = obs_source_get_name(source);
const char *id = obs_source_get_id(source);
const char *id = source->info.unversioned_id;
const char *v_id = source->info.id;
bool enabled = obs_source_enabled(source);
bool muted = obs_source_muted(source);
bool push_to_mute = obs_source_push_to_mute_enabled(source);
@ -1979,6 +2045,7 @@ obs_data_t *obs_save_source(obs_source_t *source)
obs_data_set_string(source_data, "name", name);
obs_data_set_string(source_data, "id", id);
obs_data_set_string(source_data, "versioned_id", v_id);
obs_data_set_obj(source_data, "settings", settings);
obs_data_set_int(source_data, "mixers", mixers);
obs_data_set_int(source_data, "sync", sync);
@ -2515,3 +2582,76 @@ bool obs_nv12_tex_active(void)
return video->using_nv12_tex;
}
/* ------------------------------------------------------------------------- */
/* task stuff */
struct task_wait_info {
obs_task_t task;
void *param;
os_event_t *event;
};
static void task_wait_callback(void *param)
{
struct task_wait_info *info = param;
info->task(info->param);
os_event_signal(info->event);
}
THREAD_LOCAL bool is_graphics_thread = false;
static bool in_task_thread(enum obs_task_type type)
{
/* NOTE: OBS_TASK_UI is handled independently */
if (type == OBS_TASK_GRAPHICS)
return is_graphics_thread;
assert(false);
return false;
}
void obs_queue_task(enum obs_task_type type, obs_task_t task, void *param,
bool wait)
{
if (!obs)
return;
if (type == OBS_TASK_UI) {
if (obs->ui_task_handler) {
obs->ui_task_handler(task, param, wait);
} else {
blog(LOG_ERROR, "UI task could not be queued, "
"there's no UI task handler!");
}
} else {
if (in_task_thread(type)) {
task(param);
} else if (wait) {
struct task_wait_info info = {
.task = task,
.param = param,
};
os_event_init(&info.event, OS_EVENT_TYPE_MANUAL);
obs_queue_task(type, task_wait_callback, &info, false);
os_event_wait(info.event);
os_event_destroy(info.event);
} else {
struct obs_core_video *video = &obs->video;
struct obs_task_info info = {task, param};
pthread_mutex_lock(&video->task_mutex);
circlebuf_push_back(&video->tasks, &info, sizeof(info));
pthread_mutex_unlock(&video->task_mutex);
}
}
}
void obs_set_ui_task_handler(obs_task_handler_t handler)
{
if (!obs)
return;
obs->ui_task_handler = handler;
}

View file

@ -317,7 +317,7 @@ EXPORT uint32_t obs_get_version(void);
EXPORT const char *obs_get_version_string(void);
/**
* Sets things up for calls to obs_get_cmdline_args. Called onl yonce at startup
* Sets things up for calls to obs_get_cmdline_args. Called only once at startup
* and safely copies argv/argc from main(). Subsequent calls do nothing.
*
* @param argc The count of command line arguments, from main()
@ -517,6 +517,10 @@ EXPORT bool obs_enum_source_types(size_t idx, const char **id);
* etc).
*/
EXPORT bool obs_enum_input_types(size_t idx, const char **id);
EXPORT bool obs_enum_input_types2(size_t idx, const char **id,
const char **unversioned_id);
EXPORT const char *obs_get_latest_input_type_id(const char *unversioned_id);
/**
* Enumerates all available filter source types.
@ -630,7 +634,7 @@ EXPORT gs_effect_t *obs_get_base_effect(enum obs_base_effect effect);
#ifndef SWIG
/* DEPRECATED: gets texture_rect default effect */
DEPRECATED
OBS_DEPRECATED
EXPORT gs_effect_t *obs_get_default_rect_effect(void);
#endif
@ -642,7 +646,7 @@ EXPORT proc_handler_t *obs_get_proc_handler(void);
#ifndef SWIG
/** Renders the main view */
DEPRECATED
OBS_DEPRECATED
EXPORT void obs_render_main_view(void);
#endif
@ -741,6 +745,19 @@ EXPORT void obs_apply_private_data(obs_data_t *settings);
EXPORT void obs_set_private_data(obs_data_t *settings);
EXPORT obs_data_t *obs_get_private_data(void);
typedef void (*obs_task_t)(void *param);
enum obs_task_type {
OBS_TASK_UI,
OBS_TASK_GRAPHICS,
};
EXPORT void obs_queue_task(enum obs_task_type type, obs_task_t task,
void *param, bool wait);
typedef void (*obs_task_handler_t)(obs_task_t task, void *param, bool wait);
EXPORT void obs_set_ui_task_handler(obs_task_handler_t handler);
/* ------------------------------------------------------------------------- */
/* View context */
@ -938,6 +955,7 @@ EXPORT enum obs_source_type obs_source_get_type(const obs_source_t *source);
/** Gets the source identifier */
EXPORT const char *obs_source_get_id(const obs_source_t *source);
EXPORT const char *obs_source_get_unversioned_id(const obs_source_t *source);
/** Returns the signal handler for a source */
EXPORT signal_handler_t *
@ -1175,6 +1193,8 @@ EXPORT void obs_source_output_video(obs_source_t *source,
EXPORT void obs_source_output_video2(obs_source_t *source,
const struct obs_source_frame2 *frame);
EXPORT void obs_source_set_async_rotation(obs_source_t *source, long rotation);
/**
* Preloads asynchronous video data to allow instantaneous playback
*
@ -1317,6 +1337,19 @@ EXPORT bool obs_source_audio_active(const obs_source_t *source);
EXPORT uint32_t obs_source_get_last_obs_version(const obs_source_t *source);
/** Media controls */
EXPORT void obs_source_media_play_pause(obs_source_t *source, bool pause);
EXPORT void obs_source_media_restart(obs_source_t *source);
EXPORT void obs_source_media_stop(obs_source_t *source);
EXPORT void obs_source_media_next(obs_source_t *source);
EXPORT void obs_source_media_previous(obs_source_t *source);
EXPORT int64_t obs_source_media_get_duration(obs_source_t *source);
EXPORT int64_t obs_source_media_get_time(obs_source_t *source);
EXPORT void obs_source_media_set_time(obs_source_t *source, int64_t ms);
EXPORT enum obs_media_state obs_source_media_get_state(obs_source_t *source);
EXPORT void obs_source_media_started(obs_source_t *source);
EXPORT void obs_source_media_ended(obs_source_t *source);
/* ------------------------------------------------------------------------- */
/* Transition-specific functions */
enum obs_transition_target {
@ -1333,6 +1366,7 @@ EXPORT obs_source_t *obs_transition_get_active_source(obs_source_t *transition);
enum obs_transition_mode {
OBS_TRANSITION_MODE_AUTO,
OBS_TRANSITION_MODE_MANUAL,
};
EXPORT bool obs_transition_start(obs_source_t *transition,
@ -1341,6 +1375,10 @@ EXPORT bool obs_transition_start(obs_source_t *transition,
EXPORT void obs_transition_set(obs_source_t *transition, obs_source_t *source);
EXPORT void obs_transition_set_manual_time(obs_source_t *transition, float t);
EXPORT void obs_transition_set_manual_torque(obs_source_t *transition,
float torque, float clamp);
enum obs_transition_scale_type {
OBS_TRANSITION_SCALE_MAX_ONLY,
OBS_TRANSITION_SCALE_ASPECT,
@ -1445,6 +1483,9 @@ EXPORT obs_scene_t *obs_scene_from_source(const obs_source_t *source);
EXPORT obs_sceneitem_t *obs_scene_find_source(obs_scene_t *scene,
const char *name);
EXPORT obs_sceneitem_t *obs_scene_find_source_recursive(obs_scene_t *scene,
const char *name);
EXPORT obs_sceneitem_t *obs_scene_find_sceneitem_by_id(obs_scene_t *scene,
int64_t id);
@ -1489,7 +1530,7 @@ EXPORT obs_scene_t *obs_sceneitem_get_scene(const obs_sceneitem_t *item);
EXPORT obs_source_t *obs_sceneitem_get_source(const obs_sceneitem_t *item);
/* FIXME: The following functions should be deprecated and replaced with a way
* to specify savable private user data. -Jim */
* to specify saveable private user data. -Jim */
EXPORT void obs_sceneitem_select(obs_sceneitem_t *item, bool select);
EXPORT bool obs_sceneitem_selected(const obs_sceneitem_t *item);
EXPORT bool obs_sceneitem_locked(const obs_sceneitem_t *item);
@ -1577,6 +1618,13 @@ EXPORT obs_sceneitem_t *obs_scene_insert_group(obs_scene_t *scene,
obs_sceneitem_t **items,
size_t count);
EXPORT obs_sceneitem_t *obs_scene_add_group2(obs_scene_t *scene,
const char *name, bool signal);
EXPORT obs_sceneitem_t *obs_scene_insert_group2(obs_scene_t *scene,
const char *name,
obs_sceneitem_t **items,
size_t count, bool signal);
EXPORT obs_sceneitem_t *obs_scene_get_group(obs_scene_t *scene,
const char *name);
@ -1585,6 +1633,7 @@ EXPORT bool obs_sceneitem_is_group(obs_sceneitem_t *item);
EXPORT obs_scene_t *obs_sceneitem_group_get_scene(const obs_sceneitem_t *group);
EXPORT void obs_sceneitem_group_ungroup(obs_sceneitem_t *group);
EXPORT void obs_sceneitem_group_ungroup2(obs_sceneitem_t *group, bool signal);
EXPORT void obs_sceneitem_group_add_item(obs_sceneitem_t *group,
obs_sceneitem_t *item);
@ -1603,6 +1652,9 @@ EXPORT void obs_sceneitem_group_enum_items(obs_sceneitem_t *group,
void *),
void *param);
/** Gets the group from its source, or NULL if not a group */
EXPORT obs_scene_t *obs_group_from_source(const obs_source_t *source);
EXPORT void obs_sceneitem_defer_group_resize_begin(obs_sceneitem_t *item);
EXPORT void obs_sceneitem_defer_group_resize_end(obs_sceneitem_t *item);
@ -1951,6 +2003,9 @@ EXPORT enum obs_encoder_type obs_encoder_get_type(const obs_encoder_t *encoder);
EXPORT void obs_encoder_set_scaled_size(obs_encoder_t *encoder, uint32_t width,
uint32_t height);
/** For video encoders, returns true if pre-encode scaling is enabled */
EXPORT bool obs_encoder_scaling_enabled(const obs_encoder_t *encoder);
/** For video encoders, returns the width of the encoded image */
EXPORT uint32_t obs_encoder_get_width(const obs_encoder_t *encoder);
@ -2029,11 +2084,11 @@ EXPORT uint32_t obs_encoder_get_caps(const obs_encoder_t *encoder);
#ifndef SWIG
/** Duplicates an encoder packet */
DEPRECATED
OBS_DEPRECATED
EXPORT void obs_duplicate_encoder_packet(struct encoder_packet *dst,
const struct encoder_packet *src);
DEPRECATED
OBS_DEPRECATED
EXPORT void obs_free_encoder_packet(struct encoder_packet *packet);
#endif
@ -2167,6 +2222,10 @@ static inline void obs_source_frame_destroy(struct obs_source_frame *frame)
EXPORT void obs_source_frame_copy(struct obs_source_frame *dst,
const struct obs_source_frame *src);
/* ------------------------------------------------------------------------- */
/* Get source icon type */
EXPORT enum obs_icon_type obs_source_get_icon_type(const char *id);
#ifdef __cplusplus
}
#endif

View file

@ -236,7 +236,7 @@ public:
}
OBSSignal(const OBSSignal &) = delete;
OBSSignal(OBSSignal &&other)
OBSSignal(OBSSignal &&other) noexcept
: handler(other.handler),
signal(other.signal),
callback(other.callback),
@ -249,7 +249,7 @@ public:
}
OBSSignal &operator=(const OBSSignal &) = delete;
OBSSignal &operator=(OBSSignal &&other)
OBSSignal &operator=(OBSSignal &&other) noexcept
{
Disconnect();

View file

@ -19,6 +19,7 @@
#define HAVE_DBUS @HAVE_DBUS@
#define HAVE_PULSEAUDIO @HAVE_PULSEAUDIO@
#define USE_XINPUT @USE_XINPUT@
#define NEEDS_SIMDE @NEEDS_SIMDE@
#define LIBOBS_IMAGEMAGICK_DIR_STYLE_6L 6
#define LIBOBS_IMAGEMAGICK_DIR_STYLE_7GE 7
#define LIBOBS_IMAGEMAGICK_DIR_STYLE @LIBOBS_IMAGEMAGICK_DIR_STYLE@

View file

@ -18,61 +18,26 @@
/*
* Contains hacks for getting some C99 stuff working in VC, things like
* bool, inline, stdint
* bool, stdint
*/
#define UNUSED_PARAMETER(param) (void)param
#ifdef _MSC_VER
#define DEPRECATED __declspec(deprecated)
#define OBS_DEPRECATED __declspec(deprecated)
#define FORCE_INLINE __forceinline
#else
#define DEPRECATED __attribute__((deprecated))
#define OBS_DEPRECATED __attribute__((deprecated))
#define FORCE_INLINE inline __attribute__((always_inline))
#endif
#ifdef _MSC_VER
/* Microsoft is one of the most inept companies on the face of the planet.
* The fact that even visual studio 2013 doesn't support the standard 'inline'
* keyword is so incredibly stupid that I just can't imagine what sort of
* incredibly inept moron could possibly be managing the visual C compiler
* project. They should be fired, and legally forbidden to have a job in
* ANYTHING even REMOTELY related to programming. FOREVER. This should also
* apply to the next 10 generations all of their descendants. */
#ifndef __cplusplus
#define inline __inline
#endif
#define EXPORT __declspec(dllexport)
#else
#define EXPORT
#endif
#if _MSC_VER && _MSC_VER < 0x0708
#include "vc/vc_stdint.h"
#include "vc/vc_stdbool.h"
#ifndef __off_t_defined
#define __off_t_defined
#if _FILE_OFFSET_BITS == 64
typedef long long off_t;
#else
typedef long off_t;
#endif
typedef int64_t off64_t;
#endif /* __off_t_defined */
#define SIZE_T_FORMAT "%u"
#else
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <sys/types.h>
#define SIZE_T_FORMAT "%zu"
#endif /* _MSC_VER */

View file

@ -95,7 +95,7 @@ config_t *config_create(const char *file)
static inline void remove_ref_whitespace(struct strref *ref)
{
if (ref->array) {
while (is_whitespace(*ref->array)) {
while (ref->len && is_whitespace(*ref->array)) {
ref->array++;
ref->len--;
}
@ -130,7 +130,7 @@ static bool config_parse_string(struct lexer *lex, struct strref *ref, char end)
strref_add(ref, &token.text);
}
remove_ref_whitespace(ref);
//remove_ref_whitespace(ref);
return success;
}

View file

@ -0,0 +1,36 @@
/*
* Copyright (c) 2020 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
#include <curl/curl.h>
#if defined(_WIN32) && LIBCURL_VERSION_NUM >= 0x072c00
#ifdef CURLSSLOPT_REMOVE_BEST_EFFORT
#define CURL_OBS_REVOKE_SETTING CURLSSLOPT_REVOKE_BEST_EFFORT
#else
#define CURL_OBS_REVOKE_SETTING CURLSSLOPT_NO_REVOKE
#endif
#define curl_obs_set_revoke_setting(handle) \
curl_easy_setopt(handle, CURLOPT_SSL_OPTIONS, CURL_OBS_REVOKE_SETTING)
#else
#define curl_obs_set_revoke_setting(handle)
#endif

View file

@ -284,7 +284,7 @@ static inline void darray_insert_array(const size_t element_size,
assert(array != NULL);
assert(num != 0);
assert(idx < dst->num);
assert(idx <= dst->num);
old_num = dst->num;
darray_resize(element_size, dst, dst->num + num);

View file

@ -93,5 +93,12 @@ size_t os_process_pipe_write(os_process_pipe_t *pp, const uint8_t *data,
return 0;
}
return fwrite(data, 1, len, pp->file);
size_t written = 0;
while (written < len) {
size_t ret = fwrite(data + written, 1, len - written, pp->file);
if (!ret)
return written;
written += ret;
}
return written;
}

View file

@ -38,6 +38,7 @@
#include <sys/param.h>
#include <sys/queue.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <sys/user.h>
#include <unistd.h>
#include <libprocstat.h>

View file

@ -31,9 +31,12 @@
#include "../../deps/w32-pthreads/pthread.h"
#define MAX_SZ_LEN 256
static bool have_clockfreq = false;
static LARGE_INTEGER clock_freq;
static uint32_t winver = 0;
static char win_release_id[MAX_SZ_LEN] = "unavailable";
static inline uint64_t get_clockfreq(void)
{
@ -336,28 +339,28 @@ bool os_file_exists(const char *path)
size_t os_get_abs_path(const char *path, char *abspath, size_t size)
{
wchar_t wpath[512];
wchar_t wabspath[512];
wchar_t wpath[MAX_PATH];
wchar_t wabspath[MAX_PATH];
size_t out_len = 0;
size_t len;
if (!abspath)
return 0;
len = os_utf8_to_wcs(path, 0, wpath, 512);
len = os_utf8_to_wcs(path, 0, wpath, MAX_PATH);
if (!len)
return 0;
if (_wfullpath(wabspath, wpath, 512) != NULL)
if (_wfullpath(wabspath, wpath, MAX_PATH) != NULL)
out_len = os_wcs_to_utf8(wabspath, 0, abspath, size);
return out_len;
}
char *os_get_abs_path_ptr(const char *path)
{
char *ptr = bmalloc(512);
char *ptr = bmalloc(MAX_PATH);
if (!os_get_abs_path(path, ptr, 512)) {
if (!os_get_abs_path(path, ptr, MAX_PATH)) {
bfree(ptr);
ptr = NULL;
}
@ -857,6 +860,112 @@ void get_reg_dword(HKEY hkey, LPCWSTR sub_key, LPCWSTR value_name,
#define WINVER_REG_KEY L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"
static inline void rtl_get_ver(struct win_version_info *ver)
{
RTL_OSVERSIONINFOEXW osver = {0};
HMODULE ntdll = GetModuleHandleW(L"ntdll");
NTSTATUS s;
NTSTATUS(WINAPI * get_ver)
(RTL_OSVERSIONINFOEXW *) =
(void *)GetProcAddress(ntdll, "RtlGetVersion");
if (!get_ver) {
return;
}
osver.dwOSVersionInfoSize = sizeof(osver);
s = get_ver(&osver);
if (s < 0) {
return;
}
ver->major = osver.dwMajorVersion;
ver->minor = osver.dwMinorVersion;
ver->build = osver.dwBuildNumber;
ver->revis = 0;
}
static inline bool get_reg_sz(HKEY key, const wchar_t *val, wchar_t *buf,
const size_t size)
{
DWORD dwsize = (DWORD)size;
LSTATUS status;
status = RegQueryValueExW(key, val, NULL, NULL, (LPBYTE)buf, &dwsize);
buf[(size / sizeof(wchar_t)) - 1] = 0;
return status == ERROR_SUCCESS;
}
static inline void get_reg_ver(struct win_version_info *ver)
{
HKEY key;
DWORD size, dw_val;
LSTATUS status;
wchar_t str[MAX_SZ_LEN];
status = RegOpenKeyW(HKEY_LOCAL_MACHINE, WINVER_REG_KEY, &key);
if (status != ERROR_SUCCESS)
return;
size = sizeof(dw_val);
status = RegQueryValueExW(key, L"CurrentMajorVersionNumber", NULL, NULL,
(LPBYTE)&dw_val, &size);
if (status == ERROR_SUCCESS)
ver->major = (int)dw_val;
status = RegQueryValueExW(key, L"CurrentMinorVersionNumber", NULL, NULL,
(LPBYTE)&dw_val, &size);
if (status == ERROR_SUCCESS)
ver->minor = (int)dw_val;
status = RegQueryValueExW(key, L"UBR", NULL, NULL, (LPBYTE)&dw_val,
&size);
if (status == ERROR_SUCCESS)
ver->revis = (int)dw_val;
if (get_reg_sz(key, L"CurrentBuildNumber", str, sizeof(str))) {
ver->build = wcstol(str, NULL, 10);
}
if (get_reg_sz(key, L"ReleaseId", str, sizeof(str))) {
os_wcs_to_utf8(str, 0, win_release_id, MAX_SZ_LEN);
}
RegCloseKey(key);
}
static inline bool version_higher(struct win_version_info *cur,
struct win_version_info *new)
{
if (new->major > cur->major) {
return true;
}
if (new->major == cur->major) {
if (new->minor > cur->minor) {
return true;
}
if (new->minor == cur->minor) {
if (new->build > cur->build) {
return true;
}
if (new->build == cur->build) {
return new->revis > cur->revis;
}
}
}
return false;
}
static inline void use_higher_ver(struct win_version_info *cur,
struct win_version_info *new)
{
if (version_higher(cur, new))
*cur = *new;
}
void get_win_ver(struct win_version_info *info)
{
static struct win_version_info ver = {0};
@ -866,36 +975,29 @@ void get_win_ver(struct win_version_info *info)
return;
if (!got_version) {
get_dll_ver(L"kernel32", &ver);
struct win_version_info reg_ver = {0};
struct win_version_info rtl_ver = {0};
struct win_version_info nto_ver = {0};
get_reg_ver(&reg_ver);
rtl_get_ver(&rtl_ver);
get_dll_ver(L"ntoskrnl.exe", &nto_ver);
ver = reg_ver;
use_higher_ver(&ver, &rtl_ver);
use_higher_ver(&ver, &nto_ver);
got_version = true;
if (ver.major == 10) {
HKEY key;
DWORD size, win10_revision;
LSTATUS status;
status = RegOpenKeyW(HKEY_LOCAL_MACHINE, WINVER_REG_KEY,
&key);
if (status != ERROR_SUCCESS)
return;
size = sizeof(win10_revision);
status = RegQueryValueExW(key, L"UBR", NULL, NULL,
(LPBYTE)&win10_revision,
&size);
if (status == ERROR_SUCCESS)
ver.revis = (int)win10_revision > ver.revis
? (int)win10_revision
: ver.revis;
RegCloseKey(key);
}
}
*info = ver;
}
const char *get_win_release_id(void)
{
return win_release_id;
}
uint32_t get_win_ver_int(void)
{
return get_winver();

View file

@ -25,6 +25,7 @@
#include "bmem.h"
#include "utf8.h"
#include "dstr.h"
#include "obs.h"
FILE *os_wfopen(const wchar_t *path, const char *mode)
{
@ -652,6 +653,9 @@ const char *os_get_path_extension(const char *path)
char *period;
char *slash;
if (!path[0])
return NULL;
dstr_init_copy(&temp, path);
dstr_replace(&temp, "\\", "/");
@ -708,6 +712,8 @@ char *os_generate_formatted_filename(const char *extension, bool space,
time_t now = time(0);
struct tm *cur_time;
cur_time = localtime(&now);
struct obs_video_info ovi;
obs_get_video_info(&ovi);
const size_t spec_count = 23;
static const char *spec[][2] = {
@ -728,11 +734,10 @@ char *os_generate_formatted_filename(const char *extension, bool space,
dstr_init_copy(&sf, format);
while (pos < sf.len) {
const char *cmp = sf.array + pos;
for (size_t i = 0; i < spec_count && !convert[0]; i++) {
size_t len = strlen(spec[i][0]);
const char *cmp = sf.array + pos;
if (astrcmp_n(cmp, spec[i][0], len) == 0) {
if (strlen(spec[i][1]))
strftime(convert, sizeof(convert),
@ -747,6 +752,35 @@ char *os_generate_formatted_filename(const char *extension, bool space,
}
}
if (!convert[0]) {
if (astrcmp_n(cmp, "%FPS", 4) == 0) {
if (ovi.fps_den <= 1) {
sprintf(convert, "%u", ovi.fps_num);
} else {
const double obsFPS =
(double)ovi.fps_num /
(double)ovi.fps_den;
sprintf(convert, "%.2f", obsFPS);
}
replace_text(&sf, pos, 4, convert);
} else if (astrcmp_n(cmp, "%CRES", 5) == 0) {
sprintf(convert, "%ux%u", ovi.base_width,
ovi.base_height);
replace_text(&sf, pos, 5, convert);
} else if (astrcmp_n(cmp, "%ORES", 5) == 0) {
sprintf(convert, "%ux%u", ovi.output_width,
ovi.output_height);
replace_text(&sf, pos, 5, convert);
} else if (astrcmp_n(cmp, "%VF", 3) == 0) {
strcpy(convert, get_video_format_name(
ovi.output_format));
replace_text(&sf, pos, 3, convert);
}
}
if (convert[0]) {
pos += strlen(convert);
convert[0] = 0;

258
libobs/util/simde/check.h Normal file
View file

@ -0,0 +1,258 @@
/* Check (assertions)
* Portable Snippets - https://gitub.com/nemequ/portable-snippets
* Created by Evan Nemerson <evan@nemerson.com>
*
* To the extent possible under law, the authors have waived all
* copyright and related or neighboring rights to this code. For
* details, see the Creative Commons Zero 1.0 Universal license at
* https://creativecommons.org/publicdomain/zero/1.0/
*/
#if !defined(SIMDE_CHECK_H)
#define SIMDE_CHECK_H
#if !defined(SIMDE_NDEBUG) && !defined(SIMDE_DEBUG)
#define SIMDE_NDEBUG 1
#endif
#include <stdint.h>
#if !defined(_WIN32)
#define SIMDE_SIZE_MODIFIER "z"
#define SIMDE_CHAR_MODIFIER "hh"
#define SIMDE_SHORT_MODIFIER "h"
#else
#if defined(_M_X64) || defined(__amd64__)
#define SIMDE_SIZE_MODIFIER "I64"
#else
#define SIMDE_SIZE_MODIFIER ""
#endif
#define SIMDE_CHAR_MODIFIER ""
#define SIMDE_SHORT_MODIFIER ""
#endif
#if defined(_MSC_VER) && (_MSC_VER >= 1500)
#define SIMDE__PUSH_DISABLE_MSVC_C4127 \
__pragma(warning(push)) __pragma(warning(disable : 4127))
#define SIMDE__POP_DISABLE_MSVC_C4127 __pragma(warning(pop))
#else
#define SIMDE__PUSH_DISABLE_MSVC_C4127
#define SIMDE__POP_DISABLE_MSVC_C4127
#endif
#if !defined(simde_errorf)
#include <stdio.h>
#include <stdlib.h>
#define simde_errorf(format, ...) \
(fprintf(stderr, format, __VA_ARGS__), abort())
#endif
#define simde_error(msg) simde_errorf("%s", msg)
#if defined(SIMDE_NDEBUG)
#if defined(SIMDE_CHECK_FAIL_DEFINED)
#define simde_assert(expr)
#else
#if defined(HEDLEY_ASSUME)
#define simde_assert(expr) HEDLEY_ASSUME(expr)
#elif HEDLEY_GCC_VERSION_CHECK(4, 5, 0)
#define simde_assert(expr) ((void)(!!(expr) ? 1 : (__builtin_unreachable(), 1)))
#elif HEDLEY_MSVC_VERSION_CHECK(13, 10, 0)
#define simde_assert(expr) __assume(expr)
#else
#define simde_assert(expr)
#endif
#endif
#define simde_assert_true(expr) simde_assert(expr)
#define simde_assert_false(expr) simde_assert(!(expr))
#define simde_assert_type_full(prefix, suffix, T, fmt, a, op, b) \
simde_assert(((a)op(b)))
#define simde_assert_double_equal(a, b, precision)
#define simde_assert_string_equal(a, b)
#define simde_assert_string_not_equal(a, b)
#define simde_assert_memory_equal(size, a, b)
#define simde_assert_memory_not_equal(size, a, b)
#else
#define simde_assert(expr) \
do { \
if (!HEDLEY_LIKELY(expr)) { \
simde_error("assertion failed: " #expr "\n"); \
} \
SIMDE__PUSH_DISABLE_MSVC_C4127 \
} while (0) SIMDE__POP_DISABLE_MSVC_C4127
#define simde_assert_true(expr) \
do { \
if (!HEDLEY_LIKELY(expr)) { \
simde_error("assertion failed: " #expr \
" is not true\n"); \
} \
SIMDE__PUSH_DISABLE_MSVC_C4127 \
} while (0) SIMDE__POP_DISABLE_MSVC_C4127
#define simde_assert_false(expr) \
do { \
if (!HEDLEY_LIKELY(!(expr))) { \
simde_error("assertion failed: " #expr \
" is not false\n"); \
} \
SIMDE__PUSH_DISABLE_MSVC_C4127 \
} while (0) SIMDE__POP_DISABLE_MSVC_C4127
#define simde_assert_type_full(prefix, suffix, T, fmt, a, op, b) \
do { \
T simde_tmp_a_ = (a); \
T simde_tmp_b_ = (b); \
if (!(simde_tmp_a_ op simde_tmp_b_)) { \
simde_errorf("assertion failed: %s %s %s (" prefix \
"%" fmt suffix " %s " prefix \
"%" fmt suffix ")\n", \
#a, #op, #b, simde_tmp_a_, #op, \
simde_tmp_b_); \
} \
SIMDE__PUSH_DISABLE_MSVC_C4127 \
} while (0) SIMDE__POP_DISABLE_MSVC_C4127
#define simde_assert_double_equal(a, b, precision) \
do { \
const double simde_tmp_a_ = (a); \
const double simde_tmp_b_ = (b); \
const double simde_tmp_diff_ = \
((simde_tmp_a_ - simde_tmp_b_) < 0) \
? -(simde_tmp_a_ - simde_tmp_b_) \
: (simde_tmp_a_ - simde_tmp_b_); \
if (HEDLEY_UNLIKELY(simde_tmp_diff_ > 1e-##precision)) { \
simde_errorf( \
"assertion failed: %s == %s (%0." #precision \
"g == %0." #precision "g)\n", \
#a, #b, simde_tmp_a_, simde_tmp_b_); \
} \
SIMDE__PUSH_DISABLE_MSVC_C4127 \
} while (0) SIMDE__POP_DISABLE_MSVC_C4127
#include <string.h>
#define simde_assert_string_equal(a, b) \
do { \
const char *simde_tmp_a_ = a; \
const char *simde_tmp_b_ = b; \
if (HEDLEY_UNLIKELY(strcmp(simde_tmp_a_, simde_tmp_b_) != \
0)) { \
simde_errorf( \
"assertion failed: string %s == %s (\"%s\" == \"%s\")\n", \
#a, #b, simde_tmp_a_, simde_tmp_b_); \
} \
SIMDE__PUSH_DISABLE_MSVC_C4127 \
} while (0) SIMDE__POP_DISABLE_MSVC_C4127
#define simde_assert_string_not_equal(a, b) \
do { \
const char *simde_tmp_a_ = a; \
const char *simde_tmp_b_ = b; \
if (HEDLEY_UNLIKELY(strcmp(simde_tmp_a_, simde_tmp_b_) == \
0)) { \
simde_errorf( \
"assertion failed: string %s != %s (\"%s\" == \"%s\")\n", \
#a, #b, simde_tmp_a_, simde_tmp_b_); \
} \
SIMDE__PUSH_DISABLE_MSVC_C4127 \
} while (0) SIMDE__POP_DISABLE_MSVC_C4127
#define simde_assert_memory_equal(size, a, b) \
do { \
const unsigned char *simde_tmp_a_ = \
(const unsigned char *)(a); \
const unsigned char *simde_tmp_b_ = \
(const unsigned char *)(b); \
const size_t simde_tmp_size_ = (size); \
if (HEDLEY_UNLIKELY(memcmp(simde_tmp_a_, simde_tmp_b_, \
simde_tmp_size_)) != 0) { \
size_t simde_tmp_pos_; \
for (simde_tmp_pos_ = 0; \
simde_tmp_pos_ < simde_tmp_size_; \
simde_tmp_pos_++) { \
if (simde_tmp_a_[simde_tmp_pos_] != \
simde_tmp_b_[simde_tmp_pos_]) { \
simde_errorf( \
"assertion failed: memory %s == %s, at offset %" SIMDE_SIZE_MODIFIER \
"u\n", \
#a, #b, simde_tmp_pos_); \
break; \
} \
} \
} \
SIMDE__PUSH_DISABLE_MSVC_C4127 \
} while (0) SIMDE__POP_DISABLE_MSVC_C4127
#define simde_assert_memory_not_equal(size, a, b) \
do { \
const unsigned char *simde_tmp_a_ = \
(const unsigned char *)(a); \
const unsigned char *simde_tmp_b_ = \
(const unsigned char *)(b); \
const size_t simde_tmp_size_ = (size); \
if (HEDLEY_UNLIKELY(memcmp(simde_tmp_a_, simde_tmp_b_, \
simde_tmp_size_)) == 0) { \
simde_errorf( \
"assertion failed: memory %s != %s (%" SIMDE_SIZE_MODIFIER \
"u bytes)\n", \
#a, #b, simde_tmp_size_); \
} \
SIMDE__PUSH_DISABLE_MSVC_C4127 \
} while (0) SIMDE__POP_DISABLE_MSVC_C4127
#endif
#define simde_assert_type(T, fmt, a, op, b) \
simde_assert_type_full("", "", T, fmt, a, op, b)
#define simde_assert_char(a, op, b) \
simde_assert_type_full("'\\x", "'", char, \
"02" SIMDE_CHAR_MODIFIER "x", a, op, b)
#define simde_assert_uchar(a, op, b) \
simde_assert_type_full("'\\x", "'", unsigned char, \
"02" SIMDE_CHAR_MODIFIER "x", a, op, b)
#define simde_assert_short(a, op, b) \
simde_assert_type(short, SIMDE_SHORT_MODIFIER "d", a, op, b)
#define simde_assert_ushort(a, op, b) \
simde_assert_type(unsigned short, SIMDE_SHORT_MODIFIER "u", a, op, b)
#define simde_assert_int(a, op, b) simde_assert_type(int, "d", a, op, b)
#define simde_assert_uint(a, op, b) \
simde_assert_type(unsigned int, "u", a, op, b)
#define simde_assert_long(a, op, b) simde_assert_type(long int, "ld", a, op, b)
#define simde_assert_ulong(a, op, b) \
simde_assert_type(unsigned long int, "lu", a, op, b)
#define simde_assert_llong(a, op, b) \
simde_assert_type(long long int, "lld", a, op, b)
#define simde_assert_ullong(a, op, b) \
simde_assert_type(unsigned long long int, "llu", a, op, b)
#define simde_assert_size(a, op, b) \
simde_assert_type(size_t, SIMDE_SIZE_MODIFIER "u", a, op, b)
#define simde_assert_float(a, op, b) simde_assert_type(float, "f", a, op, b)
#define simde_assert_double(a, op, b) simde_assert_type(double, "g", a, op, b)
#define simde_assert_ptr(a, op, b) \
simde_assert_type(const void *, "p", a, op, b)
#define simde_assert_int8(a, op, b) simde_assert_type(int8_t, PRIi8, a, op, b)
#define simde_assert_uint8(a, op, b) simde_assert_type(uint8_t, PRIu8, a, op, b)
#define simde_assert_int16(a, op, b) \
simde_assert_type(int16_t, PRIi16, a, op, b)
#define simde_assert_uint16(a, op, b) \
simde_assert_type(uint16_t, PRIu16, a, op, b)
#define simde_assert_int32(a, op, b) \
simde_assert_type(int32_t, PRIi32, a, op, b)
#define simde_assert_uint32(a, op, b) \
simde_assert_type(uint32_t, PRIu32, a, op, b)
#define simde_assert_int64(a, op, b) \
simde_assert_type(int64_t, PRIi64, a, op, b)
#define simde_assert_uint64(a, op, b) \
simde_assert_type(uint64_t, PRIu64, a, op, b)
#define simde_assert_ptr_equal(a, b) simde_assert_ptr(a, ==, b)
#define simde_assert_ptr_not_equal(a, b) simde_assert_ptr(a, !=, b)
#define simde_assert_null(ptr) simde_assert_ptr(ptr, ==, NULL)
#define simde_assert_not_null(ptr) simde_assert_ptr(ptr, !=, NULL)
#define simde_assert_ptr_null(ptr) simde_assert_ptr(ptr, ==, NULL)
#define simde_assert_ptr_not_null(ptr) simde_assert_ptr(ptr, !=, NULL)
#endif /* !defined(SIMDE_CHECK_H) */

1616
libobs/util/simde/hedley.h Normal file

File diff suppressed because it is too large Load diff

1356
libobs/util/simde/mmx.h Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,355 @@
/* Architecture detection
* Created by Evan Nemerson <evan@nemerson.com>
*
* To the extent possible under law, the authors have waived all
* copyright and related or neighboring rights to this code. For
* details, see the Creative Commons Zero 1.0 Universal license at
* <https://creativecommons.org/publicdomain/zero/1.0/>
*
* Different compilers define different preprocessor macros for the
* same architecture. This is an attempt to provide a single
* interface which is usable on any compiler.
*
* In general, a macro named SIMDE_ARCH_* is defined for each
* architecture the CPU supports. When there are multiple possible
* versions, we try to define the macro to the target version. For
* example, if you want to check for i586+, you could do something
* like:
*
* #if defined(SIMDE_ARCH_X86) && (SIMDE_ARCH_X86 >= 5)
* ...
* #endif
*
* You could also just check that SIMDE_ARCH_X86 >= 5 without checking
* if it's defined first, but some compilers may emit a warning about
* an undefined macro being used (e.g., GCC with -Wundef).
*
* This was originally created for SIMDe
* <https://github.com/nemequ/simde> (hence the prefix), but this
* header has no dependencies and may be used anywhere. It is
* originally based on information from
* <https://sourceforge.net/p/predef/wiki/Architectures/>, though it
* has been enhanced with additional information.
*
* If you improve this file, or find a bug, please file the issue at
* <https://github.com/nemequ/simde/issues>. If you copy this into
* your project, even if you change the prefix, please keep the links
* to SIMDe intact so others know where to report issues, submit
* enhancements, and find the latest version. */
#if !defined(SIMDE_ARCH_H)
#define SIMDE_ARCH_H
/* Alpha
<https://en.wikipedia.org/wiki/DEC_Alpha> */
#if defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA)
#if defined(__alpha_ev6__)
#define SIMDE_ARCH_ALPHA 6
#elif defined(__alpha_ev5__)
#define SIMDE_ARCH_ALPHA 5
#elif defined(__alpha_ev4__)
#define SIMDE_ARCH_ALPHA 4
#else
#define SIMDE_ARCH_ALPHA 1
#endif
#endif
/* Atmel AVR
<https://en.wikipedia.org/wiki/Atmel_AVR> */
#if defined(__AVR_ARCH__)
#define SIMDE_ARCH_AVR __AVR_ARCH__
#endif
/* AMD64 / x86_64
<https://en.wikipedia.org/wiki/X86-64> */
#if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || \
defined(__x86_64) || defined(_M_X66) || defined(_M_AMD64)
#define SIMDE_ARCH_AMD64 1
#endif
/* ARM
<https://en.wikipedia.org/wiki/ARM_architecture> */
#if defined(__ARM_ARCH_8A__)
#define SIMDE_ARCH_ARM 82
#elif defined(__ARM_ARCH_8R__)
#define SIMDE_ARCH_ARM 81
#elif defined(__ARM_ARCH_8__)
#define SIMDE_ARCH_ARM 80
#elif defined(__ARM_ARCH_7S__)
#define SIMDE_ARCH_ARM 74
#elif defined(__ARM_ARCH_7M__)
#define SIMDE_ARCH_ARM 73
#elif defined(__ARM_ARCH_7R__)
#define SIMDE_ARCH_ARM 72
#elif defined(__ARM_ARCH_7A__)
#define SIMDE_ARCH_ARM 71
#elif defined(__ARM_ARCH_7__)
#define SIMDE_ARCH_ARM 70
#elif defined(__ARM_ARCH)
#define SIMDE_ARCH_ARM (__ARM_ARCH * 10)
#elif defined(_M_ARM)
#define SIMDE_ARCH_ARM (_M_ARM * 10)
#elif defined(__arm__) || defined(__thumb__) || defined(__TARGET_ARCH_ARM) || \
defined(_ARM) || defined(_M_ARM) || defined(_M_ARM)
#define SIMDE_ARCH_ARM 1
#endif
/* AArch64
<https://en.wikipedia.org/wiki/ARM_architecture> */
#if defined(__aarch64__) || defined(_M_ARM64)
#define SIMDE_ARCH_AARCH64 10
#endif
/* Blackfin
<https://en.wikipedia.org/wiki/Blackfin> */
#if defined(__bfin) || defined(__BFIN__) || defined(__bfin__)
#define SIMDE_ARCH_BLACKFIN 1
#endif
/* CRIS
<https://en.wikipedia.org/wiki/ETRAX_CRIS> */
#if defined(__CRIS_arch_version)
#define SIMDE_ARCH_CRIS __CRIS_arch_version
#elif defined(__cris__) || defined(__cris) || defined(__CRIS) || \
defined(__CRIS__)
#define SIMDE_ARCH_CRIS 1
#endif
/* Convex
<https://en.wikipedia.org/wiki/Convex_Computer> */
#if defined(__convex_c38__)
#define SIMDE_ARCH_CONVEX 38
#elif defined(__convex_c34__)
#define SIMDE_ARCH_CONVEX 34
#elif defined(__convex_c32__)
#define SIMDE_ARCH_CONVEX 32
#elif defined(__convex_c2__)
#define SIMDE_ARCH_CONVEX 2
#elif defined(__convex__)
#define SIMDE_ARCH_CONVEX 1
#endif
/* Adapteva Epiphany
<https://en.wikipedia.org/wiki/Adapteva_Epiphany> */
#if defined(__epiphany__)
#define SIMDE_ARCH_EPIPHANY 1
#endif
/* Fujitsu FR-V
<https://en.wikipedia.org/wiki/FR-V_(microprocessor)> */
#if defined(__frv__)
#define SIMDE_ARCH_FRV 1
#endif
/* H8/300
<https://en.wikipedia.org/wiki/H8_Family> */
#if defined(__H8300__)
#define SIMDE_ARCH_H8300
#endif
/* HP/PA / PA-RISC
<https://en.wikipedia.org/wiki/PA-RISC> */
#if defined(__PA8000__) || defined(__HPPA20__) || defined(__RISC2_0__) || \
defined(_PA_RISC2_0)
#define SIMDE_ARCH_HPPA 20
#elif defined(__PA7100__) || defined(__HPPA11__) || defined(_PA_RISC1_1)
#define SIMDE_ARCH_HPPA 11
#elif defined(_PA_RISC1_0)
#define SIMDE_ARCH_HPPA 10
#elif defined(__hppa__) || defined(__HPPA__) || defined(__hppa)
#define SIMDE_ARCH_HPPA 1
#endif
/* x86
<https://en.wikipedia.org/wiki/X86> */
#if defined(_M_IX86)
#define SIMDE_ARCH_X86 (_M_IX86 / 100)
#elif defined(__I86__)
#define SIMDE_ARCH_X86 __I86__
#elif defined(i686) || defined(__i686) || defined(__i686__)
#define SIMDE_ARCH_X86 6
#elif defined(i586) || defined(__i586) || defined(__i586__)
#define SIMDE_ARCH_X86 5
#elif defined(i486) || defined(__i486) || defined(__i486__)
#define SIMDE_ARCH_X86 4
#elif defined(i386) || defined(__i386) || defined(__i386__)
#define SIMDE_ARCH_X86 3
#elif defined(_X86_) || defined(__X86__) || defined(__THW_INTEL__)
#define SIMDE_ARCH_X86 3
#endif
/* Itanium
<https://en.wikipedia.org/wiki/Itanium> */
#if defined(__ia64__) || defined(_IA64) || defined(__IA64__) || \
defined(__ia64) || defined(_M_IA64) || defined(__itanium__)
#define SIMDE_ARCH_IA64 1
#endif
/* Renesas M32R
<https://en.wikipedia.org/wiki/M32R> */
#if defined(__m32r__) || defined(__M32R__)
#define SIMDE_ARCH_M32R
#endif
/* Motorola 68000
<https://en.wikipedia.org/wiki/Motorola_68000> */
#if defined(__mc68060__) || defined(__MC68060__)
#define SIMDE_ARCH_M68K 68060
#elif defined(__mc68040__) || defined(__MC68040__)
#define SIMDE_ARCH_M68K 68040
#elif defined(__mc68030__) || defined(__MC68030__)
#define SIMDE_ARCH_M68K 68030
#elif defined(__mc68020__) || defined(__MC68020__)
#define SIMDE_ARCH_M68K 68020
#elif defined(__mc68010__) || defined(__MC68010__)
#define SIMDE_ARCH_M68K 68010
#elif defined(__mc68000__) || defined(__MC68000__)
#define SIMDE_ARCH_M68K 68000
#endif
/* Xilinx MicroBlaze
<https://en.wikipedia.org/wiki/MicroBlaze> */
#if defined(__MICROBLAZE__) || defined(__microblaze__)
#define SIMDE_ARCH_MICROBLAZE
#endif
/* MIPS
<https://en.wikipedia.org/wiki/MIPS_architecture> */
#if defined(_MIPS_ISA_MIPS64R2)
#define SIMDE_ARCH_MIPS 642
#elif defined(_MIPS_ISA_MIPS64)
#define SIMDE_ARCH_MIPS 640
#elif defined(_MIPS_ISA_MIPS32R2)
#define SIMDE_ARCH_MIPS 322
#elif defined(_MIPS_ISA_MIPS32)
#define SIMDE_ARCH_MIPS 320
#elif defined(_MIPS_ISA_MIPS4)
#define SIMDE_ARCH_MIPS 4
#elif defined(_MIPS_ISA_MIPS3)
#define SIMDE_ARCH_MIPS 3
#elif defined(_MIPS_ISA_MIPS2)
#define SIMDE_ARCH_MIPS 2
#elif defined(_MIPS_ISA_MIPS1)
#define SIMDE_ARCH_MIPS 1
#elif defined(_MIPS_ISA_MIPS) || defined(__mips) || defined(__MIPS__)
#define SIMDE_ARCH_MIPS 1
#endif
/* Matsushita MN10300
<https://en.wikipedia.org/wiki/MN103> */
#if defined(__MN10300__) || defined(__mn10300__)
#define SIMDE_ARCH_MN10300 1
#endif
/* POWER
<https://en.wikipedia.org/wiki/IBM_POWER_Instruction_Set_Architecture> */
#if defined(_M_PPC)
#define SIMDE_ARCH_POWER _M_PPC
#elif defined(_ARCH_PWR8)
#define SIMDE_ARCH_POWER 800
#elif defined(_ARCH_PWR7)
#define SIMDE_ARCH_POWER 700
#elif defined(_ARCH_PWR6)
#define SIMDE_ARCH_POWER 600
#elif defined(_ARCH_PWR5)
#define SIMDE_ARCH_POWER 500
#elif defined(_ARCH_PWR4)
#define SIMDE_ARCH_POWER 400
#elif defined(_ARCH_440) || defined(__ppc440__)
#define SIMDE_ARCH_POWER 440
#elif defined(_ARCH_450) || defined(__ppc450__)
#define SIMDE_ARCH_POWER 450
#elif defined(_ARCH_601) || defined(__ppc601__)
#define SIMDE_ARCH_POWER 601
#elif defined(_ARCH_603) || defined(__ppc603__)
#define SIMDE_ARCH_POWER 603
#elif defined(_ARCH_604) || defined(__ppc604__)
#define SIMDE_ARCH_POWER 604
#elif defined(_ARCH_605) || defined(__ppc605__)
#define SIMDE_ARCH_POWER 605
#elif defined(_ARCH_620) || defined(__ppc620__)
#define SIMDE_ARCH_POWER 620
#elif defined(__powerpc) || defined(__powerpc__) || defined(__POWERPC__) || \
defined(__ppc__) || defined(__PPC__) || defined(_ARCH_PPC) || \
defined(__ppc)
#define SIMDE_ARCH_POWER 1
#endif
/* SPARC
<https://en.wikipedia.org/wiki/SPARC> */
#if defined(__sparc_v9__) || defined(__sparcv9)
#define SIMDE_ARCH_SPARC 9
#elif defined(__sparc_v8__) || defined(__sparcv8)
#define SIMDE_ARCH_SPARC 8
#elif defined(__sparc_v7__) || defined(__sparcv7)
#define SIMDE_ARCH_SPARC 7
#elif defined(__sparc_v6__) || defined(__sparcv6)
#define SIMDE_ARCH_SPARC 6
#elif defined(__sparc_v5__) || defined(__sparcv5)
#define SIMDE_ARCH_SPARC 5
#elif defined(__sparc_v4__) || defined(__sparcv4)
#define SIMDE_ARCH_SPARC 4
#elif defined(__sparc_v3__) || defined(__sparcv3)
#define SIMDE_ARCH_SPARC 3
#elif defined(__sparc_v2__) || defined(__sparcv2)
#define SIMDE_ARCH_SPARC 2
#elif defined(__sparc_v1__) || defined(__sparcv1)
#define SIMDE_ARCH_SPARC 1
#elif defined(__sparc__) || defined(__sparc)
#define SIMDE_ARCH_SPARC 1
#endif
/* SuperH
<https://en.wikipedia.org/wiki/SuperH> */
#if defined(__sh5__) || defined(__SH5__)
#define SIMDE_ARCH_SUPERH 5
#elif defined(__sh4__) || defined(__SH4__)
#define SIMDE_ARCH_SUPERH 4
#elif defined(__sh3__) || defined(__SH3__)
#define SIMDE_ARCH_SUPERH 3
#elif defined(__sh2__) || defined(__SH2__)
#define SIMDE_ARCH_SUPERH 2
#elif defined(__sh1__) || defined(__SH1__)
#define SIMDE_ARCH_SUPERH 1
#elif defined(__sh__) || defined(__SH__)
#define SIMDE_ARCH_SUPERH 1
#endif
/* IBM System z
<https://en.wikipedia.org/wiki/IBM_System_z> */
#if defined(__370__) || defined(__THW_370__) || defined(__s390__) || \
defined(__s390x__) || defined(__zarch__) || defined(__SYSC_ZARCH__)
#define SIMDE_ARCH_SYSTEMZ
#endif
/* TMS320 DSP
<https://en.wikipedia.org/wiki/Texas_Instruments_TMS320> */
#if defined(_TMS320C6740) || defined(__TMS320C6740__)
#define SIMDE_ARCH_TMS320 6740
#elif defined(_TMS320C6700_PLUS) || defined(__TMS320C6700_PLUS__)
#define SIMDE_ARCH_TMS320 6701
#elif defined(_TMS320C6700) || defined(__TMS320C6700__)
#define SIMDE_ARCH_TMS320 6700
#elif defined(_TMS320C6600) || defined(__TMS320C6600__)
#define SIMDE_ARCH_TMS320 6600
#elif defined(_TMS320C6400_PLUS) || defined(__TMS320C6400_PLUS__)
#define SIMDE_ARCH_TMS320 6401
#elif defined(_TMS320C6400) || defined(__TMS320C6400__)
#define SIMDE_ARCH_TMS320 6400
#elif defined(_TMS320C6200) || defined(__TMS320C6200__)
#define SIMDE_ARCH_TMS320 6200
#elif defined(_TMS320C55X) || defined(__TMS320C55X__)
#define SIMDE_ARCH_TMS320 550
#elif defined(_TMS320C54X) || defined(__TMS320C54X__)
#define SIMDE_ARCH_TMS320 540
#elif defined(_TMS320C28X) || defined(__TMS320C28X__)
#define SIMDE_ARCH_TMS320 280
#endif
/* Xtensa
<https://en.wikipedia.org/wiki/> */
#if defined(__xtensa__) || defined(__XTENSA__)
#define SIMDE_ARCH_XTENSA 1
#endif
#endif /* !defined(SIMDE_ARCH_H) */

View file

@ -0,0 +1,278 @@
/* Copyright (c) 2017-2019 Evan Nemerson <evan@nemerson.com>
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#if !defined(SIMDE_COMMON_H)
#define SIMDE_COMMON_H
#include "hedley.h"
#include "check.h"
#include "simde-arch.h"
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L)
#define SIMDE_ALIGN(alignment) _Alignas(alignment)
#elif (defined(__cplusplus) && (__cplusplus >= 201103L))
#define SIMDE_ALIGN(alignment) alignas(alignment)
#elif HEDLEY_GCC_VERSION_CHECK(2, 95, 0) || \
HEDLEY_CRAY_VERSION_CHECK(8, 4, 0) || \
HEDLEY_IBM_VERSION_CHECK(11, 1, 0) || \
HEDLEY_INTEL_VERSION_CHECK(13, 0, 0) || \
HEDLEY_PGI_VERSION_CHECK(19, 4, 0) || \
HEDLEY_ARM_VERSION_CHECK(4, 1, 0) || \
HEDLEY_TINYC_VERSION_CHECK(0, 9, 24) || \
HEDLEY_TI_VERSION_CHECK(8, 1, 0)
#define SIMDE_ALIGN(alignment) __attribute__((aligned(alignment)))
#elif defined(_MSC_VER) && (!defined(_M_IX86) || defined(_M_AMD64))
#define SIMDE_ALIGN(alignment) __declspec(align(alignment))
#else
#define SIMDE_ALIGN(alignment)
#endif
#define simde_assert_aligned(alignment, val) \
simde_assert_int(((uintptr_t)(val)) % (alignment), ==, 0)
#if HEDLEY_GCC_HAS_ATTRIBUTE(vector_size, 4, 6, 0)
#define SIMDE__ENABLE_GCC_VEC_EXT
#endif
#if !defined(SIMDE_ENABLE_OPENMP) && \
((defined(_OPENMP) && (_OPENMP >= 201307L)) || \
(defined(_OPENMP_SIMD) && (_OPENMP_SIMD >= 201307L)))
#define SIMDE_ENABLE_OPENMP
#endif
#if !defined(SIMDE_ENABLE_CILKPLUS) && defined(__cilk)
#define SIMDE_ENABLE_CILKPLUS
#endif
#if defined(SIMDE_ENABLE_OPENMP)
#define SIMDE__VECTORIZE _Pragma("omp simd")
#define SIMDE__VECTORIZE_SAFELEN(l) HEDLEY_PRAGMA(omp simd safelen(l))
#define SIMDE__VECTORIZE_REDUCTION(r) HEDLEY_PRAGMA(omp simd reduction(r))
#define SIMDE__VECTORIZE_ALIGNED(a) HEDLEY_PRAGMA(omp simd aligned(a))
#elif defined(SIMDE_ENABLE_CILKPLUS)
#define SIMDE__VECTORIZE _Pragma("simd")
#define SIMDE__VECTORIZE_SAFELEN(l) HEDLEY_PRAGMA(simd vectorlength(l))
#define SIMDE__VECTORIZE_REDUCTION(r) HEDLEY_PRAGMA(simd reduction(r))
#define SIMDE__VECTORIZE_ALIGNED(a) HEDLEY_PRAGMA(simd aligned(a))
#elif defined(__INTEL_COMPILER)
#define SIMDE__VECTORIZE _Pragma("simd")
#define SIMDE__VECTORIZE_SAFELEN(l) HEDLEY_PRAGMA(simd vectorlength(l))
#define SIMDE__VECTORIZE_REDUCTION(r) HEDLEY_PRAGMA(simd reduction(r))
#define SIMDE__VECTORIZE_ALIGNED(a)
#elif defined(__clang__)
#define SIMDE__VECTORIZE _Pragma("clang loop vectorize(enable)")
#define SIMDE__VECTORIZE_SAFELEN(l) HEDLEY_PRAGMA(clang loop vectorize_width(l))
#define SIMDE__VECTORIZE_REDUCTION(r) SIMDE__VECTORIZE
#define SIMDE__VECTORIZE_ALIGNED(a)
#elif HEDLEY_GCC_VERSION_CHECK(4, 9, 0)
#define SIMDE__VECTORIZE _Pragma("GCC ivdep")
#define SIMDE__VECTORIZE_SAFELEN(l) SIMDE__VECTORIZE
#define SIMDE__VECTORIZE_REDUCTION(r) SIMDE__VECTORIZE
#define SIMDE__VECTORIZE_ALIGNED(a)
#elif HEDLEY_CRAY_VERSION_CHECK(5, 0, 0)
#define SIMDE__VECTORIZE _Pragma("_CRI ivdep")
#define SIMDE__VECTORIZE_SAFELEN(l) SIMDE__VECTORIZE
#define SIMDE__VECTORIZE_REDUCTION(r) SIMDE__VECTORIZE
#define SIMDE__VECTORIZE_ALIGNED(a)
#else
#define SIMDE__VECTORIZE
#define SIMDE__VECTORIZE_SAFELEN(l)
#define SIMDE__VECTORIZE_REDUCTION(r)
#define SIMDE__VECTORIZE_ALIGNED(a)
#endif
#if HEDLEY_GCC_HAS_ATTRIBUTE(unused, 3, 1, 0)
#define SIMDE__UNUSED __attribute__((__unused__))
#else
#define SIMDE__UNUSED
#endif
#if HEDLEY_GCC_HAS_ATTRIBUTE(artificial, 4, 3, 0)
#define SIMDE__ARTIFICIAL __attribute__((__artificial__))
#else
#define SIMDE__ARTIFICIAL
#endif
/* Intended for checking coverage, you should never use this in
production. */
#if defined(SIMDE_NO_INLINE)
#define SIMDE__FUNCTION_ATTRIBUTES HEDLEY_NEVER_INLINE SIMDE__UNUSED static
#else
#define SIMDE__FUNCTION_ATTRIBUTES HEDLEY_INLINE SIMDE__ARTIFICIAL static
#endif
#if defined(_MSC_VER)
#define SIMDE__BEGIN_DECLS \
HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(disable : 4996 4204)) \
HEDLEY_BEGIN_C_DECLS
#define SIMDE__END_DECLS HEDLEY_DIAGNOSTIC_POP HEDLEY_END_C_DECLS
#else
#define SIMDE__BEGIN_DECLS HEDLEY_BEGIN_C_DECLS
#define SIMDE__END_DECLS HEDLEY_END_C_DECLS
#endif
#if defined(__SIZEOF_INT128__)
#define SIMDE__HAVE_INT128
typedef __int128 simde_int128;
typedef unsigned __int128 simde_uint128;
#endif
/* TODO: we should at least make an attempt to detect the correct
types for simde_float32/float64 instead of just assuming float and
double. */
#if !defined(SIMDE_FLOAT32_TYPE)
#define SIMDE_FLOAT32_TYPE float
#define SIMDE_FLOAT32_C(value) value##f
#else
#define SIMDE_FLOAT32_C(value) ((SIMDE_FLOAT32_TYPE)value)
#endif
typedef SIMDE_FLOAT32_TYPE simde_float32;
HEDLEY_STATIC_ASSERT(sizeof(simde_float32) == 4,
"Unable to find 32-bit floating-point type.");
#if !defined(SIMDE_FLOAT64_TYPE)
#define SIMDE_FLOAT64_TYPE double
#define SIMDE_FLOAT64_C(value) value
#else
#define SIMDE_FLOAT32_C(value) ((SIMDE_FLOAT64_TYPE)value)
#endif
typedef SIMDE_FLOAT64_TYPE simde_float64;
HEDLEY_STATIC_ASSERT(sizeof(simde_float64) == 8,
"Unable to find 64-bit floating-point type.");
/* Whether to assume that the compiler can auto-vectorize reasonably
well. This will cause SIMDe to attempt to compose vector
operations using more simple vector operations instead of minimize
serial work.
As an example, consider the _mm_add_ss(a, b) function from SSE,
which returns { a0 + b0, a1, a2, a3 }. This pattern is repeated
for other operations (sub, mul, etc.).
The naïve implementation would result in loading a0 and b0, adding
them into a temporary variable, then splicing that value into a new
vector with the remaining elements from a.
On platforms which support vectorization, it's generally faster to
simply perform the operation on the entire vector to avoid having
to move data between SIMD registers and non-SIMD registers.
Basically, instead of the temporary variable being (a0 + b0) it
would be a vector of (a + b), which is then combined with a to form
the result.
By default, SIMDe will prefer the pure-vector versions if we detect
a vector ISA extension, but this can be overridden by defining
SIMDE_NO_ASSUME_VECTORIZATION. You can also define
SIMDE_ASSUME_VECTORIZATION if you want to force SIMDe to use the
vectorized version. */
#if !defined(SIMDE_NO_ASSUME_VECTORIZATION) && \
!defined(SIMDE_ASSUME_VECTORIZATION)
#if defined(__SSE__) || defined(__ARM_NEON) || defined(__mips_msa) || \
defined(__ALTIVEC__)
#define SIMDE_ASSUME_VECTORIZATION
#endif
#endif
/* GCC and clang have built-in functions to handle shuffling of
vectors, but the implementations are slightly different. This
macro is just an abstraction over them. Note that elem_size is in
bits but vec_size is in bytes. */
#if HEDLEY_CLANG_HAS_BUILTIN(__builtin_shufflevector)
#define SIMDE__SHUFFLE_VECTOR(elem_size, vec_size, a, b, ...) \
__builtin_shufflevector(a, b, __VA_ARGS__)
#elif HEDLEY_GCC_HAS_BUILTIN(__builtin_shuffle, 4, 7, 0) && \
!defined(__INTEL_COMPILER)
#define SIMDE__SHUFFLE_VECTOR(elem_size, vec_size, a, b, ...) \
__builtin_shuffle(a, b, \
(int##elem_size##_t __attribute__( \
(__vector_size__(vec_size)))){__VA_ARGS__})
#endif
/* Some algorithms are iterative, and fewer iterations means less
accuracy. Lower values here will result in faster, but less
accurate, calculations for some functions. */
#if !defined(SIMDE_ACCURACY_ITERS)
#define SIMDE_ACCURACY_ITERS 2
#endif
/* This will probably move into Hedley at some point, but I'd like to
more thoroughly check for other compilers which define __GNUC__
first. */
#if defined(SIMDE__REALLY_GCC)
#undef SIMDE__REALLY_GCC
#endif
#if !defined(__GNUC__) || defined(__clang__) || defined(__INTEL_COMPILER)
#define SIMDE__REALLY_GCC 0
#else
#define SIMDE__REALLY_GCC 1
#endif
#if defined(SIMDE__ASSUME_ALIGNED)
#undef SIMDE__ASSUME_ALIGNED
#endif
#if HEDLEY_INTEL_VERSION_CHECK(9, 0, 0)
#define SIMDE__ASSUME_ALIGNED(ptr, align) __assume_aligned(ptr, align)
#elif HEDLEY_MSVC_VERSION_CHECK(13, 10, 0)
#define SIMDE__ASSUME_ALIGNED(ptr, align) \
__assume((((char *)ptr) - ((char *)0)) % (align) == 0)
#elif HEDLEY_GCC_HAS_BUILTIN(__builtin_assume_aligned, 4, 7, 0)
#define SIMDE__ASSUME_ALIGNED(ptr, align) \
(ptr = (__typeof__(ptr))__builtin_assume_aligned((ptr), align))
#elif HEDLEY_CLANG_HAS_BUILTIN(__builtin_assume)
#define SIMDE__ASSUME_ALIGNED(ptr, align) \
__builtin_assume((((char *)ptr) - ((char *)0)) % (align) == 0)
#elif HEDLEY_GCC_HAS_BUILTIN(__builtin_unreachable, 4, 5, 0)
#define SIMDE__ASSUME_ALIGNED(ptr, align) \
((((char *)ptr) - ((char *)0)) % (align) == 0) \
? (1) \
: (__builtin_unreachable(), 0)
#else
#define SIMDE__ASSUME_ALIGNED(ptr, align)
#endif
/* Sometimes we run into problems with specific versions of compilers
which make the native versions unusable for us. Often this is due
to missing functions, sometimes buggy implementations, etc. These
macros are how we check for specific bugs. As they are fixed we'll
start only defining them for problematic compiler versions. */
#if !defined(SIMDE_IGNORE_COMPILER_BUGS)
#if SIMDE__REALLY_GCC
#if !HEDLEY_GCC_VERSION_CHECK(4, 9, 0)
#define SIMDE_BUG_GCC_REV_208793
#endif
#if !HEDLEY_GCC_VERSION_CHECK(5, 0, 0)
#define SIMDE_BUG_GCC_BAD_MM_SRA_EPI32 /* TODO: find relevant bug or commit */
#endif
#if !HEDLEY_GCC_VERSION_CHECK(4, 6, 0)
#define SIMDE_BUG_GCC_BAD_MM_EXTRACT_EPI8 /* TODO: find relevant bug or commit */
#endif
#endif
#if defined(__EMSCRIPTEN__)
#define SIMDE_BUG_EMSCRIPTEN_MISSING_IMPL /* Placeholder for (as yet) unfiled issues. */
#define SIMDE_BUG_EMSCRIPTEN_5242
#endif
#endif
#endif /* !defined(SIMDE_COMMON_H) */

2591
libobs/util/simde/sse.h Normal file

File diff suppressed because it is too large Load diff

4197
libobs/util/simde/sse2.h Normal file

File diff suppressed because it is too large Load diff

66
libobs/util/sse-intrin.h Normal file
View file

@ -0,0 +1,66 @@
/******************************************************************************
Copyright (C) 2019 by Peter Geis <pgwipeout@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
#pragma once
#if NEEDS_SIMDE
#include "simde/sse2.h"
#define __m128 simde__m128
#define _mm_setzero_ps simde_mm_setzero_ps
#define _mm_set_ps simde_mm_set_ps
#define _mm_add_ps simde_mm_add_ps
#define _mm_sub_ps simde_mm_sub_ps
#define _mm_mul_ps simde_mm_mul_ps
#define _mm_div_ps simde_mm_div_ps
#define _mm_set1_ps simde_mm_set1_ps
#define _mm_movehl_ps simde_mm_movehl_ps
#define _mm_shuffle_ps simde_mm_shuffle_ps
#define _mm_min_ps simde_mm_min_ps
#define _mm_max_ps simde_mm_max_ps
#define _mm_movelh_ps simde_mm_movelh_ps
#define _mm_unpacklo_ps simde_mm_unpacklo_ps
#define _mm_unpackhi_ps simde_mm_unpackhi_ps
#define _mm_load_ps simde_mm_load_ps
#define _mm_andnot_ps simde_mm_andnot_ps
#define _mm_storeu_ps simde_mm_storeu_ps
#define _mm_loadu_ps simde_mm_loadu_ps
#define __m128i simde__m128i
#define _mm_set1_epi32 simde_mm_set1_epi32
#define _mm_set1_epi16 simde_mm_set1_epi16
#define _mm_load_si128 simde_mm_load_si128
#define _mm_packs_epi32 simde_mm_packs_epi32
#define _mm_srli_si128 simde_mm_srli_si128
#define _mm_and_si128 simde_mm_and_si128
#define _mm_packus_epi16 simde_mm_packus_epi16
#define _mm_add_epi64 simde_mm_add_epi64
#define _mm_shuffle_epi32 simde_mm_shuffle_epi32
#define _mm_srai_epi16 simde_mm_srai_epi16
#define _mm_shufflelo_epi16 simde_mm_shufflelo_epi16
#define _mm_storeu_si128 simde_mm_storeu_si128
#define _MM_SHUFFLE SIMDE_MM_SHUFFLE
#define _MM_TRANSPOSE4_PS SIMDE_MM_TRANSPOSE4_PS
#else
#include <xmmintrin.h>
#include <emmintrin.h>
#endif

View file

@ -20,6 +20,7 @@
#include <string.h>
#include <stdarg.h>
#include <utility>
#include "bmem.h"
#include "config-file.h"
@ -36,7 +37,7 @@ template<typename T> class BPtr {
public:
inline BPtr(T *p = nullptr) : ptr(p) {}
inline BPtr(BPtr &&other) : ptr(other.ptr) { other.ptr = nullptr; }
inline BPtr(BPtr &&other) { *this = std::move(other); }
inline ~BPtr() { bfree(ptr); }
inline T *operator=(T *p)
@ -45,6 +46,14 @@ public:
ptr = p;
return p;
}
inline BPtr &operator=(BPtr &&other)
{
ptr = other.ptr;
other.ptr = nullptr;
return *this;
}
inline operator T *() { return ptr; }
inline T **operator&()
{
@ -68,7 +77,7 @@ class ConfigFile {
public:
inline ConfigFile() : config(NULL) {}
inline ConfigFile(ConfigFile &&other) : config(other.config)
inline ConfigFile(ConfigFile &&other) noexcept : config(other.config)
{
other.config = nullptr;
}
@ -120,7 +129,7 @@ class TextLookup {
public:
inline TextLookup(lookup_t *lookup = nullptr) : lookup(lookup) {}
inline TextLookup(TextLookup &&other) : lookup(other.lookup)
inline TextLookup(TextLookup &&other) noexcept : lookup(other.lookup)
{
other.lookup = nullptr;
}

View file

@ -1,285 +0,0 @@
// ISO C9x compliant inttypes.h for Microsoft Visual Studio
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
//
// Copyright (c) 2006 Alexander Chemeris
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. The name of the author may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _MSC_VER // [
#error "Use this header only with Microsoft Visual C++ compilers!"
#endif // _MSC_VER ]
#ifndef _MSC_INTTYPES_H_ // [
#define _MSC_INTTYPES_H_
#if _MSC_VER > 1000
#pragma once
#endif
#include "stdint.h"
// 7.8 Format conversion of integer types
typedef struct {
intmax_t quot;
intmax_t rem;
} imaxdiv_t;
// 7.8.1 Macros for format specifiers
#if !defined(__cplusplus) || \
defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198
// The fprintf macros for signed integers are:
#define PRId8 "d"
#define PRIi8 "i"
#define PRIdLEAST8 "d"
#define PRIiLEAST8 "i"
#define PRIdFAST8 "d"
#define PRIiFAST8 "i"
#define PRId16 "hd"
#define PRIi16 "hi"
#define PRIdLEAST16 "hd"
#define PRIiLEAST16 "hi"
#define PRIdFAST16 "hd"
#define PRIiFAST16 "hi"
#define PRId32 "I32d"
#define PRIi32 "I32i"
#define PRIdLEAST32 "I32d"
#define PRIiLEAST32 "I32i"
#define PRIdFAST32 "I32d"
#define PRIiFAST32 "I32i"
#define PRId64 "I64d"
#define PRIi64 "I64i"
#define PRIdLEAST64 "I64d"
#define PRIiLEAST64 "I64i"
#define PRIdFAST64 "I64d"
#define PRIiFAST64 "I64i"
#define PRIdMAX "I64d"
#define PRIiMAX "I64i"
#define PRIdPTR "Id"
#define PRIiPTR "Ii"
// The fprintf macros for unsigned integers are:
#define PRIo8 "o"
#define PRIu8 "u"
#define PRIx8 "x"
#define PRIX8 "X"
#define PRIoLEAST8 "o"
#define PRIuLEAST8 "u"
#define PRIxLEAST8 "x"
#define PRIXLEAST8 "X"
#define PRIoFAST8 "o"
#define PRIuFAST8 "u"
#define PRIxFAST8 "x"
#define PRIXFAST8 "X"
#define PRIo16 "ho"
#define PRIu16 "hu"
#define PRIx16 "hx"
#define PRIX16 "hX"
#define PRIoLEAST16 "ho"
#define PRIuLEAST16 "hu"
#define PRIxLEAST16 "hx"
#define PRIXLEAST16 "hX"
#define PRIoFAST16 "ho"
#define PRIuFAST16 "hu"
#define PRIxFAST16 "hx"
#define PRIXFAST16 "hX"
#define PRIo32 "I32o"
#define PRIu32 "I32u"
#define PRIx32 "I32x"
#define PRIX32 "I32X"
#define PRIoLEAST32 "I32o"
#define PRIuLEAST32 "I32u"
#define PRIxLEAST32 "I32x"
#define PRIXLEAST32 "I32X"
#define PRIoFAST32 "I32o"
#define PRIuFAST32 "I32u"
#define PRIxFAST32 "I32x"
#define PRIXFAST32 "I32X"
#define PRIo64 "I64o"
#define PRIu64 "I64u"
#define PRIx64 "I64x"
#define PRIX64 "I64X"
#define PRIoLEAST64 "I64o"
#define PRIuLEAST64 "I64u"
#define PRIxLEAST64 "I64x"
#define PRIXLEAST64 "I64X"
#define PRIoFAST64 "I64o"
#define PRIuFAST64 "I64u"
#define PRIxFAST64 "I64x"
#define PRIXFAST64 "I64X"
#define PRIoMAX "I64o"
#define PRIuMAX "I64u"
#define PRIxMAX "I64x"
#define PRIXMAX "I64X"
#define PRIoPTR "Io"
#define PRIuPTR "Iu"
#define PRIxPTR "Ix"
#define PRIXPTR "IX"
// The fscanf macros for signed integers are:
#define SCNd16 "hd"
#define SCNi16 "hi"
#define SCNdLEAST16 "hd"
#define SCNiLEAST16 "hi"
#define SCNdFAST16 "hd"
#define SCNiFAST16 "hi"
#define SCNd32 "ld"
#define SCNi32 "li"
#define SCNdLEAST32 "ld"
#define SCNiLEAST32 "li"
#define SCNdFAST32 "ld"
#define SCNiFAST32 "li"
#define SCNd64 "I64d"
#define SCNi64 "I64i"
#define SCNdLEAST64 "I64d"
#define SCNiLEAST64 "I64i"
#define SCNdFAST64 "I64d"
#define SCNiFAST64 "I64i"
#define SCNdMAX "I64d"
#define SCNiMAX "I64i"
#ifdef _WIN64 // [
#define SCNdPTR "I64d"
#define SCNiPTR "I64i"
#else // _WIN64 ][
#define SCNdPTR "ld"
#define SCNiPTR "li"
#endif // _WIN64 ]
// The fscanf macros for unsigned integers are:
#define SCNo16 "ho"
#define SCNu16 "hu"
#define SCNx16 "hx"
#define SCNX16 "hX"
#define SCNoLEAST16 "ho"
#define SCNuLEAST16 "hu"
#define SCNxLEAST16 "hx"
#define SCNXLEAST16 "hX"
#define SCNoFAST16 "ho"
#define SCNuFAST16 "hu"
#define SCNxFAST16 "hx"
#define SCNXFAST16 "hX"
#define SCNo32 "lo"
#define SCNu32 "lu"
#define SCNx32 "lx"
#define SCNX32 "lX"
#define SCNoLEAST32 "lo"
#define SCNuLEAST32 "lu"
#define SCNxLEAST32 "lx"
#define SCNXLEAST32 "lX"
#define SCNoFAST32 "lo"
#define SCNuFAST32 "lu"
#define SCNxFAST32 "lx"
#define SCNXFAST32 "lX"
#define SCNo64 "I64o"
#define SCNu64 "I64u"
#define SCNx64 "I64x"
#define SCNX64 "I64X"
#define SCNoLEAST64 "I64o"
#define SCNuLEAST64 "I64u"
#define SCNxLEAST64 "I64x"
#define SCNXLEAST64 "I64X"
#define SCNoFAST64 "I64o"
#define SCNuFAST64 "I64u"
#define SCNxFAST64 "I64x"
#define SCNXFAST64 "I64X"
#define SCNoMAX "I64o"
#define SCNuMAX "I64u"
#define SCNxMAX "I64x"
#define SCNXMAX "I64X"
#ifdef _WIN64 // [
#define SCNoPTR "I64o"
#define SCNuPTR "I64u"
#define SCNxPTR "I64x"
#define SCNXPTR "I64X"
#else // _WIN64 ][
#define SCNoPTR "lo"
#define SCNuPTR "lu"
#define SCNxPTR "lx"
#define SCNXPTR "lX"
#endif // _WIN64 ]
#endif // __STDC_FORMAT_MACROS ]
// 7.8.2 Functions for greatest-width integer types
// 7.8.2.1 The imaxabs function
#define imaxabs _abs64
// 7.8.2.2 The imaxdiv function
// This is modified version of div() function from Microsoft's div.c found
// in %MSVC.NET%\crt\src\div.c
#ifdef STATIC_IMAXDIV // [
static
#else // STATIC_IMAXDIV ][
_inline
#endif // STATIC_IMAXDIV ]
imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)
{
imaxdiv_t result;
result.quot = numer / denom;
result.rem = numer % denom;
if (numer < 0 && result.rem > 0) {
// did division wrong; must fix up
++result.quot;
result.rem -= denom;
}
return result;
}
// 7.8.2.3 The strtoimax and strtoumax functions
#define strtoimax _strtoi64
#define strtoumax _strtoui64
// 7.8.2.4 The wcstoimax and wcstoumax functions
#define wcstoimax _wcstoi64
#define wcstoumax _wcstoui64
#endif // _MSC_INTTYPES_H_ ]

View file

@ -1,9 +0,0 @@
#pragma once
#if !defined(__cplusplus)
typedef int8_t _Bool;
#define bool _Bool
#define true 1
#define false 0
#define __bool_true_false_are_defined 1
#endif

View file

@ -1,203 +0,0 @@
/* ISO C9x 7.18 Integer types <stdint.h>
* Based on ISO/IEC SC22/WG14 9899 Committee draft (SC22 N2794)
*
* THIS SOFTWARE IS NOT COPYRIGHTED
*
* Contributor: Danny Smith <danny_r_smith_2001@yahoo.co.nz>
*
* This source code is offered for use in the public domain. You may
* use, modify or distribute it freely.
*
* This code is distributed in the hope that it will be useful but
* WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
* DISCLAIMED. This includes but is not limited to warranties of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Date: 2000-12-02
*/
#ifndef _STDINT_H
#define _STDINT_H
#define __need_wint_t
#define __need_wchar_t
#include <stddef.h>
/* 7.18.1.1 Exact-width integer types */
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef int int32_t;
typedef unsigned uint32_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
/* 7.18.1.2 Minimum-width integer types */
typedef signed char int_least8_t;
typedef unsigned char uint_least8_t;
typedef short int_least16_t;
typedef unsigned short uint_least16_t;
typedef int int_least32_t;
typedef unsigned uint_least32_t;
typedef __int64 int_least64_t;
typedef unsigned __int64 uint_least64_t;
/* 7.18.1.3 Fastest minimum-width integer types
* Not actually guaranteed to be fastest for all purposes
* Here we use the exact-width types for 8 and 16-bit ints.
*/
typedef char int_fast8_t;
typedef unsigned char uint_fast8_t;
typedef short int_fast16_t;
typedef unsigned short uint_fast16_t;
typedef int int_fast32_t;
typedef unsigned int uint_fast32_t;
typedef __int64 int_fast64_t;
typedef unsigned __int64 uint_fast64_t;
/* 7.18.1.4 Integer types capable of holding object pointers */
/*typedef int intptr_t;
typedef unsigned uintptr_t;*/
/* 7.18.1.5 Greatest-width integer types */
typedef __int64 intmax_t;
typedef unsigned __int64 uintmax_t;
/* 7.18.2 Limits of specified-width integer types */
#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS)
/* 7.18.2.1 Limits of exact-width integer types */
#define INT8_MIN (-128)
#define INT16_MIN (-32768)
#define INT32_MIN (-2147483647 - 1)
#define INT64_MIN (-9223372036854775807LL - 1)
#define INT8_MAX 127
#define INT16_MAX 32767
#define INT32_MAX 2147483647
#define INT64_MAX 9223372036854775807LL
#define UINT8_MAX 0xff /* 255U */
#define UINT16_MAX 0xffff /* 65535U */
#define UINT32_MAX 0xffffffff /* 4294967295U */
#define UINT64_MAX 0xffffffffffffffffULL /* 18446744073709551615ULL */
/* 7.18.2.2 Limits of minimum-width integer types */
#define INT_LEAST8_MIN INT8_MIN
#define INT_LEAST16_MIN INT16_MIN
#define INT_LEAST32_MIN INT32_MIN
#define INT_LEAST64_MIN INT64_MIN
#define INT_LEAST8_MAX INT8_MAX
#define INT_LEAST16_MAX INT16_MAX
#define INT_LEAST32_MAX INT32_MAX
#define INT_LEAST64_MAX INT64_MAX
#define UINT_LEAST8_MAX UINT8_MAX
#define UINT_LEAST16_MAX UINT16_MAX
#define UINT_LEAST32_MAX UINT32_MAX
#define UINT_LEAST64_MAX UINT64_MAX
/* 7.18.2.3 Limits of fastest minimum-width integer types */
#define INT_FAST8_MIN INT8_MIN
#define INT_FAST16_MIN INT16_MIN
#define INT_FAST32_MIN INT32_MIN
#define INT_FAST64_MIN INT64_MIN
#define INT_FAST8_MAX INT8_MAX
#define INT_FAST16_MAX INT16_MAX
#define INT_FAST32_MAX INT32_MAX
#define INT_FAST64_MAX INT64_MAX
#define UINT_FAST8_MAX UINT8_MAX
#define UINT_FAST16_MAX UINT16_MAX
#define UINT_FAST32_MAX UINT32_MAX
#define UINT_FAST64_MAX UINT64_MAX
/* 7.18.2.4 Limits of integer types capable of holding
object pointers */
#if defined(_WIN64) || defined(__LP64__)
#define INTPTR_MIN INT64_MIN
#define INTPTR_MAX INT64_MAX
#define UINTPTR_MAX UINT64_MAX
#else
#define INTPTR_MIN INT32_MIN
#define INTPTR_MAX INT32_MAX
#define UINTPTR_MAX UINT32_MAX
#endif
/* 7.18.2.5 Limits of greatest-width integer types */
#define INTMAX_MIN INT64_MIN
#define INTMAX_MAX INT64_MAX
#define UINTMAX_MAX UINT64_MAX
/* 7.18.3 Limits of other integer types */
#if defined(_WIN64) || defined(__LP64__)
#define PTRDIFF_MIN INT64_MIN
#define PTRDIFF_MAX INT64_MAX
#else
#define PTRDIFF_MIN INT32_MIN
#define PTRDIFF_MAX INT32_MAX
#endif
#define SIG_ATOMIC_MIN INT32_MIN
#define SIG_ATOMIC_MAX INT32_MAX
#ifndef SIZE_MAX
#if defined(_WIN64) || defined(__LP64__)
#define SIZE_MAX UINT64_MAX
#else
#define SIZE_MAX UINT32_MAX
#endif
#endif
#if 0
#ifndef WCHAR_MIN /* also in wchar.h */
#define WCHAR_MIN 0
#define WCHAR_MAX ((wchar_t)-1) /* UINT16_MAX */
#endif
#endif
/*
* wint_t is unsigned short for compatibility with MS runtime
*/
#define WINT_MIN 0
#define WINT_MAX ((wint_t)-1) /* UINT16_MAX */
#endif /* !defined ( __cplusplus) || defined __STDC_LIMIT_MACROS */
/* 7.18.4 Macros for integer constants */
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS)
/* 7.18.4.1 Macros for minimum-width integer constants
According to Douglas Gwyn <gwyn@arl.mil>:
"This spec was changed in ISO/IEC 9899:1999 TC1; in ISO/IEC
9899:1999 as initially published, the expansion was required
to be an integer constant of precisely matching type, which
is impossible to accomplish for the shorter types on most
platforms, because C99 provides no standard way to designate
an integer constant with width less than that of type int.
TC1 changed this to require just an integer constant
*expression* with *promoted* type."
The trick used here is from Clive D W Feather.
*/
#define INT8_C(val) (INT_LEAST8_MAX - INT_LEAST8_MAX + (val))
#define INT16_C(val) (INT_LEAST16_MAX - INT_LEAST16_MAX + (val))
#define INT32_C(val) (INT_LEAST32_MAX - INT_LEAST32_MAX + (val))
#define INT64_C(val) (INT_LEAST64_MAX - INT_LEAST64_MAX + (val))
#define UINT8_C(val) (UINT_LEAST8_MAX - UINT_LEAST8_MAX + (val))
#define UINT16_C(val) (UINT_LEAST16_MAX - UINT_LEAST16_MAX + (val))
#define UINT32_C(val) (UINT_LEAST32_MAX - UINT_LEAST32_MAX + (val))
#define UINT64_C(val) (UINT_LEAST64_MAX - UINT_LEAST64_MAX + (val))
/* 7.18.4.2 Macros for greatest-width integer constants */
#define INTMAX_C(val) (INTMAX_MAX - INTMAX_MAX + (val))
#define UINTMAX_C(val) (UINTMAX_MAX - UINTMAX_MAX + (val))
#endif /* !defined ( __cplusplus) || defined __STDC_CONSTANT_MACROS */
#endif

View file

@ -39,6 +39,7 @@ public:
{
Clear();
ptr = val;
return *this;
}
inline T **operator&()

View file

@ -16,6 +16,10 @@
#pragma once
#ifdef _WIN32
#include <Unknwn.h>
#endif
/* Oh no I have my own com pointer class, the world is ending, how dare you
* write your own! */

View file

@ -29,6 +29,24 @@ struct win_version_info {
int revis;
};
static inline int win_version_compare(struct win_version_info *dst,
struct win_version_info *src)
{
if (dst->major > src->major)
return 1;
if (dst->major == src->major) {
if (dst->minor > src->minor)
return 1;
if (dst->minor == src->minor) {
if (dst->build > src->build)
return 1;
if (dst->build == src->build)
return 0;
}
}
return -1;
}
EXPORT bool is_64_bit_windows(void);
EXPORT bool get_dll_ver(const wchar_t *lib, struct win_version_info *info);
EXPORT void get_win_ver(struct win_version_info *info);