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

Unable to set property with integer value #2

Open
brucekim opened this issue Jul 26, 2021 · 5 comments
Open

Unable to set property with integer value #2

brucekim opened this issue Jul 26, 2021 · 5 comments

Comments

@brucekim
Copy link

Hi,

SetProperty() strictly checks property type and the type of value given so that it cannot set several property with integer value.

gobject.go

fakevideosrc, err := gst.NewElementWithName("videotestsrc", "vtestsrc")
	err = fakevideosrc.SetProperty("pattern", 2)
	if err != nil {
		logger.Infof("err %v", err)
	}

> log output
[main.go][func1] => err Invalid type gint for property pattern

I think, It is convenient for properties to allow integer value to be set with integer. In addition, gstreamer does like that.

In order to do this, I simply added following function, SetPropertyWithInteger().

I would like to hear your opinion.

func (v *Object) SetPropertyWithInteger(name string, value int) error {
	prop, err := ValueInit(TYPE_INT)
	if err != nil {
		return err
	}
	prop.SetInt(value)
	if err != nil {
		return fmt.Errorf("Unable to perform type conversion: %s", err.Error())
	}
	cstr := C.CString(name)
	defer C.free(unsafe.Pointer(cstr))
	C.g_object_set_property(v.GObject, (*C.gchar)(cstr), prop.native())
	return nil
}
@tinyzimmer
Copy link
Owner

If SetProperty doesn't work, use SetArg from the go-gst bindings instead. It will handle type conversion on the fly.

@tinyzimmer
Copy link
Owner

That being said, it's weird the integer isn't working. I thought I had examples doing that, but I can't seem to find them at the moment.

@brucekim
Copy link
Author

testsrc, err := gst.NewElementWithName("videotestsrc", "vtestsrc")
testsrc.SetArg("pattern", "ball")
getProp, err := testsrc.GetProperty("pattern")
logger.Infof("videosrc pattern %v %v", getProp, err)

> log out
=> videosrc pattern 18 <nil>

Yeah, I checked SetArgs works well. It takes value as string.

I think integer type of value would be necessary to set property in some cases.

In the following example, giving to integer value to SetProperty returns error message.
I think it is because "pattern" property is type of C.G_TYPE_ENUM against C.G_TYPE_INT.

fakevideosrc, err := gst.NewElementWithName("videotestsrc", "vtestsrc")
	err = fakevideosrc.SetProperty("pattern", 2)
	if err != nil {
		logger.Infof("err %v", err)
	}

> log output
[main.go][func1] => err Invalid type gint for property pattern

@tinyzimmer
Copy link
Owner

Ah yep, that makes sense. Enum properties are not handled at all. And I think it was me stumbling on an enum myself than eventually led to binding SetArg downstream.

@brucekim
Copy link
Author

I have an idea. What if an enum type of property accepts interger type of value as well in SetPropertyValue()?
Gstreamer is capable of this so making go-gst binding capable this would be nice I think.

In order to make this,
I found that enum type of properties belong to an element has a hierarchy unlike other fundamental types.
For example, pattern property of videotestsrc element has a hierarchy such as GEnum -> GstVideoTestSrcPattern in which .Depth() is two. Thus, it was necessary for searching GEum type to go upstream of propType
I would like to hear your opinion.

I share test code below.

Related PR: #3

import (
	"fmt"
	"github.com/tinyzimmer/go-glib/glib"
	"github.com/tinyzimmer/go-gst/gst"
	"testing"
)

func TestSetProperty_TypeCheck (t *testing.T) {
	//INT
	value := 10
	name := "pattern"
	//name := "timestamp-offset"
	gst.Init(nil)
	elem, err := gst.NewElement("videotestsrc")
	if err != nil {
		t.Errorf(err.Error())
	}
	gValue, err := glib.GValue(value)
	if err != nil {
		t.Errorf(err.Error())
	}
	propType, err := elem.GetPropertyType(name)
	if err != nil {
		t.Errorf(err.Error())
	}
	valType, _, err := gValue.Type()
	if err != nil {
		t.Errorf(err.Error())
	}

	fmt.Printf("propType name %v depth %v parent %v parent name %v\n",
		propType.Name(),
		propType.Depth(),
		propType.Parent(),
		propType.Parent().Name(),
		)
	fmt.Printf("valType name %v depth %v parent %v parent name %v\n",
		valType.Name(),
		valType.Depth(),
		valType.Parent(),
		valType.Parent().Name(),
		)

	switch valType {
	case glib.TYPE_INT:
		for ; propType.Depth() > 1; propType = propType.Parent() {
		}
		fmt.Printf("propType name %v depth %v parent %v parent name %v\n",
			propType.Name(),
			propType.Depth(),
			propType.Parent(),
			propType.Parent().Name(),
		)

		if propType == glib.TYPE_ENUM {
			break
		}
		fallthrough
	default:
		if valType != propType {
			fmt.Errorf("Invalid type %s for property %s", gValue.TypeName(), name)
			return
		}
	}
	fmt.Println("set property here")
}

> execution result
=== RUN   TestSetProperty_TypeCheck
propType name GstVideoTestSrcPattern depth 2 parent 48 parent name GEnum
valType name gint depth 1 parent 0 parent name 
propType name GEnum depth 1 parent 0 parent name 
set property here
--- PASS: TestSetProperty_TypeCheck (0.02s)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants