diff --git a/libobs/media-io/audio-io.c b/libobs/media-io/audio-io.c index c95abbef6..5ef62d533 100644 --- a/libobs/media-io/audio-io.c +++ b/libobs/media-io/audio-io.c @@ -23,7 +23,7 @@ #include "audio-io.h" struct audio_input { - struct audio_info format; + struct audio_convert_info conversion; void (*callback)(void *param, const struct audio_data *data); void *param; }; @@ -88,13 +88,13 @@ static inline void audio_output_removeline(struct audio_output *audio, audio_line_destroy_data(line); } -static inline size_t time_to_frames(audio_t audio, uint64_t offset) +static inline uint32_t time_to_frames(audio_t audio, uint64_t offset) { double audio_offset_d = (double)offset; audio_offset_d /= 1000000000.0; audio_offset_d *= (double)audio->info.samples_per_sec; - return (size_t)audio_offset_d; + return (uint32_t)audio_offset_d; } static inline size_t time_to_bytes(audio_t audio, uint64_t offset) @@ -146,7 +146,7 @@ static inline void mix_audio_line(struct audio_output *audio, } static inline void do_audio_output(struct audio_output *audio, - uint64_t timestamp, size_t frames) + uint64_t timestamp, uint32_t frames) { struct audio_data data; data.data = audio->mix_buffer.array; @@ -168,7 +168,7 @@ static void mix_and_output(struct audio_output *audio, uint64_t audio_time, { struct audio_line *line = audio->first_line; uint64_t time_offset = audio_time - prev_time; - size_t frames = time_to_frames(audio, time_offset); + uint32_t frames = time_to_frames(audio, time_offset); size_t bytes = frames * audio->block_size; da_resize(audio->mix_buffer, bytes); @@ -231,7 +231,8 @@ static size_t audio_get_input_idx(audio_t video, return DARRAY_INVALID; } -void audio_output_connect(audio_t audio, struct audio_info *format, +void audio_output_connect(audio_t audio, + struct audio_convert_info *conversion, void (*callback)(void *param, const struct audio_data *data), void *param) { @@ -243,12 +244,12 @@ void audio_output_connect(audio_t audio, struct audio_info *format, input.param = param; /* TODO: conversion */ - if (format) { - input.format = *format; + if (conversion) { + input.conversion = *conversion; } else { - input.format.format = audio->info.format; - input.format.speakers = audio->info.speakers; - input.format.samples_per_sec = + input.conversion.format = audio->info.format; + input.conversion.speakers = audio->info.speakers; + input.conversion.samples_per_sec = audio->info.samples_per_sec; } diff --git a/libobs/media-io/audio-io.h b/libobs/media-io/audio-io.h index 5715f1c27..c11e445d3 100644 --- a/libobs/media-io/audio-io.h +++ b/libobs/media-io/audio-io.h @@ -71,7 +71,7 @@ struct audio_output_info { uint64_t buffer_ms; }; -struct audio_info { +struct audio_convert_info { uint32_t samples_per_sec; enum audio_format format; enum speaker_layout speakers; @@ -124,7 +124,8 @@ static inline size_t get_audio_size(enum audio_format type, EXPORT int audio_output_open(audio_t *audio, struct audio_output_info *info); EXPORT void audio_output_close(audio_t audio); -EXPORT void audio_output_connect(audio_t video, struct audio_info *format, +EXPORT void audio_output_connect(audio_t video, + struct audio_convert_info *conversion, void (*callback)(void *param, const struct audio_data *data), void *param); EXPORT void audio_output_disconnect(audio_t video, diff --git a/libobs/media-io/audio-resampler-ffmpeg.c b/libobs/media-io/audio-resampler-ffmpeg.c index 744f2325e..b24795c32 100644 --- a/libobs/media-io/audio-resampler-ffmpeg.c +++ b/libobs/media-io/audio-resampler-ffmpeg.c @@ -17,9 +17,9 @@ #include "../util/bmem.h" #include "audio-resampler.h" -#include -#include #include +#include +#include struct audio_resampler { struct SwrContext *context; diff --git a/libobs/media-io/video-io.c b/libobs/media-io/video-io.c index 8e7abaa7d..9f584535e 100644 --- a/libobs/media-io/video-io.c +++ b/libobs/media-io/video-io.c @@ -24,8 +24,8 @@ #include "video-io.h" struct video_input { - struct video_info format; - void (*callback)(void *param, struct video_frame *frame); + struct video_convert_info conversion; + void (*callback)(void *param, const struct video_frame *frame); void *param; }; @@ -116,7 +116,7 @@ int video_output_open(video_t *video, struct video_output_info *info) out = bmalloc(sizeof(struct video_output)); memset(out, 0, sizeof(struct video_output)); - memcpy(&out->info, info, sizeof(struct video_info)); + memcpy(&out->info, info, sizeof(struct video_output_info)); out->frame_time = (uint64_t)(1000000000.0 * (double)info->fps_den / (double)info->fps_num); out->initialized = false; @@ -157,7 +157,7 @@ void video_output_close(video_t video) } static size_t video_get_input_idx(video_t video, - void (*callback)(void *param, struct video_frame *frame), + void (*callback)(void *param, const struct video_frame *frame), void *param) { for (size_t i = 0; i < video->inputs.num; i++) { @@ -169,8 +169,9 @@ static size_t video_get_input_idx(video_t video, return DARRAY_INVALID; } -void video_output_connect(video_t video, struct video_info *format, - void (*callback)(void *param, struct video_frame *frame), +void video_output_connect(video_t video, + struct video_convert_info *conversion, + void (*callback)(void *param, const struct video_frame *frame), void *param) { pthread_mutex_lock(&video->input_mutex); @@ -181,12 +182,18 @@ void video_output_connect(video_t video, struct video_info *format, input.param = param; /* TODO: conversion */ - if (format) { - input.format = *format; + if (conversion) { + input.conversion = *conversion; + + if (input.conversion.width == 0) + input.conversion.width = video->info.width; + if (input.conversion.height == 0) + input.conversion.height = video->info.height; } else { - input.format.type = video->info.type; - input.format.height = video->info.height; - input.format.width = video->info.width; + input.conversion.format = video->info.format; + input.conversion.width = video->info.width; + input.conversion.height = video->info.height; + input.conversion.row_align = 1; } da_push_back(video->inputs, &input); @@ -196,7 +203,7 @@ void video_output_connect(video_t video, struct video_info *format, } void video_output_disconnect(video_t video, - void (*callback)(void *param, struct video_frame *frame), + void (*callback)(void *param, const struct video_frame *frame), void *param) { pthread_mutex_lock(&video->input_mutex); diff --git a/libobs/media-io/video-io.h b/libobs/media-io/video-io.h index ac2d9ef3f..04299c57d 100644 --- a/libobs/media-io/video-io.h +++ b/libobs/media-io/video-io.h @@ -29,7 +29,7 @@ struct video_output; typedef struct video_output *video_t; enum video_format { - VIDEO_FORMAT_UNKNOWN, + VIDEO_FORMAT_NONE, /* planar 420 format */ VIDEO_FORMAT_I420, /* three-plane */ @@ -57,18 +57,18 @@ struct video_frame { struct video_output_info { const char *name; - enum video_format type; + enum video_format format; uint32_t fps_num; uint32_t fps_den; uint32_t width; uint32_t height; }; -struct video_info { - enum video_format type; +struct video_convert_info { + enum video_format format; uint32_t width; uint32_t height; - uint32_t row_size; /* if any */ + uint32_t row_align; }; #define VIDEO_OUTPUT_SUCCESS 0 @@ -78,11 +78,12 @@ struct video_info { EXPORT int video_output_open(video_t *video, struct video_output_info *info); EXPORT void video_output_close(video_t video); -EXPORT void video_output_connect(video_t video, struct video_info *format, - void (*callback)(void *param, struct video_frame *frame), +EXPORT void video_output_connect(video_t video, + struct video_convert_info *conversion, + void (*callback)(void *param, const struct video_frame *frame), void *param); EXPORT void video_output_disconnect(video_t video, - void (*callback)(void *param, struct video_frame *frame), + void (*callback)(void *param, const struct video_frame *frame), void *param); EXPORT const struct video_output_info *video_output_getinfo(video_t video); diff --git a/libobs/obs-defs.h b/libobs/obs-defs.h index 8e9725713..c15b36c0b 100644 --- a/libobs/obs-defs.h +++ b/libobs/obs-defs.h @@ -31,6 +31,3 @@ #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-output.h b/libobs/obs-output.h index 13a3b1f3f..356e63810 100644 --- a/libobs/obs-output.h +++ b/libobs/obs-output.h @@ -39,6 +39,7 @@ * + myoutput_update * + myoutput_start * + myoutput_stop + * + myoutput_active * * [and optionally] * + myoutput_pause diff --git a/libobs/obs-source.c b/libobs/obs-source.c index 062f97f5d..5b5fd4f1f 100644 --- a/libobs/obs-source.c +++ b/libobs/obs-source.c @@ -404,7 +404,7 @@ static inline enum convert_type get_convert_type(enum video_format format) case VIDEO_FORMAT_UYVY: return CONVERT_422_U; - case VIDEO_FORMAT_UNKNOWN: + case VIDEO_FORMAT_NONE: case VIDEO_FORMAT_YUVX: case VIDEO_FORMAT_UYVX: case VIDEO_FORMAT_RGBA: @@ -427,7 +427,7 @@ static inline bool is_yuv(enum video_format format) case VIDEO_FORMAT_YUVX: case VIDEO_FORMAT_UYVX: return true; - case VIDEO_FORMAT_UNKNOWN: + case VIDEO_FORMAT_NONE: case VIDEO_FORMAT_RGBA: case VIDEO_FORMAT_BGRA: case VIDEO_FORMAT_BGRX: diff --git a/libobs/obs.c b/libobs/obs.c index 67da3170c..eb8b02160 100644 --- a/libobs/obs.c +++ b/libobs/obs.c @@ -41,7 +41,7 @@ static inline void make_video_info(struct video_output_info *vi, struct obs_video_info *ovi) { vi->name = "video"; - vi->type = ovi->output_format; + vi->format = ovi->output_format; vi->fps_num = ovi->fps_num; vi->fps_den = ovi->fps_den; vi->width = ovi->output_width; @@ -381,7 +381,7 @@ bool obs_get_video_info(struct obs_video_info *ovi) ovi->base_height = video->base_height; ovi->output_width = info->width; ovi->output_height = info->height; - ovi->output_format = info->type; + ovi->output_format = info->format; ovi->fps_num = info->fps_num; ovi->fps_den = info->fps_den; diff --git a/libobs/obs.h b/libobs/obs.h index e4fbf9c21..46c65fbc8 100644 --- a/libobs/obs.h +++ b/libobs/obs.h @@ -374,9 +374,6 @@ EXPORT bool obs_source_removed(obs_source_t source); */ EXPORT uint32_t obs_source_get_output_flags(obs_source_t source); -/** Specifies whether the source can be configured */ -EXPORT bool obs_source_hasconfig(obs_source_t source); - /** Updates settings for this source */ EXPORT void obs_source_update(obs_source_t source, const char *settings); diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-output.c b/plugins/obs-ffmpeg/obs-ffmpeg-output.c new file mode 100644 index 000000000..80b85c83d --- /dev/null +++ b/plugins/obs-ffmpeg/obs-ffmpeg-output.c @@ -0,0 +1,369 @@ +/****************************************************************************** + Copyright (C) 2013 by Hugh Bailey + + 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 . +******************************************************************************/ + +#include +#include "obs-ffmpeg-output.h" + +#define FILENAME_TODO "D:\\test.mp4" + +static inline enum AVPixelFormat obs_to_ffmpeg_video_format( + enum video_format format) +{ + switch (format) { + case VIDEO_FORMAT_NONE: return AV_PIX_FMT_NONE; + case VIDEO_FORMAT_I420: return AV_PIX_FMT_YUV420P; + case VIDEO_FORMAT_NV12: return AV_PIX_FMT_NV12; + case VIDEO_FORMAT_YVYU: return AV_PIX_FMT_NONE; + case VIDEO_FORMAT_YUY2: return AV_PIX_FMT_YUYV422; + case VIDEO_FORMAT_UYVY: return AV_PIX_FMT_UYVY422; + case VIDEO_FORMAT_YUVX: return AV_PIX_FMT_NONE; + case VIDEO_FORMAT_UYVX: return AV_PIX_FMT_NONE; + case VIDEO_FORMAT_RGBA: return AV_PIX_FMT_RGBA; + case VIDEO_FORMAT_BGRA: return AV_PIX_FMT_BGRA; + case VIDEO_FORMAT_BGRX: return AV_PIX_FMT_BGRA; + } + + return AV_PIX_FMT_NONE; +} + +static bool new_stream(struct ffmpeg_data *data, AVStream **stream, + AVCodec **codec, enum AVCoecID id) +{ + *codec = avcodec_find_encoder(id); + if (!*codec) { + blog(LOG_ERROR, "Couldn't find encoder '%s'", + avcodec_get_name(id)); + return false; + } + + *stream = avformat_new_stream(data->output, *codec); + if (!*stream) { + blog(LOG_ERROR, "Couldn't create stream for encoder '%s'", + avcodec_get_name(id)); + return false; + } + + (*stream)->id = data->output->nb_streams-1; + return true; +} + +static bool open_video_codec(struct ffmpeg_data *data, + struct obs_video_info *ovi) +{ + AVCodecContext *context = data->video->codec; + int ret; + + ret = avcodec_open2(context, data->vcodec, NULL); + if (ret < 0) { + blog(LOG_ERROR, "Failed to open video codec: %s", + av_err2str(ret)); + return false; + } + + data->vframe = av_frame_alloc(); + if (!data->vframe) { + blog(LOG_ERROR, "Failed to allocate video frame"); + return false; + } + + data->vframe->format = context->pix_fmt; + data->vframe->width = context->width; + data->vframe->height = context->height; + + ret = avpicture_alloc(&data->dst_picture, context->pix_fmt, + context->width, context->height); + if (ret < 0) { + blog(LOG_ERROR, "Failed to allocate dst_picture: %s", + av_err2str(ret)); + return false; + } + + if (context->pix_fmt != AV_PIX_FMT_YUV420P) { + ret = avpicture_alloc(&data->src_picture, AV_PIX_FMT_YUV420P, + context->width, context->height); + if (ret < 0) { + blog(LOG_ERROR, "Failed to allocate src_picture: %s", + av_err2str(ret)); + return false; + } + } + + *((AVPicture*)data->vframe) = data->dst_picture; + return true; +} + +static bool create_video_stream(struct ffmpeg_data *data) +{ + AVCodecContext *context; + struct obs_video_info ovi; + + if (!obs_get_video_info(&ovi)) { + blog(LOG_ERROR, "No active video"); + return false; + } + if (!new_stream(data, &data->video, &data->vcodec, + data->output->oformat->video_codec)) + return false; + + context = data->video->codec; + context->codec_id = data->output->oformat->video_codec; + context->bit_rate = 6000000; + context->width = ovi.output_width; + context->height = ovi.output_height; + context->time_base.num = ovi.fps_den; + context->time_base.den = ovi.fps_num; + context->gop_size = 12; + context->pix_fmt = AV_PIX_FMT_YUV420P; + + if (data->output->oformat->flags & AVFMT_GLOBALHEADER) + context->flags |= CODEC_FLAG_GLOBAL_HEADER; + + return open_video_codec(data, &ovi); +} + +static bool open_audio_codec(struct ffmpeg_data *data, + struct audio_output_info *aoi) +{ + AVCodecContext *context = data->audio->codec; + int ret; + + data->aframe = av_frame_alloc(); + if (!data->aframe) { + blog(LOG_ERROR, "Failed to allocate audio frame"); + return false; + } + + ret = avcodec_open2(context, data->acodec, NULL); + if (ret < 0) { + blog(LOG_ERROR, "Failed to open audio codec: %s", + av_err2str(ret)); + return false; + } + + return true; +} + +static bool create_audio_stream(struct ffmpeg_data *data) +{ + AVCodecContext *context; + struct audio_output_info aoi; + + if (!obs_get_audio_info(&aoi)) { + blog(LOG_ERROR, "No active audio"); + return false; + } + if (!new_stream(data, &data->audio, &data->acodec, + data->output->oformat->audio_codec)) + return false; + + context = data->audio->codec; + context->bit_rate = 128000; + context->channels = get_audio_channels(aoi.speakers); + context->sample_rate = aoi.samples_per_sec; + + if (data->output->oformat->flags & AVFMT_GLOBALHEADER) + context->flags |= CODEC_FLAG_GLOBAL_HEADER; + + return open_audio_codec(data, &aoi); +} + +static inline bool init_streams(struct ffmpeg_data *data) +{ + AVOutputFormat *format = data->output->oformat; + + if (format->video_codec != AV_CODEC_ID_NONE) { + if (!create_video_stream(data)) + return false; + } + + if (format->audio_codec != AV_CODEC_ID_NONE) { + if (!create_audio_stream(data)) + return false; + } + + return true; +} + +static inline bool open_output_file(struct ffmpeg_data *data) +{ + AVOutputFormat *format = data->output->oformat; + int ret; + + if ((format->flags & AVFMT_NOFILE) == 0) { + ret = avio_open(&data->output->pb, FILENAME_TODO, + AVIO_FLAG_WRITE); + if (ret < 0) { + blog(LOG_ERROR, "Couldn't open file '%s', %s", + FILENAME_TODO, av_err2str(ret)); + return false; + } + } + + ret = avformat_write_header(data->output, NULL); + if (ret < 0) { + blog(LOG_ERROR, "Error opening file '%s': %s", + FILENAME_TODO, av_err2str(ret)); + } + + return true; +} + +static void close_video(struct ffmpeg_data *data) +{ + avcodec_close(data->video->codec); + av_free(data->src_picture.data[0]); + av_free(data->dst_picture.data[0]); + av_frame_free(&data->vframe); +} + +static void close_audio(struct ffmpeg_data *data) +{ + avcodec_close(data->audio->codec); + + av_free(data->samples[0]); + av_free(data->samples); + av_frame_free(&data->aframe); +} + +static void ffmpeg_data_free(struct ffmpeg_data *data) +{ + if (data->initialized) + av_write_trailer(data->output); + + if (data->video) + close_video(data); + if (data->audio) + close_audio(data); + if ((data->output->oformat->flags & AVFMT_NOFILE) == 0) + avio_close(data->output->pb); + + avformat_free_context(data->output); +} + +static bool ffmpeg_data_init(struct ffmpeg_data *data) +{ + memset(data, 0, sizeof(struct ffmpeg_data)); + + av_register_all(); + + /* TODO: settings */ + avformat_alloc_output_context2(&data->output, NULL, NULL, + "D:\\test.mp4"); + if (!data->output) { + blog(LOG_ERROR, "Couldn't create avformat context"); + goto fail; + } + + if (!init_streams(data)) + goto fail; + if (!open_output_file(data)) + goto fail; + + data->initialized = true; + return true; + +fail: + blog(LOG_ERROR, "ffmpeg_data_init failed"); + ffmpeg_data_free(data); + return false; +} + +/* ------------------------------------------------------------------------- */ + +const char *ffmpeg_output_getname(const char *locale) +{ + /* TODO: translation */ + return "FFmpeg file output"; +} + +struct ffmpeg_output *ffmpeg_output_create(const char *settings, + obs_output_t output) +{ + struct ffmpeg_output *data = bmalloc(sizeof(struct ffmpeg_output)); + memset(data, 0, sizeof(struct ffmpeg_output)); + + data->output = output; + + return data; +} + +void ffmpeg_output_destroy(struct ffmpeg_output *data) +{ + if (data) { + ffmpeg_data_free(&data->ff_data); + bfree(data); + } +} + +void ffmpeg_output_update(struct ffmpeg_output *data, const char *settings) +{ +} + +static void receive_video(void *param, const struct video_frame *frame) +{ +} + +static void receive_audio(void *param, const struct audio_data *frame) +{ +} + +bool ffmpeg_output_start(struct ffmpeg_output *data) +{ + video_t video = obs_video(); + audio_t audio = obs_audio(); + + if (!video || !audio) { + blog(LOG_ERROR, "ffmpeg_output_start: audio and video must " + "both be active (at least as of this writing)"); + return false; + } + + if (!ffmpeg_data_init(&data->ff_data)) + return false; + + struct audio_convert_info aci; + aci.samples_per_sec = 44100; + aci.format = AUDIO_FORMAT_16BIT; + aci.speakers = SPEAKERS_STEREO; + + struct video_convert_info vci; + vci.format = VIDEO_FORMAT_I420; + vci.width = 0; + vci.height = 0; + vci.row_align = 1; + + video_output_connect(video, &vci, receive_video, data); + audio_output_connect(audio, &aci, receive_audio, data); + data->active = true; + + return true; +} + +void ffmpeg_output_stop(struct ffmpeg_output *data) +{ + if (data->active) { + data->active = false; + video_output_disconnect(obs_video(), receive_video, data); + audio_output_disconnect(obs_audio(), receive_audio, data); + ffmpeg_data_free(&data->ff_data); + } +} + +bool ffmpeg_output_active(struct ffmpeg_output *data) +{ + return data->active; +} diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-output.h b/plugins/obs-ffmpeg/obs-ffmpeg-output.h new file mode 100644 index 000000000..67f29b4c2 --- /dev/null +++ b/plugins/obs-ffmpeg/obs-ffmpeg-output.h @@ -0,0 +1,62 @@ +/****************************************************************************** + Copyright (C) 2013 by Hugh Bailey + + 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 . +******************************************************************************/ + +#pragma once + +#include +#include + +#include +#include + +struct ffmpeg_data { + AVStream *video; + AVStream *audio; + AVCodec *acodec; + AVCodec *vcodec; + AVFormatContext *output; + struct SwsContext *swscale; + + AVFrame *vframe; + AVPicture src_picture; + AVPicture dst_picture; + + AVFrame *aframe; + uint8_t **samples; + + bool initialized; +}; + +struct ffmpeg_output { + obs_output_t output; + volatile bool active; + struct ffmpeg_data ff_data; +}; + +EXPORT const char *ffmpeg_output_getname(const char *locale); + +EXPORT struct ffmpeg_output *ffmpeg_output_create(const char *settings, + obs_output_t output); +EXPORT void ffmpeg_output_destroy(struct ffmpeg_output *data); + +EXPORT void ffmpeg_output_update(struct ffmpeg_output *data, + const char *settings); + +EXPORT bool ffmpeg_output_start(struct ffmpeg_output *data); +EXPORT void ffmpeg_output_stop(struct ffmpeg_output *data); + +EXPORT bool ffmpeg_output_active(struct ffmpeg_output *data); diff --git a/plugins/obs-ffmpeg/obs-ffmpeg.c b/plugins/obs-ffmpeg/obs-ffmpeg.c new file mode 100644 index 000000000..66d1a0392 --- /dev/null +++ b/plugins/obs-ffmpeg/obs-ffmpeg.c @@ -0,0 +1,14 @@ +#include +#include + +EXPORT const char *enum_outputs(size_t idx); + +static const char *outputs[] = {"obs_ffmpeg"}; + +const char *enum_outputs(size_t idx) +{ + if (idx >= sizeof(outputs)/sizeof(const char*)) + return NULL; + + return outputs[idx]; +} diff --git a/plugins/obs-outputs/obs-stream.c b/plugins/obs-outputs/rtmp-stream.c similarity index 98% rename from plugins/obs-outputs/obs-stream.c rename to plugins/obs-outputs/rtmp-stream.c index a7405c044..884dbc45e 100644 --- a/plugins/obs-outputs/obs-stream.c +++ b/plugins/obs-outputs/rtmp-stream.c @@ -15,7 +15,7 @@ along with this program. If not, see . ******************************************************************************/ -#include "obs-stream.h" +#include "rtmp-stream.h" const char *rtmp_stream_getname(const char *locale) { diff --git a/plugins/obs-outputs/obs-stream.h b/plugins/obs-outputs/rtmp-stream.h similarity index 100% rename from plugins/obs-outputs/obs-stream.h rename to plugins/obs-outputs/rtmp-stream.h diff --git a/vs/2013/OBS.sln b/vs/2013/OBS.sln index f82124e8b..a936c0a8b 100644 --- a/vs/2013/OBS.sln +++ b/vs/2013/OBS.sln @@ -40,6 +40,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OBS", "OBS\OBS.vcxproj", "{ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jansson", "..\..\deps\jansson\win32\vs2010\jansson.vcxproj", "{76226D20-1972-4789-A595-EDACC7A76DC3}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "obs-ffmpeg", "obs-ffmpeg\obs-ffmpeg.vcxproj", "{36970254-B1E5-4BE6-A561-301B6E7CDCE3}" + ProjectSection(ProjectDependencies) = postProject + {6F1AC2AE-6424-401A-AF9F-A771E6BEE026} = {6F1AC2AE-6424-401A-AF9F-A771E6BEE026} + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -120,6 +125,14 @@ Global {76226D20-1972-4789-A595-EDACC7A76DC3}.Release|Win32.Build.0 = Release|Win32 {76226D20-1972-4789-A595-EDACC7A76DC3}.Release|x64.ActiveCfg = Release|x64 {76226D20-1972-4789-A595-EDACC7A76DC3}.Release|x64.Build.0 = Release|x64 + {36970254-B1E5-4BE6-A561-301B6E7CDCE3}.Debug|Win32.ActiveCfg = Debug|Win32 + {36970254-B1E5-4BE6-A561-301B6E7CDCE3}.Debug|Win32.Build.0 = Debug|Win32 + {36970254-B1E5-4BE6-A561-301B6E7CDCE3}.Debug|x64.ActiveCfg = Debug|x64 + {36970254-B1E5-4BE6-A561-301B6E7CDCE3}.Debug|x64.Build.0 = Debug|x64 + {36970254-B1E5-4BE6-A561-301B6E7CDCE3}.Release|Win32.ActiveCfg = Release|Win32 + {36970254-B1E5-4BE6-A561-301B6E7CDCE3}.Release|Win32.Build.0 = Release|Win32 + {36970254-B1E5-4BE6-A561-301B6E7CDCE3}.Release|x64.ActiveCfg = Release|x64 + {36970254-B1E5-4BE6-A561-301B6E7CDCE3}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/vs/2013/obs-ffmpeg/obs-ffmpeg.vcxproj b/vs/2013/obs-ffmpeg/obs-ffmpeg.vcxproj new file mode 100644 index 000000000..9669c4e97 --- /dev/null +++ b/vs/2013/obs-ffmpeg/obs-ffmpeg.vcxproj @@ -0,0 +1,183 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {36970254-B1E5-4BE6-A561-301B6E7CDCE3} + Win32Proj + obsffmpeg + + + + DynamicLibrary + true + v120 + Unicode + + + DynamicLibrary + true + v120 + Unicode + + + DynamicLibrary + false + v120 + true + Unicode + + + DynamicLibrary + false + v120 + true + Unicode + + + + + + + + + + + + + + + + + + + true + $(FFmpegPath);$(IncludePath) + $(FFmpegPath)\lib32;$(FFmpegPath)\libavcodec;$(FFmpegPath)\libavutil;$(FFmpegPath)\libavformat;$(FFmpegPath)\libswresample;$(FFmpegPath)\libswscale;$(LibraryPath) + + + true + $(FFmpegPath);$(IncludePath) + $(FFmpegPath)\lib64;$(FFmpegPath)\libavcodec;$(FFmpegPath)\libavutil;$(FFmpegPath)\libavformat;$(FFmpegPath)\libswresample;$(FFmpegPath)\libswscale;$(LibraryPath) + + + false + $(FFmpegPath);$(IncludePath) + $(FFmpegPath)\lib32;$(FFmpegPath)\libavcodec;$(FFmpegPath)\libavutil;$(FFmpegPath)\libavformat;$(FFmpegPath)\libswresample;$(FFmpegPath)\libswscale;$(LibraryPath) + + + false + $(FFmpegPath);$(IncludePath) + $(FFmpegPath)\lib64;$(FFmpegPath)\libavcodec;$(FFmpegPath)\libavutil;$(FFmpegPath)\libavformat;$(FFmpegPath)\libswresample;$(FFmpegPath)\libswscale;$(LibraryPath) + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;OBSFFMPEG_EXPORTS;%(PreprocessorDefinitions) + ../../../libobs + + + Windows + true + $(OutDir);%(AdditionalLibraryDirectories) + avcodec.lib;avformat.lib;swscale.lib;avutil.lib;libobs.lib;%(AdditionalDependencies) + + + copy "$(OutDir)$(TargetName)$(TargetExt)" "../../../build/plugins/32bit/$(TargetName)$(TargetExt)" + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;OBSFFMPEG_EXPORTS;%(PreprocessorDefinitions) + ../../../libobs + + + Windows + true + $(OutDir);%(AdditionalLibraryDirectories) + avcodec.lib;avformat.lib;swscale.lib;avutil.lib;libobs.lib;%(AdditionalDependencies) + + + copy "$(OutDir)$(TargetName)$(TargetExt)" "../../../build/plugins/64bit/$(TargetName)$(TargetExt)" + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;OBSFFMPEG_EXPORTS;%(PreprocessorDefinitions) + ../../../libobs + + + Windows + true + true + true + $(OutDir);%(AdditionalLibraryDirectories) + avcodec.lib;avformat.lib;swscale.lib;avutil.lib;libobs.lib;%(AdditionalDependencies) + + + copy "$(OutDir)$(TargetName)$(TargetExt)" "../../../build/plugins/32bit/$(TargetName)$(TargetExt)" + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;OBSFFMPEG_EXPORTS;%(PreprocessorDefinitions) + ../../../libobs + + + Windows + true + true + true + $(OutDir);%(AdditionalLibraryDirectories) + avcodec.lib;avformat.lib;swscale.lib;avutil.lib;libobs.lib;%(AdditionalDependencies) + + + copy "$(OutDir)$(TargetName)$(TargetExt)" "../../../build/plugins/64bit/$(TargetName)$(TargetExt)" + + + + + + + + + + + + + \ No newline at end of file diff --git a/vs/2013/obs-ffmpeg/obs-ffmpeg.vcxproj.filters b/vs/2013/obs-ffmpeg/obs-ffmpeg.vcxproj.filters new file mode 100644 index 000000000..9f5287c60 --- /dev/null +++ b/vs/2013/obs-ffmpeg/obs-ffmpeg.vcxproj.filters @@ -0,0 +1,30 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + + + Header Files + + + \ No newline at end of file diff --git a/vs/2013/obs-outputs/obs-outputs.vcxproj b/vs/2013/obs-outputs/obs-outputs.vcxproj index 12e19fcc4..381497994 100644 --- a/vs/2013/obs-outputs/obs-outputs.vcxproj +++ b/vs/2013/obs-outputs/obs-outputs.vcxproj @@ -91,7 +91,11 @@ Windows true libobs.lib;%(AdditionalDependencies) + $(OutDir);%(AdditionalLibraryDirectories) + + copy "$(OutDir)$(TargetName)$(TargetExt)" "../../../build/plugins/32bit/$(TargetName)$(TargetExt)" + @@ -106,7 +110,11 @@ Windows true libobs.lib;%(AdditionalDependencies) + $(OutDir);%(AdditionalLibraryDirectories) + + copy "$(OutDir)$(TargetName)$(TargetExt)" "../../../build/plugins/64bit/$(TargetName)$(TargetExt)" + @@ -125,7 +133,11 @@ true true libobs.lib;%(AdditionalDependencies) + $(OutDir);%(AdditionalLibraryDirectories) + + copy "$(OutDir)$(TargetName)$(TargetExt)" "../../../build/plugins/32bit/$(TargetName)$(TargetExt)" + @@ -144,7 +156,11 @@ true true libobs.lib;%(AdditionalDependencies) + $(OutDir);%(AdditionalLibraryDirectories) + + copy "$(OutDir)$(TargetName)$(TargetExt)" "../../../build/plugins/64bit/$(TargetName)$(TargetExt)" + diff --git a/vs/2013/obs-outputs/obs-outputs.vcxproj.filters b/vs/2013/obs-outputs/obs-outputs.vcxproj.filters index 386f7c70a..5c59bfa57 100644 --- a/vs/2013/obs-outputs/obs-outputs.vcxproj.filters +++ b/vs/2013/obs-outputs/obs-outputs.vcxproj.filters @@ -15,21 +15,21 @@ - - Header Files - Header Files Header Files + + Header Files + - + Source Files - + Source Files