gst

package module
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 2, 2023 License: BSD-3-Clause Imports: 6 Imported by: 0

README

Go bindings for GStreamer at a very early stage of maturity.

This package is based on GLib bindings. It should be goinstalable. Try

$ go get github.com/ziutek/gst

Documentation

See examples directory and http://gopkgdoc.appspot.com/pkg/github.com/ziutek/gst

To run examples use go run command:

$ cd examples
$ go run simple.go

To run live WebM example use go run live_webm.go and open http://127.0.0.1:8080 with your browser. You probably need to wait a long time for video because of small bitrate of this stream and big buffer in you browser.

Documentation

Overview

Bindings for GStreamer API

Index

Constants

View Source
const (
	MAP_READ      = MapFlags(C.GST_MAP_READ)
	MAP_WRITE     = MapFlags(C.GST_MAP_WRITE)
	MAP_FLAG_LAST = MapFlags(C.GST_MAP_FLAG_LAST)
)
View Source
const (
	STATE_VOID_PENDING = State(C.GST_STATE_VOID_PENDING)
	STATE_NULL         = State(C.GST_STATE_NULL)
	STATE_READY        = State(C.GST_STATE_READY)
	STATE_PAUSED       = State(C.GST_STATE_PAUSED)
	STATE_PLAYING      = State(C.GST_STATE_PLAYING)
)
View Source
const (
	STATE_CHANGE_FAILURE    = StateChangeReturn(C.GST_STATE_CHANGE_FAILURE)
	STATE_CHANGE_SUCCESS    = StateChangeReturn(C.GST_STATE_CHANGE_SUCCESS)
	STATE_CHANGE_ASYNC      = StateChangeReturn(C.GST_STATE_CHANGE_ASYNC)
	STATE_CHANGE_NO_PREROLL = StateChangeReturn(C.GST_STATE_CHANGE_NO_PREROLL)
)
View Source
const (
	MESSAGE_UNKNOWN          = MessageType(C.GST_MESSAGE_UNKNOWN)
	MESSAGE_EOS              = MessageType(C.GST_MESSAGE_EOS)
	MESSAGE_ERROR            = MessageType(C.GST_MESSAGE_ERROR)
	MESSAGE_WARNING          = MessageType(C.GST_MESSAGE_WARNING)
	MESSAGE_INFO             = MessageType(C.GST_MESSAGE_INFO)
	MESSAGE_TAG              = MessageType(C.GST_MESSAGE_TAG)
	MESSAGE_BUFFERING        = MessageType(C.GST_MESSAGE_BUFFERING)
	MESSAGE_STATE_CHANGED    = MessageType(C.GST_MESSAGE_STATE_CHANGED)
	MESSAGE_STATE_DIRTY      = MessageType(C.GST_MESSAGE_STATE_DIRTY)
	MESSAGE_STEP_DONE        = MessageType(C.GST_MESSAGE_STEP_DONE)
	MESSAGE_CLOCK_PROVIDE    = MessageType(C.GST_MESSAGE_CLOCK_PROVIDE)
	MESSAGE_CLOCK_LOST       = MessageType(C.GST_MESSAGE_CLOCK_LOST)
	MESSAGE_NEW_CLOCK        = MessageType(C.GST_MESSAGE_NEW_CLOCK)
	MESSAGE_STRUCTURE_CHANGE = MessageType(C.GST_MESSAGE_STRUCTURE_CHANGE)
	MESSAGE_STREAM_STATUS    = MessageType(C.GST_MESSAGE_STREAM_STATUS)
	MESSAGE_APPLICATION      = MessageType(C.GST_MESSAGE_APPLICATION)
	MESSAGE_ELEMENT          = MessageType(C.GST_MESSAGE_ELEMENT)
	MESSAGE_SEGMENT_START    = MessageType(C.GST_MESSAGE_SEGMENT_START)
	MESSAGE_SEGMENT_DONE     = MessageType(C.GST_MESSAGE_SEGMENT_DONE)
	MESSAGE_DURATION         = MessageType(C.GST_MESSAGE_DURATION)
	MESSAGE_LATENCY          = MessageType(C.GST_MESSAGE_LATENCY)
	MESSAGE_ASYNC_START      = MessageType(C.GST_MESSAGE_ASYNC_START)
	MESSAGE_ASYNC_DONE       = MessageType(C.GST_MESSAGE_ASYNC_DONE)
	MESSAGE_REQUEST_STATE    = MessageType(C.GST_MESSAGE_REQUEST_STATE)
	MESSAGE_STEP_START       = MessageType(C.GST_MESSAGE_STEP_START)
	MESSAGE_QOS              = MessageType(C.GST_MESSAGE_QOS)
	//MESSAGE_PROGRESS         = MessageType(C.GST_MESSAGE_PROGRESS)
	MESSAGE_ANY = MessageType(C.GST_MESSAGE_ANY)
)
View Source
const (
	PAD_LINK_OK              = PadLinkReturn(C.GST_PAD_LINK_OK)
	PAD_LINK_WRONG_HIERARCHY = PadLinkReturn(C.GST_PAD_LINK_WRONG_HIERARCHY)
	PAD_LINK_WAS_LINKED      = PadLinkReturn(C.GST_PAD_LINK_WAS_LINKED)
	PAD_LINK_WRONG_DIRECTION = PadLinkReturn(C.GST_PAD_LINK_WRONG_DIRECTION)
	PAD_LINK_NOFORMAT        = PadLinkReturn(C.GST_PAD_LINK_NOFORMAT)
	PAD_LINK_NOSCHED         = PadLinkReturn(C.GST_PAD_LINK_NOSCHED)
	PAD_LINK_REFUSED         = PadLinkReturn(C.GST_PAD_LINK_REFUSED)
)
View Source
const (
	/* custom success starts here */
	GST_FLOW_CUSTOM_SUCCESS_2 = C.GST_FLOW_CUSTOM_SUCCESS_2
	GST_FLOW_CUSTOM_SUCCESS_1 = C.GST_FLOW_CUSTOM_SUCCESS_1
	GST_FLOW_CUSTOM_SUCCESS   = C.GST_FLOW_CUSTOM_SUCCESS

	/* core predefined */
	GST_FLOW_OK = C.GST_FLOW_OK
	/* expected failures */
	GST_FLOW_NOT_LINKED = C.GST_FLOW_NOT_LINKED
	GST_FLOW_FLUSHING   = C.GST_FLOW_FLUSHING
	/* error cases */
	GST_FLOW_EOS            = C.GST_FLOW_EOS
	GST_FLOW_NOT_NEGOTIATED = C.GST_FLOW_NOT_NEGOTIATED
	GST_FLOW_ERROR          = C.GST_FLOW_ERROR
	GST_FLOW_NOT_SUPPORTED  = C.GST_FLOW_NOT_SUPPORTED

	/* custom error starts here */
	GST_FLOW_CUSTOM_ERROR   = C.GST_FLOW_CUSTOM_ERROR
	GST_FLOW_CUSTOM_ERROR_1 = C.GST_FLOW_CUSTOM_ERROR_1
	GST_FLOW_CUSTOM_ERROR_2 = C.GST_FLOW_CUSTOM_ERROR_2
)
View Source
const (
	PAD_UNKNOWN = PadDirection(C.GST_PAD_UNKNOWN)
	PAD_SRC     = PadDirection(C.GST_PAD_SRC)
	PAD_SINK    = PadDirection(C.GST_PAD_SINK)
)
View Source
const (
	QUEUE_NO_LEAK         = 0 // TODO QueueLeaky(C.GST_QUEUE_NO_LEAK)
	QUEUE_LEAK_UPSTREAM   = 1 // TODO QueueLeaky(C.GST_QUEUE_LEAK_UPSTREAM)
	QUEUE_LEAK_DOWNSTREAM = 2 // TODO QueueLeaky(C.GST_QUEUE_LEAK_DOWNSTREAM)
)
View Source
const GST_PADDING = C.GST_PADDING

