Avnu / OpenAvnu

OpenAvnu - an Avnu sponsored repository for Time Sensitive Network (TSN and AVB) technology
462 stars 289 forks source link

[bug] avtp_avdecc has a wrong stream format with alsa_talker.ini -> cannot connect stream #881

Open chris-kuhr opened 4 years ago

chris-kuhr commented 4 years ago

Hi *,

when I compile avtp_pipeline and avtp_avdecc everything works fine so far. the interface and mapping modules launch as expected. I customized endpoint.ini, avdecc.ini and alsa_talker.ini. sampling rate is 96khz and 2 audio channels.

Now I want to connect it. Thus, I launch the avdecc-lib controller app. I select the endpoint and view the details. No matter what I do, it always shows the same wrong stream format for the STREAM_OUTPUT descriptor: 48khz with 8 channels.

This obviously fails, when I want to connect a 96khz/2channel listener.

what is going wrong here? already tried different repos and branches without success.

Best, Ck

chris-kuhr commented 4 years ago

I found out that it is a bug.

On startup the ini files are read correctly. A Wireshark trace shows the decimal value 30464 for the sampling rate. in hex this is 0x7700. 96000 decimal has the hex value 0x17700. Thus, somewhere the first 2 bytes seem to be nulled or cut off.

I put some printfs in the *fromBuf functions in openavb_descriptor_audio_unit.c and openavb_descriptor_stream_io.c. This verifies the wrong values are originating somewhere inside the avtp_pipeline implementation.

Can anyone help me pin down the problem?

Best, Ck

pinealservo commented 4 years ago

It's been a very long time since I worked with any of this, so I have forgotten most of the little I knew about AVDECC descriptors. But looking at the files you pointed to, it appears that the way the stream descriptors are formatted depends on the type of stream you're using. Are you using avtp audio streams or 61883 streams? In any case, it didn't look like you'd expect to find either of them holding a number like 0x17700 in a field related to sample rate; those are typically a 1-byte enumeration of valid rates like this: https://github.com/AVnu/OpenAvnu/blob/df587b7509a4dee7fa79a40eec5d6327310c472b/lib/avtp_pipeline/aem/openavb_aem_types_pub.h#L507

Maybe there's an additional ini file related to which AVTP stream encoding you're using that you need to configure?

chris-kuhr commented 4 years ago

IEEE1722.1-2013 table 7.5 says the current_sampling_rate is encoded with 4 bytes. Which I found consitently in Wireshark and the code. The descriptors you mention describe only the AVTP Audio Stream Format, which I am not using. I am using a IEC 61883 stream. The console output shows the correct sampling rate configured for 61883, but it is not correctly communicated to the AEM descriptor somewhere.

lib/avtp_pipeline/aem/openavb_aem_types_pub.h

// Sample rates IEEE Std 1722.1-2013 clause 7.3.1
typedef struct {
    U8 pull;
    U32 base;
} openavb_aem_sampling_rate_t;

Somewhere exists a bottleneck, that cuts/nulls the hi bytes of the configured sampling rate. Somewhere before this call: lib/avtp_pipeline/aem/openavb_descriptor_audio_unit.c

BIT_D2BHTONL(pDst, pSrc->current_sampling_rate.pull, 29, 0);
BIT_D2BHTONL(pDst, pSrc->current_sampling_rate.base, 0, 4);

Additionally I always have a channel count of eight channels, although two channels are configured. Seems to me like the endpoint does not communicate or store the values correctly.

I searched through all ini files I could find and tested everything I could think of in terms of configuration. Nothing changed this behavior, which I find plausible, since my last investigations.

BR and thanks for your help, Ck

chris-kuhr commented 4 years ago

is there some kind of sequence diagram that shows the callback infrastructue? It's pretty hard to verify the value propagation through all the callbacks...

pinealservo commented 4 years ago

Sorry, I have pretty much exhausted my experience/memory with the AVDECC part of the code. The only docs for it are the ones that you can find in the code directories for the overall avtp pipeline code.

chris-kuhr commented 4 years ago

Ok, thanks. I will go on the hunt... I am surprised that this bug did not occur for anyone else....

pinealservo commented 4 years ago

When the code was contributed, the AVDECC code was unfinished. Brant did most of the work of figuring out how it was meant to work and getting it to a functional state. We used it for some prototype projects, but I think most actual uses of the codebase so far have been in automotive contexts where they'd use a different control protocol. And I don't think our prototype use went beyond 48KHz at 2 channels, mostly due to limitations of the generic hardware platform we were using.

Also note that media clock recovery support is only there in the form of currently-unused hooks for it and everything surrounding media synchronization is super sketchy because of limited general API support for it on the Linux side. I'd developed an add-on board to the dev board we were using that could use generic PTP APIs to adjust and measure an external codec's clock, but that job ended before I even got the control loop working properly; never got it actually integrated into the stack.

The Alsa story for getting precise timestamps of media clock edges is not wonderful, last time I checked, and with standard interfaces the best you can do is characterize your exact hardware and driver behavior and estimate timestamps based on FIFO levels. I've got some parts in the codebase such that if you can characterize the current rate ratio between your media clock and PTP clock well enough as well as the amount of time it actually takes to start a stream from when you ask it to, you can usually convince an actual AVB listener that your talker is actually doing AVB, at least for a while until drift throws off the rate ratio of your simulated media timestamps.

