diff --git a/libobs/CMakeLists.txt b/libobs/CMakeLists.txt index 94d7294144ce197861a997fa3aa4600cfb116e99..0edccb39377515773b2477cbc211aaa9a8f6da6d 100644 --- a/libobs/CMakeLists.txt +++ b/libobs/CMakeLists.txt @@ -40,6 +40,7 @@ add_library(libobs SHARED obs-display.c obs-module.c obs-output.c + obs-encoder.c obs-scene.c obs-source.c obs-video.c diff --git a/libobs/makefile.am b/libobs/makefile.am index 074b18f26973a92fd5da534d14a4ef3e8efa69c0..9ab59a1315aaf55249d04ed4f3c14ec9cc0e33cd 100644 --- a/libobs/makefile.am +++ b/libobs/makefile.am @@ -23,6 +23,7 @@ libobs_la_SOURCES = obs.c \ obs-output.c \ obs-scene.c \ obs-source.c \ + obs-encoder.c \ obs-video.c \ util/base.c \ util/bmem.c \ diff --git a/libobs/obs-data.h b/libobs/obs-data.h index f734d14958939aa27311ce79e4258684c413b07c..bbf3599c805ffc221898a94fe68462a097f58c6d 100644 --- a/libobs/obs-data.h +++ b/libobs/obs-data.h @@ -30,6 +30,7 @@ #include "obs-source.h" #include "obs-output.h" #include "obs-service.h" +#include "obs-encoder.h" #define NUM_TEXTURES 2 @@ -71,10 +72,14 @@ struct obs_data { * linked lists. */ DARRAY(struct obs_display*) displays; DARRAY(struct obs_source*) sources; + DARRAY(struct obs_output*) outputs; + DARRAY(struct obs_encoder*) encoders; obs_source_t channels[MAX_CHANNELS]; pthread_mutex_t sources_mutex; pthread_mutex_t displays_mutex; + pthread_mutex_t outputs_mutex; + pthread_mutex_t encoders_mutex; }; struct obs_subsystem { @@ -83,6 +88,7 @@ struct obs_subsystem { DARRAY(struct source_info) filter_types; DARRAY(struct source_info) transition_types; DARRAY(struct output_info) output_types; + DARRAY(struct encoder_info) encoder_types; DARRAY(struct service_info) service_types; signal_handler_t signals; diff --git a/libobs/obs-defs.h b/libobs/obs-defs.h index c15b36c0be720cf4738b08ba8f3f9bf6807ecd9b..8e97257134980916b66fdfb1ed3dcf7fa3ebbbbc 100644 --- a/libobs/obs-defs.h +++ b/libobs/obs-defs.h @@ -31,3 +31,6 @@ #define SOURCE_ASYNC_VIDEO (1<<2) /* Async video (use with SOURCE_VIDEO) */ #define SOURCE_DEFAULT_EFFECT (1<<3) /* Source uses default/filter effect */ #define SOURCE_YUV (1<<4) /* Source is in YUV color space */ + +#define OUTPUT_VIDEO_ENCODER (1<<0) /* Output requires a video encoder */ +#define OUTPUT_AUDIO_ENCODER (1<<1) /* Ouptut requires an audio encoder */ diff --git a/libobs/obs-encoder.c b/libobs/obs-encoder.c new file mode 100644 index 0000000000000000000000000000000000000000..44275c548e0a985000e43a1235db39452250334d --- /dev/null +++ b/libobs/obs-encoder.c @@ -0,0 +1,164 @@ +/****************************************************************************** + Copyright (C) 2013 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/>. +******************************************************************************/ + +#include "obs.h" +#include "obs-data.h" + +bool load_encoder_info(void *module, const char *module_name, + const char *encoder_id, struct encoder_info *info) +{ + info->getname = load_module_subfunc(module, module_name, + encoder_id, "getname", true); + info->create = load_module_subfunc(module, module_name, + encoder_id, "create", true); + info->destroy = load_module_subfunc(module, module_name, + encoder_id, "destroy", true); + info->update = load_module_subfunc(module, module_name, + encoder_id, "update", true); + info->reset = load_module_subfunc(module, module_name, + encoder_id, "reset", true); + info->encode = load_module_subfunc(module, module_name, + encoder_id, "encode", true); + info->getheader = load_module_subfunc(module, module_name, + encoder_id, "getheader", true); + + if (!info->getname || !info->create || !info->destroy || + !info->reset || !info->encode || !info->getheader) + return false; + + info->setbitrate = load_module_subfunc(module, module_name, + encoder_id, "setbitrate", false); + info->request_keyframe = load_module_subfunc(module, module_name, + encoder_id, "request_keyframe", false); + + info->id = encoder_id; + return true; +} + +static inline struct encoder_info *get_encoder_info(const char *id) +{ + for (size_t i = 0; i < obs->encoder_types.num; i++) { + struct encoder_info *info = obs->encoder_types.array+i; + + if (strcmp(info->id, id) == 0) + return info; + } + + return NULL; +} + +const char *obs_encoder_getdisplayname(const char *id, const char *locale) +{ + struct encoder_info *ei = get_encoder_info(id); + if (!ei) + return NULL; + + return ei->getname(locale); +} + +obs_encoder_t obs_encoder_create(const char *id, const char *name, + const char *settings) +{ + struct obs_encoder *encoder; + struct encoder_info *ei = get_encoder_info(id); + + if (!ei) + return NULL; + + encoder = bmalloc(sizeof(struct obs_encoder)); + memset(encoder, 0, sizeof(struct obs_encoder)); + encoder->callbacks = *ei; + + if (pthread_mutex_init(&encoder->data_callbacks_mutex, NULL) != 0) { + bfree(encoder); + return NULL; + } + + encoder->data = ei->create(settings, encoder); + if (!encoder->data) { + pthread_mutex_destroy(&encoder->data_callbacks_mutex); + bfree(encoder); + return NULL; + } + + dstr_copy(&encoder->settings, settings); + + pthread_mutex_lock(&obs->data.encoders_mutex); + da_push_back(obs->data.encoders, &encoder); + pthread_mutex_unlock(&obs->data.encoders_mutex); + return encoder; +} + +void obs_encoder_destroy(obs_encoder_t encoder) +{ + if (encoder) { + pthread_mutex_lock(&obs->data.encoders_mutex); + da_erase_item(obs->data.encoders, &encoder); + pthread_mutex_unlock(&obs->data.encoders_mutex); + + encoder->callbacks.destroy(encoder->data); + dstr_free(&encoder->settings); + bfree(encoder); + } +} + +void obs_encoder_update(obs_encoder_t encoder, const char *settings) +{ + encoder->callbacks.update(encoder->data, settings); +} + +bool obs_encoder_reset(obs_encoder_t encoder) +{ + return encoder->callbacks.reset(encoder->data); +} + +bool obs_encoder_encode(obs_encoder_t encoder, void *frames, size_t size) +{ + /* TODO */ + //encoder->callbacks.encode(encoder->data, frames, size, packets); + return false; +} + +int obs_encoder_getheader(obs_encoder_t encoder, + struct encoder_packet **packets) +{ + return encoder->callbacks.getheader(encoder, packets); +} + +void obs_encoder_setbitrate(obs_encoder_t encoder, uint32_t bitrate, + uint32_t buffersize) +{ + if (encoder->callbacks.setbitrate) + encoder->callbacks.setbitrate(encoder->data, bitrate, + buffersize); +} + +void obs_encoder_request_keyframe(obs_encoder_t encoder) +{ + if (encoder->callbacks.request_keyframe) + encoder->callbacks.request_keyframe(encoder->data); +} + +const char *obs_encoder_get_settings(obs_encoder_t encoder) +{ + return encoder->settings.array; +} + +void obs_encoder_save_settings(obs_encoder_t encoder, const char *settings) +{ + dstr_copy(&encoder->settings, settings); +} diff --git a/libobs/obs-encoder.h b/libobs/obs-encoder.h new file mode 100644 index 0000000000000000000000000000000000000000..d534676fc2a453b61783151162fccb6ab6bcc355 --- /dev/null +++ b/libobs/obs-encoder.h @@ -0,0 +1,147 @@ +/****************************************************************************** + Copyright (C) 2013 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/>. +******************************************************************************/ + +#pragma once + +#include "util/c99defs.h" +#include "util/dstr.h" + +/* + * =========================================== + * Outputs + * =========================================== + * + * An output takes raw audio and/or video and processes and/or outputs it + * to a destination, whether that destination be a file, network, or other. + * + * A module with outputs needs to export these functions: + * + enum_outputs + * + * Each individual output is then exported by it's name. For example, an + * output named "myoutput" would have the following exports: + * + myoutput_getname + * + myoutput_create + * + myoutput_destroy + * + myoutput_start + * + myoutput_stop + * + myoutput_encoders + * + * [and optionally] + * + myoutput_setencoder + * + myoutput_getencoder + * + myoutput_config + * + myoutput_pause + * + * =========================================== + * Primary Exports + * =========================================== + * const char *enum_outputs(size_t idx); + * idx: index of the output. + * Return value: Output identifier name. NULL when no more available. + * + * =========================================== + * Output Exports + * =========================================== + * const char *[name]_getname(const char *locale); + * Returns the full translated name of the output type (seen by the user). + * + * --------------------------------------------------------- + * void *[name]_create(const char *settings, obs_output_t output); + * Creates an output. + * + * settings: Settings of the output. + * output: pointer to main output + * Return value: Internal output pointer, or NULL if failed. + * + * --------------------------------------------------------- + * void [name]_destroy(void *data); + * Destroys the output. + * + * --------------------------------------------------------- + * void [name]_update(void *data, const char *settings) + * Updates the output's settings + * + * settings: New settings of the output + * + * --------------------------------------------------------- + * bool [name]_reset(void *data) + * Starts output + * + * Return value: true if successful + * + * --------------------------------------------------------- + * int [name]_encode(void *data, void *frames, size_t size, + * struct encoder_packet **packets) + * + * frames: frame data + * size: size of data pointed to by the frame parameter + * packets: returned packets, or NULL if none + * Return value: number of output frames + * + * --------------------------------------------------------- + * bool [name]_reset(void *data) + * Resets encoder data + * + * Return value: true if successful + * + * =========================================== + * Optional Output Exports + * =========================================== + * void [name]_setbitrate(void *data, uint32_t bitrate, uint32_t buffersize); + * Sets the bitrate of the encoder + */ + +struct obs_encoder; + +struct encoder_info { + const char *id; + + const char *(*getname)(const char *locale); + + void *(*create)(const char *settings, struct obs_encoder *encoder); + void (*destroy)(void *data); + + void (*update)(void *data, const char *settings); + + bool (*reset)(void *data); + + int (*encode)(void *data, void *frames, size_t size, + struct encoder_packet **packets); + int (*getheader)(void *data, struct encoder_packet **packets); + + /* optional */ + void (*setbitrate)(void *data, uint32_t bitrate, uint32_t buffersize); + void (*request_keyframe)(void *data); +}; + +struct obs_encoder_callback { + void (*new_packet)(void *param, struct encoder_packet *packet); + void *param; +}; + +struct obs_encoder { + char *name; + void *data; + struct encoder_info callbacks; + struct dstr settings; + + pthread_mutex_t data_callbacks_mutex; + DARRAY(struct obs_encoder_callback) data_callbacks; +}; + +extern bool load_encoder_info(void *module, const char *module_name, + const char *encoder_name, struct encoder_info *info); diff --git a/libobs/obs-module.c b/libobs/obs-module.c index 236d2b1062d734c7282371ff1eb30625994697df..a9cdf6b4c09d4d3874a211feb1902880882ee035 100644 --- a/libobs/obs-module.c +++ b/libobs/obs-module.c @@ -154,6 +154,8 @@ int obs_load_module(const char *path) sizeof(struct source_info), load_source_info); module_load_exports(&mod, &obs->output_types.da, "outputs", sizeof(struct output_info), load_output_info); + module_load_exports(&mod, &obs->encoder_types.da, "encoders", + sizeof(struct encoder_info), load_encoder_info); da_push_back(obs->modules, &mod); return MODULE_SUCCESS; diff --git a/libobs/obs-output.c b/libobs/obs-output.c index f6520d1582285c73c34bd5584a3ed77f592c920f..2ca3b34551e7391d95d0c04de4cb594b3e980df4 100644 --- a/libobs/obs-output.c +++ b/libobs/obs-output.c @@ -31,13 +31,15 @@ bool load_output_info(void *module, const char *module_name, output_id, "start", true); info->stop = load_module_subfunc(module, module_name, output_id, "stop", true); + info->active = load_module_subfunc(module, module_name, + output_id, "active", true); if (!info->getname || !info->create || !info->destroy || - !info->start || !info->stop) + !info->start || !info->stop || !info->active) return false; - info->config = load_module_subfunc(module, module_name, - output_id, "config", false); + info->update = load_module_subfunc(module, module_name, + output_id, "update", false); info->pause = load_module_subfunc(module, module_name, output_id, "pause", false); @@ -55,7 +57,8 @@ static inline const struct output_info *find_output(const char *id) return NULL; } -obs_output_t obs_output_create(const char *id, const char *settings) +obs_output_t obs_output_create(const char *id, const char *name, + const char *settings) { const struct output_info *info = find_output(id); struct obs_output *output; @@ -66,29 +69,39 @@ obs_output_t obs_output_create(const char *id, const char *settings) } output = bmalloc(sizeof(struct obs_output)); + output->callbacks = *info; output->data = info->create(settings, output); if (!output->data) { bfree(output); return NULL; } + output->name = bstrdup(name); dstr_init_copy(&output->settings, settings); - memcpy(&output->callbacks, info, sizeof(struct output_info)); + + pthread_mutex_lock(&obs->data.outputs_mutex); + da_push_back(obs->data.outputs, &output); + pthread_mutex_unlock(&obs->data.outputs_mutex); return output; } void obs_output_destroy(obs_output_t output) { if (output) { + pthread_mutex_lock(&obs->data.outputs_mutex); + da_erase_item(obs->data.outputs, &output); + pthread_mutex_unlock(&obs->data.outputs_mutex); + output->callbacks.destroy(output->data); dstr_free(&output->settings); + bfree(output->name); bfree(output); } } -void obs_output_start(obs_output_t output) +bool obs_output_start(obs_output_t output) { - output->callbacks.start(output->data); + return output->callbacks.start(output->data); } void obs_output_stop(obs_output_t output) @@ -96,15 +109,15 @@ void obs_output_stop(obs_output_t output) output->callbacks.stop(output->data); } -bool obs_output_canconfig(obs_output_t output) +bool obs_output_active(obs_output_t output) { - return output->callbacks.config != NULL; + return output->callbacks.active(output); } -void obs_output_config(obs_output_t output, void *parent) +void obs_output_update(obs_output_t output, const char *settings) { - if (output->callbacks.config) - output->callbacks.config(output->data, parent); + if (output->callbacks.update) + output->callbacks.update(output->data, settings); } bool obs_output_canpause(obs_output_t output) diff --git a/libobs/obs-output.h b/libobs/obs-output.h index a4054ca839b21b742bd2ca02cf47e3d6b8549b6f..986af1a34180c2da3bb5df0f71154b2269e2448c 100644 --- a/libobs/obs-output.h +++ b/libobs/obs-output.h @@ -29,7 +29,7 @@ * to a destination, whether that destination be a file, network, or other. * * A module with outputs needs to export these functions: - * + enum_outputss + * + enum_outputs * * Each individual output is then exported by it's name. For example, an * output named "myoutput" would have the following exports: @@ -38,6 +38,7 @@ * + myoutput_destroy * + myoutput_start * + myoutput_stop + * + myoutput_encoders * * [and optionally] * + myoutput_config @@ -75,16 +76,46 @@ * settings: New settings of the output * * --------------------------------------------------------- - * void [name]_start(void *data) + * bool [name]_start(void *data) * Starts output * + * Return value: true if successful + * * --------------------------------------------------------- * void [name]_stop(void *data) * Stops output * + * --------------------------------------------------------- + * bool [name]_active(void *data) + * Returns whether currently active or not + * + * --------------------------------------------------------- + * uint32_t [name]_encoders(void *data) + * Returns 0 or a combination of the following values: + * + OUTPUT_VIDEO_ENCODER: requires a video encoder + * + OUTPUT_AUDIO_ENCODER: requires an audio encoder + * * =========================================== * Optional Output Exports * =========================================== + * bool [name]_setencoder(void *data, obs_encoder_t encoder, + * enum obs_encoder_type type) + * Sets the encoder for this output. + * + * encoder: Encoder context + * type: Type of encoder (ENCODER_VIDEO or ENCODER_AUDIO) + * + * Returns true if successful and compatible + * + * --------------------------------------------------------- + * obs_encoder_t [name]_getencoder(void *data, enum obs_encoder_type type) + * Gets the encoder for this output + * + * type: Type of encoder + * + * Returns the encoder, or NULL if none. + * + * --------------------------------------------------------- * void [name]_config(void *data, void *parent); * Called to configure the output. * @@ -105,18 +136,21 @@ struct output_info { void *(*create)(const char *settings, struct obs_output *output); void (*destroy)(void *data); - void (*start)(void *data); + bool (*start)(void *data); void (*stop)(void *data); + bool (*active)(void *data); + /* optional */ - void (*config)(void *data, void *parent); + void (*update)(void *data, const char *settings); void (*pause)(void *data); }; struct obs_output { - void *data; + char *name; + void *data; struct output_info callbacks; - struct dstr settings; + struct dstr settings; }; extern bool load_output_info(void *module, const char *module_name, diff --git a/libobs/obs-source.h b/libobs/obs-source.h index 9409a40fc49e9932f0a49773b50e01be7ecb9965..3ac07467733ae7dff9b4b472ca7a0f31b6b534ba 100644 --- a/libobs/obs-source.h +++ b/libobs/obs-source.h @@ -81,7 +81,9 @@ * Returns a combination of one of the following values: * + SOURCE_VIDEO: source has video * + SOURCE_AUDIO: source has audio - * + SOURCE_ASYNC: video is sent asynchronously via RAM + * + SOURCE_ASYNC_VIDEO: video is sent asynchronously via RAM + * + SOURCE_DEFAULT_EFFECT: source uses default effect + * + SOURCE_YUV: source is in YUV color space * * --------------------------------------------------------- * uint32_t [name]_getwidth(void *data); diff --git a/libobs/obs.c b/libobs/obs.c index 99dd36ebfe15722070c3c5e7567572bc8a993940..67da3170c8621185f78db573a47680a2cf82b507 100644 --- a/libobs/obs.c +++ b/libobs/obs.c @@ -238,6 +238,10 @@ static bool obs_init_data(void) goto fail; if (pthread_mutex_init(&data->displays_mutex, &attr) != 0) goto fail; + if (pthread_mutex_init(&data->outputs_mutex, &attr) != 0) + goto fail; + if (pthread_mutex_init(&data->encoders_mutex, &attr) != 0) + goto fail; success = true; @@ -254,6 +258,10 @@ static void obs_free_data(void) for (i = 0; i < MAX_CHANNELS; i++) obs_set_output_source(i, NULL); + while (data->outputs.num) + obs_output_destroy(data->outputs.array[0]); + while (data->encoders.num) + obs_encoder_destroy(data->encoders.array[0]); while (data->displays.num) obs_display_destroy(data->displays.array[0]); @@ -262,6 +270,11 @@ static void obs_free_data(void) obs_source_release(data->sources.array[i]); da_free(data->sources); pthread_mutex_unlock(&obs->data.sources_mutex); + + pthread_mutex_destroy(&data->sources_mutex); + pthread_mutex_destroy(&data->displays_mutex); + pthread_mutex_destroy(&data->outputs_mutex); + pthread_mutex_destroy(&data->encoders_mutex); } static inline bool obs_init_handlers(void) @@ -487,17 +500,41 @@ void obs_set_output_source(uint32_t channel, obs_source_t source) } } -void obs_enum_sources(bool (*enum_proc)(obs_source_t, void*), void *param) +void obs_enum_outputs(bool (*enum_proc)(void*, obs_output_t), void *param) +{ + struct obs_data *data = &obs->data; + + pthread_mutex_lock(&data->outputs_mutex); + + for (size_t i = 0; i < data->outputs.num; i++) + if (!enum_proc(param, data->outputs.array[i])) + break; + + pthread_mutex_unlock(&data->outputs_mutex); +} + +void obs_enum_encoders(bool (*enum_proc)(void*, obs_encoder_t), void *param) +{ + struct obs_data *data = &obs->data; + + pthread_mutex_lock(&data->encoders_mutex); + + for (size_t i = 0; i < data->encoders.num; i++) + if (!enum_proc(param, data->encoders.array[i])) + break; + + pthread_mutex_unlock(&data->encoders_mutex); +} + +void obs_enum_sources(bool (*enum_proc)(void*, obs_source_t), void *param) { struct obs_data *data = &obs->data; - size_t i; pthread_mutex_lock(&data->sources_mutex); - for (i = 0; i < data->sources.num; i++) { - if (!enum_proc(data->sources.array[i], param)) + for (size_t i = 0; i < data->sources.num; i++) + if (!enum_proc(param, data->sources.array[i])) break; - } pthread_mutex_unlock(&data->sources_mutex); } diff --git a/libobs/obs.h b/libobs/obs.h index 78b9683df4bb0c4c7ad0c8d943591977afa72b1b..d3c7adfb20db7fd03f8fc40a70a519929998f66e 100644 --- a/libobs/obs.h +++ b/libobs/obs.h @@ -50,6 +50,11 @@ enum obs_source_type { SOURCE_SCENE }; +enum obs_encoder_type { + ENCODER_VIDEO, + ENCODER_AUDIO +}; + enum obs_video_type { OBS_VIDEO_YUV, OBS_VIDEO_RGB @@ -136,12 +141,29 @@ static inline void source_frame_destroy(struct source_frame *frame) } } +enum packet_priority { + PACKET_PRIORITY_DISPOSABLE, + PACKET_PRIORITY_LOW, + PACKET_PRIORITY_PFRAME, + PACKET_PRIORITY_IFRAME, + PACKET_PRIORITY_OTHER /* audio usually */ +}; + +struct encoder_packet { + int64_t dts; + int64_t pts; + void *data; + size_t size; + enum packet_priority priority; +}; + /* opaque types */ struct obs_display; struct obs_source; struct obs_scene; struct obs_scene_item; struct obs_output; +struct obs_encoder; struct obs_service; typedef struct obs_display *obs_display_t; @@ -149,6 +171,7 @@ typedef struct obs_source *obs_source_t; typedef struct obs_scene *obs_scene_t; typedef struct obs_scene_item *obs_sceneitem_t; typedef struct obs_output *obs_output_t; +typedef struct obs_encoder *obs_encoder_t; typedef struct obs_service *obs_service_t; /* ------------------------------------------------------------------------- */ @@ -254,7 +277,15 @@ EXPORT obs_source_t obs_get_output_source(uint32_t channel); * Callback function returns true to continue enumeration, or false to end * enumeration. */ -EXPORT void obs_enum_sources(bool (*enum_proc)(obs_source_t, void*), +EXPORT void obs_enum_sources(bool (*enum_proc)(void*, obs_source_t), + void *param); + +/** Enumerates outputs */ +EXPORT void obs_enum_outputs(bool (*enum_proc)(void*, obs_output_t), + void *param); + +/** Enumerates encoders */ +EXPORT void obs_enum_encoders(bool (*enum_proc)(void*, obs_encoder_t), void *param); /** @@ -504,26 +535,30 @@ EXPORT void obs_sceneitem_getscale(obs_sceneitem_t item, struct vec2 *scale); /* ------------------------------------------------------------------------- */ /* Outputs */ +EXPORT const char *obs_output_getdisplayname(const char *id, + const char *locale); + /** * Creates an output. * * Outputs allow outputting to file, outputting to network, outputting to * directshow, or other custom outputs. */ -EXPORT obs_output_t obs_output_create(const char *name, const char *settings); +EXPORT obs_output_t obs_output_create(const char *id, const char *name, + const char *settings); EXPORT void obs_output_destroy(obs_output_t output); /** Starts the output. */ -EXPORT void obs_output_start(obs_output_t output); +EXPORT bool obs_output_start(obs_output_t output); /** Stops the output. */ EXPORT void obs_output_stop(obs_output_t output); -/** Specifies whether the output can be configured */ -EXPORT bool obs_output_canconfig(obs_output_t output); +/** Returns whether the output is active */ +EXPORT bool obs_output_active(obs_output_t output); -/** Opens a configuration panel with the specified parent window */ -EXPORT void obs_output_config(obs_output_t output, void *parent); +/** Updates the settings for this output context */ +EXPORT void obs_output_update(obs_output_t output, const char *settings); /** Specifies whether the output can be paused */ EXPORT bool obs_output_canpause(obs_output_t output); @@ -539,13 +574,52 @@ EXPORT void obs_output_save_settings(obs_output_t output, const char *settings); +/* ------------------------------------------------------------------------- */ +/* Stream Encoders */ +EXPORT const char *obs_encoder_getdisplayname(const char *id, + const char *locale); + +EXPORT obs_encoder_t obs_encoder_create(const char *id, const char *name, + const char *settings); +EXPORT void obs_encoder_destroy(obs_encoder_t encoder); + +EXPORT void obs_encoder_update(obs_encoder_t encoder, const char *settings); + +EXPORT bool obs_encoder_reset(obs_encoder_t encoder); + +EXPORT bool obs_encoder_encode(obs_encoder_t encoder, void *frames, + size_t size); +EXPORT int obs_encoder_getheader(obs_encoder_t encoder, + struct encoder_packet **packets); + +EXPORT bool obs_encoder_start(obs_encoder_t encoder, + void (*new_packet)(void *param, struct encoder_packet *packet), + void *param); +EXPORT bool obs_encoder_stop(obs_encoder_t encoder, + void (*new_packet)(void *param, struct encoder_packet *packet), + void *param); + +EXPORT void obs_encoder_setbitrate(obs_encoder_t encoder, uint32_t bitrate, + uint32_t buffersize); + +EXPORT void obs_encoder_request_keyframe(obs_encoder_t encoder); + +EXPORT const char *obs_encoder_get_settings(obs_encoder_t encoder); + +EXPORT void obs_encoder_save_settings(obs_encoder_t encoder, + const char *settings); + + /* ------------------------------------------------------------------------- */ /* Stream Services */ +EXPORT const char *obs_service_getdisplayname(const char *id, + const char *locale); + EXPORT obs_service_t obs_service_create(const char *service, const char *settings); EXPORT void obs_service_destroy(obs_service_t service); -EXPORT void obs_service_setdata(obs_service_t service,const char *attribute, +EXPORT void obs_service_setdata(obs_service_t service, const char *attribute, const char *data); EXPORT const char *obs_service_getdata(obs_service_t service, const char *attribute); diff --git a/plugins/obs-outputs/obs-outputs.c b/plugins/obs-outputs/obs-outputs.c index 6ce9ace17d951638fd96ee1b30458a304c959c6e..a9dd9b99965f921bd5298a19f7f921f0cbd3576a 100644 --- a/plugins/obs-outputs/obs-outputs.c +++ b/plugins/obs-outputs/obs-outputs.c @@ -1,3 +1,4 @@ +#include <string.h> #include "obs-outputs.h" static const char *outputs[] = {"rtmp_stream"}; diff --git a/plugins/obs-outputs/obs-outputs.h b/plugins/obs-outputs/obs-outputs.h index 4e24817cf552265b59d763037a44a10ac96b097b..0601083d23a9d3305cad15c32550f538bfc548dd 100644 --- a/plugins/obs-outputs/obs-outputs.h +++ b/plugins/obs-outputs/obs-outputs.h @@ -1,5 +1,5 @@ #pragma once -#include "util/c99defs.h" +#include <util/c99defs.h> EXPORT const char *enum_outputs(size_t idx); diff --git a/plugins/obs-outputs/obs-stream.c b/plugins/obs-outputs/obs-stream.c index cc0cf383dc9f63a7c81bdcb9049068e5a2a11eaf..a7405c0446c5b40814ce2b81075fa4417dbb986b 100644 --- a/plugins/obs-outputs/obs-stream.c +++ b/plugins/obs-outputs/obs-stream.c @@ -1,6 +1,23 @@ +/****************************************************************************** + Copyright (C) 2013 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/>. +******************************************************************************/ + #include "obs-stream.h" -void *rtmp_stream_getname(const char *locale) +const char *rtmp_stream_getname(const char *locale) { /* TODO: locale stuff */ return "RTMP Stream"; @@ -8,21 +25,26 @@ void *rtmp_stream_getname(const char *locale) void *rtmp_stream_create(const char *settings, obs_output_t output) { - + struct rtmp_stream *stream = bmalloc(sizeof(struct rtmp_stream)); + memset(stream, 0, sizeof(struct rtmp_stream)); +} + +void rtmp_stream_destroy(struct rtmp_stream *stream) +{ } -void *rtmp_stream_destroy(void *data) +void rtmp_stream_update(struct rtmp_stream *stream, const char *settings) { } -void *rtmp_stream_update(void *data, const char *settings) +bool rtmp_stream_start(struct rtmp_stream *stream) { } -void rtmp_stream_start(void *data) +void rtmp_stream_stop(struct rtmp_stream *stream) { } -void rtmp_stream_stop(void *data) +bool rtmp_stream_active(struct rtmp_stream *stream) { } diff --git a/plugins/obs-outputs/obs-stream.h b/plugins/obs-outputs/obs-stream.h index f6f151ebacc05bbf09c2170fb4178ee3e40c2ded..02edeb73aaba3dced91b0029437240661322fbc3 100644 --- a/plugins/obs-outputs/obs-stream.h +++ b/plugins/obs-outputs/obs-stream.h @@ -1,15 +1,39 @@ +/****************************************************************************** + Copyright (C) 2013 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/>. +******************************************************************************/ + #pragma once -#include "util/c99defs.h" -#include "obs.h" +#include <util/c99defs.h> +#include <obs.h> struct rtmp_stream { - obs_output_t handler; + obs_output_t output; + obs_encoder_t video_encoder; + obs_encoder_t audio_encoder; + obs_service_t service; + + bool active; }; -EXPORT void *rtmp_stream_getname(const char *locale); +EXPORT const char *rtmp_stream_getname(const char *locale); EXPORT void *rtmp_stream_create(const char *settings, obs_output_t output); -EXPORT void *rtmp_stream_destroy(void *data); -EXPORT void *rtmp_stream_update(void *data, const char *settings); -EXPORT void rtmp_stream_start(void *data); -EXPORT void rtmp_stream_stop(void *data); +EXPORT void rtmp_stream_destroy(struct rtmp_stream *stream); +EXPORT void rtmp_stream_update(struct rtmp_stream *stream, + const char *settings); +EXPORT bool rtmp_stream_start(struct rtmp_stream *stream); +EXPORT void rtmp_stream_stop(struct rtmp_stream *stream); +EXPORT bool rtmp_stream_active(struct rtmp_stream *stream); diff --git a/plugins/obs-outputs/obs-x264.c b/plugins/obs-outputs/obs-x264.c new file mode 100644 index 0000000000000000000000000000000000000000..d65d7e27c0dd0614239f7b16c589089dadb89ae1 --- /dev/null +++ b/plugins/obs-outputs/obs-x264.c @@ -0,0 +1,58 @@ +/****************************************************************************** + Copyright (C) 2013 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/>. +******************************************************************************/ + +#include "obs-x264.h" + +const char *obs_x264_getname(const char *locale) +{ + /* TODO locale lookup */ + return "x264 (Software)"; +} + +struct obs_x264 *obs_x264_create(const char *settings, obs_encoder_t encoder) +{ + struct obs_x264 *data = bmalloc(sizeof(struct obs_x264)); +} + +void obs_x264_destroy(struct obs_x264 *data) +{ +} + +void obs_x264_update(struct obs_x264 *data, const char *settings) +{ +} + +void obs_x264_reset(struct obs_x264 *data) +{ +} + +int obs_x264_encode(struct obs_x264 *data, struct encoder_packet **packets) +{ +} + +int obs_x264_getheader(struct obs_x264 *data, struct encoder_packet **packets) +{ +} + +void obs_x264_setbitrate(struct obs_x264 *data, uint32_t bitrate, + uint32_t buffersize) +{ +} + +void obs_x264_request_keyframe(struct obs_x264 *data) +{ +} diff --git a/plugins/obs-outputs/obs-x264.h b/plugins/obs-outputs/obs-x264.h new file mode 100644 index 0000000000000000000000000000000000000000..8190ce28b8ffc60c178908d44d7f6e695f7bd46e --- /dev/null +++ b/plugins/obs-outputs/obs-x264.h @@ -0,0 +1,49 @@ +/****************************************************************************** + Copyright (C) 2013 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/>. +******************************************************************************/ + +#pragma once + +#include <util/c99defs.h> +#include <obs.h> +#include <x264.h> + +struct obs_x264 { + obs_encoder_t encoder; + + x264_param_t params; + x264_t *context; + x264_picture_t pic_out; +}; + +EXPORT const char *obs_x264_getname(const char *locale); + +EXPORT struct obs_x264 *obs_x264_create(const char *settings, + obs_encoder_t encoder); +EXPORT void obs_x264_destroy(struct obs_x264 *data); + +EXPORT void obs_x264_update(struct obs_x264 *data, const char *settings); + +EXPORT void obs_x264_reset(struct obs_x264 *data); + +EXPORT int obs_x264_encode(struct obs_x264 *data, + struct encoder_packet **packets); +EXPORT int obs_x264_getheader(struct obs_x264 *data, + struct encoder_packet **packets); + +EXPORT void obs_x264_setbitrate(struct obs_x264 *data, uint32_t bitrate, + uint32_t buffersize); +EXPORT void obs_x264_request_keyframe(struct obs_x264 *data); diff --git a/vs/2013/libobs/libobs.vcxproj b/vs/2013/libobs/libobs.vcxproj index 481988a8ec1c3ba0295734c44839833a650513df..899fcec4c63cf42cf5a245c7416c93836429518a 100644 --- a/vs/2013/libobs/libobs.vcxproj +++ b/vs/2013/libobs/libobs.vcxproj @@ -45,6 +45,7 @@ <ClInclude Include="..\..\..\libobs\media-io\video-io.h" /> <ClInclude Include="..\..\..\libobs\obs-data.h" /> <ClInclude Include="..\..\..\libobs\obs-defs.h" /> + <ClInclude Include="..\..\..\libobs\obs-encoder.h" /> <ClInclude Include="..\..\..\libobs\obs-module.h" /> <ClInclude Include="..\..\..\libobs\obs-output.h" /> <ClInclude Include="..\..\..\libobs\obs-scene.h" /> @@ -91,6 +92,7 @@ <ClCompile Include="..\..\..\libobs\media-io\format-conversion.c" /> <ClCompile Include="..\..\..\libobs\media-io\video-io.c" /> <ClCompile Include="..\..\..\libobs\obs-display.c" /> + <ClCompile Include="..\..\..\libobs\obs-encoder.c" /> <ClCompile Include="..\..\..\libobs\obs-module.c" /> <ClCompile Include="..\..\..\libobs\obs-output.c" /> <ClCompile Include="..\..\..\libobs\obs-scene.c" /> diff --git a/vs/2013/libobs/libobs.vcxproj.filters b/vs/2013/libobs/libobs.vcxproj.filters index e79d369ce8df644ea4e8a6e6d5e821d50bf07cba..ce920f27abf7c147be48c0a81c3ed0e61f0c00c6 100644 --- a/vs/2013/libobs/libobs.vcxproj.filters +++ b/vs/2013/libobs/libobs.vcxproj.filters @@ -198,6 +198,9 @@ <ClInclude Include="..\..\..\libobs\callback\signal.h"> <Filter>callback\Header Files</Filter> </ClInclude> + <ClInclude Include="..\..\..\libobs\obs-encoder.h"> + <Filter>libobs\Header Files</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <ClCompile Include="..\..\..\libobs\obs-output.c"> @@ -326,5 +329,8 @@ <ClCompile Include="..\..\..\libobs\callback\proc.c"> <Filter>callback\Source Files</Filter> </ClCompile> + <ClCompile Include="..\..\..\libobs\obs-encoder.c"> + <Filter>libobs\Source Files</Filter> + </ClCompile> </ItemGroup> </Project> \ No newline at end of file diff --git a/vs/2013/obs-outputs/obs-outputs.vcxproj b/vs/2013/obs-outputs/obs-outputs.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..12e19fcc49c885987a4643656d742bd114048aec --- /dev/null +++ b/vs/2013/obs-outputs/obs-outputs.vcxproj @@ -0,0 +1,162 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{CDC3B5C9-2BEA-4509-A2A8-6477506010ED}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>obsoutputs</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v120</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v120</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v120</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v120</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;OBSOUTPUTS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../../libobs</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>libobs.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;OBSOUTPUTS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../../libobs</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>libobs.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;OBSOUTPUTS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../../libobs</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>libobs.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;OBSOUTPUTS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../../libobs</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>libobs.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClInclude Include="..\..\..\plugins\obs-outputs\obs-outputs.h" /> + <ClInclude Include="..\..\..\plugins\obs-outputs\obs-stream.h" /> + <ClInclude Include="..\..\..\plugins\obs-outputs\obs-x264.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\..\plugins\obs-outputs\obs-outputs.c" /> + <ClCompile Include="..\..\..\plugins\obs-outputs\obs-stream.c" /> + <ClCompile Include="..\..\..\plugins\obs-outputs\obs-x264.c" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/vs/2013/obs-outputs/obs-outputs.vcxproj.filters b/vs/2013/obs-outputs/obs-outputs.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..386f7c70ad9412bc92e762c00690d2120d6cecd9 --- /dev/null +++ b/vs/2013/obs-outputs/obs-outputs.vcxproj.filters @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\plugins\obs-outputs\obs-stream.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\plugins\obs-outputs\obs-outputs.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\plugins\obs-outputs\obs-x264.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\..\plugins\obs-outputs\obs-stream.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\..\plugins\obs-outputs\obs-outputs.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\..\plugins\obs-outputs\obs-x264.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> +</Project> \ No newline at end of file