Variables

View Source
var CLOCK_TIME_NONE = uint64(C.GST_CLOCK_TIME_NONE)
View Source
var TYPE_FOURCC, TYPE_INT_RANGE, TYPE_FRACTION glib.Type

Functions

func Btoi

func Btoi(b bool) int

func FilenameToURI

func FilenameToURI(filename string) (string, error)

returns (uri, gerror)

func Free

func Free(ptr *Memory)

func GetVersion

func GetVersion() (int, int, int, int)

func Itob

func Itob(i int) bool

Types

type AppSink

type AppSink struct {
	BaseSink
}

func NewAppSink

func NewAppSink(name string) *AppSink

func (*AppSink) AsAppSink

func (a *AppSink) AsAppSink() *AppSink

func (*AppSink) GetCaps

func (a *AppSink) GetCaps() *Caps

GetCaps implements GstCaps * gst_app_sink_get_caps ()

func (*AppSink) GetDrop

func (a *AppSink) GetDrop() bool

gboolean gst_app_sink_get_drop ()

func (*AppSink) GetMaxBuffers

func (a *AppSink) GetMaxBuffers() uint

GetMaxBuffers implements guint gst_app_sink_get_max_buffers ()

func (*AppSink) PullSample

func (a *AppSink) PullSample() *Sample