I wish I could help more, but I'm no longer employed to work on AVB-related things and although I've personally got enough AVB-capable hardware to set up my own little lab, I have enough other hobbies that I haven't got around to it yet, and I'm not sure I'd want to dive into trying to get it to work in Linux anyway. I'm much happier trying to do real-time stuff on microcontrollers or even FPGAs where there are fewer monkeys trying to put wrenches into the timing mechanisms.

chris-kuhr commented 4 years ago

I don't want to blame or anything! I was just curious. I am very thankful for your awesome work! And good luck with your new job!

I want to use a different timing strategy, than avtp_pipeline.

I have a JACK server, which is connected to a media clock talker. I want to create a JACK interface, so that I can have several software talkers.

I am just usinh the alsa_talker for debugging purposes. By the way, I have to implement a "talker scheduler" to realize this, right?

chris-kuhr commented 4 years ago

First success!

In file lib/avtp_pipeline/avdecc/openavb_avdecc_read_ini_pub.h:

line 120 needs to be changed. It uses U16 for the audioRate. It ought to be U32. This solves the problem with the audio unit descriptor.

Now I have to find the STREAM_OUTPUT descriptor problem. I will create a pr as soon as I got both bugs.

tbc...

chris-kuhr commented 4 years ago

further success...

the line pDescriptor->stream_formats[0].subtypes.iec_61883_6_am824.label_mbla_cnt = 8; in file lib/avtp_pipeline/aem/openavb_descriptor_stream_io.c explains the channel count of eight. The line pDescriptor->stream_formats[0].subtypes.iec_61883_6_am824.fdf_sfc = 0x02; has also the default samplerate of 48kHz and needs fixing. The correct value for 96kHz would be 0x04.

Now I have to figure what I have to do to fill it with the proper value...

chris-kuhr commented 4 years ago

Darn... Another bug. this time in avdecc-lib. it doesn't read the stream output descriptor correctly. the stream format value is mostly wrong. only the sampling rate is correct by accident... have to post in avdecc-lib repo...

andrew-elder commented 4 years ago

@chris-kuhr - I assume you are using the avdecc-lib submodule from this repo? We are WAY overdue for updating it.... Let me see about creating a pull request....

chris-kuhr commented 4 years ago

I already update avdecc-lib in my fork manually to the most recent master branch commit b77cddc8127c9d609c1d5cc4bccc34290aabc917. The problem consists. I double checked and cloned a fresh copy from audioscience repo but its the same version and problem.

----------------------- STREAM_OUTPUT -----------------------
descriptor_type: STREAM_OUTPUT
descriptor_index: 0
object_name = Stream Output 0
localized_description = 65535
clock_domain_index = 0
stream_flags = 0x2
    clock_sync_source = 0
    class_a = 1
    class_b = 0
    supports_encrypted = 0
    primary_backup_valid = 0
    primary_backup_valid = 0
    secondary_backup_supported = 0
    secondary_backup_valid = 0
    tertiary_backup_supported = 0
    tertiary_backup_valid = 0
current_format_name = IEC61883-6_AM824_MBLA_96KHZ_8CH
backup_talker_entity_id_0 = 0x0
backup_talker_unique_0 = 0
backup_talker_entity_id_1 = 0x0
backup_talker_unique_1 = 0
backup_talker_entity_id_2 = 0x0
backup_talker_unique_2 = 0
backedup_talker_entity_id = 0x0
backedup_talker_unique = 0
avb_interface_index = 0
buffer_length = 0
number_of_formats = 1
    stream_format_0 = IEC61883-6_AM824_MBLA_96KHZ_8CH

It ought to be 96kHz and 2 channels.

Wireshark shows the correct values sent from the endpoint (FDF SFC: 0x4, Label Multi-Bit Linear Audio Count: 2):

Ethernet II, Src: IntelCor_3f:be:a3 (a0:36:9f:3f:be:a3), Dst: IntelCor_3f:be:a3 (a0:36:9f:3f:be:a3)
IEEE 1722 Protocol
IEEE 1722.1 Protocol
    .... 0001 = Message Type: AEM_RESPONSE (1)
    0000 0... = Status: SUCCESS (0x00)
    .... .000 1001 1100 = Control Data Length: 156
    Target GUID: 0xa0369ffffe3fbea3
    Controller GUID: 0xa0369fffff3fbea3
    Sequence ID: 4
    0... .... = U Flag: False
    .000 0000 0000 0100 = Command Type: READ_DESCRIPTOR (0x0004)
    Configuration: 0
    Descriptor Type: STREAM_OUTPUT (0x0006)
        Descriptor Index: 0x0000
        Object Name: Stream Output 0
        Localized Description: 65535
        Clock Domain ID: 0
        Stream Flags: 0x0002
        Stream Format
            0... .... = Version: 0x0
            .000 0000 = Subtype: 0x00
            1... .... = SF: True
            ..10 0000 = FMT: 0x20
            0000 0... = FDF EVT: 0x00
            .... .100 = FDF SFC: 0x4
            DBS: 0x08
            0... .... = Blocking Flag: False
            .1.. .... = NonBlocking Flag: True
            Label IEC 60958 Count: 0
            Label Multi-Bit Linear Audio Count: 2
            0000 .... = Label Midi Slot Count: 0
            .... 0000 = Label SMPTE Slot Count: 0
----------------------8<---------------------------------------------------------

Should I take this to the audioscience repo for help?

Best, Ck

chris-kuhr commented 4 years ago

Opened an issue at avdecc-lib repo: https://github.com/audioscience/avdecc-lib/issues/405

chris-kuhr commented 4 years ago

I have created a pr to fix at least these small problems...

888

It is still required to use the configuration parameters of the ini file, instead of the initialization. But I suppose I won't be able to do that any time soon.