Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

src: codec_adapter: Add process passthrough path #3766

Closed
wants to merge 1 commit into from

Conversation

johnylin76
Copy link
Contributor

If the passthrough flag is enabled, on process() the data in the input
buffer should be directly copied to the output buffer.

We should determine how and when to set the passthrough flag.

@@ -261,7 +277,12 @@ int codec_process(struct comp_dev *dev)
return -EPERM;
}

ret = codec->ops->process(dev);
// TODO: how to set cd->passthrough flag?
if (cd->passthrough) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

via topology?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, but we have no example of enum or on/off controls I think is why it's left as a todo

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@juimonen any example so thi scan be added into topology and code here ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have examples of enums in tdfb, @johnylin76 please us those

Copy link
Member

@cujomalainey cujomalainey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realized that we may need to add a "passthrough_possible" flag. for codecs that more "encodecs/decoders" (e.g. MP3 decoder). We could do a simple source_hwparams == sink_hwparams as a check

Copy link
Member

@lgirdwood lgirdwood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume the use case here is runtime switching into and out of passthrough mode ?

@@ -261,7 +277,12 @@ int codec_process(struct comp_dev *dev)
return -EPERM;
}

ret = codec->ops->process(dev);
// TODO: how to set cd->passthrough flag?
if (cd->passthrough) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@juimonen any example so thi scan be added into topology and code here ?

@dbaluta
Copy link
Collaborator

dbaluta commented Jan 22, 2021

I assume the use case here is runtime switching into and out of passthrough mode ?

OK, makes sense. If the switching is a runtime I think the best way is to forget about doing this via topology file and use a kcontrol widget associated with codec adapter component.

@cujomalainey
Copy link
Member

I assume the use case here is runtime switching into and out of passthrough mode ?

OK, makes sense. If the switching is a runtime I think the best way is to forget about doing this via topology file and use a kcontrol widget associated with codec adapter component.

Yes, that is the plan is to do this via runtime controls, not topology. So as long as the process is not doing any any sort of format conversion (i.e. sink_hw_params == source_hw_params) we can shut of the processing easily from userspace regardless of whether the codec added a passthrough mode

@johnylin76
Copy link
Contributor Author

I assume the use case here is runtime switching into and out of passthrough mode ?

OK, makes sense. If the switching is a runtime I think the best way is to forget about doing this via topology file and use a kcontrol widget associated with codec adapter component.

Yes, that is the plan is to do this via runtime controls, not topology. So as long as the process is not doing any any sort of format conversion (i.e. sink_hw_params == source_hw_params) we can shut of the processing easily from userspace regardless of whether the codec added a passthrough mode

Agree to the concept "passthrough_possible". However I suspect current codec adapter is still specified to sample processing (not including encoder/decoder). For example, ca_config only stores channels, one sample_width, and one sample_rate, and cpd provides no information but data. (I am surprised that there is no format (S16, S24,...) information for codec.) So I think that the encoder/decoder might be probably not considered by codec adapter?

"passthrough" flag should be a runtime control in generic layer (like ca_config) rather than in codec layer. However runtime config now only supports params in codec layer. I think we should create a ca_runtime_config, or preserve an id of codec_param for it?

@lgirdwood
Copy link
Member

@plbossart @johnylin76 @cujomalainey @dbaluta this actually gave me an idea when we are pass a nonfree processing component UUID in a topology (where there are no nonfree componentes in the FW) we can assign it to this passthrough (and emit obvious FW / kernel warnings). Topology will still load, user will get sound albeit without the 3rd party processing.

@cujomalainey
Copy link
Member

That would actually optimize our fallback mechanism for closed source processing when using the open source builds. Excellent idea. So we should default the adapter to Y in this case?

@lgirdwood
Copy link
Member

That would actually optimize our fallback mechanism for closed source processing when using the open source builds. Excellent idea. So we should default the adapter to Y in this case?

Probably yes (on CAVS platforms). It's not huge. @mrajwa any inputs here ?

@mrajwa
Copy link
Contributor

mrajwa commented Feb 9, 2021

So I think that the encoder/decoder might be probably not considered by codec adapter?
However I suspect current codec adapter is still specified to sample processing (not including encoder/decoder)