PullSample implements GstSample * gst_app_sink_pull_sample ()

func (*AppSink) SetCaps

func (a *AppSink) SetCaps(caps *Caps)

SetCaps implements void gst_app_sink_set_caps()

func (*AppSink) SetDrop

func (a *AppSink) SetDrop(drop bool)

SetDrop implements void gst_app_sink_set_drop ()

func (*AppSink) SetEmitSignals

func (a *AppSink) SetEmitSignals(emit bool)

SetEmitSignals implements void gst_app_sink_set_emit_signals ()

func (*AppSink) SetMaxBuffers

func (a *AppSink) SetMaxBuffers(buffers int)

SetMaxBuffers implements void gst_app_sink_set_max_buffers ()

func (*AppSink) TryPullSample

func (a *AppSink) TryPullSample(timeout uint64) *Sample

GstSample * gst_app_sink_try_pull_sample ()

type AppSrc

type AppSrc struct {
	BaseSrc
}

func NewAppSrc

func NewAppSrc(name string) *AppSrc

func (*AppSrc) AsAppSrc

func (b *AppSrc) AsAppSrc() *AppSrc

func (*AppSrc) EndOfStream

func (b *AppSrc) EndOfStream() int

func (*AppSrc) PushBuffer

func (b *AppSrc) PushBuffer(buffer *Buffer) int

func (*AppSrc) SetCaps

func (b *AppSrc) SetCaps(caps *Caps)

type BaseSink

type BaseSink struct {
	Element
}

func (*BaseSink) AsBaseSink

func (b *BaseSink) AsBaseSink() *BaseSink

func (*BaseSink) GetSync

func (b *BaseSink) GetSync() bool

GetSync implements gboolean gst_base_sink_get_sync ()

func (*BaseSink) SetAsync

func (b *BaseSink) SetAsync(enabled bool)

void gst_base_sink_set_async_enabled ()

func (*BaseSink) SetSync

func (b *BaseSink) SetSync(sync bool)

SetSync implements void gst_base_sink_set_sync ()

type BaseSrc

type BaseSrc struct {
	Element
}

func (*BaseSrc) AsBaseSrc

func (b *BaseSrc) AsBaseSrc() *BaseSrc

type BaseTransform

type BaseTransform struct {
	Element
}

func (*BaseTransform) AsBaseTransform

func (b *BaseTransform) AsBaseTransform() *BaseTransform

func (*BaseTransform) ReconfigureSink

func (b *BaseTransform) ReconfigureSink()

func (*BaseTransform) ReconfigureSrc

func (b *BaseTransform) ReconfigureSrc()

func (*BaseTransform) UpdateSrcCaps

func (b *BaseTransform) UpdateSrcCaps(caps *Caps) bool

type Bin

type Bin struct {
	Element
}

func NewBin

func NewBin(name string) *Bin

func ParseBinFromDescription

func ParseBinFromDescription(desc string) (*Bin, error)

Similar to gst_parse_launch, but makes a bin instead of a pipeline

func (*Bin) Add

func (b *Bin) Add(els ...*Element) bool

func (*Bin) AsBin

func (b *Bin) AsBin() *Bin

func (*Bin) GetByName

func (b *Bin) GetByName(name string) *Element

GetByName returns the element with the given name from a bin. Returns nil if no element with the given name is found in the bin.

func (*Bin) Remove

func (b *Bin) Remove(els ...*Element) bool

type Buffer

type Buffer struct {
	GstBuffer *GstBufferStruct
}

