Selaa lähdekoodia

libobs: Change service max res. to res. list

(This commit also modifies rtmp-services and UI)

Changes the maximum resolution size to a resolution list, and splits the
maximum FPS to its own function.

(Note: ABI has not been modified because the last changes still haven't
been released yet, so it's safe to modify this as long as the changes
haven't been officially released)
jp9000 5 vuotta sitten
vanhempi
sitoutus
ebbe8d1bf9

+ 33 - 7
UI/window-basic-auto-config-test.cpp

@@ -963,6 +963,27 @@ void AutoConfigTestPage::TestRecordingEncoderThread()
 #define QUALITY_SAME "Basic.Settings.Output.Simple.RecordingQuality.Stream"
 #define QUALITY_HIGH "Basic.Settings.Output.Simple.RecordingQuality.Small"
 
+void set_closest_res(int &cx, int &cy, struct obs_service_resolution *res_list,
+		     size_t count)
+{
+	int best_pixel_diff = 0x7FFFFFFF;
+	int start_cx = cx;
+	int start_cy = cy;
+
+	for (size_t i = 0; i < count; i++) {
+		struct obs_service_resolution &res = res_list[i];
+		int pixel_cx_diff = abs(start_cx - res.cx);
+		int pixel_cy_diff = abs(start_cy - res.cy);
+		int pixel_diff = pixel_cx_diff + pixel_cy_diff;
+
+		if (pixel_diff < best_pixel_diff) {
+			best_pixel_diff = pixel_diff;
+			cx = res.cx;
+			cy = res.cy;
+		}
+	}
+}
+
 void AutoConfigTestPage::FinalizeResults()
 {
 	ui->stackedWidget->setCurrentIndex(1);
@@ -1013,13 +1034,18 @@ void AutoConfigTestPage::FinalizeResults()
 		obs_service_apply_encoder_settings(service, vencoder_settings,
 						   nullptr);
 
-		int maxCX, maxCY, maxFPS;
-		obs_service_get_max_res_fps(service, &maxCX, &maxCY, &maxFPS);
-
-		if (maxCX && wiz->idealResolutionCX > maxCX)
-			wiz->idealResolutionCX = maxCX;
-		if (maxCY && wiz->idealResolutionCY > maxCY)
-			wiz->idealResolutionCY = maxCY;
+		struct obs_service_resolution *res_list;
+		size_t res_count;
+		int maxFPS;
+		obs_service_get_supported_resolutions(service, &res_list,
+						      &res_count);
+		obs_service_get_max_fps(service, &maxFPS);
+
+		if (res_list) {
+			set_closest_res(wiz->idealResolutionCX,
+					wiz->idealResolutionCY, res_list,
+					res_count);
+		}
 		if (maxFPS) {
 			double idealFPS = (double)wiz->idealFPSNum /
 					  (double)wiz->idealFPSDen;

+ 26 - 12
libobs/obs-service.c

@@ -419,22 +419,36 @@ const char *obs_service_get_output_type(const obs_service_t *service)
 	return NULL;
 }
 
-void obs_service_get_max_res_fps(const obs_service_t *service, int *cx, int *cy,
-				 int *fps)
+void obs_service_get_supported_resolutions(
+	const obs_service_t *service,
+	struct obs_service_resolution **resolutions, size_t *count)
 {
-	if (cx)
-		*cx = 0;
-	if (cy)
-		*cy = 0;
-	if (fps)
-		*fps = 0;
+	if (!obs_service_valid(service, "obs_service_supported_resolutions"))
+		return;
+	if (!obs_ptr_valid(resolutions, "obs_service_supported_resolutions"))
+		return;
+	if (!obs_ptr_valid(count, "obs_service_supported_resolutions"))
+		return;
 
-	if (!obs_service_valid(service, "obs_service_get_max_res_fps"))
+	*resolutions = NULL;
+	*count = 0;
+
+	if (service->info.get_supported_resolutions)
+		service->info.get_supported_resolutions(service->context.data,
+							resolutions, count);
+}
+
+void obs_service_get_max_fps(const obs_service_t *service, int *fps)
+{
+	if (!obs_service_valid(service, "obs_service_get_max_fps"))
 		return;
+	if (!obs_ptr_valid(fps, "obs_service_get_max_fps"))
+		return;
+
+	*fps = 0;
 
-	if (service->info.get_max_res_fps)
-		service->info.get_max_res_fps(service->context.data, cx, cy,
-					      fps);
+	if (service->info.get_max_fps)
+		service->info.get_max_fps(service->context.data, fps);
 }
 
 void obs_service_get_max_bitrate(const obs_service_t *service,

+ 9 - 1
libobs/obs-service.h

@@ -28,6 +28,11 @@
 extern "C" {
 #endif
 
+struct obs_service_resolution {
+	int cx;
+	int cy;
+};
+
 struct obs_service_info {
 	/* required */
 	const char *id;
@@ -74,7 +79,10 @@ struct obs_service_info {
 
 	const char *(*get_output_type)(void *data);
 
-	void (*get_max_res_fps)(void *data, int *cx, int *cy, int *fps);
+	void (*get_supported_resolutions)(
+		void *data, struct obs_service_resolution **resolutions,
+		size_t *count);
+	void (*get_max_fps)(void *data, int *fps);
 
 	void (*get_max_bitrate)(void *data, int *video_bitrate,
 				int *audio_bitrate);

+ 4 - 2
libobs/obs.h

@@ -2231,8 +2231,10 @@ EXPORT void *obs_service_get_type_data(obs_service_t *service);
 
 EXPORT const char *obs_service_get_id(const obs_service_t *service);
 
-EXPORT void obs_service_get_max_res_fps(const obs_service_t *service, int *cx,
-					int *cy, int *fps);
+EXPORT void obs_service_get_supported_resolutions(
+	const obs_service_t *service,
+	struct obs_service_resolution **resolutions, size_t *count);
+EXPORT void obs_service_get_max_fps(const obs_service_t *service, int *fps);
 
 EXPORT void obs_service_get_max_bitrate(const obs_service_t *service,
 					int *video_bitrate, int *audio_bitrate);

+ 2 - 2
plugins/rtmp-services/data/package.json

@@ -1,10 +1,10 @@
 {
 	"url": "https://obsproject.com/obs2_update/rtmp-services",
-	"version": 151,
+	"version": 160,
 	"files": [
 		{
 			"name": "services.json",
-			"version": 151
+			"version": 160
 		}
 	]
 }

+ 5 - 2
plugins/rtmp-services/data/services.json

@@ -477,8 +477,11 @@
             "recommended": {
                 "keyint": 2,
                 "profile": "main",
-                "max width": 1280,
-                "max height": 720,
+                "supported resolutions": [
+                    "1280x720",
+                    "852x480",
+                    "480x360"
+                ],
                 "max fps": 30,
                 "max video bitrate": 6000,
                 "max audio bitrate": 128

+ 47 - 14
plugins/rtmp-services/rtmp-common.c

@@ -16,8 +16,8 @@ struct rtmp_common {
 	char *key;
 
 	char *output;
-	int max_cx;
-	int max_cy;
+	struct obs_service_resolution *supported_resolutions;
+	size_t supported_resolutions_count;
 	int max_fps;
 
 	bool supports_additional_audio_track;
@@ -77,8 +77,34 @@ static void update_recommendations(struct rtmp_common *service, json_t *rec)
 	if (out)
 		service->output = bstrdup(out);
 
-	service->max_cx = get_int_val(rec, "max width");
-	service->max_cy = get_int_val(rec, "max height");
+	json_t *sr = json_object_get(rec, "supported resolutions");
+	if (sr && json_is_array(sr)) {
+		DARRAY(struct obs_service_resolution) res_list;
+		json_t *res_obj;
+		size_t index;
+
+		da_init(res_list);
+
+		json_array_foreach (sr, index, res_obj) {
+			if (!json_is_string(res_obj))
+				continue;
+
+			const char *res_str = json_string_value(res_obj);
+			struct obs_service_resolution res;
+			if (sscanf(res_str, "%dx%d", &res.cx, &res.cy) != 2)
+				continue;
+			if (res.cx <= 0 || res.cy <= 0)
+				continue;
+
+			da_push_back(res_list, &res);
+		}
+
+		if (res_list.num) {
+			service->supported_resolutions = res_list.array;
+			service->supported_resolutions_count = res_list.num;
+		}
+	}
+
 	service->max_fps = get_int_val(rec, "max fps");
 }
 
@@ -90,14 +116,15 @@ static void rtmp_common_update(void *data, obs_data_t *settings)
 	bfree(service->server);
 	bfree(service->output);
 	bfree(service->key);
+	bfree(service->supported_resolutions);
 
 	service->service = bstrdup(obs_data_get_string(settings, "service"));
 	service->server = bstrdup(obs_data_get_string(settings, "server"));
 	service->key = bstrdup(obs_data_get_string(settings, "key"));
 	service->supports_additional_audio_track = false;
 	service->output = NULL;
-	service->max_cx = 0;
-	service->max_cy = 0;
+	service->supported_resolutions = NULL;
+	service->supported_resolutions_count = 0;
 	service->max_fps = 0;
 
 	json_t *root = open_services_file();
@@ -131,6 +158,7 @@ static void rtmp_common_destroy(void *data)
 {
 	struct rtmp_common *service = data;
 
+	bfree(service->supported_resolutions);
 	bfree(service->service);
 	bfree(service->server);
 	bfree(service->output);
@@ -679,15 +707,19 @@ static bool supports_multitrack(void *data)
 	return service->supports_additional_audio_track;
 }
 
-static void rtmp_common_get_max_res_fps(void *data, int *cx, int *cy, int *fps)
+static void rtmp_common_get_supported_resolutions(
+	void *data, struct obs_service_resolution **resolutions, size_t *count)
+{
+	struct rtmp_common *service = data;
+	*count = service->supported_resolutions_count;
+	*resolutions = bmemdup(service->supported_resolutions,
+			       *count * sizeof(struct obs_service_resolution));
+}
+
+static void rtmp_common_get_max_fps(void *data, int *fps)
 {
 	struct rtmp_common *service = data;
-	if (cx)
-		*cx = service->max_cx;
-	if (cy)
-		*cy = service->max_cy;
-	if (fps)
-		*fps = service->max_fps;
+	*fps = service->max_fps;
 }
 
 static void rtmp_common_get_max_bitrate(void *data, int *video_bitrate,
@@ -737,6 +769,7 @@ struct obs_service_info rtmp_common_service = {
 	.get_key = rtmp_common_key,
 	.apply_encoder_settings = rtmp_common_apply_settings,
 	.get_output_type = rtmp_common_get_output_type,
-	.get_max_res_fps = rtmp_common_get_max_res_fps,
+	.get_supported_resolutions = rtmp_common_get_supported_resolutions,
+	.get_max_fps = rtmp_common_get_max_fps,
 	.get_max_bitrate = rtmp_common_get_max_bitrate,
 };