codec_adapter, as the name suggest doesn't perform any encoding/deciding by itself. So if you need some additional, not already present variables struct codec_data and in particular its *private member is the place to go.

Probably yes (on CAVS platforms). It's not huge. @mrajwa any inputs here ?

I am OK with the passthru default setting in the topology which can be overloaded by RUNTIME params.

@cujomalainey
Copy link
Member

I think the idea here is to go past params. E.g. if topology asks for codec adapter with cadence core but firmware doesnt have cadence core but does have codec adapter, then adapter would install in passthrough mode just to keep audio working.

@mrajwa
Copy link
Contributor

mrajwa commented Feb 9, 2021

I think the idea here is to go past params. E.g. if topology asks for codec adapter with cadence core but firmware doesnt have cadence core but does have codec adapter, then adapter would install in passthrough mode just to keep audio working.

Hmm but if FW has codec_adapter on some pipeline then it should be tied with some processing lib right? What's the point of having "dummy" adapter with no lib bounded? I am also not sure about "keep audio working" part, can you describe this situation?

@cujomalainey
Copy link
Member

Sure, hypothetical situation. Chromeos launches device with processing lib. Due to licensing restrictions, final sof firmware build is only part of private chromeos builds. Therefore, the public (chromium) builds need a different firmware without the processing lib. Rather than also duplicating the topology to also remove the processing lib from the topology, this would allow the same topology to be used but the codec_adapter would just default to a passthrough since the processing lib was not part of the firmware image.

In other words, users will be able to grab private topologies and reuse them with public/dev SOF builds.

@dbaluta
Copy link
Collaborator

dbaluta commented Feb 10, 2021

@cujomalainey ideally we should separate somehow sof firmware binary from processing libraries binaries, in the same way Linux kernel separates kernel Image from modules. Or in the space way, user space binaries use shared libraries.

As it is now, sof-.ri needs all binaries stitched together, so we are stuck with different .ri binaries to solve the licensing restrictions. I think the proposed solution for pass through is a reasonable compromise.

@cujomalainey
Copy link
Member

I agree, dynamic libs would be an excellent solution but it is not something we have unfortunately. It would also make my job easier

@dbaluta
Copy link
Collaborator

dbaluta commented Feb 10, 2021

Will try to attack this dynamic libs approach with Google Summer of Code project :).

@lgirdwood
Copy link
Member

Will try to attack this dynamic libs approach with Google Summer of Code project :).

Good to hear - The simplest method given the GSoC time constraints is to statically map a library into a known memory offset i.e.

  1. We "reserve" region(s) of heap for dynamic text, data and bss
  2. load library via IPC request - kernel passes in the library and copy to reserved region (this needs to be cache managed too).
  3. Add IPC to unload library.
    This should be the fastest and integrate with current, build and linker scripts.

The optimal solution is to do the runtime linking and adress remapping (like Linux does), but this will take longer.

@cujomalainey
Copy link
Member

cujomalainey commented Feb 10, 2021

Random thought, could we possibly design it in a way to thin provision the code regions? I.e.

Build firmware that when completely loaded uses > system memory constraint but has the expectation that topology will only trigger certain modules to be loaded and the subset will be less than system memory.

I am thinking for the chrome case. Say platform X has device A with processing lib J, and Device B with processing lib K. A firmware with both lib J and K would exceed system memory limits. Since they all use the same system image, currently each firmware would have to be built independently and have unique paths. But with with this mechanism there would be one firmware image and the topology would trigger only loading the proper modules for the device.

Or does this simply fall under runtime linking?

@dbaluta
Copy link
Collaborator

dbaluta commented Feb 11, 2021

@cujomalainey I would expect most of the decisions should be taken at runtime linking. I am yet to study this.
Although, I find that deciding, statically, which lib to use when creating the topology is not of our best ideas. In topology the user should only provide codec_adapter component type (e.g Cadence, Dummy, waves) and then the actual library which will be loaded should be decided at runtime.

How do I see things:

  • create topology with codec adapter component
  • Linux kernel boots, loads the pipeline but it doesn't need to load the library yet
  • later, when someone decides to use the compress card is the moment when the library is loaded.
    • e.g cplay -c 1 -d 0 -I MP3 sample.mp3
    • when cplay stops library is unloaded
  • later, we can use the compress card with other library
    • e.g cplay -c 1 -d 0 -I AAC sample.aac

