sr99622 / libonvif

Onvif library with GUI implementation and built in YOLOX
GNU Lesser General Public License v2.1
176 stars 45 forks source link

onvif-gui uses the system's locale #95

Open MarcKe opened 3 months ago

MarcKe commented 3 months ago

Hi,

I've been having an interesting issue while using onvif-gui on my debian. I've been using debian in my native language German and I could not set encoder settings of the camera I am using. The reason is that a comma is used instead of a dot for floats. This usually only happens if you use a locale in your code that defaults to this behavior. An example is (unfortunate for me) the German locale.

char quality_buf[128] = {0};
sprintf(quality_buf, "%f", onvif_data->quality);

so this would result in "10,00000" instead of "10.00000" for 10f.

I can fix this by simply changing to en_US. I do not really get why the locale would be used in the first place tho. I only had a glimpse at the code and could not see the actual cause for the locale usage. a look into some message via wireshark:

<SOAP-ENV:Envelope
    xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope"
    xmlns:trt="http://www.onvif.org/ver10/media/wsdl"
    xmlns:tt="http://www.onvif.org/ver10/schema"
    xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
    xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    <SOAP-ENV:Header>
        <wsse:Security
        </SOAP-ENV:Header>
    <SOAP-ENV:Body>
        <trt:SetVideoEncoderConfiguration>
            <trt:Configuration
                token="video_encoder_h264">
                <tt:Name>
                <tt:UseCount>
                <tt:Encoding>
                <tt:Resolution>
                <tt:Quality>
                    10,000000
                    </tt:Quality>
                <tt:RateControl>
                <tt:H264>
                <tt:Multicast>
                <tt:SessionTimeout>
                </trt:Configuration>
            <trt:ForcePersistence>
            </trt:SetVideoEncoderConfiguration>
        </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>
sr99622 commented 3 months ago

Hello,

Thank you for bringing this up, I was not aware that this was an issue. It's hard to know for sure why this happens, it seems to come up in various situations, perhaps due to some platform dependent causes. Maybe a better way of doing this would be to force the decimal point by using a more specific format

    sprintf(quality_buf, "%.4f", onvif_data->quality);
MarcKe commented 3 months ago

That would not really help as the dot is just syntax in the format string. I also corrected the title as it only seems to affect onvif-gui, onvif-util is fine.

sr99622 commented 3 months ago

You are correct, the format doesn't help. I'm thinking the issue in onvif-gui is that an underlying library is changing the locale and this affect is seen by any part of the application. I am not well versed in internationalization issues, so my initial response was naive. It is a surprisingly complex topic. I think maybe the best approach is to hack the string and say that a float will only have one decimal point (or comma) and force the replacement of any comma with a decimal point.

    sprintf(quality_buf, "%f", onvif_data->quality);
    for (int i = 0; i < strlen(quality_buf); i++) {
        if (quality_buf[i] == ',')
            quality_buf[i] = '.';
    }

Not really my favorite approach, but it seems to work, and more complex solutions don't seem to provide any further benefit. There's only one spot in the program where this is used, so at least it is limited.

Thank you so much for analyzing this issue and finding the cause, as a lifetime US locale user, these sorts of things seem to always be a surprise to me as my world view is pretty limited.