// Seek() is a wrapper around gst_element_seek(). func (v *Element) Seek(rate float64, format Format, flags SeekFlags, startType SeekType, start int64, stopType SeekType, stop int64) bool { c := C.gst_element_seek(v.native(), C.gdouble(rate), C.GstFormat(format), C.GstSeekFlags(flags), C.GstSeekType(startType), C.gint64(start), C.GstSeekType(stopType), C.gint64(stop)) return gobool(c) }
// Set value to i func (v *Value) Set(i interface{}) { if vg, ok := i.(ValueGetter); ok { vg.Value().Copy(v) return } // Other types r := reflect.ValueOf(i) switch r.Kind() { case reflect.Invalid: C.g_value_reset(v.g()) case reflect.Bool: C.g_value_set_boolean(v.g(), gBoolean(r.Bool())) case reflect.Int: C.g_value_set_long(v.g(), C.glong(i.(int))) case reflect.Int8: C.g_value_set_schar(v.g(), C.gint8(i.(int8))) case reflect.Int32: C.g_value_set_int(v.g(), C.gint(i.(int32))) case reflect.Int64: C.g_value_set_int64(v.g(), C.gint64(i.(int64))) case reflect.Uint: C.g_value_set_ulong(v.g(), C.gulong(i.(uint))) case reflect.Uint8: C.g_value_set_uchar(v.g(), C.guchar(i.(uint8))) case reflect.Uint32: C.g_value_set_uint(v.g(), C.guint(i.(uint32))) case reflect.Uint64: C.g_value_set_uint64(v.g(), C.guint64(i.(uint64))) case reflect.Float32: C.g_value_set_float(v.g(), C.gfloat(i.(float32))) case reflect.Float64: C.g_value_set_double(v.g(), C.gdouble(i.(float64))) case reflect.Ptr: C.g_value_set_pointer(v.g(), C.gpointer(r.Pointer())) case reflect.String: C.g_value_set_static_string(v.g(), (*C.gchar)(C.CString(r.String()))) default: panic("Can't represent Go value in Glib type system.") } }
//----------------------------------------------------------------------- // GValue //----------------------------------------------------------------------- func GValueFromNative(value interface{}) *C.GValue { var gv *C.GValue if _, ok := value.(WrappedObject); ok { value = value.(WrappedObject).GetInternalValue() } if _, ok := value.(GObject); ok { value = value.(GObject).Object } if _, ok := value.(GValue); ok { value = value.(GValue).Value } switch value.(type) { case bool: gv = C.init_gvalue_bool(gbool(value.(bool))) break case byte: gv = C.init_gvalue_byte(C.guchar(value.(byte))) break case int: gv = C.init_gvalue_int(C.gint(value.(int))) break case uint: gv = C.init_gvalue_uint(C.guint(value.(uint))) break case int64: gv = C.init_gvalue_int64(C.gint64(value.(int64))) break case float32: gv = C.init_gvalue_double(C.gdouble(value.(float32))) break case float64: gv = C.init_gvalue_double(C.gdouble(value.(float64))) break case string: { pval := C.CString(value.(string)) defer C.free_string(pval) gv = C.init_gvalue_string(C.to_gcharptr(pval)) } break default: //gv = C.init_gvalue_pointer(C.gpointer(unsafe.Pointer(&value))); break } return gv }
// SeekSimple() is a wrapper around gst_element_seek_simple(). func (v *Element) SeekSimple(format Format, flags SeekFlags, pos int64) bool { c := C.gst_element_seek_simple(v.native(), C.GstFormat(format), C.GstSeekFlags(flags), C.gint64(pos)) return gobool(c) }
// pointerVal attempts to return an unsafe.Pointer for value. // Not all types are understood, in which case a nil Pointer // is returned. func pointerVal(value interface{}) unsafe.Pointer { var p unsafe.Pointer switch v := value.(type) { case bool: c := gbool(v) p = unsafe.Pointer(&c) case int8: c := C.gint8(v) p = unsafe.Pointer(&c) case int16: c := C.gint16(v) p = unsafe.Pointer(&c) case int32: c := C.gint32(v) p = unsafe.Pointer(&c) case int64: c := C.gint64(v) p = unsafe.Pointer(&c) case int: c := C.gint(v) p = unsafe.Pointer(&c) case uint8: c := C.guchar(v) p = unsafe.Pointer(&c) case uint16: c := C.guint16(v) p = unsafe.Pointer(&c) case uint32: c := C.guint32(v) p = unsafe.Pointer(&c) case uint64: c := C.guint64(v) p = unsafe.Pointer(&c) case uint: c := C.guint(v) p = unsafe.Pointer(&c) case uintptr: p = unsafe.Pointer(C.gpointer(v)) case float32: c := C.gfloat(v) p = unsafe.Pointer(&c) case float64: c := C.gdouble(v) p = unsafe.Pointer(&c) case string: cstr := C.CString(v) defer C.free(unsafe.Pointer(cstr)) p = unsafe.Pointer(cstr) default: if pv, ok := value.(unsafe.Pointer); ok { p = pv } else { val := reflect.ValueOf(value) switch val.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: c := C.int(val.Int()) p = unsafe.Pointer(&c) case reflect.Uintptr, reflect.Ptr, reflect.UnsafePointer: p = unsafe.Pointer(C.gpointer(val.Pointer())) } } } return p }
// SetInt64 is a wrapper around g_value_set_int64(). func (v *Value) SetInt64(val int64) { C.g_value_set_int64(v.native(), C.gint64(val)) }
func GIdleAddFull(priority int, callback interface{}, data ...interface{}) uint { cl, id := gobject.CreateCustomClosure(callback, data...) _closures[id] = cl return uint(C._g_idle_add_full(C.gint(priority), C.gint64(id))) }
// Set() is a wrapper around g_object_set(). However, unlike // g_object_set(), this function only sets one name value pair. Make // multiple calls to this function to set multiple properties. func (v *Object) Set(name string, value interface{}) error { cstr := C.CString(name) defer C.free(unsafe.Pointer(cstr)) if _, ok := value.(Object); ok { value = value.(Object).GObject } var p unsafe.Pointer = nil switch value.(type) { case bool: c := gbool(value.(bool)) p = unsafe.Pointer(&c) case int8: c := C.gint8(value.(int8)) p = unsafe.Pointer(&c) case int16: c := C.gint16(value.(int16)) p = unsafe.Pointer(&c) case int32: c := C.gint32(value.(int32)) p = unsafe.Pointer(&c) case int64: c := C.gint64(value.(int64)) p = unsafe.Pointer(&c) case int: c := C.gint(value.(int)) p = unsafe.Pointer(&c) case uint8: c := C.guchar(value.(uint8)) p = unsafe.Pointer(&c) case uint16: c := C.guint16(value.(uint16)) p = unsafe.Pointer(&c) case uint32: c := C.guint32(value.(uint32)) p = unsafe.Pointer(&c) case uint64: c := C.guint64(value.(uint64)) p = unsafe.Pointer(&c) case uint: c := C.guint(value.(uint)) p = unsafe.Pointer(&c) case uintptr: p = unsafe.Pointer(C.gpointer(value.(uintptr))) case float32: c := C.gfloat(value.(float32)) p = unsafe.Pointer(&c) case float64: c := C.gdouble(value.(float64)) p = unsafe.Pointer(&c) case string: cstr := C.CString(value.(string)) defer C.free(unsafe.Pointer(cstr)) p = unsafe.Pointer(cstr) default: if pv, ok := value.(unsafe.Pointer); ok { p = pv } else { // Constants with separate types are not type asserted // above, so do a runtime check here instead. val := reflect.ValueOf(value) switch val.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: c := C.int(val.Int()) p = unsafe.Pointer(&c) case reflect.Uintptr: p = unsafe.Pointer(C.gpointer(val.Pointer())) } } } // Can't call g_object_set() as it uses a variable arg list, use a // wrapper instead if p != nil { C._g_object_set_one(C.gpointer(v.GObject), (*C.gchar)(cstr), p) return nil } else { return errors.New("Unable to perform type conversion") } }
func GTimeoutAddSecondsFull(priority int, interval uint, callback interface{}, data ...interface{}) uint { cl, id := gobject.CreateCustomClosure(callback, data...) _closures[id] = cl return uint(C._g_timeout_add_seconds_full(C.gint(priority), C.guint(interval), C.gint64(id))) }
func GlibInt64(i int64) C.gint64 { return C.gint64(i) }
func PlayProcess(cs chan byte, loop *C.GMainLoop) { var pipeline *C.GstElement // 定义组件 var bus *C.GstBus wg := new(sync.WaitGroup) sig_out := make(chan bool) g_wg.Add(1) defer close(sig_out) defer g_wg.Done() if g_isOutOfOrder { outOfOrder(g_list) debug.FreeOSMemory() } start := g_list.Front() end := g_list.Back() e := g_list.Front() v0 := GString("playbin") v1 := GString("play") pipeline = C.gst_element_factory_make(v0, v1) GFree(unsafe.Pointer(v0)) GFree(unsafe.Pointer(v1)) // 得到 管道的消息总线 bus = C.pipeline_get_bus(unsafe.Pointer(pipeline)) if bus == (*C.GstBus)(nil) { fmt.Println("GstBus element could not be created.Exiting.") return } C.bus_add_watch(unsafe.Pointer(bus), unsafe.Pointer(loop)) // 开始循环 go func(sig_quit chan bool) { wg.Add(1) i := 0 LOOP_RUN: for !g_isQuit { if i != 0 { C.media_ready(unsafe.Pointer(pipeline)) C.media_play(unsafe.Pointer(pipeline)) } C.g_main_loop_run(loop) C.media_stop(unsafe.Pointer(pipeline)) switch g_play_style { case PLAY_STYLE_SINGLE: sig_quit <- true break LOOP_RUN case PLAY_STYLE_ORDER: if e != end { e = e.Next() } else { break LOOP_RUN } case PLAY_STYLE_SHUFFLE: if e != end { e = e.Next() } else { break LOOP_RUN } case PLAY_STYLE_SLOOP: case PLAY_STYLE_ALOOP: if e != end { e = e.Next() } else { e = start } } fpath, ok := e.Value.(string) if ok { v2 := GString(fpath) C.set_path(unsafe.Pointer(pipeline), v2) GFree(unsafe.Pointer(v2)) } else { break } i++ } C.object_unref(unsafe.Pointer(pipeline)) wg.Done() }(sig_out) fpath, ok := e.Value.(string) if ok { // fmt.Printf("filename[%s]\n", fpath) v2 := GString(fpath) C.set_path(unsafe.Pointer(pipeline), v2) GFree(unsafe.Pointer(v2)) C.media_ready(unsafe.Pointer(pipeline)) C.media_play(unsafe.Pointer(pipeline)) //C.set_mute(unsafe.Pointer(pipeline)) lb := true for lb { select { case op := <-cs: switch op { case 's': C.media_pause(unsafe.Pointer(pipeline)) case 'r': C.media_play(unsafe.Pointer(pipeline)) case 'n': switch g_play_style { case PLAY_STYLE_SINGLE: lb = false g_isQuit = true case PLAY_STYLE_ORDER: fallthrough case PLAY_STYLE_SHUFFLE: C.media_stop(unsafe.Pointer(pipeline)) if e != end { e = e.Next() } else { lb = false g_isQuit = true } case PLAY_STYLE_SLOOP: C.media_stop(unsafe.Pointer(pipeline)) case PLAY_STYLE_ALOOP: if e != end { e = e.Next() } else { e = start } } if !lb { fpath, ok := e.Value.(string) if ok { v2 := GString(fpath) C.set_path(unsafe.Pointer(pipeline), v2) GFree(unsafe.Pointer(v2)) C.media_ready(unsafe.Pointer(pipeline)) C.media_play(unsafe.Pointer(pipeline)) } else { lb = false g_isQuit = true } } //C.g_main_loop_quit(loop) case 'p': switch g_play_style { case PLAY_STYLE_SINGLE: // do nothing ??? case PLAY_STYLE_ORDER: fallthrough case PLAY_STYLE_SHUFFLE: C.media_stop(unsafe.Pointer(pipeline)) if e != start { e = e.Prev() fpath, ok := e.Value.(string) if ok { v2 := GString(fpath) C.set_path(unsafe.Pointer(pipeline), v2) GFree(unsafe.Pointer(v2)) C.media_ready(unsafe.Pointer(pipeline)) C.media_play(unsafe.Pointer(pipeline)) } else { lb = false g_isQuit = true } } else { lb = false g_isQuit = true } case PLAY_STYLE_SLOOP: C.media_stop(unsafe.Pointer(pipeline)) fpath, ok := e.Value.(string) if ok { v2 := GString(fpath) C.set_path(unsafe.Pointer(pipeline), v2) GFree(unsafe.Pointer(v2)) C.media_ready(unsafe.Pointer(pipeline)) C.media_play(unsafe.Pointer(pipeline)) } case PLAY_STYLE_ALOOP: C.media_stop(unsafe.Pointer(pipeline)) if e != start { e = e.Prev() } else { e = end } fpath, ok := e.Value.(string) if ok { v2 := GString(fpath) C.set_path(unsafe.Pointer(pipeline), v2) GFree(unsafe.Pointer(v2)) C.media_ready(unsafe.Pointer(pipeline)) C.media_play(unsafe.Pointer(pipeline)) } } case 'q': lb = false g_isQuit = true case '+': g_volume_size++ C.set_volume(unsafe.Pointer(pipeline), C.int(g_volume_size)) case '-': g_volume_size-- if g_volume_size < 0 { g_volume_size = 0 } C.set_volume(unsafe.Pointer(pipeline), C.int(g_volume_size)) case 't': C.media_seek(unsafe.Pointer(pipeline), C.gint64(5)) } case vv0 := <-sig_out: if vv0 { C.g_main_loop_quit(loop) wg.Wait() g_wg.Done() g_wg.Wait() close(sig_out) os.Exit(0) } } } } else { // 路径非法 return } C.g_main_loop_quit(loop) wg.Wait() }
// g_value_set_int64 func (this *Value) SetInt(v int64) { C.g_value_set_int64(this.asC(), C.gint64(v)) }
func GInt64(val interface{}) *GValue { i := val.(int64) iv := C.gint64(i) return CreateCGValue(G_TYPE_INT64, unsafe.Pointer(&iv)) }