So, we should be able to run all sorts of algorithms from dynamically loaded libraries and the constraint here would be that the memory needed in order to run this to be at least equal with the size of largest library binary.

This will be a very interesting feature to have.

Also, right now all the modules + sof firmware are compiled under the same sof-.ri this is a very big limitation both because of licensing and of the size of sof-.ri.

@cujomalainey I understand your question. I am yet to process the suggestions from @lgirdwood

Later edit: I understand now @lgirdwood suggestion and it makes sense.

@cujomalainey
Copy link
Member

Hmm, that makes for a different usage than for processing libs which will not need swapping out. This may need a meeting and design proposal.

@lgirdwood lgirdwood added the codec Issues related to a 3rd party codec HW or driver label Feb 24, 2021
@lgirdwood lgirdwood added this to the v1.8 milestone Feb 24, 2021
If the passthrough flag is enabled, on process() the data in the input
buffer should be directly copied to the output buffer.

The passthrough flag is implemented to be set/get by topology enum
control.

Signed-off-by: Pin-chih Lin <johnylin@google.com>
@johnylin76
Copy link
Contributor Author

I have implemented set/get passthrough flag by enum control.
However I met an dmesg error on loading topology of SOF testing on Delbin

2021-03-02T09:55:40.185038Z DEBUG kernel: [    6.377578] sof-audio-pci 0000:00:1f.3: tplg: load control type 2 name : CA Setup Config5
2021-03-02T09:55:40.185038Z DEBUG kernel: [    6.377579] sof-audio-pci 0000:00:1f.3: tplg: load kcontrol index 23 chans 0
2021-03-02T09:55:40.185039Z DEBUG kernel: [    6.377580] sof-audio-pci 0000:00:1f.3: tplg: load control type 2 name : CA Runtime Params5
2021-03-02T09:55:40.185041Z DEBUG kernel: [    6.377582] sof-audio-pci 0000:00:1f.3: tplg: load kcontrol index 23 chans 0
2021-03-02T09:55:40.185041Z DEBUG kernel: [    6.377584] sof-audio-pci 0000:00:1f.3: tplg: load control type 3 name : CA PassThrough5
2021-03-02T09:55:40.185042Z DEBUG kernel: [    6.377586] sof-audio-pci 0000:00:1f.3: tplg: load kcontrol index 23 chans 1 comp_id 23
2021-03-02T09:55:40.185043Z DEBUG kernel: [    6.377587] sof-audio-pci 0000:00:1f.3: tplg: ready widget id 23 pipe 5 type 33 name : CODEC_ADAPTER5.0 stream none
2021-03-02T09:55:40.185044Z ERR kernel: [    6.377589] sof-audio-pci 0000:00:1f.3: error: no scontrol for widget CODEC_ADAPTER5.0
2021-03-02T09:55:40.185046Z ERR kernel: [    6.377592] sof-audio-pci 0000:00:1f.3: error: process loading failed
2021-03-02T09:55:40.185047Z ERR kernel: [    6.377595] sof-audio-pci 0000:00:1f.3: error: DSP failed to add widget id 0 type 33 name : CODEC_ADAPTER5.0 stream none reply 0
2021-03-02T09:55:40.185048Z ERR kernel: [    6.377597] sof-audio-pci 0000:00:1f.3: ASoC: failed to load widget CODEC_ADAPTER5.0
2021-03-02T09:55:40.185048Z ERR kernel: [    6.377599] sof-audio-pci 0000:00:1f.3: ASoC: topology: could not load header: -22

According to error message "no scontrol for widget" from the source code, it reports error because there is no private data for enum control?
https://lxr.missinglinkelectronics.com/linux/sound/soc/sof/topology.c#L1795

Does it mean we need the definition of private data for enum control just like byte control?

