forked from CoSMoSoftware/OBS-studio-webrtc
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add millicast support (closes CoSMoSoftware#36)
- Loading branch information
1 parent
6a2d062
commit 6554179
Showing
16 changed files
with
653 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
#include <stdio.h> | ||
#include <obs-module.h> | ||
#include <obs-avc.h> | ||
#include <util/platform.h> | ||
#include <util/dstr.h> | ||
#include <util/threading.h> | ||
#include <inttypes.h> | ||
#include <rtc_base/platform_file.h> | ||
#include <rtc_base/bitrateallocationstrategy.h> | ||
#include <modules/audio_processing/include/audio_processing.h> | ||
|
||
#define warn(format, ...) blog(LOG_WARNING, format, ##__VA_ARGS__) | ||
#define info(format, ...) blog(LOG_INFO, format, ##__VA_ARGS__) | ||
#define debug(format, ...) blog(LOG_DEBUG, format, ##__VA_ARGS__) | ||
|
||
#define OPT_DROP_THRESHOLD "drop_threshold_ms" | ||
#define OPT_PFRAME_DROP_THRESHOLD "pframe_drop_threshold_ms" | ||
#define OPT_MAX_SHUTDOWN_TIME_SEC "max_shutdown_time_sec" | ||
#define OPT_BIND_IP "bind_ip" | ||
#define OPT_NEWSOCKETLOOP_ENABLED "new_socket_loop_enabled" | ||
#define OPT_LOWLATENCY_ENABLED "low_latency_mode_enabled" | ||
|
||
#include "WebRTCStream.h" | ||
|
||
extern "C" const char *millicast_stream_getname(void *unused) | ||
{ | ||
info("millicast_stream_getname"); | ||
UNUSED_PARAMETER(unused); | ||
return obs_module_text("MILLICASTStream"); | ||
} | ||
|
||
|
||
extern "C" void millicast_stream_destroy(void *data) | ||
{ | ||
info("millicast_stream_destroy"); | ||
//Get stream | ||
WebRTCStream* stream = (WebRTCStream*)data; | ||
//Stop it | ||
stream->stop(); | ||
//Remove ref and let it self destroy | ||
stream->Release(); | ||
} | ||
|
||
extern "C" void *millicast_stream_create(obs_data_t *settings, obs_output_t *output) | ||
{ | ||
info("millicast_stream_create"); | ||
//Create new stream | ||
WebRTCStream* stream = new WebRTCStream(output); | ||
//Don't allow it to be deleted | ||
stream->AddRef(); | ||
//Return it | ||
return (void*)stream; | ||
} | ||
|
||
extern "C" void millicast_stream_stop(void *data, uint64_t ts) | ||
{ | ||
info("millicast_stream_stop"); | ||
//Get stream | ||
WebRTCStream* stream = (WebRTCStream*)data; | ||
//Stop it | ||
stream->stop(); | ||
//Remove ref and let it self destroy | ||
stream->Release(); | ||
} | ||
|
||
extern "C" bool millicast_stream_start(void *data) | ||
{ | ||
info("millicast_stream_start"); | ||
//Get stream | ||
WebRTCStream* stream = (WebRTCStream*)data; | ||
//Don't allow it to be deleted | ||
stream->AddRef(); | ||
//Start it | ||
return stream->start(WebRTCStream::Millicast); | ||
} | ||
|
||
extern "C" void millicast_receive_video(void *data, struct video_data *frame) | ||
{ | ||
//Get stream | ||
WebRTCStream* stream = (WebRTCStream*)data; | ||
//Process audio | ||
stream->onVideoFrame(frame); | ||
} | ||
extern "C" void millicast_receive_audio(void *data, struct audio_data *frame) | ||
{ | ||
//Get stream | ||
WebRTCStream* stream = (WebRTCStream*)data; | ||
//Process audio | ||
stream->onAudioFrame(frame); | ||
} | ||
|
||
extern "C" void millicast_stream_defaults(obs_data_t *defaults) | ||
{ | ||
info("millicast_stream_defaults"); | ||
obs_data_set_default_int(defaults, OPT_DROP_THRESHOLD, 700); | ||
obs_data_set_default_int(defaults, OPT_PFRAME_DROP_THRESHOLD, 900); | ||
obs_data_set_default_int(defaults, OPT_MAX_SHUTDOWN_TIME_SEC, 30); | ||
obs_data_set_default_string(defaults, OPT_BIND_IP, "default"); | ||
obs_data_set_default_bool(defaults, OPT_NEWSOCKETLOOP_ENABLED, false); | ||
obs_data_set_default_bool(defaults, OPT_LOWLATENCY_ENABLED, false); | ||
} | ||
|
||
extern "C" obs_properties_t *millicast_stream_properties(void *unused) | ||
{ | ||
info("millicast_stream_properties"); | ||
UNUSED_PARAMETER(unused); | ||
|
||
obs_properties_t *props = obs_properties_create(); | ||
|
||
obs_properties_add_int(props, OPT_DROP_THRESHOLD, | ||
obs_module_text("MILLICASTStream.DropThreshold"), | ||
200, 10000, 100); | ||
|
||
obs_properties_add_bool(props, OPT_NEWSOCKETLOOP_ENABLED, | ||
obs_module_text("MILLICASTStream.NewSocketLoop")); | ||
obs_properties_add_bool(props, OPT_LOWLATENCY_ENABLED, | ||
obs_module_text("MILLICASTStream.LowLatencyMode")); | ||
|
||
return props; | ||
} | ||
|
||
extern "C" uint64_t millicast_stream_total_bytes_sent(void *data) | ||
{ | ||
//Get stream | ||
WebRTCStream* stream = (WebRTCStream*)data; | ||
return stream->getBitrate (); | ||
} | ||
|
||
extern "C" int millicast_stream_dropped_frames(void *data) | ||
{ | ||
return 0; | ||
} | ||
|
||
extern "C" float millicast_stream_congestion(void *data) | ||
{ | ||
return 0.0f; | ||
} | ||
|
||
extern "C" { | ||
struct obs_output_info millicast_output_info = { | ||
"millicast_output", //id | ||
OBS_OUTPUT_AV | OBS_OUTPUT_SERVICE | OBS_OUTPUT_MULTI_TRACK, //flags | ||
millicast_stream_getname, //get_name | ||
millicast_stream_create, //create | ||
millicast_stream_destroy, //destroy | ||
millicast_stream_start, //start | ||
millicast_stream_stop, //stop | ||
millicast_receive_video, //raw_video | ||
millicast_receive_audio, //raw_audio | ||
nullptr, //encoded_packet | ||
nullptr, //update | ||
millicast_stream_defaults, //get_defaults | ||
millicast_stream_properties, //get_properties | ||
nullptr, //pause | ||
millicast_stream_total_bytes_sent, //get_total_bytes | ||
millicast_stream_dropped_frames, //get_dropped_frame | ||
nullptr, //type_data | ||
nullptr, ////free_type_data | ||
millicast_stream_congestion, //get_congestion | ||
nullptr, //get_connect_time_ms | ||
"vp8", //encoded_video_codecs | ||
"opus" //encoded_audio_codecs | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
#include <obs-module.h> | ||
#include <obs-avc.h> | ||
#include <util/platform.h> | ||
#include <util/circlebuf.h> | ||
#include <util/dstr.h> | ||
#include <util/threading.h> | ||
#include <inttypes.h> | ||
#include "librtmp/rtmp.h" | ||
#include "librtmp/log.h" | ||
#include "flv-mux.h" | ||
#include "net-if.h" | ||
|
||
#ifdef _WIN32 | ||
#include <Iphlpapi.h> | ||
#else | ||
#include <sys/ioctl.h> | ||
#endif | ||
|
||
#define do_log(level, format, ...) \ | ||
blog(level, "[spankchain stream: '%s'] " format, \ | ||
obs_output_get_name(stream->output), ##__VA_ARGS__) | ||
|
||
#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) | ||
#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) | ||
#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__) | ||
|
||
#define OPT_DROP_THRESHOLD "drop_threshold_ms" | ||
#define OPT_PFRAME_DROP_THRESHOLD "pframe_drop_threshold_ms" | ||
#define OPT_MAX_SHUTDOWN_TIME_SEC "max_shutdown_time_sec" | ||
#define OPT_BIND_IP "bind_ip" | ||
#define OPT_NEWSOCKETLOOP_ENABLED "new_socket_loop_enabled" | ||
#define OPT_LOWLATENCY_ENABLED "low_latency_mode_enabled" | ||
|
||
//#define TEST_FRAMEDROPS | ||
|
||
#ifdef TEST_FRAMEDROPS | ||
|
||
#define DROPTEST_MAX_KBPS 3000 | ||
#define DROPTEST_MAX_BYTES (DROPTEST_MAX_KBPS * 1000 / 8) | ||
|
||
struct droptest_info { | ||
uint64_t ts; | ||
size_t size; | ||
}; | ||
#endif | ||
|
||
struct spankchain_stream { | ||
obs_output_t *output; | ||
|
||
pthread_mutex_t packets_mutex; | ||
struct circlebuf packets; | ||
bool sent_headers; | ||
|
||
volatile bool connecting; | ||
pthread_t connect_thread; | ||
|
||
volatile bool active; | ||
volatile bool disconnected; | ||
pthread_t send_thread; | ||
|
||
int max_shutdown_time_sec; | ||
|
||
os_sem_t *send_sem; | ||
os_event_t *stop_event; | ||
uint64_t stop_ts; | ||
uint64_t shutdown_timeout_ts; | ||
|
||
struct dstr path, key; | ||
struct dstr username, password; | ||
struct dstr encoder_name; | ||
struct dstr bind_ip; | ||
|
||
/* frame drop variables */ | ||
int64_t drop_threshold_usec; | ||
int64_t min_drop_dts_usec; | ||
int64_t pframe_drop_threshold_usec; | ||
int64_t pframe_min_drop_dts_usec; | ||
int min_priority; | ||
float congestion; | ||
|
||
int64_t last_dts_usec; | ||
|
||
uint64_t total_bytes_sent; | ||
int dropped_frames; | ||
|
||
#ifdef TEST_FRAMEDROPS | ||
struct circlebuf droptest_info; | ||
size_t droptest_size; | ||
#endif | ||
|
||
RTMP rtmp; | ||
|
||
bool new_socket_loop; | ||
bool low_latency_mode; | ||
bool disable_send_window_optimization; | ||
bool socket_thread_active; | ||
pthread_t socket_thread; | ||
uint8_t *write_buf; | ||
size_t write_buf_len; | ||
size_t write_buf_size; | ||
pthread_mutex_t write_buf_mutex; | ||
os_event_t *buffer_space_available_event; | ||
os_event_t *buffer_has_data_event; | ||
os_event_t *socket_available_event; | ||
os_event_t *send_thread_signaled_exit; | ||
}; | ||
|
||
#ifdef _WIN32 | ||
void *socket_thread_windows(void *data); | ||
#endif | ||
|
Oops, something went wrong.