func NewBuffer

func NewBuffer() *Buffer

NewBuffer implements GstBuffer * gst_buffer_new ()

func NewBufferAllocate

func NewBufferAllocate(size uint) *Buffer

NewBufferAllocate implements GstBuffer * gst_buffer_new_allocate ()

func (*Buffer) AppendMemory

func (b *Buffer) AppendMemory(memory *Memory)

AppendMemory implements void gst_buffer_append_memory ()

func (*Buffer) Fill

func (b *Buffer) Fill(offset uint, src unsafe.Pointer, size uint) int

Fill implements gsize gst_buffer_fill ()

func (*Buffer) GetDuration

func (b *Buffer) GetDuration() uint64

func (*Buffer) GetSize

func (b *Buffer) GetSize() uint

GetSize implements gsize gst_buffer_get_size ()

func (*Buffer) Map

func (b *Buffer) Map(flags MapFlags) (bool, *MapInfo)

Map implements gboolean gst_buffer_map ()

func (*Buffer) MemSet

func (b *Buffer) MemSet(offset uint, val byte, size uint) int

MemSet implements gsize gst_buffer_memset ()

func (*Buffer) SetDTS

func (b *Buffer) SetDTS(value uint64)

SetDTS implements #define GST_BUFFER_DTS()

func (*Buffer) SetDuration

func (b *Buffer) SetDuration(value uint64)

SetDuration implements #define GST_BUFFER_DURATION()

func (*Buffer) SetOffset

func (b *Buffer) SetOffset(value uint64)

SetOffset implements #define GST_BUFFER_OFFSET()

func (*Buffer) SetOffsetEnd

func (b *Buffer) SetOffsetEnd(value uint64)

SetOffsetEnd implements #define GST_BUFFER_OFFSET_END()

func (*Buffer) SetPTS

func (b *Buffer) SetPTS(value uint64)

SetPTS implements #define GST_BUFFER_PTS()

func (*Buffer) Unmap

func (b *Buffer) Unmap(mi *MapInfo)

void gst_buffer_unmap ()

func (*Buffer) Unref

func (b *Buffer) Unref()

Unref implements void gst_buffer_unref ()

type BufferPool

type BufferPool struct {
	Object GstObj

	Flushing gint

	GstBufferPoolPrivate *GstBufferPoolPrivate
	// contains filtered or unexported fields
}

type Bus

type Bus struct {
	GstObj
}

func NewBus

func NewBus() *Bus

func (*Bus) AddSignalWatch

func (b *Bus) AddSignalWatch()

func (*Bus) AddSignalWatchFull

func (b *Bus) AddSignalWatchFull(priority int)

func (*Bus) AsBus

func (b *Bus) AsBus() *Bus

func (*Bus) DisableSyncMessageEmission

func (b *Bus) DisableSyncMessageEmission()

func (*Bus) EnableSyncMessageEmission

func (b *Bus) EnableSyncMessageEmission()

func (*Bus) HavePending

func (b *Bus) HavePending() bool

func (*Bus) Peek

func (b *Bus) Peek() *Message

func (*Bus) Poll

func (b *Bus) Poll(events MessageType, timeout int64) *Message

func (*Bus) Pop

func (b *Bus) Pop() *Message

func (*Bus) PopFiltered

func (b *Bus) PopFiltered(types MessageType) *Message

func (*Bus) Post

func (b *Bus) Post(msg *Message) bool

func (*Bus) RemoveSignalWatch

func (b *Bus) RemoveSignalWatch()

func (*Bus) SetFlushing

func (b *Bus) SetFlushing(flushing bool)

func (*Bus) TimedPop

func (b *Bus) TimedPop(timeout uint64) *Message

func (*Bus) TimedPopFiltered

func (b *Bus) TimedPopFiltered(timeout uint64, types MessageType) *Message

type Caps

type Caps C.GstCaps

func CapsFromString

func CapsFromString(s string) *Caps

func NewCapsAny

func NewCapsAny() *Caps

func NewCapsEmpty

func NewCapsEmpty() *Caps

func NewCapsSimple

func NewCapsSimple(media_type string, fields glib.Params) *Caps

func (*Caps) AppendStructure

func (c *Caps) AppendStructure(media_type string, fields glib.Params)

func (*Caps) GetSize

func (c *Caps) GetSize() int

func (*Caps) GetStructure

func (c *Caps) GetStructure(v uint) *Structure

func (*Caps) Ref

func (c *Caps) Ref() *Caps

func (*Caps) RefCount

func (c *Caps) RefCount() int

func (*Caps) String

func (c *Caps) String() string

func (*Caps) Unref

func (c *Caps) Unref()

type CapsFilter

type CapsFilter struct {
	BaseTransform
}

func NewCapsFilter

func NewCapsFilter(name string) *CapsFilter

func (*CapsFilter) SetCaps

func (b *CapsFilter) SetCaps(caps *Caps)

func (*CapsFilter) SetResolution

func (b *CapsFilter) SetResolution(width, height int)

type Clock

type Clock struct {
	GstObj
}

func (*Clock) AsClock

func (c *Clock) AsClock() *Clock

type Element

type Element struct {
	GstObj
}

func ElementFactoryMake

func ElementFactoryMake(factory_name, name string) *Element

TODO: Move ElementFactoryMake to element_factory.go

func (*Element) AddPad

func (e *Element) AddPad(p *Pad) bool

func (*Element) AsElement

func (e *Element) AsElement() *Element

func (*Element) GetBus

func (e *Element) GetBus() *Bus

func (*Element) GetRequestPad

func (e *Element) GetRequestPad(name string) *Pad

func (*Element) GetState

func (e *Element) GetState(timeout_ns int64) (state, pending State,
	ret StateChangeReturn)

func (*Element) GetStaticPad

func (e *Element) GetStaticPad(name string) *Pad
func (e *Element) Link(next ...*Element) bool

func (*Element) LinkFiltered

func (e *Element) LinkFiltered(dst *Element, filter *Caps) bool

func (*Element) LinkPads

func (e *Element) LinkPads(pad_name string, dst *Element, dst_pad_name string) bool

func (*Element) SetState

func (e *Element) SetState(state State) StateChangeReturn
func (e *Element) Unlink(next ...*Element)

func (*Element) UnlinkPads

func (e *Element) UnlinkPads(pad_name string, dst *Element, dst_pad_name string)

type Fourcc

type Fourcc uint32

func MakeFourcc

func MakeFourcc(a, b, c, d byte) Fourcc

func StrFourcc

func StrFourcc(s string) Fourcc

func ValueFourcc

func ValueFourcc(v *glib.Value) Fourcc

func (Fourcc) String

func (f Fourcc) String() string

func (Fourcc) Type

func (f Fourcc) Type() glib.Type

func (Fourcc) Value

func (f Fourcc) Value() *glib.Value

type Fraction

type Fraction struct {
	Numer, Denom int
}

func ValueFraction

func ValueFraction(v *glib.Value) *Fraction

func (*Fraction) String

func (r *Fraction) String() string

func (*Fraction) Type

func (f *Fraction) Type() glib.Type

func (*Fraction) Value

func (f *Fraction) Value() *glib.Value

type GhostPad

type GhostPad struct {
	Pad
}

func NewGhostPad

func NewGhostPad(name string, target *Pad) *GhostPad

func NewGhostPadNoTarget

func NewGhostPadNoTarget(name string, dir PadDirection) *GhostPad

func (*GhostPad) AsGhostPad

func (p *GhostPad) AsGhostPad() *GhostPad

func (*GhostPad) Construct

func (p *GhostPad) Construct() bool

func (*GhostPad) GetTarget

func (p *GhostPad) GetTarget() *Pad

func (*GhostPad) SetTarget

func (p *GhostPad) SetTarget(new_target *Pad) bool

type GstBufferPoolPrivate

type GstBufferPoolPrivate C.GstBufferPoolPrivate

type GstBufferStruct

type GstBufferStruct C.GstBuffer

type GstObj

type GstObj struct {
	glib.Object
}

func (*GstObj) AsGstObj

func (o *GstObj) AsGstObj() *GstObj

func (*GstObj) GetName

func (o *GstObj) GetName() string

MT safe.

func (*GstObj) GetParent

func (o *GstObj) GetParent() *GstObj

Returns the parent of o. Increases the refcount of the parent object so you should Unref it after usage.

func (*GstObj) GetPathString

func (o *GstObj) GetPathString() string