ret = process_passthrough(dev);
} else {
ret = codec->ops->process(dev);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for curly brackets here.

@johnylin76
Copy link
Contributor Author

Hi @singalsu and @juimonen ,
Do you have any debug direction to provide? Do we need private data for enum control, or is there wrong usage in my current implementation?
Thanks a lot.

I have implemented set/get passthrough flag by enum control.
However I met an dmesg error on loading topology of SOF testing on Delbin

2021-03-02T09:55:40.185038Z DEBUG kernel: [    6.377578] sof-audio-pci 0000:00:1f.3: tplg: load control type 2 name : CA Setup Config5
2021-03-02T09:55:40.185038Z DEBUG kernel: [    6.377579] sof-audio-pci 0000:00:1f.3: tplg: load kcontrol index 23 chans 0
2021-03-02T09:55:40.185039Z DEBUG kernel: [    6.377580] sof-audio-pci 0000:00:1f.3: tplg: load control type 2 name : CA Runtime Params5
2021-03-02T09:55:40.185041Z DEBUG kernel: [    6.377582] sof-audio-pci 0000:00:1f.3: tplg: load kcontrol index 23 chans 0
2021-03-02T09:55:40.185041Z DEBUG kernel: [    6.377584] sof-audio-pci 0000:00:1f.3: tplg: load control type 3 name : CA PassThrough5
2021-03-02T09:55:40.185042Z DEBUG kernel: [    6.377586] sof-audio-pci 0000:00:1f.3: tplg: load kcontrol index 23 chans 1 comp_id 23
2021-03-02T09:55:40.185043Z DEBUG kernel: [    6.377587] sof-audio-pci 0000:00:1f.3: tplg: ready widget id 23 pipe 5 type 33 name : CODEC_ADAPTER5.0 stream none
2021-03-02T09:55:40.185044Z ERR kernel: [    6.377589] sof-audio-pci 0000:00:1f.3: error: no scontrol for widget CODEC_ADAPTER5.0
2021-03-02T09:55:40.185046Z ERR kernel: [    6.377592] sof-audio-pci 0000:00:1f.3: error: process loading failed
2021-03-02T09:55:40.185047Z ERR kernel: [    6.377595] sof-audio-pci 0000:00:1f.3: error: DSP failed to add widget id 0 type 33 name : CODEC_ADAPTER5.0 stream none reply 0
2021-03-02T09:55:40.185048Z ERR kernel: [    6.377597] sof-audio-pci 0000:00:1f.3: ASoC: failed to load widget CODEC_ADAPTER5.0
2021-03-02T09:55:40.185048Z ERR kernel: [    6.377599] sof-audio-pci 0000:00:1f.3: ASoC: topology: could not load header: -22

According to error message "no scontrol for widget" from the source code, it reports error because there is no private data for enum control?
https://lxr.missinglinkelectronics.com/linux/sound/soc/sof/topology.c#L1795

Does it mean we need the definition of private data for enum control just like byte control?

@johnylin76 johnylin76 requested a review from juimonen March 3, 2021 07:24
@johnylin76 johnylin76 requested a review from singalsu March 3, 2021 07:24
@dbaluta
Copy link
Collaborator

dbaluta commented Mar 3, 2021

@johnylin76 do you have a separate m4 topology for your usecase?

@juimonen
Copy link

juimonen commented Mar 3, 2021

@johnylin76 do you have this in your kernel? thesofproject/linux#2423, you need to have it for multiple different types of control in 1 widget...

@johnylin76
Copy link
Contributor Author

@johnylin76 do you have this in your kernel? thesofproject/linux#2423, you need to have it for multiple different types of control in 1 widget...

I didn't have that, and I think this is probably the root cause. Will give it a try.
Thanks a lot.

@johnylin76
Copy link
Contributor Author

@johnylin76 do you have a separate m4 topology for your usecase?

Do you mean the top-level topology like sof-tgl-*.m4? Yes I have but I didn't upload to this PR because it is just for testing purpose.

@dbaluta
Copy link
Collaborator

dbaluta commented Mar 4, 2021

Do you mean the top-level topology like sof-tgl-*.m4? Yes I have but I didn't upload to this PR because it is just for testing purpose.
@johnylin76 Yes. I wanted to have a look at it. But I think the fix is as @juimonen said.

@lgirdwood
Copy link
Member

@juimonen do we have an ETA for thesofproject/linux#2423 landing upstream ?

@paulstelian97
Copy link
Collaborator

Please resubmit with "main" as PR base branch.

@johnylin76 johnylin76 deleted the passthrough branch June 30, 2022 03:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
codec Issues related to a 3rd party codec HW or driver
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants