# Spatial layers has lower resolution

**URL:** https://mediasoup.discourse.group/t/spatial-layers-has-lower-resolution/2778
**Category:** Integration
**Created:** [May 10, 2021, 7:18am UTC](https://mediasoup.discourse.group/t/spatial-layers-has-lower-resolution/2778 "2021-05-10T07:18:19Z")
**Posts on this page:** 18
**Page:** 1

<div class="post-metadata">

### Author: ![piranna](https://yyz2.discourse-cdn.com/free1/user_avatar/mediasoup.discourse.group/piranna/32/934_2.png) [@piranna](https://mediasoup.discourse.group/u/piranna)
#### Post date: [May 10, 2021, 7:18am UTC](https://mediasoup.discourse.group/t/spatial-layers-has-lower-resolution/2778/1 "2021-05-10T07:18:19Z")

</div>

Maybe a Simulcast generic question, but probably of interest anyway.

I have set the usual three Simulcast scalings: 4, 2, 1. When camera video has a resolution lower than 720p, not all three layers are being encoded in Chrome, as pointed out in [simulcast - consumer is selecting invalid temporal layer](https://mediasoup.discourse.group/t/simulcast-consumer-is-selecting-invalid-temporal-layer/82), so for a 640p video I get only two layers. Problems is, when setting layer two (index: 1) with `consumer.setPreferredLayer({spatialLayer: 1})`, video has a `videoHeight` of 320, like scalings are `[4, 2, 1]` instead of `[2, 1]`.

It somewhat made sense because they are the scaling values I set, but I was expecting that since Mediasoup told me Chrome was generating only two Simulcast spatial layers, setting the number two would be the highest quality one, without doing scaling, but results say other thing. Should I calc in advance the number of spatial layers my camera will generate and take them in account when setting the simulcast config? Or does Mediasoup can tell me the number of layers it receives from the camera?

---

<div class="post-metadata">

### Author: ![ibc](https://yyz2.discourse-cdn.com/free1/user_avatar/mediasoup.discourse.group/ibc/32/1540_2.png) [@ibc](https://mediasoup.discourse.group/u/ibc)
#### Post date: [May 10, 2021, 10:07am UTC](https://mediasoup.discourse.group/t/spatial-layers-has-lower-resolution/2778/2 "2021-05-10T10:07:42Z")

</div>

> [@piranna](#):
>
> Problems is, when setting layer two (index: 1) with `consumer.setPreferredLayer({spatialLayer: 1})` , video has a `videoHeight` of 320, like scalings are `[4, 2, 1]` instead of `[2, 1]` .

Just to confirm that you are passing proper encodings to the producer, enable spatial layer 0 in the consumer and check the received resolution.

TIP: The fact that you tell getUserMedia to generate 640p video does NOT mean that the encoder is gonna encode the same resolution. It may generate a minor resolution (even for the highest simulcast stream) if there are CPU issues or uplink limitation/issues.

---

<div class="post-metadata">

### Author: ![vpalmisano](https://yyz2.discourse-cdn.com/free1/user_avatar/mediasoup.discourse.group/vpalmisano/32/43_2.png) [@vpalmisano](https://mediasoup.discourse.group/u/vpalmisano)
#### Post date: [May 10, 2021, 2:05pm UTC](https://mediasoup.discourse.group/t/spatial-layers-has-lower-resolution/2778/3 "2021-05-10T14:05:09Z")

</div>

Maybe related to this: [Talking heads application, 352x288, strange scalable video coding - #7 by OllieJones](https://mediasoup.discourse.group/t/talking-heads-application-352x288-strange-scalable-video-coding/2511/7)

---

<div class="post-metadata">

### Author: ![piranna](https://yyz2.discourse-cdn.com/free1/user_avatar/mediasoup.discourse.group/piranna/32/934_2.png) [@piranna](https://mediasoup.discourse.group/u/piranna)
#### Post date: [May 12, 2021, 8:48am UTC](https://mediasoup.discourse.group/t/spatial-layers-has-lower-resolution/2778/4 "2021-05-12T08:48:38Z")

</div>

> Just to confirm that you are passing proper encodings to the producer, enable spatial layer 0 in the consumer and check the received resolution.

Do you mean `consumer.setPreferredLayer({spatialLayer: 0})`? That’s interesting, because doing so, the `changedlayers` event tells me that `spatialLayer` is `null`, not `0`, besides that it seems to works correctly. With 1 or 2 works correctly. I was thinking to open an issue about that, but didn’t have time to finish to investigate it in the code to be sure it was a fault on my side and not a bug or intended behaviour on Mediasoup.

> It may generate a minor resolution (even for the highest simulcast stream) if there are CPU issues or uplink limitation/issues.

I know that, and in fact I’ve seen myself how it was changuing in realtime 🙂

---

<div class="post-metadata">

### Author: ![ibc](https://yyz2.discourse-cdn.com/free1/user_avatar/mediasoup.discourse.group/ibc/32/1540_2.png) [@ibc](https://mediasoup.discourse.group/u/ibc)
#### Post date: [May 12, 2021, 8:54am UTC](https://mediasoup.discourse.group/t/spatial-layers-has-lower-resolution/2778/5 "2021-05-12T08:54:55Z")

</div>

Check the mediasoup demo, please. I promise there is no issue here at all. This is super tested.

---

<div class="post-metadata">

### Author: ![piranna](https://yyz2.discourse-cdn.com/free1/user_avatar/mediasoup.discourse.group/piranna/32/934_2.png) [@piranna](https://mediasoup.discourse.group/u/piranna)
#### Post date: [May 12, 2021, 9:05am UTC](https://mediasoup.discourse.group/t/spatial-layers-has-lower-resolution/2778/6 "2021-05-12T09:05:14Z")

</div>

I was not thinking there would be a bug, but instead that being both zero and null “falsy” Javascript values, that there would be some kind of optimization there. We are using a (heavily) modified (old) version of EduMeet, that’s a fork of mediasoup-demo, so yes, it would make sense to take a look to a current version as reference of best practices 🙂

---

<div class="post-metadata">

### Author: ![piranna](https://yyz2.discourse-cdn.com/free1/user_avatar/mediasoup.discourse.group/piranna/32/934_2.png) [@piranna](https://mediasoup.discourse.group/u/piranna)
#### Post date: [May 12, 2021, 9:27am UTC](https://mediasoup.discourse.group/t/spatial-layers-has-lower-resolution/2778/7 "2021-05-12T09:27:35Z")

</div>

> Maybe related to this: [Talking heads application, 352x288, strange scalable video coding - #7 by OllieJones](https://mediasoup.discourse.group/t/talking-heads-application-352x288-strange-scalable-video-coding/2511/7)

Seems like a similar issue, specially at the end of this comment:

> [@Talking heads application, 352x288, strange scalable video coding](https://mediasoup.discourse.group/t/talking-heads-application-352x288-strange-scalable-video-coding/2511/4):
>
> Please excuse the slow response to your questions. I want to make sure I have a clue what I’m talking about before answering. My requirement is low-res talking heads, with manageable bandwidth for mobile. I have something working the way I want it to. But I don’t understand why it works. It is a kludge. I appreciate any wisdom you can share about this. I use these three encodings const encodings = [ { maxBitrate: 128000, scaleResolutionDownBy: 4 }, { maxBitrate: 384000, scaleRes…

---

<div class="post-metadata">

### Author: ![piranna](https://yyz2.discourse-cdn.com/free1/user_avatar/mediasoup.discourse.group/piranna/32/934_2.png) [@piranna](https://mediasoup.discourse.group/u/piranna)
#### Post date: [May 14, 2021, 8:05am UTC](https://mediasoup.discourse.group/t/spatial-layers-has-lower-resolution/2778/8 "2021-05-14T08:05:48Z")

</div>

I have just compare current mediasoup-demo code with our own one. Both of them are getting total number of spatial and temporal layers with next code:

```auto
		const { spatialLayers, temporalLayers }
			= mediasoupClient.parseScalabilityMode(
				consumer.rtpParameters.encodings[0].scalabilityMode
			);

```

Thing is, printing them show they are 3 spatial and 3 temporal layers, but the logs about the producer score shows only two of them:

```auto
0: {encodingIdx: 0, rid: "r0", score: 10, ssrc: 127565124}
1: {encodingIdx: 1, rid: "r1", score: 0, ssrc: 611333117}

```

I’ve checked my webcam specs (Slimbook Pro2 integrated one) and according to [Review #6169 about “Chicony USB 2.0 Camera” | Webcam Reviews | Webcam Test](https://webcamtests.com/reviews/6169) it can produce 640x480@17fps (yes, an odd framerate…), so according to Chrome values, it’s correctly generating only 2 spatial layers. Maybe related to that fact, consumer scores show that producer scores is a 3-items array, as it dictates the scalability mode, but the third entry (index = 2), that would be the one with highest quality with a [4, 2, 1] scalability array, has a quality of zero. That quality makes sense since producer is generating only 2 layers, so there’s not a third one, but OTOH, setting to use index = 1, that’s the one with the highest quality provided by Chrome and my webcam, is giving me a 320x240 video, that matchs with a 2x scale factor:

```auto
1. producerScore: 10
2. producerScores: Array(3)
  1. 0: 10
  2. 1: 10
  3. 2: 0
3. score: 10

```

That leads me to think: maybe should be check the resolution of the video track generated by `getUserMedia()` before setting the encodings array in `transport.produce()`, both by hand or by the `produce()` method itself, so in case the number of layers that Chome can generate for that resolution are less than the desired ones, then we can remove the encodings with the highest scaling factor?

---

<div class="post-metadata">

### Author: ![ibc](https://yyz2.discourse-cdn.com/free1/user_avatar/mediasoup.discourse.group/ibc/32/1540_2.png) [@ibc](https://mediasoup.discourse.group/u/ibc)
#### Post date: [May 14, 2021, 8:18am UTC](https://mediasoup.discourse.group/t/spatial-layers-has-lower-resolution/2778/9 "2021-05-14T08:18:30Z")

</div>

You didn’t answer to this: [Spatial layers has lower resolution - #2 by ibc](https://mediasoup.discourse.group/t/spatial-layers-has-lower-resolution/2778/2)

I repeat: call `consumer.setPreferredLayers({ spatial: 0 })` and check received video resolution. Yes, I say `0`, so the lowest one.

Then, rewrite your code with just 2 encodings instead of 3 and ese how it behaves.

PS: There are many factors that make Chrome generate less spatial layers (simulcast streams) than requested: resolution of video input, resolution of captured video, network conditions, system/CPU status, etc.

---

<div class="post-metadata">

### Author: ![piranna](https://yyz2.discourse-cdn.com/free1/user_avatar/mediasoup.discourse.group/piranna/32/934_2.png) [@piranna](https://mediasoup.discourse.group/u/piranna)
#### Post date: [May 14, 2021, 8:26am UTC](https://mediasoup.discourse.group/t/spatial-layers-has-lower-resolution/2778/10 "2021-05-14T08:26:57Z")

</div>

> [@ibc](#):
>
> I repeat: call `consumer.setPreferredLayers({ spatial: 0 })` and check received video resolution. Yes, I say `0` , so the lowest one.

I know zero is lowest one. I have already check with logs that when spatial or temporal are set to zero, the one set to zero is returned as null in the changedlayers` event, and received video resolution didn’t changed, it’s always 320x240. Anyway, I’ll try to set it explicitly and see what’s the actual result, instead of only with events and logs.

> [@ibc](#):
>
> Then, rewrite your code with just 2 encodings instead of 3 and ese how it behaves.

That’s what I was planning to check first.

> [@ibc](#):
>
> PS: There are many factors that make Chrome generate less spatial layers (simulcast streams) than requested: resolution of video input, resolution of captured video, network conditions, system/CPU status, etc.

Then, we would need to know what’s the actual value dynamically, isn’t it?

---

<div class="post-metadata">

### Author: ![vpalmisano](https://yyz2.discourse-cdn.com/free1/user_avatar/mediasoup.discourse.group/vpalmisano/32/43_2.png) [@vpalmisano](https://mediasoup.discourse.group/u/vpalmisano)
#### Post date: [May 14, 2021, 8:31am UTC](https://mediasoup.discourse.group/t/spatial-layers-has-lower-resolution/2778/11 "2021-05-14T08:31:50Z")

</div>

> [@piranna](#):
>
> That leads me to think: maybe should be check the resolution of the video track generated by `getUserMedia()` before setting the encodings array in `transport.produce()` , both by hand or by the `produce()` method itself, so in case the number of layers that Chome can generate for that resolution are less than the desired ones, then we can remove the encodings with the highest scaling factor?

Yes, and take into account the spatial level configuration shown in the chromium source code (including the minimum and maximum bitrates).  
Anyway, after the startup phase, the browser could decide to change the encoding resolution on-fly, and also stopping to send some levels if an high CPU usage is detected.

---

<div class="post-metadata">

### Author: ![ibc](https://yyz2.discourse-cdn.com/free1/user_avatar/mediasoup.discourse.group/ibc/32/1540_2.png) [@ibc](https://mediasoup.discourse.group/u/ibc)
#### Post date: [May 14, 2021, 9:06am UTC](https://mediasoup.discourse.group/t/spatial-layers-has-lower-resolution/2778/12 "2021-05-14T09:06:10Z")

</div>

> [@piranna](#):
>
> Then, we would need to know what’s the actual value dynamically, isn’t it?

No, we don’t. Just open the demo and try disabling spatial layers via click in the info overlay over your own video view.

To be clear: yes, you are having an unexpected behavior but that’s not how things work. Let’s focus on your issue (I expect wrong usage of the given encodings, but you didn’t past the exact encodings array you are passing to the producer).

---

<div class="post-metadata">

### Author: ![piranna](https://yyz2.discourse-cdn.com/free1/user_avatar/mediasoup.discourse.group/piranna/32/934_2.png) [@piranna](https://mediasoup.discourse.group/u/piranna)
#### Post date: [May 14, 2021, 9:09am UTC](https://mediasoup.discourse.group/t/spatial-layers-has-lower-resolution/2778/13 "2021-05-14T09:09:16Z")

</div>

> [@vpalmisano](#):
>
> Yes, and take into account the spatial level configuration shown in the chromium source code (including the minimum and maximum bitrates).

Great, I’ll try it 🙂

> [@vpalmisano](#):
>
> Anyway, after the startup phase, the browser could decide to change the encoding resolution on-fly, and also stopping to send some levels if an high CPU usage is detected.

So, how can we control this after the startup phase? Does I need to parse the encodings from time to time and adjust to them? Does we have some event lo listen similar to `changedlayers` but for this info?

Sorry if this it’s already in the docs, I swear I’ve read it, but trying to achieve so much fine grain control, maybe I’ve missing something on it…

---

<div class="post-metadata">

### Author: ![ibc](https://yyz2.discourse-cdn.com/free1/user_avatar/mediasoup.discourse.group/ibc/32/1540_2.png) [@ibc](https://mediasoup.discourse.group/u/ibc)
#### Post date: [May 14, 2021, 9:20am UTC](https://mediasoup.discourse.group/t/spatial-layers-has-lower-resolution/2778/14 "2021-05-14T09:20:04Z")

</div>

> [@piranna](#):
>
> So, how can we control this after the startup phase? Does I need to parse the encodings from time to time and adjust to them? Does we have some event lo listen similar to `changedlayers` but for this info?

I insist: here you are assuming (based on the issue you are having) something that is not true and you are looking for a way to fix something that must not be fixed.

---

<div class="post-metadata">

### Author: ![vpalmisano](https://yyz2.discourse-cdn.com/free1/user_avatar/mediasoup.discourse.group/vpalmisano/32/43_2.png) [@vpalmisano](https://mediasoup.discourse.group/u/vpalmisano)
#### Post date: [May 14, 2021, 10:29am UTC](https://mediasoup.discourse.group/t/spatial-layers-has-lower-resolution/2778/15 "2021-05-14T10:29:16Z")

</div>

> [@piranna](#):
>
> So, how can we control this after the startup phase? Does I need to parse the encodings from time to time and adjust to them? Does we have some event lo listen similar to `changedlayers` but for this info?

You cannot control it after it has started.

---

<div class="post-metadata">

### Author: ![piranna](https://yyz2.discourse-cdn.com/free1/user_avatar/mediasoup.discourse.group/piranna/32/934_2.png) [@piranna](https://mediasoup.discourse.group/u/piranna)
#### Post date: [May 14, 2021, 11:50am UTC](https://mediasoup.discourse.group/t/spatial-layers-has-lower-resolution/2778/16 "2021-05-14T11:50:34Z")

</div>

> [@vpalmisano](#):
>
> You cannot control it after it has started.

Not control, but get notified when it happens so I can take countermeasures 🙂

---

<div class="post-metadata">

### Author: ![vpalmisano](https://yyz2.discourse-cdn.com/free1/user_avatar/mediasoup.discourse.group/vpalmisano/32/43_2.png) [@vpalmisano](https://mediasoup.discourse.group/u/vpalmisano)
#### Post date: [May 14, 2021, 11:52am UTC](https://mediasoup.discourse.group/t/spatial-layers-has-lower-resolution/2778/17 "2021-05-14T11:52:44Z")

</div>

What you can see is that at the receiver (client) side the video resolution doesn’t match the nominal simulcast configuration.

---

<div class="post-metadata">

### Author: ![piranna](https://yyz2.discourse-cdn.com/free1/user_avatar/mediasoup.discourse.group/piranna/32/934_2.png) [@piranna](https://mediasoup.discourse.group/u/piranna)
#### Post date: [May 14, 2021, 11:55am UTC](https://mediasoup.discourse.group/t/spatial-layers-has-lower-resolution/2778/18 "2021-05-14T11:55:56Z")

</div>

I was looking for an explicit event, but yes, I can compare values and emit that event myself, thanks 🙂
