mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	media-session: add and parse channelmap in routes and stream
This commit is contained in:
		
							parent
							
								
									231c3c8b8e
								
							
						
					
					
						commit
						2b95afeddc
					
				
					 2 changed files with 104 additions and 1 deletions
				
			
		| 
						 | 
					@ -115,6 +115,26 @@ static void add_idle_timeout(struct impl *impl)
 | 
				
			||||||
	pw_loop_update_timer(main_loop, impl->idle_timeout, &value, NULL, false);
 | 
						pw_loop_update_timer(main_loop, impl->idle_timeout, &value, NULL, false);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint32_t channel_from_name(const char *name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
						for (i = 0; spa_type_audio_channel[i].name; i++) {
 | 
				
			||||||
 | 
							if (strcmp(name, spa_debug_type_short_name(spa_type_audio_channel[i].name)) == 0)
 | 
				
			||||||
 | 
								return spa_type_audio_channel[i].type;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return SPA_AUDIO_CHANNEL_UNKNOWN;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char *channel_to_name(uint32_t channel)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
						for (i = 0; spa_type_audio_channel[i].name; i++) {
 | 
				
			||||||
 | 
							if (spa_type_audio_channel[i].type == channel)
 | 
				
			||||||
 | 
								return spa_debug_type_short_name(spa_type_audio_channel[i].name);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return "UNK";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static char *serialize_props(struct device *dev, const struct spa_pod *param)
 | 
					static char *serialize_props(struct device *dev, const struct spa_pod *param)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_pod_prop *prop;
 | 
						struct spa_pod_prop *prop;
 | 
				
			||||||
| 
						 | 
					@ -152,6 +172,20 @@ static char *serialize_props(struct device *dev, const struct spa_pod *param)
 | 
				
			||||||
			fprintf(f, " ]");
 | 
								fprintf(f, " ]");
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							case SPA_PROP_channelMap:
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								uint32_t i, n_vals;
 | 
				
			||||||
 | 
								uint32_t map[SPA_AUDIO_MAX_CHANNELS];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								n_vals = spa_pod_copy_array(&prop->value, SPA_TYPE_Id,
 | 
				
			||||||
 | 
										map, SPA_AUDIO_MAX_CHANNELS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								fprintf(f, "%s\"channels\": [", (comma ? ", " : ""));
 | 
				
			||||||
 | 
								for (i = 0; i < n_vals; i++)
 | 
				
			||||||
 | 
									fprintf(f, "%s\"%s\"", (i == 0 ? " " : ", "), channel_to_name(map[i]));
 | 
				
			||||||
 | 
								fprintf(f, " ]");
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -216,6 +250,23 @@ static int restore_route(struct device *dev, const char *val, uint32_t index, ui
 | 
				
			||||||
			spa_pod_builder_prop(&b, SPA_PROP_channelVolumes, 0);
 | 
								spa_pod_builder_prop(&b, SPA_PROP_channelVolumes, 0);
 | 
				
			||||||
			spa_pod_builder_array(&b, sizeof(float), SPA_TYPE_Float,
 | 
								spa_pod_builder_array(&b, sizeof(float), SPA_TYPE_Float,
 | 
				
			||||||
					n_vols, vols);
 | 
										n_vols, vols);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else if (strncmp(value, "\"channels\"", len) == 0) {
 | 
				
			||||||
 | 
								uint32_t n_ch;
 | 
				
			||||||
 | 
								uint32_t map[SPA_AUDIO_MAX_CHANNELS];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (spa_json_enter_array(&it[1], &it[2]) <= 0)
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								for (n_ch = 0; n_ch < SPA_AUDIO_MAX_CHANNELS; n_ch++) {
 | 
				
			||||||
 | 
									char chname[16];
 | 
				
			||||||
 | 
					                                if (spa_json_get_string(&it[2], chname, sizeof(chname)) <= 0)
 | 
				
			||||||
 | 
					                                        break;
 | 
				
			||||||
 | 
									map[n_ch] = channel_from_name(chname);
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
								spa_pod_builder_prop(&b, SPA_PROP_channelMap, 0);
 | 
				
			||||||
 | 
								spa_pod_builder_array(&b, sizeof(uint32_t), SPA_TYPE_Id,
 | 
				
			||||||
 | 
										n_ch, map);
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			if (spa_json_next(&it[1], &value) <= 0)
 | 
								if (spa_json_next(&it[1], &value) <= 0)
 | 
				
			||||||
                                break;
 | 
					                                break;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -122,6 +122,26 @@ static void session_destroy(void *data)
 | 
				
			||||||
	free(impl);
 | 
						free(impl);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint32_t channel_from_name(const char *name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
						for (i = 0; spa_type_audio_channel[i].name; i++) {
 | 
				
			||||||
 | 
							if (strcmp(name, spa_debug_type_short_name(spa_type_audio_channel[i].name)) == 0)
 | 
				
			||||||
 | 
								return spa_type_audio_channel[i].type;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return SPA_AUDIO_CHANNEL_UNKNOWN;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char *channel_to_name(uint32_t channel)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
						for (i = 0; spa_type_audio_channel[i].name; i++) {
 | 
				
			||||||
 | 
							if (spa_type_audio_channel[i].type == channel)
 | 
				
			||||||
 | 
								return spa_debug_type_short_name(spa_type_audio_channel[i].name);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return "UNK";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static char *serialize_props(struct stream *str, const struct spa_pod *param)
 | 
					static char *serialize_props(struct stream *str, const struct spa_pod *param)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_pod_prop *prop;
 | 
						struct spa_pod_prop *prop;
 | 
				
			||||||
| 
						 | 
					@ -159,13 +179,28 @@ static char *serialize_props(struct stream *str, const struct spa_pod *param)
 | 
				
			||||||
			fprintf(f, " ]");
 | 
								fprintf(f, " ]");
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							case SPA_PROP_channelMap:
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								uint32_t i, n_ch;
 | 
				
			||||||
 | 
								uint32_t map[SPA_AUDIO_MAX_CHANNELS];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								n_ch = spa_pod_copy_array(&prop->value, SPA_TYPE_Id,
 | 
				
			||||||
 | 
										map, SPA_AUDIO_MAX_CHANNELS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								fprintf(f, "%s\"channels\": [", (comma ? ", " : ""));
 | 
				
			||||||
 | 
								for (i = 0; i < n_ch; i++)
 | 
				
			||||||
 | 
									fprintf(f, "%s\"%s\"", (i == 0 ? " ":", "), channel_to_name(map[i]));
 | 
				
			||||||
 | 
								fprintf(f, " ]");
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		comma = true;
 | 
							comma = true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (str->obj->target_node != NULL)
 | 
						if (str->obj->target_node != NULL)
 | 
				
			||||||
		fprintf(f, "\"target-node\": \"%s\"", str->obj->target_node);
 | 
							fprintf(f, "%s\"target-node\": \"%s\"",
 | 
				
			||||||
 | 
									(comma ? ", " : ""), str->obj->target_node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fprintf(f, " }");
 | 
						fprintf(f, " }");
 | 
				
			||||||
        fclose(f);
 | 
					        fclose(f);
 | 
				
			||||||
| 
						 | 
					@ -279,6 +314,23 @@ static int restore_stream(struct stream *str, const char *val)
 | 
				
			||||||
			spa_pod_builder_array(&b, sizeof(float), SPA_TYPE_Float,
 | 
								spa_pod_builder_array(&b, sizeof(float), SPA_TYPE_Float,
 | 
				
			||||||
					n_vols, vols);
 | 
										n_vols, vols);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							else if (strncmp(value, "\"channels\"", len) == 0) {
 | 
				
			||||||
 | 
								uint32_t n_ch;
 | 
				
			||||||
 | 
								uint32_t map[SPA_AUDIO_MAX_CHANNELS];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (spa_json_enter_array(&it[1], &it[2]) <= 0)
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								for (n_ch = 0; n_ch < SPA_AUDIO_MAX_CHANNELS; n_ch++) {
 | 
				
			||||||
 | 
									char chname[16];
 | 
				
			||||||
 | 
					                                if (spa_json_get_string(&it[2], chname, sizeof(chname)) <= 0)
 | 
				
			||||||
 | 
					                                        break;
 | 
				
			||||||
 | 
									map[n_ch] = channel_from_name(chname);
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
								spa_pod_builder_prop(&b, SPA_PROP_channelMap, 0);
 | 
				
			||||||
 | 
								spa_pod_builder_array(&b, sizeof(uint32_t), SPA_TYPE_Id,
 | 
				
			||||||
 | 
										n_ch, map);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		else if (strncmp(value, "\"target-node\"", len) == 0) {
 | 
							else if (strncmp(value, "\"target-node\"", len) == 0) {
 | 
				
			||||||
			char name[1024];
 | 
								char name[1024];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue