vladimirvivien / go4vl

A Go library for working with the Video for Linux API (V4L2).
MIT License
245 stars 45 forks source link

Incorrect parsed FrameSize in getFrameSize function #52

Closed vincent-vinf closed 1 year ago

vincent-vinf commented 1 year ago

reproduce

Use the following code to view the supported Frame Sizes.

func main() {
    devName := "/dev/video0"
    dev, err := device.Open(
        devName,
    )
    if err != nil {
        panic(err)
    }
    info, err := v4l2.GetAllFormatFrameSizes(dev.Fd())
    if err != nil {
        panic(err)
    }
    marshal, err := json.MarshalIndent(info, "", "    ")
    if err != nil {
        panic(err)
    }
    fmt.Println(string(marshal))
}

The following error value was returned.

[
    {
        "Index": 0,
        "Type": 3,
        "PixelFormat": 842093913,
        "Size": {
            "MinWidth": 2,
            "MaxWidth": 32,
            "StepWidth": 2464,
            "MinHeight": 2,
            "MaxHeight": 0,
            "StepHeight": 0
        }
    },
    {
        "Index": 0,
        "Type": 3,
        "PixelFormat": 1448695129,
        "Size": {
            "MinWidth": 2,
            "MaxWidth": 32,
            "StepWidth": 2464,
            "MinHeight": 2,
            "MaxHeight": 0,
            "StepHeight": 0
        }
    },
    {
        "Index": 0,
        "Type": 3,
        "PixelFormat": 859981650,
        "Size": {
            "MinWidth": 2,
            "MaxWidth": 32,
            "StepWidth": 2464,
            "MinHeight": 2,
            "MaxHeight": 0,
            "StepHeight": 0
        }
    },
    {
        "Index": 0,
        "Type": 3,
        "PixelFormat": 1195724874,
        "Size": {
            "MinWidth": 2,
            "MaxWidth": 32,
            "StepWidth": 2464,
            "MinHeight": 2,
            "MaxHeight": 0,
            "StepHeight": 0
        }
    },
    {
        "Index": 0,
        "Type": 3,
        "PixelFormat": 875967048,
        "Size": {
            "MinWidth": 2,
            "MaxWidth": 32,
            "StepWidth": 2464,
            "MinHeight": 2,
            "MaxHeight": 0,
            "StepHeight": 0
        }
    },
    {
        "Index": 0,
        "Type": 3,
        "PixelFormat": 1196444237,
        "Size": {
            "MinWidth": 2,
            "MaxWidth": 32,
            "StepWidth": 2464,
            "MinHeight": 2,
            "MaxHeight": 0,
            "StepHeight": 0
        }
    },
    {
        "Index": 0,
        "Type": 3,
        "PixelFormat": 1431918169,
        "Size": {
            "MinWidth": 2,
            "MaxWidth": 32,
            "StepWidth": 2464,
            "MinHeight": 2,
            "MaxHeight": 0,
            "StepHeight": 0
        }
    },
    {
        "Index": 0,
        "Type": 3,
        "PixelFormat": 1498765654,
        "Size": {
            "MinWidth": 2,
            "MaxWidth": 32,
            "StepWidth": 2464,
            "MinHeight": 2,
            "MaxHeight": 0,
            "StepHeight": 0
        }
    },
    {
        "Index": 0,
        "Type": 3,
        "PixelFormat": 1498831189,
        "Size": {
            "MinWidth": 2,
            "MaxWidth": 32,
            "StepWidth": 2464,
            "MinHeight": 2,
            "MaxHeight": 0,
            "StepHeight": 0
        }
    },
    {
        "Index": 0,
        "Type": 3,
        "PixelFormat": 842094158,
        "Size": {
            "MinWidth": 2,
            "MaxWidth": 32,
            "StepWidth": 2464,
            "MinHeight": 2,
            "MaxHeight": 0,
            "StepHeight": 0
        }
    },
    {
        "Index": 0,
        "Type": 3,
        "PixelFormat": 861030210,
        "Size": {
            "MinWidth": 2,
            "MaxWidth": 32,
            "StepWidth": 2464,
            "MinHeight": 2,
            "MaxHeight": 0,
            "StepHeight": 0
        }
    },
    {
        "Index": 0,
        "Type": 3,
        "PixelFormat": 842094169,
        "Size": {
            "MinWidth": 2,
            "MaxWidth": 32,
            "StepWidth": 2464,
            "MinHeight": 2,
            "MaxHeight": 0,
            "StepHeight": 0
        }
    },
    {
        "Index": 0,
        "Type": 3,
        "PixelFormat": 825382478,
        "Size": {
            "MinWidth": 2,
            "MaxWidth": 32,
            "StepWidth": 2464,
            "MinHeight": 2,
            "MaxHeight": 0,
            "StepHeight": 0
        }
    },
    {
        "Index": 0,
        "Type": 3,
        "PixelFormat": 875714642,
        "Size": {
            "MinWidth": 2,
            "MaxWidth": 32,
            "StepWidth": 2464,
            "MinHeight": 2,
            "MaxHeight": 0,
            "StepHeight": 0
        }
    }
]

expected behavior

Returned the correct value.

{
    "Index": 0,
    "Type": 3,
    "PixelFormat": 875714642,
    "Size": {
        "MinWidth": 32,
        "MaxWidth": 3280,
        "StepWidth": 2,
        "MinHeight": 32,
        "MaxHeight": 2464,
        "StepHeight": 2
    }
}

possible reason

From the output, we can see that the value has been shifted forward by 2 units. The guess is that there is an error in the type conversion from c to golang.

https://github.com/vladimirvivien/go4vl/blob/efb35e7d2ec70f6334cad2de3248589117dfec88/v4l2/format_framesizes.go#L70-L72

According to the documentation, size information is contained in a union. The problem was fixed using the following code.

    case FrameSizeTypeStepwise, FrameSizeTypeContinuous:
        // Calculate pointer to access stepwise member
        frameSize.Size = *(*FrameSize)(unsafe.Pointer(&frmSizeEnum.anon0[0]))
vladimirvivien commented 1 year ago

@vincent-vinf Thank you for opening this issue. I see you also proposed a fixed. Will take a look.

Apologies in the delay in responding.