Generates a string describing the path of object in the object hierarchy. Only useful (or used) for debugging.

func (*GstObj) SetName

func (o *GstObj) SetName(name string) bool

Sets the name of object. Returns true if the name could be set. MT safe.

func (*GstObj) SetParent

func (o *GstObj) SetParent(p *GstObj) bool

Sets the parent of o to p. This function causes the parent-set signal to be emitted when the parent was successfully set.

func (*GstObj) Unparent

func (o *GstObj) Unparent()

Clear the parent of object, removing the associated reference. This function decreases the refcount of o. MT safe. Grabs and releases object's lock.

type GstSampleStruct

type GstSampleStruct C.GstSample

type IntRange

type IntRange struct {
	Start, End int
}

func ValueRange

func ValueRange(v *glib.Value) *IntRange

func (*IntRange) String

func (r *IntRange) String() string

func (*IntRange) Type

func (r *IntRange) Type() glib.Type

func (*IntRange) Value

func (r *IntRange) Value() *glib.Value

type MapFlags

type MapFlags C.GstMapFlags

func (MapFlags) String

func (f MapFlags) String() string

type MapInfo

type MapInfo C.GstMapInfo

func (*MapInfo) GetData

func (m *MapInfo) GetData() []byte

type Memory

type Memory C.GstMemory

func Allocate

func Allocate(size uint32) *Memory

type Message

type Message C.GstMessage

func (*Message) GetSrc

func (m *Message) GetSrc() *GstObj

func (*Message) GetStructure

func (m *Message) GetStructure() (string, glib.Params)

func (*Message) GetType

func (m *Message) GetType() MessageType

func (*Message) ParseError

func (m *Message) ParseError() (err *glib.Error, debug string)

func (*Message) ParseWarning

func (m *Message) ParseWarning() (err *glib.Error, debug string)

func (*Message) Ref

func (m *Message) Ref() *Message

func (*Message) Type

func (m *Message) Type() glib.Type

func (*Message) Unref

func (m *Message) Unref()

type MessageType

type MessageType C.GstMessageType

func (MessageType) String

func (t MessageType) String() string

type Pad

type Pad struct {
	GstObj
}

func (*Pad) AsPad

func (p *Pad) AsPad() *Pad
func (p *Pad) CanLink(sink_pad *Pad) bool

func (*Pad) GetCurrentCaps

func (p *Pad) GetCurrentCaps() *Caps
func (p *Pad) Link(sink_pad *Pad) PadLinkReturn

type PadDirection

type PadDirection C.GstPadDirection

func (PadDirection) String

func (p PadDirection) String() string

type PadLinkReturn

type PadLinkReturn C.GstPadLinkReturn

func (PadLinkReturn) String

func (p PadLinkReturn) String() string

type Pipeline

type Pipeline struct {
	Bin
}

func NewPipeline

func NewPipeline(name string) *Pipeline

func ParseLaunch

func ParseLaunch(pipeline_description string) (*Pipeline, error)

func (*Pipeline) AsPipeline

func (p *Pipeline) AsPipeline() *Pipeline

type QueueLeaky

type QueueLeaky int // TODO C.GstQueueLeaky

func (QueueLeaky) String

func (q QueueLeaky) String() string

type Sample

type Sample struct {
	GstSample *GstSampleStruct
}

func (*Sample) GetBuffer

func (s *Sample) GetBuffer() *Buffer

GetBuffer implements GstBuffer * gst_sample_get_buffer ()

func (*Sample) GetCaps

func (s *Sample) GetCaps() *Caps

GetCaps implements GstCaps * gst_sample_get_caps ()

func (*Sample) Unref

func (s *Sample) Unref()

Unref implements void gst_sample_unref ()

type State

type State C.GstState

func (State) String

func (s State) String() string

type StateChangeReturn

type StateChangeReturn C.GstStateChangeReturn

type Structure

type Structure C.GstStructure

func (*Structure) GetInt

func (s *Structure) GetInt(field string) int

func (*Structure) GetString

func (s *Structure) GetString(field string) string

func (*Structure) ToString

func (s *Structure) ToString() string

Directories

Path Synopsis
This simple test application create live H264 (or WebM - see commented lines) content from test source, decode it and display.
This simple test application create live H264 (or WebM - see commented lines) content from test source, decode it and display.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL