├── goav ├── _config.yml ├── example │ ├── sample.mp4 │ ├── versions.go │ └── tutorial01.go ├── go.mod ├── avformat │ ├── rational.go │ ├── packet.go │ ├── media_types.go │ ├── flags.go │ ├── avformat_test.go │ ├── stream.go │ ├── codec_context_struct.go │ ├── stream_struct.go │ └── context_struct.go ├── go.sum ├── avutil │ ├── log.go │ ├── error.go │ ├── avutil.go │ ├── dict.go │ └── memory.go ├── goav.go ├── avfilter │ ├── filter.go │ ├── graph.go │ └── avfilter.go ├── avdevice │ ├── format.go │ └── avdevice.go ├── LICENSE ├── avcodec │ ├── rational.go │ ├── packet_struct.go │ ├── bitstreamfilter.go │ ├── pixelformat.go │ ├── flags.go │ ├── avpicture.go │ ├── packet.go │ └── pixel.go ├── swresample │ ├── swresample.go │ └── context.go ├── swscale │ ├── context.go │ ├── vector.go │ └── swscale.go └── README.md ├── redigo └── redis │ ├── go18.go │ ├── commandinfo_test.go │ ├── go17.go │ ├── commandinfo.go │ ├── list_test.go │ ├── redis_test.go │ ├── pubsub_test.go │ ├── zpop_example_test.go │ ├── script_test.go │ ├── script.go │ ├── log.go │ ├── pubsub.go │ ├── redis.go │ ├── pubsub_example_test.go │ ├── test_test.go │ └── reply_test.go ├── unit_test ├── cron.go ├── nats.go ├── wait.go ├── heap.go ├── json.go ├── h264_rtp_send.go ├── redis.go ├── channel.go ├── rtp.go ├── decoder.go └── encoder.go ├── cron ├── constantdelay.go ├── constantdelay_test.go ├── spec.go ├── doc.go ├── parser_test.go └── cron.go ├── encoder └── encoder.go ├── rtp └── packet.go ├── h264 └── parser.go └── decoder └── decoder.go /goav/_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-minimal -------------------------------------------------------------------------------- /goav/example/sample.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanade2010/goav_rtp_h264_overlay_example/HEAD/goav/example/sample.mp4 -------------------------------------------------------------------------------- /redigo/redis/go18.go: -------------------------------------------------------------------------------- 1 | // +build go1.8 2 | 3 | package redis 4 | 5 | import "crypto/tls" 6 | 7 | func cloneTLSConfig(cfg *tls.Config) *tls.Config { 8 | return cfg.Clone() 9 | } 10 | -------------------------------------------------------------------------------- /goav/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/giorgisio/goav 2 | 3 | require ( 4 | github.com/gosuri/uilive v0.0.0-20170323041506-ac356e6e42cd // indirect 5 | github.com/gosuri/uiprogress v0.0.0-20170224063937-d0567a9d84a1 // indirect 6 | ) 7 | -------------------------------------------------------------------------------- /unit_test/cron.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | 4 | import( 5 | "../cron" 6 | "fmt" 7 | "time" 8 | "os" 9 | ) 10 | 11 | func main() { 12 | 13 | args := os.Args 14 | fmt.Println(args) 15 | 16 | cron := cron.New() 17 | 18 | cron.Start() 19 | 20 | cron.AddFunc("*/3 * * * * ?", func(){fmt.Println("tick happen!")}) 21 | 22 | time.Sleep(10000*time.Second) 23 | } -------------------------------------------------------------------------------- /goav/avformat/rational.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a MIT license that can be found in the LICENSE file. 2 | // Giorgis (habtom@giorgis.io) 3 | 4 | package avformat 5 | 6 | //#cgo pkg-config: libavutil 7 | //#include 8 | import "C" 9 | import "github.com/giorgisio/goav/avcodec" 10 | 11 | func newRational(r C.struct_AVRational) avcodec.Rational { 12 | return avcodec.NewRational(int(r.num), int(r.den)) 13 | } 14 | -------------------------------------------------------------------------------- /goav/go.sum: -------------------------------------------------------------------------------- 1 | github.com/gosuri/uilive v0.0.0-20170323041506-ac356e6e42cd h1:1e+0Z+T4t1mKL5xxvxXh5FkjuiToQGKreCobLu7lR3Y= 2 | github.com/gosuri/uilive v0.0.0-20170323041506-ac356e6e42cd/go.mod h1:qkLSc0A5EXSP6B04TrN4oQoxqFI7A8XvoXSlJi8cwk8= 3 | github.com/gosuri/uiprogress v0.0.0-20170224063937-d0567a9d84a1 h1:4iPLwzjiWGBQnYdtKbg/JNlGlEEvklrrMdjypdA1LKQ= 4 | github.com/gosuri/uiprogress v0.0.0-20170224063937-d0567a9d84a1/go.mod h1:C1RTYn4Sc7iEyf6j8ft5dyoZ4212h8G1ol9QQluh5+0= 5 | -------------------------------------------------------------------------------- /unit_test/nats.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | nats "../nats.go" 5 | "time" 6 | // "fmt" 7 | ) 8 | 9 | func main() { 10 | 11 | // Connect to a server 12 | nc, _ := nats.Connect(nats.DefaultURL) 13 | 14 | b := []byte{0,1} 15 | 16 | // Simple Async Subscriber 17 | nc.Publish("aaa:SwitchingChan", b) 18 | 19 | // Channel Subscriber 20 | /*ch := make(chan *nats.Msg, 64) 21 | sub, err := nc.ChanSubscribe("foo", ch) 22 | msg := <- ch*/ 23 | 24 | 25 | time.Sleep(10*time.Hour) 26 | 27 | // Close connection 28 | nc.Close() 29 | 30 | } 31 | -------------------------------------------------------------------------------- /goav/avformat/packet.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a MIT license that can be found in the LICENSE file. 2 | // Giorgis (habtom@giorgis.io) 3 | 4 | package avformat 5 | 6 | //#cgo pkg-config: libavformat 7 | //#include 8 | import "C" 9 | import ( 10 | "unsafe" 11 | 12 | "github.com/giorgisio/goav/avcodec" 13 | ) 14 | 15 | func toCPacket(pkt *avcodec.Packet) *C.struct_AVPacket { 16 | return (*C.struct_AVPacket)(unsafe.Pointer(pkt)) 17 | } 18 | 19 | func fromCPacket(pkt *C.struct_AVPacket) *avcodec.Packet { 20 | return (*avcodec.Packet)(unsafe.Pointer(pkt)) 21 | } 22 | -------------------------------------------------------------------------------- /goav/avformat/media_types.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a MIT license that can be found in the LICENSE file. 2 | 3 | package avformat 4 | 5 | //#cgo pkg-config: libavutil 6 | //#include 7 | import "C" 8 | 9 | const ( 10 | AVMEDIA_TYPE_UNKNOWN = C.AVMEDIA_TYPE_UNKNOWN 11 | AVMEDIA_TYPE_VIDEO = C.AVMEDIA_TYPE_VIDEO 12 | AVMEDIA_TYPE_AUDIO = C.AVMEDIA_TYPE_AUDIO 13 | AVMEDIA_TYPE_DATA = C.AVMEDIA_TYPE_DATA 14 | AVMEDIA_TYPE_SUBTITLE = C.AVMEDIA_TYPE_SUBTITLE 15 | AVMEDIA_TYPE_ATTACHMENT = C.AVMEDIA_TYPE_ATTACHMENT 16 | AVMEDIA_TYPE_NB = C.AVMEDIA_TYPE_NB 17 | ) 18 | -------------------------------------------------------------------------------- /goav/avutil/log.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a MIT license that can be found in the LICENSE file. 2 | // Giorgis (habtom@giorgis.io) 3 | 4 | package avutil 5 | 6 | /* 7 | #cgo pkg-config: libavutil 8 | #include 9 | #include 10 | */ 11 | import "C" 12 | 13 | const ( 14 | AV_LOG_QUIET = -8 15 | AV_LOG_PANIC = 0 16 | AV_LOG_FATAL = 8 17 | AV_LOG_ERROR = 16 18 | AV_LOG_WARNING = 24 19 | AV_LOG_INFO = 32 20 | AV_LOG_VERBOSE = 40 21 | AV_LOG_DEBUG = 48 22 | AV_LOG_TRACE = 56 23 | ) 24 | 25 | func AvLogSetLevel(level int) { 26 | C.av_log_set_level(C.int(level)) 27 | } 28 | 29 | func AvLogGetLevel() int { 30 | return int(C.av_log_get_level()) 31 | } 32 | -------------------------------------------------------------------------------- /goav/goav.go: -------------------------------------------------------------------------------- 1 | //Use of this source code is governed by a MIT license that can be found in the LICENSE file. 2 | //Giorgis (habtom@giorgis.io) 3 | 4 | /* 5 | Package goav contains golang binding for FFmpeg. 6 | 7 | A comprehensive binding to the ffmpeg video/audio manipulation library: 8 | https://www.ffmpeg.org/ 9 | 10 | Contains: 11 | 12 | libavcodec: encoding/decoding library 13 | libavfilter: graph-based frame editing library 14 | libavformat: I/O and muxing/demuxing library 15 | libavdevice: special devices muxing/demuxing library 16 | libavutil: common utility library 17 | libswresample: audio resampling, format conversion and mixing 18 | libpostproc: post processing library 19 | libswscale: color conversion and scaling library 20 | */ 21 | package goav 22 | -------------------------------------------------------------------------------- /goav/avfilter/filter.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a MIT license that can be found in the LICENSE file. 2 | // Giorgis (habtom@giorgis.io) 3 | 4 | package avfilter 5 | 6 | /* 7 | #cgo pkg-config: libavfilter 8 | #include 9 | */ 10 | import "C" 11 | 12 | //Get a filter definition matching the given name. 13 | func AvfilterGetByName(n string) *Filter { 14 | return (*Filter)(C.avfilter_get_by_name(C.CString(n))) 15 | } 16 | 17 | //Register a filter. 18 | func (f *Filter) AvfilterRegister() int { 19 | return int(C.avfilter_register((*C.struct_AVFilter)(f))) 20 | } 21 | 22 | //Iterate over all registered filters. 23 | func (f *Filter) AvfilterNext() *Filter { 24 | return (*Filter)(C.avfilter_next((*C.struct_AVFilter)(f))) 25 | } 26 | -------------------------------------------------------------------------------- /redigo/redis/commandinfo_test.go: -------------------------------------------------------------------------------- 1 | package redis 2 | 3 | import "testing" 4 | 5 | func TestLookupCommandInfo(t *testing.T) { 6 | for _, n := range []string{"watch", "WATCH", "wAtch"} { 7 | if lookupCommandInfo(n) == (commandInfo{}) { 8 | t.Errorf("LookupCommandInfo(%q) = CommandInfo{}, expected non-zero value", n) 9 | } 10 | } 11 | } 12 | 13 | func benchmarkLookupCommandInfo(b *testing.B, names ...string) { 14 | for i := 0; i < b.N; i++ { 15 | for _, c := range names { 16 | lookupCommandInfo(c) 17 | } 18 | } 19 | } 20 | 21 | func BenchmarkLookupCommandInfoCorrectCase(b *testing.B) { 22 | benchmarkLookupCommandInfo(b, "watch", "WATCH", "monitor", "MONITOR") 23 | } 24 | 25 | func BenchmarkLookupCommandInfoMixedCase(b *testing.B) { 26 | benchmarkLookupCommandInfo(b, "wAtch", "WeTCH", "monItor", "MONiTOR") 27 | } 28 | -------------------------------------------------------------------------------- /unit_test/wait.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import( 4 | "time" 5 | "fmt" 6 | ) 7 | 8 | var w1 chan struct{} = make(chan struct{}) 9 | var w2 chan struct{} = make(chan struct{}) 10 | var wall chan struct{} = make(chan struct{}) 11 | 12 | 13 | 14 | func w1fun() { 15 | 16 | time.Sleep(6*time.Second) 17 | 18 | w1 <- struct{}{} 19 | <- wall 20 | fmt.Println("---w1 wall") 21 | 22 | } 23 | 24 | func w2fun() { 25 | 26 | time.Sleep(4*time.Second) 27 | 28 | w2 <- struct{}{} 29 | <- wall 30 | fmt.Println("---w2 wall") 31 | 32 | } 33 | 34 | func main() { 35 | 36 | fmt.Println("---main---") 37 | 38 | go w1fun() 39 | go w2fun() 40 | 41 | <- w1 42 | fmt.Println("---w1") 43 | <- w2 44 | fmt.Println("---w2") 45 | 46 | wall <- struct{}{} 47 | wall <- struct{}{} 48 | 49 | time.Sleep(30*time.Hour) 50 | 51 | } -------------------------------------------------------------------------------- /goav/example/versions.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | 6 | "github.com/giorgisio/goav/avcodec" 7 | "github.com/giorgisio/goav/avdevice" 8 | "github.com/giorgisio/goav/avfilter" 9 | "github.com/giorgisio/goav/avformat" 10 | "github.com/giorgisio/goav/avutil" 11 | "github.com/giorgisio/goav/swresample" 12 | "github.com/giorgisio/goav/swscale" 13 | ) 14 | 15 | func main() { 16 | 17 | // Register all formats and codecs 18 | avformat.AvRegisterAll() 19 | avcodec.AvcodecRegisterAll() 20 | 21 | log.Printf("AvFilter Version:\t%v", avfilter.AvfilterVersion()) 22 | log.Printf("AvDevice Version:\t%v", avdevice.AvdeviceVersion()) 23 | log.Printf("SWScale Version:\t%v", swscale.SwscaleVersion()) 24 | log.Printf("AvUtil Version:\t%v", avutil.AvutilVersion()) 25 | log.Printf("AvCodec Version:\t%v", avcodec.AvcodecVersion()) 26 | log.Printf("Resample Version:\t%v", swresample.SwresampleLicense()) 27 | 28 | } 29 | -------------------------------------------------------------------------------- /goav/avformat/flags.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a MIT license that can be found in the LICENSE file. 2 | // Giorgis (habtom@giorgis.io) 3 | 4 | //Package avformat provides some generic global options, which can be set on all the muxers and demuxers. 5 | //In addition each muxer or demuxer may support so-called private options, which are specific for that component. 6 | //Supported formats (muxers and demuxers) provided by the libavformat library 7 | package avformat 8 | 9 | //#cgo pkg-config: libavformat libavcodec libavutil libavdevice libavfilter libswresample libswscale 10 | //#include 11 | //#include 12 | //#include 13 | //#include 14 | //#include 15 | //#include 16 | //#include 17 | import "C" 18 | 19 | const ( 20 | AVIO_FLAG_READ = int(C.AVIO_FLAG_READ) 21 | AVIO_FLAG_WRITE = int(C.AVIO_FLAG_WRITE) 22 | AVIO_FLAG_READ_WRITE = int(C.AVIO_FLAG_READ_WRITE) 23 | ) 24 | -------------------------------------------------------------------------------- /goav/avutil/error.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a MIT license that can be found in the LICENSE file. 2 | // Giorgis (habtom@giorgis.io) 3 | 4 | // Package avutil is a utility library to aid portable multimedia programming. 5 | // It contains safe portable string functions, random number generators, data structures, 6 | // additional mathematics functions, cryptography and multimedia related functionality. 7 | // Some generic features and utilities provided by the libavutil library 8 | package avutil 9 | 10 | //#cgo pkg-config: libavutil 11 | //#include 12 | //#include 13 | //static const char *error2string(int code) { return av_err2str(code); } 14 | import "C" 15 | import "errors" 16 | 17 | const ( 18 | AvErrorEOF = -('E' | ('O' << 8) | ('F' << 16) | (' ' << 24)) 19 | AvErrorEAGAIN = -35 20 | ) 21 | 22 | func ErrorFromCode(code int) error { 23 | if code >= 0 { 24 | return nil 25 | } 26 | 27 | return errors.New(C.GoString(C.error2string(C.int(code)))) 28 | } 29 | -------------------------------------------------------------------------------- /goav/avformat/avformat_test.go: -------------------------------------------------------------------------------- 1 | 2 | package avformat_test 3 | 4 | import ( 5 | "testing" 6 | 7 | "github.com/giorgisio/goav/avformat" 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func TestAvUrlSplitWithSufficientSizes(t *testing.T) { 12 | url := "rtsp://user:password@example.com:554/path" 13 | var port int 14 | proto, authorization, hostname, path := avformat.AvUrlSplit(100, 100, 100, &port, 100, url) 15 | 16 | assert.Equal(t, "rtsp", proto) 17 | assert.Equal(t, "user:password", authorization) 18 | assert.Equal(t, "example.com", hostname) 19 | assert.Equal(t, 554, port) 20 | assert.Equal(t, "/path", path) 21 | } 22 | 23 | func TestAvUrlSplitWithInsufficientSizes(t *testing.T) { 24 | url := "https://user:password@example.com:443/here/is/the/path" 25 | proto, authorization, hostname, path := avformat.AvUrlSplit(3, 5, 5, nil, 5, url) 26 | 27 | assert.Equal(t, "ht", proto) 28 | assert.Equal(t, "user", authorization) 29 | assert.Equal(t, "exam", hostname) 30 | assert.Equal(t, "/her", path) 31 | } 32 | -------------------------------------------------------------------------------- /cron/constantdelay.go: -------------------------------------------------------------------------------- 1 | package cron 2 | 3 | import "time" 4 | 5 | // ConstantDelaySchedule represents a simple recurring duty cycle, e.g. "Every 5 minutes". 6 | // It does not support jobs more frequent than once a second. 7 | type ConstantDelaySchedule struct { 8 | Delay time.Duration 9 | } 10 | 11 | // Every returns a crontab Schedule that activates once every duration. 12 | // Delays of less than a second are not supported (will round up to 1 second). 13 | // Any fields less than a Second are truncated. 14 | func Every(duration time.Duration) ConstantDelaySchedule { 15 | if duration < time.Second { 16 | duration = time.Second 17 | } 18 | return ConstantDelaySchedule{ 19 | Delay: duration - time.Duration(duration.Nanoseconds())%time.Second, 20 | } 21 | } 22 | 23 | // Next returns the next time this should be run. 24 | // This rounds so that the next activation time will be on the second. 25 | func (schedule ConstantDelaySchedule) Next(t time.Time) time.Time { 26 | return t.Add(schedule.Delay - time.Duration(t.Nanosecond())*time.Nanosecond) 27 | } 28 | -------------------------------------------------------------------------------- /goav/avdevice/format.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a MIT license that can be found in the LICENSE file. 2 | // Giorgis (habtom@giorgis.io) 3 | 4 | package avdevice 5 | 6 | /* 7 | #cgo pkg-config: libavdevice 8 | #include 9 | */ 10 | import "C" 11 | 12 | //Audio input devices iterator. 13 | func (d *InputFormat) AvInputAudioDeviceNext() *InputFormat { 14 | return (*InputFormat)(C.av_input_audio_device_next((*C.struct_AVInputFormat)(d))) 15 | } 16 | 17 | //Video input devices iterator. 18 | func (d *InputFormat) AvInputVideoDeviceNext() *InputFormat { 19 | return (*InputFormat)(C.av_input_video_device_next((*C.struct_AVInputFormat)(d))) 20 | } 21 | 22 | //Audio output devices iterator. 23 | func (d *OutputFormat) AvOutputAudioDeviceNext() *OutputFormat { 24 | return (*OutputFormat)(C.av_output_audio_device_next((*C.struct_AVOutputFormat)(d))) 25 | } 26 | 27 | //Video output devices iterator. 28 | func (d *OutputFormat) AvOutputVideoDeviceNext() *OutputFormat { 29 | return (*OutputFormat)(C.av_output_video_device_next((*C.struct_AVOutputFormat)(d))) 30 | } 31 | -------------------------------------------------------------------------------- /goav/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 H.G. Giorgis 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /redigo/redis/go17.go: -------------------------------------------------------------------------------- 1 | // +build go1.7,!go1.8 2 | 3 | package redis 4 | 5 | import "crypto/tls" 6 | 7 | func cloneTLSConfig(cfg *tls.Config) *tls.Config { 8 | return &tls.Config{ 9 | Rand: cfg.Rand, 10 | Time: cfg.Time, 11 | Certificates: cfg.Certificates, 12 | NameToCertificate: cfg.NameToCertificate, 13 | GetCertificate: cfg.GetCertificate, 14 | RootCAs: cfg.RootCAs, 15 | NextProtos: cfg.NextProtos, 16 | ServerName: cfg.ServerName, 17 | ClientAuth: cfg.ClientAuth, 18 | ClientCAs: cfg.ClientCAs, 19 | InsecureSkipVerify: cfg.InsecureSkipVerify, 20 | CipherSuites: cfg.CipherSuites, 21 | PreferServerCipherSuites: cfg.PreferServerCipherSuites, 22 | ClientSessionCache: cfg.ClientSessionCache, 23 | MinVersion: cfg.MinVersion, 24 | MaxVersion: cfg.MaxVersion, 25 | CurvePreferences: cfg.CurvePreferences, 26 | DynamicRecordSizingDisabled: cfg.DynamicRecordSizingDisabled, 27 | Renegotiation: cfg.Renegotiation, 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /unit_test/heap.go: -------------------------------------------------------------------------------- 1 | // This example demonstrates an integer heap built using the heap interface. 2 | package main 3 | import ( 4 | "container/heap" 5 | "fmt" 6 | ) 7 | // An IntHeap is a min-heap of ints. 8 | type IntHeap []int 9 | func (h IntHeap) Len() int { return len(h) } 10 | func (h IntHeap) Less(i, j int) bool { return h[i] < h[j] } 11 | func (h IntHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } 12 | func (h *IntHeap) Push(x interface{}) { 13 | // Push and Pop use pointer receivers because they modify the slice's length, 14 | // not just its contents. 15 | *h = append(*h, x.(int)) 16 | } 17 | func (h *IntHeap) Pop() interface{} { 18 | old := *h 19 | n := len(old) 20 | x := old[n-1] 21 | *h = old[0 : n-1] 22 | return x 23 | } 24 | // This example inserts several ints into an IntHeap, checks the minimum, 25 | // and removes them in order of priority. 26 | func main() { 27 | h := &IntHeap{2, 1, 5} 28 | heap.Init(h) 29 | heap.Push(h, 3) 30 | fmt.Printf("minimum: %d\n", (*h)[0]) 31 | for h.Len() > 0 { 32 | fmt.Printf("%d ", heap.Pop(h)) 33 | } 34 | // Output: 35 | // minimum: 1 36 | // 1 2 3 5 37 | } -------------------------------------------------------------------------------- /goav/avcodec/rational.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a MIT license that can be found in the LICENSE file. 2 | // Giorgis (habtom@giorgis.io) 3 | 4 | //Package avcodec contains the codecs (decoders and encoders) provided by the libavcodec library 5 | //Provides some generic global options, which can be set on all the encoders and decoders. 6 | package avcodec 7 | 8 | //#cgo pkg-config: libavformat libavcodec libavutil 9 | //#include 10 | //#include 11 | //#include 12 | //#include 13 | //#include 14 | //#include 15 | //#include 16 | //#include 17 | import "C" 18 | import "fmt" 19 | 20 | func (r Rational) Num() int { 21 | return int(r.num) 22 | } 23 | 24 | func (r Rational) Den() int { 25 | return int(r.den) 26 | } 27 | 28 | func (r Rational) String() string { 29 | return fmt.Sprintln("%d/%d", int(r.num), int(r.den)) 30 | } 31 | 32 | func (r *Rational) Assign(o Rational) { 33 | r.Set(o.Num(), o.Den()) 34 | } 35 | 36 | func (r *Rational) Set(num, den int) { 37 | r.num, r.den = C.int(num), C.int(den) 38 | } 39 | 40 | func NewRational(num, den int) Rational { 41 | return Rational{ 42 | num: C.int(num), 43 | den: C.int(den), 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /goav/swresample/swresample.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a MIT license that can be found in the LICENSE file. 2 | // Giorgis (habtom@giorgis.io) 3 | 4 | // Package swresample provides a high-level interface to the libswresample library audio resampling utilities 5 | // The process of changing the sampling rate of a discrete signal to obtain a new discrete representation of the underlying continuous signal. 6 | package swresample 7 | 8 | /* 9 | #cgo pkg-config: libswresample 10 | #include 11 | */ 12 | import "C" 13 | 14 | type ( 15 | Context C.struct_SwrContext 16 | Frame C.struct_AVFrame 17 | Class C.struct_AVClass 18 | AvSampleFormat C.enum_AVSampleFormat 19 | ) 20 | 21 | //Get the Class for Context. 22 | func SwrGetClass() *Class { 23 | return (*Class)(C.swr_get_class()) 24 | } 25 | 26 | //Context constructor functions.Allocate Context. 27 | func SwrAlloc() *Context { 28 | return (*Context)(C.swr_alloc()) 29 | } 30 | 31 | //Configuration accessors 32 | func SwresampleVersion() uint { 33 | return uint(C.swresample_version()) 34 | } 35 | 36 | func SwresampleConfiguration() string { 37 | return C.GoString(C.swresample_configuration()) 38 | } 39 | 40 | func SwresampleLicense() string { 41 | return C.GoString(C.swresample_license()) 42 | } 43 | -------------------------------------------------------------------------------- /goav/avcodec/packet_struct.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a MIT license that can be found in the LICENSE file. 2 | // Giorgis (habtom@giorgis.io) 3 | 4 | package avcodec 5 | 6 | //#cgo pkg-config: libavcodec 7 | //#include 8 | import "C" 9 | 10 | func (p *Packet) Buf() *AvBufferRef { 11 | return (*AvBufferRef)(p.buf) 12 | } 13 | func (p *Packet) Duration() int { 14 | return int(p.duration) 15 | } 16 | func (p *Packet) Flags() int { 17 | return int(p.flags) 18 | } 19 | func (p *Packet) SetFlags(flags int) { 20 | p.flags = C.int(flags) 21 | } 22 | func (p *Packet) SideDataElems() int { 23 | return int(p.side_data_elems) 24 | } 25 | func (p *Packet) Size() int { 26 | return int(p.size) 27 | } 28 | func (p *Packet) StreamIndex() int { 29 | return int(p.stream_index) 30 | } 31 | func (p *Packet) SetStreamIndex(idx int) { 32 | p.stream_index = C.int(idx) 33 | } 34 | func (p *Packet) ConvergenceDuration() int64 { 35 | return int64(p.convergence_duration) 36 | } 37 | func (p *Packet) Dts() int64 { 38 | return int64(p.dts) 39 | } 40 | func (p *Packet) SetDts(dts int64) { 41 | p.dts = C.int64_t(dts) 42 | } 43 | func (p *Packet) Pos() int64 { 44 | return int64(p.pos) 45 | } 46 | func (p *Packet) Pts() int64 { 47 | return int64(p.pts) 48 | } 49 | func (p *Packet) SetPts(pts int64) { 50 | p.dts = C.int64_t(pts) 51 | } 52 | func (p *Packet) Data() *uint8 { 53 | return (*uint8)(p.data) 54 | } 55 | -------------------------------------------------------------------------------- /goav/avcodec/bitstreamfilter.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a MIT license that can be found in the LICENSE file. 2 | // Giorgis (habtom@giorgis.io) 3 | 4 | package avcodec 5 | 6 | //#cgo pkg-config: libavcodec 7 | //#include 8 | import "C" 9 | import ( 10 | "unsafe" 11 | ) 12 | 13 | //Register a bitstream filter. 14 | func (b *BitStreamFilter) AvRegisterBitstreamFilter() { 15 | C.av_register_bitstream_filter((*C.struct_AVBitStreamFilter)(b)) 16 | } 17 | 18 | //BitStreamFilter *av_bitstream_filter_next (const BitStreamFilter *f) 19 | func (f *BitStreamFilter) AvBitstreamFilterNext() *BitStreamFilter { 20 | return (*BitStreamFilter)(C.av_bitstream_filter_next((*C.struct_AVBitStreamFilter)(f))) 21 | } 22 | 23 | //Filter bitstream. 24 | func (bfx *BitStreamFilterContext) AvBitstreamFilterFilter(ctxt *Context, a string, p **uint8, ps *int, b *uint8, bs, k int) int { 25 | return int(C.av_bitstream_filter_filter((*C.struct_AVBitStreamFilterContext)(bfx), (*C.struct_AVCodecContext)(ctxt), C.CString(a), (**C.uint8_t)(unsafe.Pointer(p)), (*C.int)(unsafe.Pointer(ps)), (*C.uint8_t)(b), C.int(bs), C.int(k))) 26 | } 27 | 28 | //Release bitstream filter context. 29 | func (bfx *BitStreamFilterContext) AvBitstreamFilterClose() { 30 | C.av_bitstream_filter_close((*C.struct_AVBitStreamFilterContext)(bfx)) 31 | } 32 | 33 | //Create and initialize a bitstream filter context given a bitstream filter name. 34 | func AvBitstreamFilterInit(n string) *BitStreamFilterContext { 35 | return (*BitStreamFilterContext)(C.av_bitstream_filter_init(C.CString(n))) 36 | } 37 | -------------------------------------------------------------------------------- /goav/avcodec/pixelformat.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a MIT license that can be found in the LICENSE file. 2 | // Giorgis (habtom@giorgis.io) 3 | 4 | package avcodec 5 | 6 | //#cgo pkg-config: libavcodec 7 | //#include 8 | import "C" 9 | import ( 10 | "unsafe" 11 | ) 12 | 13 | //Utility function to access log2_chroma_w log2_chroma_h from the pixel format AvPixFmtDescriptor. 14 | func (p PixelFormat) AvcodecGetChromaSubSample(h, v *int) { 15 | C.avcodec_get_chroma_sub_sample((C.enum_AVPixelFormat)(p), (*C.int)(unsafe.Pointer(h)), (*C.int)(unsafe.Pointer(v))) 16 | } 17 | 18 | //Return a value representing the fourCC code associated to the pixel format pix_fmt, or 0 if no associated fourCC code can be found. 19 | func (p PixelFormat) AvcodecPixFmtToCodecTag() uint { 20 | return uint(C.avcodec_pix_fmt_to_codec_tag((C.enum_AVPixelFormat)(p))) 21 | } 22 | 23 | func (p PixelFormat) AvcodecGetPixFmtLoss(f PixelFormat, a int) int { 24 | return int(C.avcodec_get_pix_fmt_loss((C.enum_AVPixelFormat)(p), (C.enum_AVPixelFormat)(f), C.int(a))) 25 | } 26 | 27 | //Find the best pixel format to convert to given a certain source pixel format. 28 | func (p *PixelFormat) AvcodecFindBestPixFmtOfList(s PixelFormat, a int, l *int) PixelFormat { 29 | return (PixelFormat)(C.avcodec_find_best_pix_fmt_of_list((*C.enum_AVPixelFormat)(p), (C.enum_AVPixelFormat)(s), C.int(a), (*C.int)(unsafe.Pointer(l)))) 30 | } 31 | 32 | func (p PixelFormat) AvcodecFindBestPixFmtOf2(f2, s PixelFormat, a int, l *int) PixelFormat { 33 | return (PixelFormat)(C.avcodec_find_best_pix_fmt_of_2((C.enum_AVPixelFormat)(p), (C.enum_AVPixelFormat)(f2), (C.enum_AVPixelFormat)(s), C.int(a), (*C.int)(unsafe.Pointer(l)))) 34 | } 35 | -------------------------------------------------------------------------------- /goav/swscale/context.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a MIT license that can be found in the LICENSE file. 2 | // Giorgis (habtom@giorgis.io) 3 | 4 | package swscale 5 | 6 | //#cgo pkg-config: libswscale libavutil 7 | //#include 8 | import "C" 9 | import ( 10 | "unsafe" 11 | ) 12 | 13 | //Allocate an empty Context. 14 | func SwsAllocContext() *Context { 15 | return (*Context)(C.sws_alloc_context()) 16 | } 17 | 18 | //Initialize the swscaler context sws_context. 19 | func SwsInitContext(ctxt *Context, sf, df *Filter) int { 20 | return int(C.sws_init_context((*C.struct_SwsContext)(ctxt), (*C.struct_SwsFilter)(sf), (*C.struct_SwsFilter)(df))) 21 | } 22 | 23 | //Free the swscaler context swsContext. 24 | func SwsFreecontext(ctxt *Context) { 25 | C.sws_freeContext((*C.struct_SwsContext)(ctxt)) 26 | } 27 | 28 | //Allocate and return an Context. 29 | func SwsGetcontext(sw, sh int, sf PixelFormat, dw, dh int, df PixelFormat, f int, sfl, dfl *Filter, p *int) *Context { 30 | return (*Context)(C.sws_getContext(C.int(sw), C.int(sh), (C.enum_AVPixelFormat)(sf), C.int(dw), C.int(dh), (C.enum_AVPixelFormat)(df), C.int(f), (*C.struct_SwsFilter)(sfl), (*C.struct_SwsFilter)(dfl), (*C.double)(unsafe.Pointer(p)))) 31 | } 32 | 33 | //Check if context can be reused, otherwise reallocate a new one. 34 | func SwsGetcachedcontext(ctxt *Context, sw, sh int, sf PixelFormat, dw, dh int, df PixelFormat, f int, sfl, dfl *Filter, p *float64) *Context { 35 | return (*Context)(C.sws_getCachedContext((*C.struct_SwsContext)(ctxt), C.int(sw), C.int(sh), (C.enum_AVPixelFormat)(sf), C.int(dw), C.int(dh), (C.enum_AVPixelFormat)(df), C.int(f), (*C.struct_SwsFilter)(sfl), (*C.struct_SwsFilter)(dfl), (*C.double)(p))) 36 | } 37 | -------------------------------------------------------------------------------- /redigo/redis/commandinfo.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Gary Burd 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 | // not use this file except in compliance with the License. You may obtain 5 | // a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | // License for the specific language governing permissions and limitations 13 | // under the License. 14 | 15 | package redis 16 | 17 | import ( 18 | "strings" 19 | ) 20 | 21 | const ( 22 | connectionWatchState = 1 << iota 23 | connectionMultiState 24 | connectionSubscribeState 25 | connectionMonitorState 26 | ) 27 | 28 | type commandInfo struct { 29 | // Set or Clear these states on connection. 30 | Set, Clear int 31 | } 32 | 33 | var commandInfos = map[string]commandInfo{ 34 | "WATCH": {Set: connectionWatchState}, 35 | "UNWATCH": {Clear: connectionWatchState}, 36 | "MULTI": {Set: connectionMultiState}, 37 | "EXEC": {Clear: connectionWatchState | connectionMultiState}, 38 | "DISCARD": {Clear: connectionWatchState | connectionMultiState}, 39 | "PSUBSCRIBE": {Set: connectionSubscribeState}, 40 | "SUBSCRIBE": {Set: connectionSubscribeState}, 41 | "MONITOR": {Set: connectionMonitorState}, 42 | } 43 | 44 | func init() { 45 | for n, ci := range commandInfos { 46 | commandInfos[strings.ToLower(n)] = ci 47 | } 48 | } 49 | 50 | func lookupCommandInfo(commandName string) commandInfo { 51 | if ci, ok := commandInfos[commandName]; ok { 52 | return ci 53 | } 54 | return commandInfos[strings.ToUpper(commandName)] 55 | } 56 | -------------------------------------------------------------------------------- /goav/avformat/stream.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a MIT license that can be found in the LICENSE file. 2 | // Giorgis (habtom@giorgis.io) 3 | 4 | package avformat 5 | 6 | //#cgo pkg-config: libavformat 7 | //#include 8 | import "C" 9 | import ( 10 | "github.com/giorgisio/goav/avcodec" 11 | ) 12 | 13 | //Rational av_stream_get_r_frame_rate (const Stream *s) 14 | func (s *Stream) AvStreamGetRFrameRate() avcodec.Rational { 15 | return newRational(C.av_stream_get_r_frame_rate((*C.struct_AVStream)(s))) 16 | } 17 | 18 | //void av_stream_set_r_frame_rate (Stream *s, Rational r) 19 | func (s *Stream) AvStreamSetRFrameRate(r avcodec.Rational) { 20 | rat := C.struct_AVRational{ 21 | num: C.int(r.Num()), 22 | den: C.int(r.Den()), 23 | } 24 | 25 | C.av_stream_set_r_frame_rate((*C.struct_AVStream)(s), rat) 26 | } 27 | 28 | //struct CodecParserContext * av_stream_get_parser (const Stream *s) 29 | func (s *Stream) AvStreamGetParser() *CodecParserContext { 30 | return (*CodecParserContext)(C.av_stream_get_parser((*C.struct_AVStream)(s))) 31 | } 32 | 33 | // //char * av_stream_get_recommended_encoder_configuration (const Stream *s) 34 | // func (s *Stream) AvStreamGetRecommendedEncoderConfiguration() string { 35 | // return C.GoString(C.av_stream_get_recommended_encoder_configuration((*C.struct_AVStream)(s))) 36 | // } 37 | 38 | // //void av_stream_set_recommended_encoder_configuration (Stream *s, char *configuration) 39 | // func (s *Stream) AvStreamSetRecommendedEncoderConfiguration( c string) { 40 | // C.av_stream_set_recommended_encoder_configuration((*C.struct_AVStream)(s), C.CString(c)) 41 | // } 42 | 43 | //int64_t av_stream_get_end_pts (const Stream *st) 44 | //Returns the pts of the last muxed packet + its duration. 45 | func (s *Stream) AvStreamGetEndPts() int64 { 46 | return int64(C.av_stream_get_end_pts((*C.struct_AVStream)(s))) 47 | } 48 | -------------------------------------------------------------------------------- /unit_test/json.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import( 4 | "../gjson" 5 | "fmt" 6 | "encoding/json" 7 | //"os" 8 | ) 9 | 10 | type RoomInfo struct { 11 | ID int `json:"id"` 12 | Name string `json:"name"` 13 | Address struct { 14 | AudioPort int `json:"audio_port"` 15 | VedioPort int `json:"vedio_port"` 16 | } `json:"address"` 17 | Accounts []string `json:"accounts"` 18 | } 19 | 20 | func main() { 21 | 22 | // parse json 23 | room := "{\"id\":3,\"name\":\"A401\",\"address\":{\"audio_port\":10000,\"vedio_port\":10002},\"accounts\":[\"1\",\"2\"]}" 24 | 25 | id := gjson.Get(room, "id") 26 | name := gjson.Get(room, "name") 27 | address := gjson.Get(room, "address") 28 | accounts := gjson.Get(room, "accounts") 29 | vPort := gjson.Get(room, "address.vedio_port") 30 | 31 | fmt.Println("id :", id.Int()) 32 | fmt.Println("name :", name.String()) 33 | fmt.Println("vport to string :", vPort.String()) 34 | fmt.Println("address : ", address.Type , address) 35 | fmt.Println("accounts : ", accounts.Type , accounts, accounts.Array()) 36 | 37 | // encode json 38 | type ColorGroup struct { 39 | ID int 40 | Name string 41 | Colors []string 42 | } 43 | group := ColorGroup{ 44 | ID: 1, 45 | Name: "Reds", 46 | Colors: []string{"Crimson", "Red", "Ruby", "Maroon"}, 47 | } 48 | b, err := json.Marshal(group) 49 | if err != nil { 50 | fmt.Println("error:", err) 51 | } 52 | 53 | fmt.Println(string(b)) 54 | 55 | 56 | //test room info 57 | 58 | js := RoomInfo{ 59 | ID: 0, 60 | Name: "default", 61 | //Address: {0, 0}, 62 | } 63 | 64 | js.Accounts = append(js.Accounts, "s0", "s1") 65 | 66 | b, err = json.Marshal(js) 67 | if err != nil { 68 | fmt.Println("error:", err) 69 | } 70 | 71 | fmt.Println(string(b)) 72 | 73 | } -------------------------------------------------------------------------------- /cron/constantdelay_test.go: -------------------------------------------------------------------------------- 1 | package cron 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | ) 7 | 8 | func TestConstantDelayNext(t *testing.T) { 9 | tests := []struct { 10 | time string 11 | delay time.Duration 12 | expected string 13 | }{ 14 | // Simple cases 15 | {"Mon Jul 9 14:45 2012", 15*time.Minute + 50*time.Nanosecond, "Mon Jul 9 15:00 2012"}, 16 | {"Mon Jul 9 14:59 2012", 15 * time.Minute, "Mon Jul 9 15:14 2012"}, 17 | {"Mon Jul 9 14:59:59 2012", 15 * time.Minute, "Mon Jul 9 15:14:59 2012"}, 18 | 19 | // Wrap around hours 20 | {"Mon Jul 9 15:45 2012", 35 * time.Minute, "Mon Jul 9 16:20 2012"}, 21 | 22 | // Wrap around days 23 | {"Mon Jul 9 23:46 2012", 14 * time.Minute, "Tue Jul 10 00:00 2012"}, 24 | {"Mon Jul 9 23:45 2012", 35 * time.Minute, "Tue Jul 10 00:20 2012"}, 25 | {"Mon Jul 9 23:35:51 2012", 44*time.Minute + 24*time.Second, "Tue Jul 10 00:20:15 2012"}, 26 | {"Mon Jul 9 23:35:51 2012", 25*time.Hour + 44*time.Minute + 24*time.Second, "Thu Jul 11 01:20:15 2012"}, 27 | 28 | // Wrap around months 29 | {"Mon Jul 9 23:35 2012", 91*24*time.Hour + 25*time.Minute, "Thu Oct 9 00:00 2012"}, 30 | 31 | // Wrap around minute, hour, day, month, and year 32 | {"Mon Dec 31 23:59:45 2012", 15 * time.Second, "Tue Jan 1 00:00:00 2013"}, 33 | 34 | // Round to nearest second on the delay 35 | {"Mon Jul 9 14:45 2012", 15*time.Minute + 50*time.Nanosecond, "Mon Jul 9 15:00 2012"}, 36 | 37 | // Round up to 1 second if the duration is less. 38 | {"Mon Jul 9 14:45:00 2012", 15 * time.Millisecond, "Mon Jul 9 14:45:01 2012"}, 39 | 40 | // Round to nearest second when calculating the next time. 41 | {"Mon Jul 9 14:45:00.005 2012", 15 * time.Minute, "Mon Jul 9 15:00 2012"}, 42 | 43 | // Round to nearest second for both. 44 | {"Mon Jul 9 14:45:00.005 2012", 15*time.Minute + 50*time.Nanosecond, "Mon Jul 9 15:00 2012"}, 45 | } 46 | 47 | for _, c := range tests { 48 | actual := Every(c.delay).Next(getTime(c.time)) 49 | expected := getTime(c.expected) 50 | if actual != expected { 51 | t.Errorf("%s, \"%s\": (expected) %v != %v (actual)", c.time, c.delay, expected, actual) 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /redigo/redis/list_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Gary Burd 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 | // not use this file except in compliance with the License. You may obtain 5 | // a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | // License for the specific language governing permissions and limitations 13 | // under the License. 14 | 15 | // +build go1.9 16 | 17 | package redis 18 | 19 | import "testing" 20 | 21 | func TestPoolList(t *testing.T) { 22 | var idle idleList 23 | var a, b, c poolConn 24 | 25 | check := func(pcs ...*poolConn) { 26 | if idle.count != len(pcs) { 27 | t.Fatal("idle.count != len(pcs)") 28 | } 29 | if len(pcs) == 0 { 30 | if idle.front != nil { 31 | t.Fatalf("front not nil") 32 | } 33 | if idle.back != nil { 34 | t.Fatalf("back not nil") 35 | } 36 | return 37 | } 38 | if idle.front != pcs[0] { 39 | t.Fatal("front != pcs[0]") 40 | } 41 | if idle.back != pcs[len(pcs)-1] { 42 | t.Fatal("back != pcs[len(pcs)-1]") 43 | } 44 | if idle.front.prev != nil { 45 | t.Fatal("front.prev != nil") 46 | } 47 | if idle.back.next != nil { 48 | t.Fatal("back.next != nil") 49 | } 50 | for i := 1; i < len(pcs)-1; i++ { 51 | if pcs[i-1].next != pcs[i] { 52 | t.Fatal("pcs[i-1].next != pcs[i]") 53 | } 54 | if pcs[i+1].prev != pcs[i] { 55 | t.Fatal("pcs[i+1].prev != pcs[i]") 56 | } 57 | } 58 | } 59 | 60 | idle.pushFront(&c) 61 | check(&c) 62 | idle.pushFront(&b) 63 | check(&b, &c) 64 | idle.pushFront(&a) 65 | check(&a, &b, &c) 66 | idle.popFront() 67 | check(&b, &c) 68 | idle.popFront() 69 | check(&c) 70 | idle.popFront() 71 | check() 72 | 73 | idle.pushFront(&c) 74 | check(&c) 75 | idle.pushFront(&b) 76 | check(&b, &c) 77 | idle.pushFront(&a) 78 | check(&a, &b, &c) 79 | idle.popBack() 80 | check(&a, &b) 81 | idle.popBack() 82 | check(&a) 83 | idle.popBack() 84 | check() 85 | } 86 | -------------------------------------------------------------------------------- /unit_test/h264_rtp_send.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | log "github.com/astaxie/beego/logs" 5 | 6 | "net" 7 | "io/ioutil" 8 | "time" 9 | "../rtp" 10 | ) 11 | 12 | func PackH264DataToNalus(bytes []byte) [][]byte { 13 | l := len(bytes) 14 | var startPos []int 15 | var nalus [][]byte 16 | j := 0 // split nalu in bytes to nalus 17 | for i := 0; i < l - 5; i++ { 18 | if bytes[i] == 0 && bytes[i+1] == 0 && bytes[i+2] == 1 { 19 | if i > 0 && bytes[i-1] == 0 {//parameter set startpos 20 | startPos = append(startPos, i-1) 21 | } else { 22 | startPos = append(startPos, i) 23 | } 24 | j++ 25 | if j > 1 { 26 | b := bytes[startPos[j-2]:startPos[j-1]] 27 | nalus = append(nalus, b) 28 | } 29 | } 30 | } 31 | nalus = append(nalus, bytes[startPos[j-1]:]) 32 | if len(nalus) != len(startPos) { 33 | panic("unknown error at split nalu in bytes to nalus ") 34 | } 35 | 36 | return nalus 37 | } 38 | 39 | func main() { 40 | raddr, err := net.ResolveUDPAddr("udp", "0.0.0.0:10000") 41 | if err != nil{ 42 | log.Critical("net ResolveUDPAddr Error.") 43 | } 44 | 45 | log.Debug("remote vedio addresses : ", raddr.IP, ":", raddr.Port) 46 | 47 | conn, err := net.DialUDP("udp4", nil, raddr) 48 | if err != nil { 49 | log.Critical("net DialUDP.") 50 | return 51 | } 52 | 53 | defer conn.Close() 54 | 55 | data, err := ioutil.ReadFile("/home/ailumiyana/open_src/h264_to_rtp/720p.h264") 56 | if err != nil { 57 | log.Debug("File reading error", err) 58 | return 59 | } 60 | log.Debug("Open Success.") 61 | l := len(data) 62 | log.Debug("size of file:", l) 63 | 64 | rtpPacket := rtp.NewDefaultPacketWithH264Type() 65 | 66 | nalus := PackH264DataToNalus(data) 67 | 68 | for _, v := range nalus { 69 | rps := rtpPacket.ParserNaluToRtpPayload(v) 70 | 71 | // H264 30FPS : 90000 / 30 : diff = 3000 72 | rtpPacket.SetTimeStamp(rtpPacket.TimeStamp() + 3000) 73 | 74 | for _, q := range rps { 75 | rtpPacket.SetSequence(rtpPacket.Sequence() + 1) 76 | rtpPacket.SetPayload(q) 77 | conn.Write(rtpPacket.GetRtpBytes()) 78 | } 79 | 80 | time.Sleep(30*time.Millisecond) 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /goav/avcodec/flags.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a MIT license that can be found in the LICENSE file. 2 | // Giorgis (habtom@giorgis.io) 3 | 4 | package avcodec 5 | 6 | //#cgo pkg-config: libavcodec 7 | //#include 8 | import "C" 9 | 10 | const ( 11 | AV_CODEC_FLAG_UNALIGNED = int(C.AV_CODEC_FLAG_UNALIGNED) 12 | AV_CODEC_FLAG_QSCALE = int(C.AV_CODEC_FLAG_QSCALE) 13 | AV_CODEC_FLAG_4MV = int(C.AV_CODEC_FLAG_4MV) 14 | AV_CODEC_FLAG_OUTPUT_CORRUPT = int(C.AV_CODEC_FLAG_OUTPUT_CORRUPT) 15 | AV_CODEC_FLAG_QPEL = int(C.AV_CODEC_FLAG_QPEL) 16 | AV_CODEC_FLAG_PASS1 = int(C.AV_CODEC_FLAG_PASS1) 17 | AV_CODEC_FLAG_PASS2 = int(C.AV_CODEC_FLAG_PASS2) 18 | AV_CODEC_FLAG_LOOP_FILTER = int(C.AV_CODEC_FLAG_LOOP_FILTER) 19 | AV_CODEC_FLAG_GRAY = int(C.AV_CODEC_FLAG_GRAY) 20 | AV_CODEC_FLAG_PSNR = int(C.AV_CODEC_FLAG_PSNR) 21 | AV_CODEC_FLAG_TRUNCATED = int(C.AV_CODEC_FLAG_TRUNCATED) 22 | AV_CODEC_FLAG_INTERLACED_DCT = int(C.AV_CODEC_FLAG_INTERLACED_DCT) 23 | AV_CODEC_FLAG_LOW_DELAY = int(C.AV_CODEC_FLAG_LOW_DELAY) 24 | AV_CODEC_FLAG_GLOBAL_HEADER = int(C.AV_CODEC_FLAG_GLOBAL_HEADER) 25 | AV_CODEC_FLAG_BITEXACT = int(C.AV_CODEC_FLAG_BITEXACT) 26 | AV_CODEC_FLAG_AC_PRED = int(C.AV_CODEC_FLAG_AC_PRED) 27 | AV_CODEC_FLAG_INTERLACED_ME = int(C.AV_CODEC_FLAG_INTERLACED_ME) 28 | AV_CODEC_FLAG_CLOSED_GOP = int(C.AV_CODEC_FLAG_CLOSED_GOP) 29 | AV_CODEC_FLAG2_FAST = int(C.AV_CODEC_FLAG2_FAST) 30 | AV_CODEC_FLAG2_NO_OUTPUT = int(C.AV_CODEC_FLAG2_NO_OUTPUT) 31 | AV_CODEC_FLAG2_LOCAL_HEADER = int(C.AV_CODEC_FLAG2_LOCAL_HEADER) 32 | AV_CODEC_FLAG2_DROP_FRAME_TIMECODE = int(C.AV_CODEC_FLAG2_DROP_FRAME_TIMECODE) 33 | AV_CODEC_FLAG2_CHUNKS = int(C.AV_CODEC_FLAG2_CHUNKS) 34 | AV_CODEC_FLAG2_IGNORE_CROP = int(C.AV_CODEC_FLAG2_IGNORE_CROP) 35 | AV_CODEC_FLAG2_SHOW_ALL = int(C.AV_CODEC_FLAG2_SHOW_ALL) 36 | AV_CODEC_FLAG2_EXPORT_MVS = int(C.AV_CODEC_FLAG2_EXPORT_MVS) 37 | AV_CODEC_FLAG2_SKIP_MANUAL = int(C.AV_CODEC_FLAG2_SKIP_MANUAL) 38 | AV_CODEC_FLAG2_RO_FLUSH_NOOP = int(C.AV_CODEC_FLAG2_RO_FLUSH_NOOP) 39 | ) 40 | -------------------------------------------------------------------------------- /goav/avutil/avutil.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a MIT license that can be found in the LICENSE file. 2 | // Giorgis (habtom@giorgis.io) 3 | 4 | // Package avutil is a utility library to aid portable multimedia programming. 5 | // It contains safe portable string functions, random number generators, data structures, 6 | // additional mathematics functions, cryptography and multimedia related functionality. 7 | // Some generic features and utilities provided by the libavutil library 8 | package avutil 9 | 10 | //#cgo pkg-config: libavutil 11 | //#include 12 | //#include 13 | import "C" 14 | import ( 15 | "unsafe" 16 | ) 17 | 18 | type ( 19 | Options C.struct_AVOptions 20 | AvTree C.struct_AVTree 21 | Rational C.struct_AVRational 22 | MediaType C.enum_AVMediaType 23 | AvPictureType C.enum_AVPictureType 24 | PixelFormat C.enum_AVPixelFormat 25 | File C.FILE 26 | ) 27 | 28 | //Return the LIBAvUTIL_VERSION_INT constant. 29 | func AvutilVersion() uint { 30 | return uint(C.avutil_version()) 31 | } 32 | 33 | //Return the libavutil build-time configuration. 34 | func AvutilConfiguration() string { 35 | return C.GoString(C.avutil_configuration()) 36 | } 37 | 38 | //Return the libavutil license. 39 | func AvutilLicense() string { 40 | return C.GoString(C.avutil_license()) 41 | } 42 | 43 | //Return a string describing the media_type enum, NULL if media_type is unknown. 44 | func AvGetMediaTypeString(mt MediaType) string { 45 | return C.GoString(C.av_get_media_type_string((C.enum_AVMediaType)(mt))) 46 | } 47 | 48 | //Return a single letter to describe the given picture type pict_type. 49 | func AvGetPictureTypeChar(pt AvPictureType) string { 50 | return string(C.av_get_picture_type_char((C.enum_AVPictureType)(pt))) 51 | } 52 | 53 | //Return x default pointer in case p is NULL. 54 | func AvXIfNull(p, x int) { 55 | C.av_x_if_null(unsafe.Pointer(&p), unsafe.Pointer(&x)) 56 | } 57 | 58 | //Compute the length of an integer list. 59 | func AvIntListLengthForSize(e uint, l int, t uint64) uint { 60 | return uint(C.av_int_list_length_for_size(C.uint(e), unsafe.Pointer(&l), (C.uint64_t)(t))) 61 | } 62 | 63 | //Open a file using a UTF-8 filename. 64 | func AvFopenUtf8(p, m string) *File { 65 | f := C.av_fopen_utf8(C.CString(p), C.CString(m)) 66 | return (*File)(f) 67 | } 68 | 69 | //Return the fractional representation of the internal time base. 70 | func AvGetTimeBaseQ() Rational { 71 | return (Rational)(C.av_get_time_base_q()) 72 | } -------------------------------------------------------------------------------- /goav/avcodec/avpicture.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a MIT license that can be found in the LICENSE file. 2 | // Giorgis (habtom@giorgis.io) 3 | package avcodec 4 | 5 | //#cgo pkg-config: libavcodec 6 | //#include 7 | import "C" 8 | import ( 9 | "unsafe" 10 | ) 11 | 12 | // AvpictureFill - Setup the picture fields based on the specified image parameters and the provided image data buffer. 13 | func (p *Picture) AvpictureFill(pt *uint8, pf PixelFormat, w, h int) int { 14 | return int(C.avpicture_fill((*C.struct_AVPicture)(p), (*C.uint8_t)(pt), (C.enum_AVPixelFormat)(pf), C.int(w), C.int(h))) 15 | } 16 | 17 | // AvpictureLayout copies pixel data from an Picture into a buffer. 18 | func (p *Picture) AvpictureLayout(pf PixelFormat, w, h int, d *string, ds int) int { 19 | return int(C.avpicture_layout((*C.struct_AVPicture)(p), (C.enum_AVPixelFormat)(pf), C.int(w), C.int(h), (*C.uchar)(unsafe.Pointer(d)), C.int(ds))) 20 | } 21 | 22 | // AvPictureCopy -Copy image src to dst. 23 | func (p *Picture) AvPictureCopy(d *Picture, pf PixelFormat, w, h int) { 24 | C.av_picture_copy((*C.struct_AVPicture)(d), (*C.struct_AVPicture)(p), (C.enum_AVPixelFormat)(pf), C.int(w), C.int(h)) 25 | } 26 | 27 | // AvPictureCrop - Crop image top and left side. 28 | func (p *Picture) AvPictureCrop(d *Picture, pf PixelFormat, t, l int) int { 29 | return int(C.av_picture_crop((*C.struct_AVPicture)(d), (*C.struct_AVPicture)(p), (C.enum_AVPixelFormat)(pf), C.int(t), C.int(l))) 30 | } 31 | 32 | // AvPicturePad - Pad image. 33 | func (p *Picture) AvPicturePad(d *Picture, h, w int, pf PixelFormat, t, b, l, r int, c *int) int { 34 | return int(C.av_picture_pad((*C.struct_AVPicture)(d), (*C.struct_AVPicture)(p), (C.int)(h), (C.int)(w), (C.enum_AVPixelFormat)(pf), (C.int)(t), (C.int)(b), (C.int)(l), (C.int)(r), (*C.int)(unsafe.Pointer(c)))) 35 | } 36 | 37 | // AvpictureAlloc - Free a picture previously allocated by avpicture_alloc(). Allocate memory for the pixels of a picture and setup the Picture fields for it. 38 | func (p *Picture) AvpictureAlloc(t PixelFormat, w, h int) int { 39 | return int(C.avpicture_alloc((*C.struct_AVPicture)(p), (C.enum_AVPixelFormat)(t), C.int(w), C.int(h))) 40 | } 41 | 42 | // AvpictureFree - Free 43 | func (p *Picture) AvpictureFree() { 44 | C.avpicture_free((*C.struct_AVPicture)(p)) 45 | } 46 | 47 | // AvpictureGetSize - Calculate the size in bytes that a picture of the given width and height would occupy if stored in the given picture format. 48 | func AvpictureGetSize(pf PixelFormat, w, h int) int { 49 | return int(C.avpicture_get_size((C.enum_AVPixelFormat)(pf), C.int(w), C.int(h))) 50 | } 51 | -------------------------------------------------------------------------------- /goav/swscale/vector.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a MIT license that can be found in the LICENSE file. 2 | // Giorgis (habtom@giorgis.io) 3 | 4 | package swscale 5 | 6 | //#cgo pkg-config: libswscale libavutil 7 | //#include 8 | import "C" 9 | import ( 10 | "unsafe" 11 | ) 12 | 13 | //Allocate and return an uninitialized vector with length coefficients. 14 | func SwsAllocvec(l int) *Vector { 15 | return (*Vector)(C.sws_allocVec(C.int(l))) 16 | } 17 | 18 | //Return a normalized Gaussian curve used to filter stuff quality = 3 is high quality, lower is lower quality. 19 | func SwsGetgaussianvec(v, q float64) *Vector { 20 | return (*Vector)(unsafe.Pointer(C.sws_getGaussianVec(C.double(v), C.double(q)))) 21 | } 22 | 23 | //Allocate and return a vector with length coefficients, all with the same value c. 24 | func SwsGetconstvec(c float64, l int) *Vector { 25 | return (*Vector)(unsafe.Pointer(C.sws_getConstVec(C.double(c), C.int(l)))) 26 | } 27 | 28 | //Allocate and return a vector with just one coefficient, with value 1.0. 29 | func SwsGetidentityvec() *Vector { 30 | return (*Vector)(unsafe.Pointer(C.sws_getIdentityVec())) 31 | } 32 | 33 | //Scale all the coefficients of a by the scalar value. 34 | func (a *Vector) SwsScalevec(s float64) { 35 | C.sws_scaleVec((*C.struct_SwsVector)(unsafe.Pointer(a)), C.double(s)) 36 | } 37 | 38 | //Scale all the coefficients of a so that their sum equals height. 39 | func (a *Vector) SwsNormalizevec(h float64) { 40 | C.sws_normalizeVec((*C.struct_SwsVector)(a), C.double(h)) 41 | } 42 | 43 | func (a *Vector) SwsConvvec(b *Vector) { 44 | C.sws_convVec((*C.struct_SwsVector)(a), (*C.struct_SwsVector)(b)) 45 | } 46 | 47 | func (a *Vector) SwsAddvec(b *Vector) { 48 | C.sws_addVec((*C.struct_SwsVector)(a), (*C.struct_SwsVector)(b)) 49 | } 50 | 51 | func (a *Vector) SwsSubvec(b *Vector) { 52 | C.sws_subVec((*C.struct_SwsVector)(a), (*C.struct_SwsVector)(b)) 53 | } 54 | 55 | func (a *Vector) SwsShiftvec(s int) { 56 | C.sws_shiftVec((*C.struct_SwsVector)(a), C.int(s)) 57 | } 58 | 59 | //Allocate and return a clone of the vector a, that is a vector with the same coefficients as a. 60 | func (a *Vector) SwsClonevec() *Vector { 61 | return (*Vector)(unsafe.Pointer(C.sws_cloneVec((*C.struct_SwsVector)(a)))) 62 | } 63 | 64 | //Print with av_log() a textual representation of the vector a if log_level <= av_log_level. 65 | func (a *Vector) SwsPrintvec2(lctx *Class, l int) { 66 | C.sws_printVec2((*C.struct_SwsVector)(a), (*C.struct_AVClass)(lctx), C.int(l)) 67 | } 68 | 69 | func (a *Vector) SwsFreevec() { 70 | C.sws_freeVec((*C.struct_SwsVector)(a)) 71 | } 72 | -------------------------------------------------------------------------------- /redigo/redis/redis_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Gary Burd 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 | // not use this file except in compliance with the License. You may obtain 5 | // a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | // License for the specific language governing permissions and limitations 13 | // under the License. 14 | 15 | package redis_test 16 | 17 | import ( 18 | "testing" 19 | "time" 20 | 21 | "github.com/gomodule/redigo/redis" 22 | ) 23 | 24 | type timeoutTestConn int 25 | 26 | func (tc timeoutTestConn) Do(string, ...interface{}) (interface{}, error) { 27 | return time.Duration(-1), nil 28 | } 29 | func (tc timeoutTestConn) DoWithTimeout(timeout time.Duration, cmd string, args ...interface{}) (interface{}, error) { 30 | return timeout, nil 31 | } 32 | 33 | func (tc timeoutTestConn) Receive() (interface{}, error) { 34 | return time.Duration(-1), nil 35 | } 36 | func (tc timeoutTestConn) ReceiveWithTimeout(timeout time.Duration) (interface{}, error) { 37 | return timeout, nil 38 | } 39 | 40 | func (tc timeoutTestConn) Send(string, ...interface{}) error { return nil } 41 | func (tc timeoutTestConn) Err() error { return nil } 42 | func (tc timeoutTestConn) Close() error { return nil } 43 | func (tc timeoutTestConn) Flush() error { return nil } 44 | 45 | func testTimeout(t *testing.T, c redis.Conn) { 46 | r, err := c.Do("PING") 47 | if r != time.Duration(-1) || err != nil { 48 | t.Errorf("Do() = %v, %v, want %v, %v", r, err, time.Duration(-1), nil) 49 | } 50 | r, err = redis.DoWithTimeout(c, time.Minute, "PING") 51 | if r != time.Minute || err != nil { 52 | t.Errorf("DoWithTimeout() = %v, %v, want %v, %v", r, err, time.Minute, nil) 53 | } 54 | r, err = c.Receive() 55 | if r != time.Duration(-1) || err != nil { 56 | t.Errorf("Receive() = %v, %v, want %v, %v", r, err, time.Duration(-1), nil) 57 | } 58 | r, err = redis.ReceiveWithTimeout(c, time.Minute) 59 | if r != time.Minute || err != nil { 60 | t.Errorf("ReceiveWithTimeout() = %v, %v, want %v, %v", r, err, time.Minute, nil) 61 | } 62 | } 63 | 64 | func TestConnTimeout(t *testing.T) { 65 | testTimeout(t, timeoutTestConn(0)) 66 | } 67 | 68 | func TestPoolConnTimeout(t *testing.T) { 69 | p := &redis.Pool{Dial: func() (redis.Conn, error) { return timeoutTestConn(0), nil }} 70 | testTimeout(t, p.Get()) 71 | } 72 | -------------------------------------------------------------------------------- /redigo/redis/pubsub_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Gary Burd 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 | // not use this file except in compliance with the License. You may obtain 5 | // a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | // License for the specific language governing permissions and limitations 13 | // under the License. 14 | 15 | package redis_test 16 | 17 | import ( 18 | "reflect" 19 | "testing" 20 | "time" 21 | 22 | "github.com/gomodule/redigo/redis" 23 | ) 24 | 25 | func expectPushed(t *testing.T, c redis.PubSubConn, message string, expected interface{}) { 26 | actual := c.Receive() 27 | if !reflect.DeepEqual(actual, expected) { 28 | t.Errorf("%s = %v, want %v", message, actual, expected) 29 | } 30 | } 31 | 32 | func TestPushed(t *testing.T) { 33 | pc, err := redis.DialDefaultServer() 34 | if err != nil { 35 | t.Fatalf("error connection to database, %v", err) 36 | } 37 | defer pc.Close() 38 | 39 | sc, err := redis.DialDefaultServer() 40 | if err != nil { 41 | t.Fatalf("error connection to database, %v", err) 42 | } 43 | defer sc.Close() 44 | 45 | c := redis.PubSubConn{Conn: sc} 46 | 47 | c.Subscribe("c1") 48 | expectPushed(t, c, "Subscribe(c1)", redis.Subscription{Kind: "subscribe", Channel: "c1", Count: 1}) 49 | c.Subscribe("c2") 50 | expectPushed(t, c, "Subscribe(c2)", redis.Subscription{Kind: "subscribe", Channel: "c2", Count: 2}) 51 | c.PSubscribe("p1") 52 | expectPushed(t, c, "PSubscribe(p1)", redis.Subscription{Kind: "psubscribe", Channel: "p1", Count: 3}) 53 | c.PSubscribe("p2") 54 | expectPushed(t, c, "PSubscribe(p2)", redis.Subscription{Kind: "psubscribe", Channel: "p2", Count: 4}) 55 | c.PUnsubscribe() 56 | expectPushed(t, c, "Punsubscribe(p1)", redis.Subscription{Kind: "punsubscribe", Channel: "p1", Count: 3}) 57 | expectPushed(t, c, "Punsubscribe()", redis.Subscription{Kind: "punsubscribe", Channel: "p2", Count: 2}) 58 | 59 | pc.Do("PUBLISH", "c1", "hello") 60 | expectPushed(t, c, "PUBLISH c1 hello", redis.Message{Channel: "c1", Data: []byte("hello")}) 61 | 62 | c.Ping("hello") 63 | expectPushed(t, c, `Ping("hello")`, redis.Pong{Data: "hello"}) 64 | 65 | c.Conn.Send("PING") 66 | c.Conn.Flush() 67 | expectPushed(t, c, `Send("PING")`, redis.Pong{}) 68 | 69 | c.Ping("timeout") 70 | got := c.ReceiveWithTimeout(time.Minute) 71 | if want := (redis.Pong{Data: "timeout"}); want != got { 72 | t.Errorf("recv /w timeout got %v, want %v", got, want) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /redigo/redis/zpop_example_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Gary Burd 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 | // not use this file except in compliance with the License. You may obtain 5 | // a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | // License for the specific language governing permissions and limitations 13 | // under the License. 14 | 15 | package redis_test 16 | 17 | import ( 18 | "fmt" 19 | 20 | "github.com/gomodule/redigo/redis" 21 | ) 22 | 23 | // zpop pops a value from the ZSET key using WATCH/MULTI/EXEC commands. 24 | func zpop(c redis.Conn, key string) (result string, err error) { 25 | 26 | defer func() { 27 | // Return connection to normal state on error. 28 | if err != nil { 29 | c.Do("DISCARD") 30 | } 31 | }() 32 | 33 | // Loop until transaction is successful. 34 | for { 35 | if _, err := c.Do("WATCH", key); err != nil { 36 | return "", err 37 | } 38 | 39 | members, err := redis.Strings(c.Do("ZRANGE", key, 0, 0)) 40 | if err != nil { 41 | return "", err 42 | } 43 | if len(members) != 1 { 44 | return "", redis.ErrNil 45 | } 46 | 47 | c.Send("MULTI") 48 | c.Send("ZREM", key, members[0]) 49 | queued, err := c.Do("EXEC") 50 | if err != nil { 51 | return "", err 52 | } 53 | 54 | if queued != nil { 55 | result = members[0] 56 | break 57 | } 58 | } 59 | 60 | return result, nil 61 | } 62 | 63 | // zpopScript pops a value from a ZSET. 64 | var zpopScript = redis.NewScript(1, ` 65 | local r = redis.call('ZRANGE', KEYS[1], 0, 0) 66 | if r ~= nil then 67 | r = r[1] 68 | redis.call('ZREM', KEYS[1], r) 69 | end 70 | return r 71 | `) 72 | 73 | // This example implements ZPOP as described at 74 | // http://redis.io/topics/transactions using WATCH/MULTI/EXEC and scripting. 75 | func Example_zpop() { 76 | c, err := dial() 77 | if err != nil { 78 | fmt.Println(err) 79 | return 80 | } 81 | defer c.Close() 82 | 83 | // Add test data using a pipeline. 84 | 85 | for i, member := range []string{"red", "blue", "green"} { 86 | c.Send("ZADD", "zset", i, member) 87 | } 88 | if _, err := c.Do(""); err != nil { 89 | fmt.Println(err) 90 | return 91 | } 92 | 93 | // Pop using WATCH/MULTI/EXEC 94 | 95 | v, err := zpop(c, "zset") 96 | if err != nil { 97 | fmt.Println(err) 98 | return 99 | } 100 | fmt.Println(v) 101 | 102 | // Pop using a script. 103 | 104 | v, err = redis.String(zpopScript.Do(c, "zset")) 105 | if err != nil { 106 | fmt.Println(err) 107 | return 108 | } 109 | fmt.Println(v) 110 | 111 | // Output: 112 | // red 113 | // blue 114 | } 115 | -------------------------------------------------------------------------------- /redigo/redis/script_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Gary Burd 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 | // not use this file except in compliance with the License. You may obtain 5 | // a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | // License for the specific language governing permissions and limitations 13 | // under the License. 14 | 15 | package redis_test 16 | 17 | import ( 18 | "fmt" 19 | "reflect" 20 | "testing" 21 | "time" 22 | 23 | "github.com/gomodule/redigo/redis" 24 | ) 25 | 26 | var ( 27 | // These variables are declared at package level to remove distracting 28 | // details from the examples. 29 | c redis.Conn 30 | reply interface{} 31 | err error 32 | ) 33 | 34 | func ExampleScript() { 35 | // Initialize a package-level variable with a script. 36 | var getScript = redis.NewScript(1, `return redis.call('get', KEYS[1])`) 37 | 38 | // In a function, use the script Do method to evaluate the script. The Do 39 | // method optimistically uses the EVALSHA command. If the script is not 40 | // loaded, then the Do method falls back to the EVAL command. 41 | reply, err = getScript.Do(c, "foo") 42 | } 43 | 44 | func TestScript(t *testing.T) { 45 | c, err := redis.DialDefaultServer() 46 | if err != nil { 47 | t.Fatalf("error connection to database, %v", err) 48 | } 49 | defer c.Close() 50 | 51 | // To test fall back in Do, we make script unique by adding comment with current time. 52 | script := fmt.Sprintf("--%d\nreturn {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}", time.Now().UnixNano()) 53 | s := redis.NewScript(2, script) 54 | reply := []interface{}{[]byte("key1"), []byte("key2"), []byte("arg1"), []byte("arg2")} 55 | 56 | v, err := s.Do(c, "key1", "key2", "arg1", "arg2") 57 | if err != nil { 58 | t.Errorf("s.Do(c, ...) returned %v", err) 59 | } 60 | 61 | if !reflect.DeepEqual(v, reply) { 62 | t.Errorf("s.Do(c, ..); = %v, want %v", v, reply) 63 | } 64 | 65 | err = s.Load(c) 66 | if err != nil { 67 | t.Errorf("s.Load(c) returned %v", err) 68 | } 69 | 70 | err = s.SendHash(c, "key1", "key2", "arg1", "arg2") 71 | if err != nil { 72 | t.Errorf("s.SendHash(c, ...) returned %v", err) 73 | } 74 | 75 | err = c.Flush() 76 | if err != nil { 77 | t.Errorf("c.Flush() returned %v", err) 78 | } 79 | 80 | v, err = c.Receive() 81 | if !reflect.DeepEqual(v, reply) { 82 | t.Errorf("s.SendHash(c, ..); c.Receive() = %v, want %v", v, reply) 83 | } 84 | 85 | err = s.Send(c, "key1", "key2", "arg1", "arg2") 86 | if err != nil { 87 | t.Errorf("s.Send(c, ...) returned %v", err) 88 | } 89 | 90 | err = c.Flush() 91 | if err != nil { 92 | t.Errorf("c.Flush() returned %v", err) 93 | } 94 | 95 | v, err = c.Receive() 96 | if !reflect.DeepEqual(v, reply) { 97 | t.Errorf("s.Send(c, ..); c.Receive() = %v, want %v", v, reply) 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /redigo/redis/script.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Gary Burd 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 | // not use this file except in compliance with the License. You may obtain 5 | // a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | // License for the specific language governing permissions and limitations 13 | // under the License. 14 | 15 | package redis 16 | 17 | import ( 18 | "crypto/sha1" 19 | "encoding/hex" 20 | "io" 21 | "strings" 22 | ) 23 | 24 | // Script encapsulates the source, hash and key count for a Lua script. See 25 | // http://redis.io/commands/eval for information on scripts in Redis. 26 | type Script struct { 27 | keyCount int 28 | src string 29 | hash string 30 | } 31 | 32 | // NewScript returns a new script object. If keyCount is greater than or equal 33 | // to zero, then the count is automatically inserted in the EVAL command 34 | // argument list. If keyCount is less than zero, then the application supplies 35 | // the count as the first value in the keysAndArgs argument to the Do, Send and 36 | // SendHash methods. 37 | func NewScript(keyCount int, src string) *Script { 38 | h := sha1.New() 39 | io.WriteString(h, src) 40 | return &Script{keyCount, src, hex.EncodeToString(h.Sum(nil))} 41 | } 42 | 43 | func (s *Script) args(spec string, keysAndArgs []interface{}) []interface{} { 44 | var args []interface{} 45 | if s.keyCount < 0 { 46 | args = make([]interface{}, 1+len(keysAndArgs)) 47 | args[0] = spec 48 | copy(args[1:], keysAndArgs) 49 | } else { 50 | args = make([]interface{}, 2+len(keysAndArgs)) 51 | args[0] = spec 52 | args[1] = s.keyCount 53 | copy(args[2:], keysAndArgs) 54 | } 55 | return args 56 | } 57 | 58 | // Hash returns the script hash. 59 | func (s *Script) Hash() string { 60 | return s.hash 61 | } 62 | 63 | // Do evaluates the script. Under the covers, Do optimistically evaluates the 64 | // script using the EVALSHA command. If the command fails because the script is 65 | // not loaded, then Do evaluates the script using the EVAL command (thus 66 | // causing the script to load). 67 | func (s *Script) Do(c Conn, keysAndArgs ...interface{}) (interface{}, error) { 68 | v, err := c.Do("EVALSHA", s.args(s.hash, keysAndArgs)...) 69 | if e, ok := err.(Error); ok && strings.HasPrefix(string(e), "NOSCRIPT ") { 70 | v, err = c.Do("EVAL", s.args(s.src, keysAndArgs)...) 71 | } 72 | return v, err 73 | } 74 | 75 | // SendHash evaluates the script without waiting for the reply. The script is 76 | // evaluated with the EVALSHA command. The application must ensure that the 77 | // script is loaded by a previous call to Send, Do or Load methods. 78 | func (s *Script) SendHash(c Conn, keysAndArgs ...interface{}) error { 79 | return c.Send("EVALSHA", s.args(s.hash, keysAndArgs)...) 80 | } 81 | 82 | // Send evaluates the script without waiting for the reply. 83 | func (s *Script) Send(c Conn, keysAndArgs ...interface{}) error { 84 | return c.Send("EVAL", s.args(s.src, keysAndArgs)...) 85 | } 86 | 87 | // Load loads the script without evaluating it. 88 | func (s *Script) Load(c Conn) error { 89 | _, err := c.Do("SCRIPT", "LOAD", s.src) 90 | return err 91 | } 92 | -------------------------------------------------------------------------------- /unit_test/redis.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | /*import( 4 | //"github.com/go-redis/redis" 5 | "fmt" 6 | "time" 7 | //"reflect" 8 | "unsafe" 9 | "../redigo/redis" 10 | log "github.com/astaxie/beego/logs" 11 | ) 12 | 13 | type SubscribeCallback func (channel, message string) 14 | 15 | type Subscriber struct { 16 | client redis.PubSubConn 17 | cbMap map[string]SubscribeCallback 18 | } 19 | 20 | func (c *Subscriber) Connect(ip string, port uint16) { 21 | conn, err := redis.Dial("tcp", "127.0.0.1:6379") 22 | if err != nil { 23 | log.Critical("redis dial failed.") 24 | } 25 | 26 | c.client = redis.PubSubConn{conn} 27 | c.cbMap = make(map[string]SubscribeCallback) 28 | 29 | go func() { 30 | for { 31 | log.Debug("wait...") 32 | switch res := c.client.Receive().(type) { 33 | case redis.Message: 34 | channel := (*string)(unsafe.Pointer(&res.Channel)) 35 | message := (*string)(unsafe.Pointer(&res.Data)) 36 | c.cbMap[*channel](*channel, *message) 37 | case redis.Subscription: 38 | fmt.Printf("%s: %s %d\n", res.Channel, res.Kind, res.Count) 39 | case error: 40 | log.Error("errorr...") 41 | continue 42 | } 43 | } 44 | }() 45 | 46 | } 47 | 48 | func (c *Subscriber) Close() { 49 | err := c.client.Close() 50 | if err != nil{ 51 | log.Error("redis close error.") 52 | } 53 | } 54 | 55 | func (c *Subscriber) Subscribe(channel interface{}, cb SubscribeCallback) { 56 | err := c.client.Subscribe(channel) 57 | if err != nil{ 58 | log.Critical("redis Subscribe error.") 59 | } 60 | 61 | c.cbMap[channel.(string)] = cb 62 | } 63 | 64 | func TestCallback1(chann, msg string){ 65 | log.Debug("TestCallback1 channel : ", chann, " message : ", msg) 66 | } 67 | 68 | func TestCallback2(chann, msg string){ 69 | log.Debug("TestCallback2 channel : ", chann, " message : ", msg) 70 | } 71 | 72 | func TestCallback3(chann, msg string){ 73 | log.Debug("TestCallback3 channel : ", chann, " message : ", msg) 74 | } 75 | 76 | func main() { 77 | 78 | log.Info("===========main start============") 79 | 80 | var sub Subscriber 81 | sub.Connect("127.0.0.1", 6397) 82 | sub.Subscribe("test_chan1", TestCallback1) 83 | sub.Subscribe("test_chan2", TestCallback2) 84 | sub.Subscribe("test_chan3", TestCallback3) 85 | 86 | for{ 87 | time.Sleep(1 * time.Second) 88 | } 89 | }*/ 90 | 91 | 92 | import( 93 | "../redigo/redis" 94 | log "github.com/astaxie/beego/logs" 95 | ) 96 | 97 | func main() { 98 | conn, err := redis.Dial("tcp", "127.0.0.1:6379") 99 | if err != nil { 100 | log.Critical("redis dial failed.") 101 | } 102 | defer conn.Close() 103 | 104 | _, err = conn.Do("select", 3) 105 | if err != nil { 106 | log.Critical("redis select failed.") 107 | return 108 | } 109 | 110 | nill, err := conn.Do("get", nil) 111 | if err != nil { 112 | log.Critical("redis select failed.") 113 | return 114 | } 115 | 116 | log.Debug(nill) 117 | 118 | log.Debug("--------start---------") 119 | 120 | v, err := conn.Do("get", "xiaozhang") 121 | if err != nil { 122 | log.Critical("redis get failed.") 123 | return 124 | } 125 | log.Debug("-------- end ---------") 126 | 127 | log.Debug(v) 128 | 129 | } -------------------------------------------------------------------------------- /goav/README.md: -------------------------------------------------------------------------------- 1 | # goav 2 | Golang binding for FFmpeg 3 | 4 | A comprehensive binding to the ffmpeg video/audio manipulation library. 5 | 6 | [![GoDoc](https://godoc.org/github.com/giorgisio/goav?status.svg)](https://godoc.org/github.com/giorgisio/goav) 7 | 8 | ## Usage 9 | 10 | `````go 11 | 12 | import "github.com/giorgisio/goav/avformat" 13 | 14 | func main() { 15 | 16 | filename := "sample.mp4" 17 | 18 | // Register all formats and codecs 19 | avformat.AvRegisterAll() 20 | 21 | ctx := avformat.AvformatAllocContext() 22 | 23 | // Open video file 24 | if avformat.AvformatOpenInput(&ctx, filename, nil, nil) != 0 { 25 | log.Println("Error: Couldn't open file.") 26 | return 27 | } 28 | 29 | // Retrieve stream information 30 | if ctx.AvformatFindStreamInfo(nil) < 0 { 31 | log.Println("Error: Couldn't find stream information.") 32 | 33 | // Close input file and free context 34 | ctx.AvformatCloseInput() 35 | return 36 | } 37 | 38 | //... 39 | 40 | } 41 | ````` 42 | 43 | ## Libraries 44 | 45 | * `avcodec` corresponds to the ffmpeg library: libavcodec [provides implementation of a wider range of codecs] 46 | * `avformat` corresponds to the ffmpeg library: libavformat [implements streaming protocols, container formats and basic I/O access] 47 | * `avutil` corresponds to the ffmpeg library: libavutil [includes hashers, decompressors and miscellaneous utility functions] 48 | * `avfilter` corresponds to the ffmpeg library: libavfilter [provides a mean to alter decoded Audio and Video through chain of filters] 49 | * `avdevice` corresponds to the ffmpeg library: libavdevice [provides an abstraction to access capture and playback devices] 50 | * `swresample` corresponds to the ffmpeg library: libswresample [implements audio mixing and resampling routines] 51 | * `swscale` corresponds to the ffmpeg library: libswscale [implements color conversion and scaling routines] 52 | 53 | 54 | ## Installation 55 | 56 | [FFMPEG INSTALL INSTRUCTIONS] (https://github.com/FFmpeg/FFmpeg/blob/master/INSTALL.md) 57 | 58 | ``` sh 59 | sudo apt-get -y install autoconf automake build-essential libass-dev libfreetype6-dev libsdl1.2-dev libtheora-dev libtool libva-dev libvdpau-dev libvorbis-dev libxcb1-dev libxcb-shm0-dev libxcb-xfixes0-dev pkg-config texi2html zlib1g-dev 60 | 61 | sudo apt install -y libavdevice-dev libavfilter-dev libswscale-dev libavcodec-dev libavformat-dev libswresample-dev libavutil-dev 62 | 63 | sudo apt-get install yasm 64 | 65 | export FFMPEG_ROOT=$HOME/ffmpeg 66 | export CGO_LDFLAGS="-L$FFMPEG_ROOT/lib/ -lavcodec -lavformat -lavutil -lswscale -lswresample -lavdevice -lavfilter" 67 | export CGO_CFLAGS="-I$FFMPEG_ROOT/include" 68 | export LD_LIBRARY_PATH=$HOME/ffmpeg/lib 69 | ``` 70 | 71 | ``` 72 | go get github.com/giorgisio/goav 73 | 74 | ``` 75 | 76 | ## More Examples 77 | 78 | Coding examples are available in the examples/ directory. 79 | 80 | ## Note 81 | - Function names in Go are consistent with that of the libraries to help with easy search 82 | - [cgo: Extending Go with C](http://blog.giorgis.io/cgo-examples) 83 | - goav comes with absolutely no warranty. 84 | 85 | ## Contribute 86 | - Fork this repo and create your own feature branch. 87 | - Follow standard Go conventions 88 | - Test your code. 89 | - Create pull request 90 | 91 | ## TODO 92 | 93 | - [ ] Returning Errors 94 | - [ ] Garbage Collection 95 | - [X] Review included/excluded functions from each library 96 | - [ ] Go Tests 97 | - [ ] Possible restructuring packages 98 | - [x] Tutorial01.c 99 | - [ ] More Tutorial 100 | 101 | ## License 102 | This library is under the [MIT License](http://opensource.org/licenses/MIT) 103 | -------------------------------------------------------------------------------- /encoder/encoder.go: -------------------------------------------------------------------------------- 1 | package encoder 2 | 3 | import ( 4 | log "github.com/astaxie/beego/logs" 5 | 6 | "../goav/avcodec" 7 | "../goav/avutil" 8 | 9 | "unsafe" 10 | ) 11 | 12 | 13 | type Encoder struct { 14 | codec *avcodec.Codec 15 | context *avcodec.Context 16 | pkt *avcodec.Packet 17 | } 18 | 19 | func AllocAll(codecId avcodec.CodecId) *Encoder{ 20 | pkt := avcodec.AvPacketAlloc() 21 | if pkt == nil { 22 | log.Critical("AvPacketAlloc failed.") 23 | } 24 | 25 | codec := avcodec.AvcodecFindEncoder(codecId) 26 | if codec == nil { 27 | log.Critical("AvcodecFindDecoder failed.") 28 | } 29 | 30 | context := codec.AvcodecAllocContext3() 31 | if context == nil { 32 | log.Critical("AvcodecAllocContext3 failed.") 33 | } 34 | 35 | /*err := context.AvcodecOpen2(codec, nil) 36 | if err < 0 { 37 | log.Critical("AvcodecOpen2 failed.") 38 | }*/ 39 | 40 | return &Encoder{ 41 | codec, 42 | context, 43 | pkt, 44 | } 45 | } 46 | 47 | func (d *Encoder) Packet() *avcodec.Packet { 48 | return d.pkt 49 | } 50 | 51 | func (d *Encoder) Context() *avcodec.Context { 52 | return d.context 53 | } 54 | 55 | func (e *Encoder) SetEncodeParams(width int, height int, pxlFmt avcodec.PixelFormat, hasBframes bool, gopSize, num, den int) { 56 | e.context.SetEncodeParams2(width, height, pxlFmt, hasBframes, gopSize) 57 | e.context.SetTimebase(num, den) 58 | 59 | err := e.context.AvcodecOpen2(e.codec, nil) 60 | if err < 0 { 61 | log.Critical("AvcodecOpen2 failed.") 62 | } 63 | } 64 | 65 | func (e *Encoder) SetAudioEncodeParamsAndOpened() { 66 | e.context.SetAudioEncodeParams() 67 | 68 | err := e.context.AvcodecOpen2(e.codec, nil) 69 | if err < 0 { 70 | log.Critical("AvcodecOpen2 failed.") 71 | } 72 | } 73 | 74 | func (e *Encoder) SetVideoEncodeParamsAndOpened(width int, height int, pxlFmt avcodec.PixelFormat, hasBframes bool, gopSize, num, den int) { 75 | e.context.SetEncodeParams2(width, height, pxlFmt, hasBframes, gopSize) 76 | e.context.SetTimebase(num, den) 77 | 78 | err := e.context.AvcodecOpen2(e.codec, nil) 79 | if err < 0 { 80 | log.Critical("AvcodecOpen2 failed.") 81 | } 82 | } 83 | 84 | // 0 success 85 | func (e *Encoder) GeneratePacket(frame *avutil.Frame) int { 86 | ret := e.context.AvcodecSendFrame((*avcodec.Frame)(unsafe.Pointer(frame))) 87 | if ret < 0 { 88 | log.Trace("AvcodecSendFrame err ", avutil.ErrorFromCode(ret)) 89 | return ret 90 | } 91 | 92 | ret = e.context.AvcodecReceivePacket(e.pkt) 93 | if ret < 0 { 94 | log.Trace("AvcodecReceivePacket err ", avutil.ErrorFromCode(ret)) 95 | return ret 96 | } 97 | 98 | return ret 99 | } 100 | 101 | func (e *Encoder) SendFrame(frame *avutil.Frame) int { 102 | ret := e.context.AvcodecSendFrame((*avcodec.Frame)(unsafe.Pointer(frame))) 103 | if ret < 0 { 104 | log.Trace("AvcodecSendFrame err ", avutil.ErrorFromCode(ret)) 105 | return ret 106 | } 107 | return ret 108 | } 109 | 110 | func (e *Encoder) ReapPacket() *avcodec.Packet { 111 | ret := e.context.AvcodecReceivePacket(e.pkt) 112 | if ret < 0 { 113 | log.Trace("AvcodecReceivePacket err ", avutil.ErrorFromCode(ret)) 114 | return nil 115 | } 116 | 117 | return e.pkt 118 | } 119 | 120 | func (e *Encoder) ToBytes() []byte { 121 | data0 := e.Packet().Data() 122 | buf := make([]byte, e.Packet().GetPacketSize()) 123 | start := uintptr(unsafe.Pointer(data0)) 124 | for i := 0; i < e.Packet().GetPacketSize(); i++ { 125 | elem := *(*uint8)(unsafe.Pointer(start + uintptr(i))) 126 | buf[i] = elem 127 | } 128 | 129 | //e.Packet().AvPacketUnref() 130 | return buf 131 | } 132 | -------------------------------------------------------------------------------- /unit_test/channel.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import( 4 | "time" 5 | "fmt" 6 | "net" 7 | "../cron" 8 | log "github.com/astaxie/beego/logs" 9 | ) 10 | 11 | type Channel struct { 12 | id int // channel id 13 | pktChan chan []byte // h264 pkt chan 14 | } 15 | 16 | func New() *Channel { 17 | return &Channel{ 18 | -1, 19 | make(chan []byte), 20 | } 21 | } 22 | 23 | func (c *Channel) Id() int { 24 | return c.id 25 | } 26 | 27 | func (c *Channel) Chan() chan []byte { 28 | return c.pktChan 29 | } 30 | 31 | var channelMap = make(map[string]*Channel) 32 | var channels = make([]*Channel, 16) 33 | 34 | func LinstenAndServe() { 35 | log.Info("==========system init==========") 36 | 37 | //localAddress := net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: 8008}; 38 | vedioAddr, err := net.ResolveUDPAddr("udp", "0.0.0.0:8000") 39 | if err != nil{ 40 | log.Critical("net ResolveUDPAddr Error.") 41 | } 42 | 43 | log.Debug("local vedio addresses : ", vedioAddr.IP, ":", vedioAddr.Port) 44 | 45 | serv, err := net.ListenUDP("udp", vedioAddr) 46 | if err != nil { 47 | log.Critical("net ListenUDP.") 48 | } 49 | 50 | defer serv.Close() 51 | 52 | log.Debug("rtp server started.") 53 | 54 | autoId := 0 55 | buffer := make([]byte, 1400) 56 | 57 | for { 58 | n, remoteAddr, err := serv.ReadFromUDP(buffer) 59 | log.Debug("on message") 60 | if err != nil { 61 | log.Error("failed to read UDP msg because of ", err.Error()) 62 | return 63 | } 64 | 65 | value, ok := channelMap[remoteAddr.String()] 66 | if !ok { 67 | channelMap[remoteAddr.String()] = channels[autoId] 68 | value = channels[autoId] 69 | autoId++ 70 | } 71 | 72 | value.Chan() <- buffer 73 | time.Sleep(1*time.Second) 74 | 75 | log.Debug("recv ", n, " message from ", remoteAddr.String())//, ": ", hex.EncodeToString(rtpParser.Buffer())) 76 | log.Debug(buffer) 77 | } 78 | 79 | } 80 | 81 | type onFrame struct { 82 | chanId int 83 | frame string 84 | } 85 | 86 | func (of *onFrame) Id() int { 87 | return of.chanId 88 | } 89 | 90 | func (of *onFrame) Frame() string { 91 | return of.frame 92 | } 93 | 94 | var flush chan bool = make(chan bool) 95 | var updateFrame chan *onFrame = make(chan *onFrame) 96 | 97 | flushTick := time.NewTicker(300*time.Millisecond) 98 | 99 | func testChanSelect() { 100 | 101 | back_frames := []string{"chan 0", "chan 1", "chan 2", "chan 3"} 102 | 103 | // back_str := "I'm Back String." 104 | 105 | 106 | for { 107 | fmt.Println(back_frames) 108 | select { 109 | case frame := <- updateFrame : 110 | back_frames[frame.Id()] = frame.Frame() 111 | fmt.Println("update frame : ", frame.Frame()) 112 | 113 | case <- flushTick.C : 114 | fmt.Println("on time flush frame to filter") 115 | fmt.Println(back_frames) 116 | } 117 | } 118 | } 119 | 120 | func main() { 121 | cron := cron.New() 122 | 123 | 124 | go testChanSelect() 125 | 126 | i := "*" 127 | 128 | /*for j := 0; j < 30 ; j++ { 129 | //updateFrame <- &onFrame{0, i} 130 | flush <- true 131 | fmt.Println("update frame on chan 0 : ", i) 132 | time.Sleep(1*time.Second) 133 | i += " *" 134 | } 135 | 136 | time.Sleep(10000*time.Second)*/ 137 | 138 | 139 | 140 | //cron.AddFunc("*/0.5 * * * * ?", func(){flush <- true}) 141 | cron.AddFunc("*/1 * * * * ?", func(){i += " *"}) 142 | 143 | cron.AddFunc("*/3 * * * * ?", func(){updateFrame <- &onFrame{0, i}}) 144 | 145 | //cron.AddFunc("*/3 * * * * ?", func(){updateFrame <- &onFrame{1, i}}) 146 | //cron.AddFunc("*/3 * * * * ?", func(){updateFrame <- &onFrame{2, i}}) 147 | 148 | cron.Start() 149 | 150 | time.Sleep(10000*time.Second) 151 | } -------------------------------------------------------------------------------- /goav/avfilter/graph.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a MIT license that can be found in the LICENSE file. 2 | // Giorgis (habtom@giorgis.io) 3 | 4 | package avfilter 5 | 6 | /* 7 | #cgo pkg-config: libavfilter 8 | #include 9 | */ 10 | import "C" 11 | import ( 12 | "unsafe" 13 | ) 14 | 15 | //Allocate a filter graph. 16 | func AvfilterGraphAlloc() *Graph { 17 | return (*Graph)(C.avfilter_graph_alloc()) 18 | } 19 | 20 | //Create a new filter instance in a filter graph. 21 | func (g *Graph) AvfilterGraphAllocFilter(f *Filter, n string) *Context { 22 | return (*Context)(C.avfilter_graph_alloc_filter((*C.struct_AVFilterGraph)(g), (*C.struct_AVFilter)(f), C.CString(n))) 23 | } 24 | 25 | //Get a filter instance identified by instance name from graph. 26 | func (g *Graph) AvfilterGraphGetFilter(n string) *Context { 27 | return (*Context)(C.avfilter_graph_get_filter((*C.struct_AVFilterGraph)(g), C.CString(n))) 28 | } 29 | 30 | //Enable or disable automatic format conversion inside the graph. 31 | func (g *Graph) AvfilterGraphSetAutoConvert(f uint) { 32 | C.avfilter_graph_set_auto_convert((*C.struct_AVFilterGraph)(g), C.uint(f)) 33 | } 34 | 35 | //Check validity and configure all the links and formats in the graph. 36 | func (g *Graph) AvfilterGraphConfig(l int) int { 37 | return int(C.avfilter_graph_config((*C.struct_AVFilterGraph)(g), unsafe.Pointer(&l))) 38 | } 39 | 40 | //Free a graph, destroy its links, and set *graph to NULL. 41 | func (g *Graph) AvfilterGraphFree() { 42 | C.avfilter_graph_free((**C.struct_AVFilterGraph)(unsafe.Pointer(&g))) 43 | } 44 | 45 | //Add a graph described by a string to a graph. 46 | func (g *Graph) AvfilterGraphParse(f string, i, o *Input, l int) int { 47 | return int(C.avfilter_graph_parse((*C.struct_AVFilterGraph)(g), C.CString(f), (*C.struct_AVFilterInOut)(i), (*C.struct_AVFilterInOut)(o), unsafe.Pointer(&l))) 48 | } 49 | 50 | //Add a graph described by a string to a graph. 51 | func (g *Graph) AvfilterGraphParsePtr(f string, i, o **Input, l int) int { 52 | return int(C.avfilter_graph_parse_ptr((*C.struct_AVFilterGraph)(g), C.CString(f), (**C.struct_AVFilterInOut)(unsafe.Pointer(i)), (**C.struct_AVFilterInOut)(unsafe.Pointer(o)), unsafe.Pointer(&l))) 53 | } 54 | 55 | //Add a graph described by a string to a graph. 56 | func (g *Graph) AvfilterGraphParse2(f string, i, o **Input) int { 57 | return int(C.avfilter_graph_parse2((*C.struct_AVFilterGraph)(g), C.CString(f), (**C.struct_AVFilterInOut)(unsafe.Pointer(i)), (**C.struct_AVFilterInOut)(unsafe.Pointer(o)))) 58 | } 59 | 60 | //Send a command to one or more filter instances. 61 | func (g *Graph) AvfilterGraphSendCommand(t, cmd, arg, res string, resl, f int) int { 62 | return int(C.avfilter_graph_send_command((*C.struct_AVFilterGraph)(g), C.CString(t), C.CString(cmd), C.CString(arg), C.CString(res), C.int(resl), C.int(f))) 63 | } 64 | 65 | //Queue a command for one or more filter instances. 66 | func (g *Graph) AvfilterGraphQueueCommand(t, cmd, arg string, f int, ts C.double) int { 67 | return int(C.avfilter_graph_queue_command((*C.struct_AVFilterGraph)(g), C.CString(t), C.CString(cmd), C.CString(arg), C.int(f), ts)) 68 | } 69 | 70 | //Dump a graph into a human-readable string representation. 71 | func (g *Graph) AvfilterGraphDump(o string) string { 72 | return C.GoString(C.avfilter_graph_dump((*C.struct_AVFilterGraph)(g), C.CString(o))) 73 | } 74 | 75 | //Request a frame on the oldest sink 76 | func (g *Graph) AvfilterGraphRequestOldestlink() int { 77 | return int(C.avfilter_graph_request_oldest((*C.struct_AVFilterGraph)(g))) 78 | } 79 | 80 | //Create and add a filter instance into an existing graph. 81 | func AvfilterGraphCreateFilter(cx **Context, f *Filter, n, a string, o int, g *Graph) int { 82 | return int(C.avfilter_graph_create_filter((**C.struct_AVFilterContext)(unsafe.Pointer(cx)), (*C.struct_AVFilter)(f), C.CString(n), C.CString(a), unsafe.Pointer(&o), (*C.struct_AVFilterGraph)(g))) 83 | } 84 | -------------------------------------------------------------------------------- /goav/swresample/context.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a MIT license that can be found in the LICENSE file. 2 | // Giorgis (habtom@giorgis.io) 3 | 4 | package swresample 5 | 6 | /* 7 | #cgo pkg-config: libswresample 8 | #include 9 | */ 10 | import "C" 11 | import ( 12 | "unsafe" 13 | ) 14 | 15 | //Initialize context after user parameters have been set. 16 | func (s *Context) SwrInit() int { 17 | return int(C.swr_init((*C.struct_SwrContext)(s))) 18 | } 19 | 20 | //Check whether an swr context has been initialized or not. 21 | func (s *Context) SwrIsInitialized() int { 22 | return int(C.swr_is_initialized((*C.struct_SwrContext)(s))) 23 | } 24 | 25 | //Allocate Context if needed and set/reset common parameters. 26 | func (s *Context) SwrAllocSetOpts(ocl int64, osf AvSampleFormat, osr int, icl int64, isf AvSampleFormat, isr, lo, lc int) *Context { 27 | return (*Context)(C.swr_alloc_set_opts((*C.struct_SwrContext)(s), C.int64_t(ocl), (C.enum_AVSampleFormat)(osf), C.int(osr), C.int64_t(icl), (C.enum_AVSampleFormat)(isf), C.int(isr), C.int(lo), unsafe.Pointer(&lc))) 28 | } 29 | 30 | //Context destructor functions. Free the given Context and set the pointer to NULL. 31 | func (s *Context) SwrFree() { 32 | C.swr_free((**C.struct_SwrContext)(unsafe.Pointer(s))) 33 | } 34 | 35 | //Closes the context so that swr_is_initialized() returns 0. 36 | func (s *Context) SwrClose() { 37 | C.swr_close((*C.struct_SwrContext)(s)) 38 | } 39 | 40 | //Core conversion functions. Convert audio 41 | func (s *Context) SwrConvert(out **uint8, oc int, in **uint8, ic int) int { 42 | return int(C.swr_convert((*C.struct_SwrContext)(s), (**C.uint8_t)(unsafe.Pointer(out)), C.int(oc), (**C.uint8_t)(unsafe.Pointer(in)), C.int(ic))) 43 | } 44 | 45 | //Convert the next timestamp from input to output timestamps are in 1/(in_sample_rate * out_sample_rate) units. 46 | func (s *Context) SwrNextPts(pts int64) int64 { 47 | return int64(C.swr_next_pts((*C.struct_SwrContext)(s), C.int64_t(pts))) 48 | } 49 | 50 | //Low-level option setting functions 51 | //These functons provide a means to set low-level options that is not possible with the AvOption API. 52 | //Activate resampling compensation ("soft" compensation). 53 | func (s *Context) SwrSetCompensation(sd, cd int) int { 54 | return int(C.swr_set_compensation((*C.struct_SwrContext)(s), C.int(sd), C.int(cd))) 55 | } 56 | 57 | //Set a customized input channel mapping. 58 | func (s *Context) SwrSetChannelMapping(cm *int) int { 59 | return int(C.swr_set_channel_mapping((*C.struct_SwrContext)(s), (*C.int)(unsafe.Pointer(cm)))) 60 | } 61 | 62 | //Set a customized remix matrix. 63 | func (s *Context) SwrSetMatrix(m *int, t int) int { 64 | return int(C.swr_set_matrix((*C.struct_SwrContext)(s), (*C.double)(unsafe.Pointer(m)), C.int(t))) 65 | } 66 | 67 | //Sample handling functions. Drops the specified number of output samples. 68 | func (s *Context) SwrDropOutput(c int) int { 69 | return int(C.swr_drop_output((*C.struct_SwrContext)(s), C.int(c))) 70 | } 71 | 72 | //Injects the specified number of silence samples. 73 | func (s *Context) SwrInjectSilence(c int) int { 74 | return int(C.swr_inject_silence((*C.struct_SwrContext)(s), C.int(c))) 75 | } 76 | 77 | //Gets the delay the next input sample will experience relative to the next output sample. 78 | func (s *Context) SwrGetDelay(b int64) int64 { 79 | return int64(C.swr_get_delay((*C.struct_SwrContext)(s), C.int64_t(b))) 80 | } 81 | 82 | //Frame based API. Convert the samples in the input Frame and write them to the output Frame. 83 | func (s *Context) SwrConvertFrame(o, i *Frame) int { 84 | return int(C.swr_convert_frame((*C.struct_SwrContext)(s), (*C.struct_AVFrame)(o), (*C.struct_AVFrame)(i))) 85 | } 86 | 87 | //Configure or reconfigure the Context using the information provided by the AvFrames. 88 | func (s *Context) SwrConfigFrame(o, i *Frame) int { 89 | return int(C.swr_config_frame((*C.struct_SwrContext)(s), (*C.struct_AVFrame)(o), (*C.struct_AVFrame)(i))) 90 | } 91 | -------------------------------------------------------------------------------- /goav/avutil/dict.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a MIT license that can be found in the LICENSE file. 2 | // Giorgis (habtom@giorgis.io) 3 | 4 | // Package avutil is a utility library to aid portable multimedia programming. 5 | // It contains safe portable string functions, random number generators, data structures, 6 | // additional mathematics functions, cryptography and multimedia related functionality. 7 | // Some generic features and utilities provided by the libavutil library 8 | package avutil 9 | 10 | //#cgo pkg-config: libavutil 11 | //#include 12 | //#include 13 | //#include 14 | import "C" 15 | import ( 16 | "unsafe" 17 | ) 18 | 19 | type ( 20 | Dictionary C.struct_AVDictionary 21 | DictionaryEntry C.struct_AVDictionaryEntry 22 | ) 23 | 24 | const ( 25 | AV_DICT_MATCH_CASE = int(C.AV_DICT_MATCH_CASE) 26 | AV_DICT_IGNORE_SUFFIX = int(C.AV_DICT_IGNORE_SUFFIX) 27 | AV_DICT_DONT_STRDUP_KEY = int(C.AV_DICT_DONT_STRDUP_KEY) 28 | AV_DICT_DONT_STRDUP_VAL = int(C.AV_DICT_DONT_STRDUP_VAL) 29 | AV_DICT_DONT_OVERWRITE = int(C.AV_DICT_DONT_OVERWRITE) 30 | AV_DICT_APPEND = int(C.AV_DICT_APPEND) 31 | AV_DICT_MULTIKEY = int(C.AV_DICT_MULTIKEY) 32 | ) 33 | 34 | func (d *Dictionary) AvDictGet(key string, prev *DictionaryEntry, flags int) *DictionaryEntry { 35 | Ckey := C.CString(key) 36 | defer C.free(unsafe.Pointer(Ckey)) 37 | 38 | return (*DictionaryEntry)(C.av_dict_get( 39 | (*C.struct_AVDictionary)(d), 40 | Ckey, 41 | (*C.struct_AVDictionaryEntry)(prev), 42 | C.int(flags), 43 | )) 44 | } 45 | 46 | func (d *Dictionary) AvDictCount() int { 47 | return int(C.av_dict_count((*C.struct_AVDictionary)(d))) 48 | } 49 | 50 | func (d *Dictionary) AvDictSet(key, value string, flags int) int { 51 | Ckey := C.CString(key) 52 | defer C.free(unsafe.Pointer(Ckey)) 53 | 54 | Cvalue := C.CString(value) 55 | defer C.free(unsafe.Pointer(Cvalue)) 56 | 57 | return int(C.av_dict_set( 58 | (**C.struct_AVDictionary)(unsafe.Pointer(&d)), 59 | Ckey, 60 | Cvalue, 61 | C.int(flags), 62 | )) 63 | } 64 | 65 | func (d *Dictionary) AvDictSetInt(key string, value int64, flags int) int { 66 | Ckey := C.CString(key) 67 | defer C.free(unsafe.Pointer(Ckey)) 68 | 69 | return int(C.av_dict_set_int( 70 | (**C.struct_AVDictionary)(unsafe.Pointer(&d)), 71 | Ckey, 72 | C.int64_t(value), 73 | C.int(flags), 74 | )) 75 | } 76 | 77 | func (d *Dictionary) AvDictParseString(str, key_val_sep, pairs_sep string, flags int) int { 78 | Cstr := C.CString(str) 79 | defer C.free(unsafe.Pointer(Cstr)) 80 | 81 | Ckey_val_sep := C.CString(key_val_sep) 82 | defer C.free(unsafe.Pointer(Ckey_val_sep)) 83 | 84 | Cpairs_sep := C.CString(pairs_sep) 85 | defer C.free(unsafe.Pointer(Cpairs_sep)) 86 | 87 | return int(C.av_dict_parse_string( 88 | (**C.struct_AVDictionary)(unsafe.Pointer(&d)), 89 | Cstr, 90 | Ckey_val_sep, 91 | Cpairs_sep, 92 | C.int(flags), 93 | )) 94 | } 95 | 96 | func (d *Dictionary) AvDictCopy(src *Dictionary, flags int) int { 97 | return int(C.av_dict_copy( 98 | (**C.struct_AVDictionary)(unsafe.Pointer(&d)), 99 | (*C.struct_AVDictionary)(unsafe.Pointer(src)), 100 | C.int(flags), 101 | )) 102 | } 103 | 104 | func (d *Dictionary) AvDictFree() { 105 | C.av_dict_free((**C.struct_AVDictionary)(unsafe.Pointer(&d))) 106 | } 107 | 108 | func (d *Dictionary) AvDictGetString(key_val_sep, pairs_sep byte) (int, string) { 109 | var Cbuf *C.char 110 | 111 | ret := int(C.av_dict_get_string( 112 | (*C.struct_AVDictionary)(d), 113 | (**C.char)(&Cbuf), 114 | C.char(key_val_sep), 115 | C.char(pairs_sep), 116 | )) 117 | 118 | var buf string 119 | if ret == 0 { 120 | buf = C.GoString(Cbuf) 121 | C.free(unsafe.Pointer(Cbuf)) 122 | } 123 | 124 | return ret, buf 125 | } 126 | 127 | func (d *DictionaryEntry) Key() string { 128 | return C.GoString(d.key) 129 | } 130 | 131 | func (d *DictionaryEntry) Value() string { 132 | return C.GoString(d.value) 133 | } 134 | -------------------------------------------------------------------------------- /rtp/packet.go: -------------------------------------------------------------------------------- 1 | package rtp 2 | 3 | import( 4 | "encoding/binary" 5 | ) 6 | 7 | const ( 8 | MaxRtpPayloadSize int = 1500 - 64 9 | ) 10 | type Packet struct { 11 | header [12]byte 12 | payload []byte 13 | } 14 | 15 | type shardUnitA struct { 16 | fuIndicator byte 17 | fuHeader byte 18 | } 19 | 20 | func NewDefaultPacketWithH264Type() *Packet { 21 | h := [12]byte { 22 | 0x80, //version 2 no P, X, CSRC 0 23 | 0x60, //type h264, Mark 0 24 | 0x00, 0x00, // initial seq 25 | 0x00, 0x00, 0x00, 0x00, // timestamp 26 | 0x00, 0x00, 0x00, 0x00, // SSRC 27 | } 28 | 29 | return &Packet{ 30 | header : h, 31 | } 32 | } 33 | 34 | // Sequence returns the sequence number as uint16 in host order. 35 | func (p *Packet) Sequence() uint16 { 36 | return binary.BigEndian.Uint16(p.header[2:]) 37 | } 38 | 39 | func (p *Packet) SetSequence(seq uint16) { 40 | binary.BigEndian.PutUint16(p.header[2:], seq) 41 | } 42 | 43 | func (p *Packet) Header() [12]byte { 44 | return p.header 45 | } 46 | 47 | func (p *Packet) PayloadType() byte { 48 | return (p.header[1] & 0x7f) 49 | } 50 | 51 | func (p *Packet) SetPayloadType(typ byte) { 52 | p.header[1] = p.header[1] & 0x80 53 | typ = typ & 0x7f 54 | p.header[1] = p.header[1] | typ 55 | } 56 | 57 | func (p *Packet) TimeStamp() uint32{ 58 | return binary.BigEndian.Uint32(p.header[4:]) 59 | } 60 | 61 | // setRtpTimeStamp takes a 32 unsigned timestamp in host order and sets it in network order in SR. 62 | func (p *Packet) SetTimeStamp(stamp uint32) { 63 | binary.BigEndian.PutUint32(p.header[4:], stamp) 64 | } 65 | 66 | func (p *Packet) SetSsrc(ssrc uint32) { 67 | binary.BigEndian.PutUint32(p.header[8:], ssrc) 68 | } 69 | 70 | func (p *Packet) SetPayload(pay []byte) { 71 | p.payload = pay[0:] 72 | } 73 | 74 | func (p *Packet) GetRtpBytes() []byte { 75 | rp := append(p.header[0:], p.payload[0:]...) 76 | return rp 77 | } 78 | 79 | func (p *Packet) ParserNaluToRtpPayload(nalu []byte) [][]byte { 80 | 81 | var ret [][]byte 82 | var n []byte 83 | 84 | if nalu[0] == 0 && nalu[1] == 0 && nalu[2] == 1 { 85 | n = nalu[3:] 86 | } else { 87 | n = nalu[4:] 88 | } 89 | 90 | if len(n) < MaxRtpPayloadSize { 91 | ret = append(ret, n) 92 | } else { 93 | //0 是F 94 | //11 是NRI 95 | //11100 是FU Type,这里是28,即FU-A 96 | //1 是S,Start,说明是分片的第一包 97 | //0 是E,End,如果是分片的最后一包,设置为1,这里不是 98 | //0 是R,Remain,保留位,总是0 99 | //00101 是NAl Type 100 | saStart := shardUnitA{0, 0} 101 | saStart.fuIndicator = saStart.fuIndicator | n[0] 102 | saStart.fuIndicator = (saStart.fuIndicator & 0xe0) | 0x1c 103 | saStart.fuHeader = (saStart.fuHeader | 0x80) | (n[0] & 0x1f) 104 | 105 | saSlice := shardUnitA{0, 0} 106 | saSlice.fuIndicator = saSlice.fuIndicator | n[0] 107 | saSlice.fuIndicator = (saSlice.fuIndicator & 0xe0) | 0x1c 108 | saSlice.fuHeader = saSlice.fuHeader | (n[0] & 0x1f) 109 | 110 | saEnd := shardUnitA{0, 0} 111 | saEnd.fuIndicator = saEnd.fuIndicator | n[0] 112 | saEnd.fuIndicator = (saEnd.fuIndicator & 0xe0) | 0x1c 113 | saEnd.fuHeader = (saEnd.fuHeader | 0x40) | (n[0] & 0x1f) 114 | 115 | 116 | offset := 1 //n offset 117 | start := append(make([]byte, 0), saStart.fuIndicator, saStart.fuHeader) 118 | start = append(start, n[offset:MaxRtpPayloadSize + offset - 2]...) 119 | ret = append(ret, start) 120 | offset = offset + MaxRtpPayloadSize - 2 121 | 122 | remain := len(n) - MaxRtpPayloadSize - 1 123 | 124 | for remain > MaxRtpPayloadSize - 2 { 125 | slice := append(make([]byte, 0), saSlice.fuIndicator, saSlice.fuHeader) 126 | slice = append(slice, n[offset:MaxRtpPayloadSize + offset - 2]...) 127 | ret = append(ret, slice) 128 | offset = offset + MaxRtpPayloadSize - 2 129 | remain = remain - MaxRtpPayloadSize - 2 130 | } 131 | 132 | end := append(make([]byte, 0), saEnd.fuIndicator, saEnd.fuHeader) 133 | end = append(end, n[offset:]...) 134 | ret = append(ret, end) 135 | 136 | } 137 | 138 | return ret 139 | } 140 | 141 | -------------------------------------------------------------------------------- /h264/parser.go: -------------------------------------------------------------------------------- 1 | package h264 2 | 3 | import ( 4 | ) 5 | 6 | const ( 7 | i_frame byte = 0 8 | p_frame byte = 1 9 | b_frame byte = 2 10 | ) 11 | 12 | const ( 13 | NalueTypeNotDefined byte = 0 14 | NalueTypeSlice byte = 1 //slice_layer_without_partioning_rbsp() sliceheader 15 | NalueTypeDpa byte = 2 // slice_data_partition_a_layer_rbsp( ), slice_header 16 | NalueTypeDpb byte = 3 // slice_data_partition_b_layer_rbsp( ) 17 | NalueTypeDpc byte = 4 // slice_data_partition_c_layer_rbsp( ) 18 | NalueTypeIdr byte = 5 // slice_layer_without_partitioning_rbsp( ),sliceheader 19 | NalueTypeSei byte = 6 //sei_rbsp( ) 20 | NalueTypeSps byte = 7 //seq_parameter_set_rbsp( ) 21 | NalueTypePps byte = 8 //pic_parameter_set_rbsp( ) 22 | NalueTypeAud byte = 9 // access_unit_delimiter_rbsp( ) 23 | NalueTypeEoesq byte = 10 //end_of_seq_rbsp( ) 24 | NalueTypeEostream byte = 11 //end_of_stream_rbsp( ) 25 | NalueTypeFiller byte = 12 //filler_data_rbsp( ) 26 | NalueTypeFuA byte = 28 //Shard unitA 27 | NalueTypeFuB byte = 29 //Shard unitB 28 | ) 29 | 30 | var ParameterSetStartCode = []byte{0x00, 0x00, 0x00, 0x01} 31 | var StartCode = []byte{0x00, 0x00, 0x01} 32 | 33 | type Parser struct { 34 | naluByte byte 35 | shardA *shardUnitA 36 | 37 | // deprecated 38 | internalBuffer []byte // use ParserToInternalSlice() to get a complete nalu packet 39 | } 40 | 41 | type shardUnitA struct { 42 | fuIndicator byte 43 | fuHeader byte 44 | } 45 | 46 | func NewParser() *Parser { 47 | return &Parser{ 48 | naluByte : 0, 49 | shardA : &shardUnitA{0, 0}, 50 | } 51 | } 52 | 53 | func (p *Parser) FillNaluHead(h byte) { 54 | p.naluByte = h 55 | p.shardA.fuIndicator = 0 56 | p.shardA.fuHeader = 0 57 | } 58 | 59 | func (p *Parser) NaluType() byte { 60 | return p.naluByte & 0x1f 61 | } 62 | 63 | func (p *Parser) ShardA() *shardUnitA { 64 | return p.shardA 65 | } 66 | 67 | func (p *Parser) FillShadUnitA(s [2]byte) { 68 | p.shardA.fuIndicator = s[0] 69 | p.shardA.fuHeader = s[1] 70 | } 71 | 72 | func (s *shardUnitA) IsStart() bool { 73 | return (s.fuHeader & 0x80) == 0x80 74 | } 75 | 76 | func (s *shardUnitA) IsEnd() bool { 77 | return (s.fuHeader & 0x40) == 0x40 78 | } 79 | 80 | func (s *shardUnitA) NaluType() byte { 81 | return s.fuHeader & 0x1f 82 | } 83 | 84 | func (s *shardUnitA) NaluHeader() byte { 85 | s1 := s.fuIndicator & 0xe0 86 | s2 := s.fuHeader & 0x1f 87 | 88 | return (s1 | s2) 89 | } 90 | 91 | 92 | // deprecated 93 | // must clear with ClearInternalBuffer() 94 | func (p *Parser) ParserToInternalSlice(pkt []byte) bool { 95 | p.FillNaluHead(pkt[0]) 96 | 97 | if p.NaluType() == NalueTypeFuA { 98 | p.FillShadUnitA([2]byte{pkt[0], pkt[1]}) 99 | 100 | if p.ShardA().IsStart() { 101 | //fmt.Println("-----is fuA start------") 102 | p.internalBuffer = append(p.internalBuffer, StartCode[0:]...) 103 | p.internalBuffer = append(p.internalBuffer, p.ShardA().NaluHeader()) 104 | p.internalBuffer = append(p.internalBuffer, pkt[2:]...) 105 | return false 106 | } else if p.ShardA().IsEnd() { 107 | //fmt.Println("-----is fuA end--------") 108 | p.internalBuffer = append(p.internalBuffer, pkt[2:]...) 109 | //fmt.Println("len: ", len(p.internalBuffer), ":\n", hex.EncodeToString(p.internalBuffer)) 110 | return true 111 | } else { 112 | //fmt.Println("-----is fuA slice------") 113 | if len(p.internalBuffer) > 1920*1080*3 { 114 | panic("internalBuffer to Large, fix me") 115 | } 116 | 117 | p.internalBuffer = append(p.internalBuffer, pkt[2:]...) 118 | return false 119 | } 120 | } else { 121 | //fmt.Println("nalu : ", p.NaluType()) 122 | 123 | p.internalBuffer = append(p.internalBuffer, StartCode[0:]...) 124 | p.internalBuffer = append(p.internalBuffer, pkt[0:]...) 125 | //fmt.Println("len: ", len(p.internalBuffer), ":\n", hex.EncodeToString(p.internalBuffer)) 126 | 127 | return true 128 | } 129 | } 130 | 131 | func (p *Parser) GetInternalBuffer() []byte{ 132 | return p.internalBuffer 133 | } 134 | 135 | func (p *Parser) ClearInternalBuffer() { 136 | p.internalBuffer = p.internalBuffer[0:0] 137 | } -------------------------------------------------------------------------------- /cron/spec.go: -------------------------------------------------------------------------------- 1 | package cron 2 | 3 | import "time" 4 | 5 | // SpecSchedule specifies a duty cycle (to the second granularity), based on a 6 | // traditional crontab specification. It is computed initially and stored as bit sets. 7 | type SpecSchedule struct { 8 | Second, Minute, Hour, Dom, Month, Dow uint64 9 | } 10 | 11 | // bounds provides a range of acceptable values (plus a map of name to value). 12 | type bounds struct { 13 | min, max uint 14 | names map[string]uint 15 | } 16 | 17 | // The bounds for each field. 18 | var ( 19 | seconds = bounds{0, 59, nil} 20 | minutes = bounds{0, 59, nil} 21 | hours = bounds{0, 23, nil} 22 | dom = bounds{1, 31, nil} 23 | months = bounds{1, 12, map[string]uint{ 24 | "jan": 1, 25 | "feb": 2, 26 | "mar": 3, 27 | "apr": 4, 28 | "may": 5, 29 | "jun": 6, 30 | "jul": 7, 31 | "aug": 8, 32 | "sep": 9, 33 | "oct": 10, 34 | "nov": 11, 35 | "dec": 12, 36 | }} 37 | dow = bounds{0, 6, map[string]uint{ 38 | "sun": 0, 39 | "mon": 1, 40 | "tue": 2, 41 | "wed": 3, 42 | "thu": 4, 43 | "fri": 5, 44 | "sat": 6, 45 | }} 46 | ) 47 | 48 | const ( 49 | // Set the top bit if a star was included in the expression. 50 | starBit = 1 << 63 51 | ) 52 | 53 | // Next returns the next time this schedule is activated, greater than the given 54 | // time. If no time can be found to satisfy the schedule, return the zero time. 55 | func (s *SpecSchedule) Next(t time.Time) time.Time { 56 | // General approach: 57 | // For Month, Day, Hour, Minute, Second: 58 | // Check if the time value matches. If yes, continue to the next field. 59 | // If the field doesn't match the schedule, then increment the field until it matches. 60 | // While incrementing the field, a wrap-around brings it back to the beginning 61 | // of the field list (since it is necessary to re-verify previous field 62 | // values) 63 | 64 | // Start at the earliest possible time (the upcoming second). 65 | t = t.Add(1*time.Second - time.Duration(t.Nanosecond())*time.Nanosecond) 66 | 67 | // This flag indicates whether a field has been incremented. 68 | added := false 69 | 70 | // If no time is found within five years, return zero. 71 | yearLimit := t.Year() + 5 72 | 73 | WRAP: 74 | if t.Year() > yearLimit { 75 | return time.Time{} 76 | } 77 | 78 | // Find the first applicable month. 79 | // If it's this month, then do nothing. 80 | for 1< 0 152 | dowMatch bool = 1< 0 153 | ) 154 | if s.Dom&starBit > 0 || s.Dow&starBit > 0 { 155 | return domMatch && dowMatch 156 | } 157 | return domMatch || dowMatch 158 | } 159 | -------------------------------------------------------------------------------- /goav/avformat/codec_context_struct.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a MIT license that can be found in the LICENSE file. 2 | // Giorgis (habtom@giorgis.io) 3 | 4 | //Package avformat provides some generic global options, which can be set on all the muxers and demuxers. 5 | //In addition each muxer or demuxer may support so-called private options, which are specific for that component. 6 | //Supported formats (muxers and demuxers) provided by the libavformat library 7 | package avformat 8 | 9 | //#cgo pkg-config: libavformat libavcodec libavutil libavdevice libavfilter libswresample libswscale 10 | //#include 11 | //#include 12 | //#include 13 | //#include 14 | //#include 15 | //#include 16 | //#include 17 | import "C" 18 | import ( 19 | "reflect" 20 | "unsafe" 21 | 22 | "github.com/giorgisio/goav/avcodec" 23 | ) 24 | 25 | func (cctxt *CodecContext) Type() MediaType { 26 | return MediaType(cctxt.codec_type) 27 | } 28 | 29 | func (cctxt *CodecContext) SetBitRate(br int64) { 30 | cctxt.bit_rate = C.int64_t(br) 31 | } 32 | 33 | func (cctxt *CodecContext) GetCodecId() CodecId { 34 | return CodecId(cctxt.codec_id) 35 | } 36 | 37 | func (cctxt *CodecContext) SetCodecId(codecId CodecId) { 38 | cctxt.codec_id = C.enum_AVCodecID(codecId) 39 | } 40 | 41 | func (cctxt *CodecContext) GetCodecType() MediaType { 42 | return MediaType(cctxt.codec_type) 43 | } 44 | 45 | func (cctxt *CodecContext) SetCodecType(ctype MediaType) { 46 | cctxt.codec_type = C.enum_AVMediaType(ctype) 47 | } 48 | 49 | func (cctxt *CodecContext) GetTimeBase() avcodec.Rational { 50 | return newRational(cctxt.time_base) 51 | } 52 | 53 | func (cctxt *CodecContext) SetTimeBase(timeBase avcodec.Rational) { 54 | cctxt.time_base.num = C.int(timeBase.Num()) 55 | cctxt.time_base.den = C.int(timeBase.Den()) 56 | } 57 | 58 | func (cctx *CodecContext) GetWidth() int { 59 | return int(cctx.width) 60 | } 61 | 62 | func (cctx *CodecContext) SetWidth(w int) { 63 | cctx.width = C.int(w) 64 | } 65 | 66 | func (cctx *CodecContext) GetHeight() int { 67 | return int(cctx.height) 68 | } 69 | 70 | func (cctx *CodecContext) SetHeight(h int) { 71 | cctx.height = C.int(h) 72 | } 73 | 74 | func (cctx *CodecContext) GetPixelFormat() avcodec.PixelFormat { 75 | return avcodec.PixelFormat(C.int(cctx.pix_fmt)) 76 | } 77 | 78 | func (cctx *CodecContext) SetPixelFormat(fmt avcodec.PixelFormat) { 79 | cctx.pix_fmt = C.enum_AVPixelFormat(C.int(fmt)) 80 | } 81 | 82 | func (cctx *CodecContext) GetFlags() int { 83 | return int(cctx.flags) 84 | } 85 | 86 | func (cctx *CodecContext) SetFlags(flags int) { 87 | cctx.flags = C.int(flags) 88 | } 89 | 90 | func (cctx *CodecContext) GetMeRange() int { 91 | return int(cctx.me_range) 92 | } 93 | 94 | func (cctx *CodecContext) SetMeRange(r int) { 95 | cctx.me_range = C.int(r) 96 | } 97 | 98 | func (cctx *CodecContext) GetMaxQDiff() int { 99 | return int(cctx.max_qdiff) 100 | } 101 | 102 | func (cctx *CodecContext) SetMaxQDiff(v int) { 103 | cctx.max_qdiff = C.int(v) 104 | } 105 | 106 | func (cctx *CodecContext) GetQMin() int { 107 | return int(cctx.qmin) 108 | } 109 | 110 | func (cctx *CodecContext) SetQMin(v int) { 111 | cctx.qmin = C.int(v) 112 | } 113 | 114 | func (cctx *CodecContext) GetQMax() int { 115 | return int(cctx.qmax) 116 | } 117 | 118 | func (cctx *CodecContext) SetQMax(v int) { 119 | cctx.qmax = C.int(v) 120 | } 121 | 122 | func (cctx *CodecContext) GetQCompress() float32 { 123 | return float32(cctx.qcompress) 124 | } 125 | 126 | func (cctx *CodecContext) SetQCompress(v float32) { 127 | cctx.qcompress = C.float(v) 128 | } 129 | 130 | func (cctx *CodecContext) GetExtraData() []byte { 131 | header := reflect.SliceHeader{ 132 | Data: uintptr(unsafe.Pointer(cctx.extradata)), 133 | Len: int(cctx.extradata_size), 134 | Cap: int(cctx.extradata_size), 135 | } 136 | 137 | return *((*[]byte)(unsafe.Pointer(&header))) 138 | } 139 | 140 | func (cctx *CodecContext) SetExtraData(data []byte) { 141 | header := (*reflect.SliceHeader)(unsafe.Pointer(&data)) 142 | 143 | cctx.extradata = (*C.uint8_t)(unsafe.Pointer(header.Data)) 144 | cctx.extradata_size = C.int(header.Len) 145 | } 146 | 147 | func (cctx *CodecContext) Release() { 148 | C.avcodec_close((*C.struct_AVCodecContext)(unsafe.Pointer(cctx))) 149 | C.av_freep(unsafe.Pointer(cctx)) 150 | } 151 | -------------------------------------------------------------------------------- /goav/avdevice/avdevice.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a MIT license that can be found in the LICENSE file. 2 | // Giorgis (habtom@giorgis.io) 3 | 4 | // Package avdevice deals with the input and output devices provided by the libavdevice library 5 | // The libavdevice library provides the same interface as libavformat. 6 | // Namely, an input device is considered like a demuxer, and an output device like a muxer, 7 | // and the interface and generic device options are the same provided by libavformat 8 | package avdevice 9 | 10 | /* 11 | #cgo pkg-config: libavdevice 12 | #include 13 | */ 14 | import "C" 15 | import ( 16 | "unsafe" 17 | ) 18 | 19 | type ( 20 | AvDeviceRect C.struct_AVDeviceRect 21 | AvDeviceCapabilitiesQuery C.struct_AVDeviceCapabilitiesQuery 22 | AvDeviceInfo C.struct_AVDeviceInfo 23 | AvDeviceInfoList C.struct_AVDeviceInfoList 24 | InputFormat C.struct_AVInputFormat 25 | OutputFormat C.struct_AVOutputFormat 26 | AvFormatContext C.struct_AVFormatContext 27 | Dictionary C.struct_AVDictionary 28 | AvAppToDevMessageType C.enum_AVAppToDevMessageType 29 | AvDevToAppMessageType C.enum_AVDevToAppMessageType 30 | ) 31 | 32 | //unsigned avdevice_version (void) 33 | func AvdeviceVersion() uint { 34 | return uint(C.avdevice_version()) 35 | } 36 | 37 | //Return the libavdevice build-time configuration. 38 | func AvdeviceConfiguration() string { 39 | return C.GoString(C.avdevice_configuration()) 40 | } 41 | 42 | //Return the libavdevice license. 43 | func AvdeviceLicense() string { 44 | return C.GoString(C.avdevice_license()) 45 | } 46 | 47 | //Initialize libavdevice and register all the input and output devices. 48 | func AvdeviceRegisterAll() { 49 | C.avdevice_register_all() 50 | } 51 | 52 | //Send control message from application to device. 53 | func AvdeviceAppToDevControlMessage(s *AvFormatContext, m AvAppToDevMessageType, da int, d uintptr) int { 54 | return int(C.avdevice_app_to_dev_control_message((*C.struct_AVFormatContext)(s), (C.enum_AVAppToDevMessageType)(m), unsafe.Pointer(&da), C.size_t(d))) 55 | } 56 | 57 | //Send control message from device to application. 58 | func AvdeviceDevToAppControlMessage(fcxt *AvFormatContext, m AvDevToAppMessageType, da int, d uintptr) int { 59 | return int(C.avdevice_dev_to_app_control_message((*C.struct_AVFormatContext)(fcxt), (C.enum_AVDevToAppMessageType)(m), unsafe.Pointer(&da), C.size_t(d))) 60 | } 61 | 62 | //Initialize capabilities probing API based on AvOption API. 63 | func AvdeviceCapabilitiesCreate(c **AvDeviceCapabilitiesQuery, s *AvFormatContext, d **Dictionary) int { 64 | return int(C.avdevice_capabilities_create((**C.struct_AVDeviceCapabilitiesQuery)(unsafe.Pointer(c)), (*C.struct_AVFormatContext)(s), (**C.struct_AVDictionary)(unsafe.Pointer(d)))) 65 | } 66 | 67 | //Free resources created by avdevice_capabilities_create() 68 | func AvdeviceCapabilitiesFree(c **AvDeviceCapabilitiesQuery, s *AvFormatContext) { 69 | C.avdevice_capabilities_free((**C.struct_AVDeviceCapabilitiesQuery)(unsafe.Pointer(c)), (*C.struct_AVFormatContext)(s)) 70 | } 71 | 72 | //List devices. 73 | func AvdeviceListDevices(s *AvFormatContext, d **AvDeviceInfoList) int { 74 | return int(C.avdevice_list_devices((*C.struct_AVFormatContext)(s), (**C.struct_AVDeviceInfoList)(unsafe.Pointer(d)))) 75 | } 76 | 77 | //Convenient function to free result of avdeviceListDevices(). 78 | func AvdeviceFreeListDevices(d **AvDeviceInfoList) { 79 | C.avdevice_free_list_devices((**C.struct_AVDeviceInfoList)(unsafe.Pointer(d))) 80 | } 81 | 82 | // //int avdevice_list_input_sources (struct InputFormat *device, const char *device_name, Dictionary *device_options, AvDeviceInfoList **device_list) 83 | // //List devices. 84 | // func AvdeviceListInputSources(d *InputFormat, dv string, do *Dictionary, dl **AvDeviceInfoList) int { 85 | // return int(C.avdevice_list_input_sources((*C.struct_AVInputFormat)(d), C.CString(dv), (*C.struct_AVDictionary)(do), (**C.struct_AVDeviceInfoList)(unsafe.Pointer(dl)))) 86 | // } 87 | 88 | // //int avdevice_list_output_sinks (struct OutputFormat *device, const char *device_name, Dictionary *device_options, AvDeviceInfoList **device_list) 89 | // func AvdeviceListOutputSinks(d *OutputFormat, dn string, di *Dictionary, dl **AvDeviceInfoList) int { 90 | // return int(C.avdevice_list_output_sinks((*C.struct_AVOutputFormat)(d), C.CString(dn), (*C.struct_AVDictionary)(di), (**C.struct_AVDeviceInfoList)(unsafe.Pointer(dl)))) 91 | // } 92 | -------------------------------------------------------------------------------- /redigo/redis/log.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Gary Burd 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 | // not use this file except in compliance with the License. You may obtain 5 | // a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | // License for the specific language governing permissions and limitations 13 | // under the License. 14 | 15 | package redis 16 | 17 | import ( 18 | "bytes" 19 | "fmt" 20 | "log" 21 | "time" 22 | ) 23 | 24 | var ( 25 | _ ConnWithTimeout = (*loggingConn)(nil) 26 | ) 27 | 28 | // NewLoggingConn returns a logging wrapper around a connection. 29 | func NewLoggingConn(conn Conn, logger *log.Logger, prefix string) Conn { 30 | if prefix != "" { 31 | prefix = prefix + "." 32 | } 33 | return &loggingConn{conn, logger, prefix, nil} 34 | } 35 | 36 | //NewLoggingConnFilter returns a logging wrapper around a connection and a filter function. 37 | func NewLoggingConnFilter(conn Conn, logger *log.Logger, prefix string, skip func(cmdName string) bool) Conn { 38 | if prefix != "" { 39 | prefix = prefix + "." 40 | } 41 | return &loggingConn{conn, logger, prefix, skip} 42 | } 43 | 44 | type loggingConn struct { 45 | Conn 46 | logger *log.Logger 47 | prefix string 48 | skip func(cmdName string) bool 49 | } 50 | 51 | func (c *loggingConn) Close() error { 52 | err := c.Conn.Close() 53 | var buf bytes.Buffer 54 | fmt.Fprintf(&buf, "%sClose() -> (%v)", c.prefix, err) 55 | c.logger.Output(2, buf.String()) 56 | return err 57 | } 58 | 59 | func (c *loggingConn) printValue(buf *bytes.Buffer, v interface{}) { 60 | const chop = 32 61 | switch v := v.(type) { 62 | case []byte: 63 | if len(v) > chop { 64 | fmt.Fprintf(buf, "%q...", v[:chop]) 65 | } else { 66 | fmt.Fprintf(buf, "%q", v) 67 | } 68 | case string: 69 | if len(v) > chop { 70 | fmt.Fprintf(buf, "%q...", v[:chop]) 71 | } else { 72 | fmt.Fprintf(buf, "%q", v) 73 | } 74 | case []interface{}: 75 | if len(v) == 0 { 76 | buf.WriteString("[]") 77 | } else { 78 | sep := "[" 79 | fin := "]" 80 | if len(v) > chop { 81 | v = v[:chop] 82 | fin = "...]" 83 | } 84 | for _, vv := range v { 85 | buf.WriteString(sep) 86 | c.printValue(buf, vv) 87 | sep = ", " 88 | } 89 | buf.WriteString(fin) 90 | } 91 | default: 92 | fmt.Fprint(buf, v) 93 | } 94 | } 95 | 96 | func (c *loggingConn) print(method, commandName string, args []interface{}, reply interface{}, err error) { 97 | if c.skip != nil && c.skip(commandName) { 98 | return 99 | } 100 | var buf bytes.Buffer 101 | fmt.Fprintf(&buf, "%s%s(", c.prefix, method) 102 | if method != "Receive" { 103 | buf.WriteString(commandName) 104 | for _, arg := range args { 105 | buf.WriteString(", ") 106 | c.printValue(&buf, arg) 107 | } 108 | } 109 | buf.WriteString(") -> (") 110 | if method != "Send" { 111 | c.printValue(&buf, reply) 112 | buf.WriteString(", ") 113 | } 114 | fmt.Fprintf(&buf, "%v)", err) 115 | c.logger.Output(3, buf.String()) 116 | } 117 | 118 | func (c *loggingConn) Do(commandName string, args ...interface{}) (interface{}, error) { 119 | reply, err := c.Conn.Do(commandName, args...) 120 | c.print("Do", commandName, args, reply, err) 121 | return reply, err 122 | } 123 | 124 | func (c *loggingConn) DoWithTimeout(timeout time.Duration, commandName string, args ...interface{}) (interface{}, error) { 125 | reply, err := DoWithTimeout(c.Conn, timeout, commandName, args...) 126 | c.print("DoWithTimeout", commandName, args, reply, err) 127 | return reply, err 128 | } 129 | 130 | func (c *loggingConn) Send(commandName string, args ...interface{}) error { 131 | err := c.Conn.Send(commandName, args...) 132 | c.print("Send", commandName, args, nil, err) 133 | return err 134 | } 135 | 136 | func (c *loggingConn) Receive() (interface{}, error) { 137 | reply, err := c.Conn.Receive() 138 | c.print("Receive", "", nil, reply, err) 139 | return reply, err 140 | } 141 | 142 | func (c *loggingConn) ReceiveWithTimeout(timeout time.Duration) (interface{}, error) { 143 | reply, err := ReceiveWithTimeout(c.Conn, timeout) 144 | c.print("ReceiveWithTimeout", "", nil, reply, err) 145 | return reply, err 146 | } 147 | -------------------------------------------------------------------------------- /goav/avcodec/packet.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a MIT license that can be found in the LICENSE file. 2 | // Giorgis (habtom@giorgis.io) 3 | 4 | package avcodec 5 | 6 | //#cgo pkg-config: libavcodec 7 | //#include 8 | import "C" 9 | import ( 10 | "unsafe" 11 | ) 12 | 13 | const ( 14 | AV_PKT_FLAG_KEY = int(C.AV_PKT_FLAG_KEY) 15 | AV_PKT_FLAG_CORRUPT = int(C.AV_PKT_FLAG_CORRUPT) 16 | AV_PKT_FLAG_DISCARD = int(C.AV_PKT_FLAG_DISCARD) 17 | ) 18 | 19 | //Initialize optional fields of a packet with default values. 20 | func (p *Packet) AvInitPacket() { 21 | C.av_init_packet((*C.struct_AVPacket)(p)) 22 | p.size = 0 23 | p.data = nil 24 | } 25 | 26 | func (p *Packet) GetPacketSize() int { 27 | return int(p.size) 28 | } 29 | 30 | //Allocate the payload of a packet and initialize its fields with default values. 31 | func (p *Packet) AvNewPacket(s int) int { 32 | return int(C.av_new_packet((*C.struct_AVPacket)(p), C.int(s))) 33 | } 34 | 35 | //Reduce packet size, correctly zeroing padding. 36 | func (p *Packet) AvShrinkPacket(s int) { 37 | C.av_shrink_packet((*C.struct_AVPacket)(p), C.int(s)) 38 | } 39 | 40 | //Increase packet size, correctly zeroing padding. 41 | func (p *Packet) AvGrowPacket(s int) int { 42 | return int(C.av_grow_packet((*C.struct_AVPacket)(p), C.int(s))) 43 | } 44 | 45 | //Initialize a reference-counted packet from av_malloc()ed data. 46 | func (p *Packet) AvPacketFromData(d *uint8, s int) int { 47 | return int(C.av_packet_from_data((*C.struct_AVPacket)(p), (*C.uint8_t)(d), C.int(s))) 48 | 49 | } 50 | 51 | func (p *Packet) AvDupPacket() int { 52 | return int(C.av_dup_packet((*C.struct_AVPacket)(p))) 53 | 54 | } 55 | 56 | //Copy packet, including contents. 57 | func (p *Packet) AvCopyPacket(r *Packet) int { 58 | return int(C.av_copy_packet((*C.struct_AVPacket)(p), (*C.struct_AVPacket)(r))) 59 | 60 | } 61 | 62 | //Copy packet side data. 63 | func (p *Packet) AvCopyPacketSideData(r *Packet) int { 64 | return int(C.av_copy_packet_side_data((*C.struct_AVPacket)(p), (*C.struct_AVPacket)(r))) 65 | 66 | } 67 | 68 | //Free a packet. 69 | func (p *Packet) AvFreePacket() { 70 | C.av_free_packet((*C.struct_AVPacket)(p)) 71 | 72 | } 73 | 74 | //Allocate new information of a packet. 75 | func (p *Packet) AvPacketNewSideData(t AvPacketSideDataType, s int) *uint8 { 76 | return (*uint8)(C.av_packet_new_side_data((*C.struct_AVPacket)(p), (C.enum_AVPacketSideDataType)(t), C.int(s))) 77 | } 78 | 79 | //Shrink the already allocated side data buffer. 80 | func (p *Packet) AvPacketShrinkSideData(t AvPacketSideDataType, s int) int { 81 | return int(C.av_packet_shrink_side_data((*C.struct_AVPacket)(p), (C.enum_AVPacketSideDataType)(t), C.int(s))) 82 | } 83 | 84 | //Get side information from packet. 85 | func (p *Packet) AvPacketGetSideData(t AvPacketSideDataType, s *int) *uint8 { 86 | return (*uint8)(C.av_packet_get_side_data((*C.struct_AVPacket)(p), (C.enum_AVPacketSideDataType)(t), (*C.int)(unsafe.Pointer(s)))) 87 | } 88 | 89 | //int av_packet_merge_side_data (Packet *pkt) 90 | func (p *Packet) AvPacketMergeSideData() int { 91 | return int(C.av_packet_merge_side_data((*C.struct_AVPacket)(p))) 92 | } 93 | 94 | //int av_packet_split_side_data (Packet *pkt) 95 | func (p *Packet) AvPacketSplitSideData() int { 96 | return int(C.av_packet_split_side_data((*C.struct_AVPacket)(p))) 97 | } 98 | 99 | //Convenience function to free all the side data stored. 100 | func (p *Packet) AvPacketFreeSideData() { 101 | C.av_packet_free_side_data((*C.struct_AVPacket)(p)) 102 | } 103 | 104 | //Setup a new reference to the data described by a given packet. 105 | func (p *Packet) AvPacketRef(s *Packet) int { 106 | return int(C.av_packet_ref((*C.struct_AVPacket)(p), (*C.struct_AVPacket)(s))) 107 | } 108 | 109 | //Wipe the packet. 110 | func (p *Packet) AvPacketUnref() { 111 | C.av_packet_unref((*C.struct_AVPacket)(p)) 112 | } 113 | 114 | //Move every field in src to dst and reset src. 115 | func (p *Packet) AvPacketMoveRef(s *Packet) { 116 | C.av_packet_move_ref((*C.struct_AVPacket)(p), (*C.struct_AVPacket)(s)) 117 | } 118 | 119 | //Copy only "properties" fields from src to dst. 120 | func (p *Packet) AvPacketCopyProps(s *Packet) int { 121 | return int(C.av_packet_copy_props((*C.struct_AVPacket)(p), (*C.struct_AVPacket)(s))) 122 | } 123 | 124 | //Convert valid timing fields (timestamps / durations) in a packet from one timebase to another. 125 | func (p *Packet) AvPacketRescaleTs(r, r2 Rational) { 126 | C.av_packet_rescale_ts((*C.struct_AVPacket)(p), (C.struct_AVRational)(r), (C.struct_AVRational)(r2)) 127 | } -------------------------------------------------------------------------------- /unit_test/rtp.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | "net" 6 | "time" 7 | "encoding/hex" 8 | "../rtp" 9 | "../h264" 10 | log "github.com/astaxie/beego/logs" 11 | ) 12 | 13 | //connMap := make(map[string]net.UDPConn) 14 | 15 | func testRtpParser() { 16 | 17 | log.Info("==========system init==========") 18 | 19 | vedioAddr, err := net.ResolveUDPAddr("udp", "0.0.0.0:8000") 20 | if err != nil{ 21 | log.Critical("net ResolveUDPAddr Error.") 22 | } 23 | 24 | log.Debug("local audio addresses : ", vedioAddr.IP, ":", vedioAddr.Port) 25 | 26 | vedioConn, err := net.ListenUDP("udp", vedioAddr) 27 | if err != nil { 28 | log.Critical("net ListenUDP.") 29 | } 30 | 31 | defer vedioConn.Close() 32 | 33 | log.Debug("rtp serve started.") 34 | 35 | conn := vedioConn 36 | 37 | rtpParser := rtp.NewParser(8124) 38 | 39 | for { 40 | log.Debug("on message") 41 | 42 | n, remoteAddr, err := conn.ReadFromUDP(rtpParser.Buffer()) 43 | if err != nil { 44 | log.Error("failed to read UDP msg because of ", err.Error()) 45 | return 46 | } 47 | rtpParser.SetPacketLength(n); 48 | 49 | log.Debug("recv ", n, " message from ", remoteAddr)//, ": ", hex.EncodeToString(rtpParser.Buffer())) 50 | rtpParser.Print("rtp vedio"); 51 | 52 | log.Debug("Payload() : ", hex.EncodeToString(rtpParser.Payload())) 53 | 54 | } 55 | time.Sleep(100*time.Millisecond) 56 | } 57 | 58 | func testRtpPacket(){ 59 | 60 | rp := rtp.NewDefaultPacketWithH264Type() 61 | 62 | seq := 0xffff 63 | 64 | rp.SetSequence(uint16(seq)) 65 | rp.SetTimeStamp(0x11112222) 66 | 67 | rp.SetPayload([]byte{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}) 68 | 69 | log.Debug(hex.EncodeToString(rp.GetRtpBytes())) 70 | 71 | } 72 | 73 | func testRtpSendH264() { 74 | 75 | conn, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.ParseIP("0.0.0.0"), Port: 8001}) 76 | if err != nil { 77 | log.Critical("net ListenUDP.") 78 | return 79 | } 80 | 81 | defer conn.Close() 82 | 83 | file, err := os.Open("../des4.h264") 84 | if err != nil { 85 | panic("error open file :") 86 | } 87 | s, err := file.Stat() 88 | if err != nil { 89 | panic("error Stat file.") 90 | } 91 | l := s.Size() 92 | 93 | cache := make([]byte, l) 94 | 95 | n, err := file.Read(cache) 96 | if err != nil { 97 | panic("read file error.") 98 | } 99 | 100 | /*he, err := os.Create("./tmp.hex") 101 | if err != nil { 102 | panic("create file error.") 103 | } 104 | 105 | he.WriteString(hex.EncodeToString(cache))*/ 106 | 107 | log.Debug("read n :", n) 108 | rtpPacket := rtp.NewDefaultPacketWithH264Type() 109 | rtpPacket.SetTimeStamp(0) 110 | 111 | parser := h264.NewParser() 112 | 113 | var startPos []int 114 | var nalus [][]byte 115 | j := 0 // split nalu in cache to nalus 116 | 117 | for i := 0; i < n - 5; i++ { 118 | if cache[i] == 0 && cache[i+1] == 0 && cache[i+2] == 1 { 119 | if i > 0 && cache[i-1] == 0 {//parameter set startpos 120 | startPos = append(startPos, i-1) 121 | } else { 122 | startPos = append(startPos, i) 123 | } 124 | j++ 125 | if j > 1 { 126 | b := cache[startPos[j-2]:startPos[j-1]] 127 | nalus = append(nalus, b) 128 | } 129 | } 130 | } 131 | nalus = append(nalus, cache[startPos[j-1]:]) 132 | if len(nalus) != len(startPos) { 133 | panic("unknown error at split nalu in cache to nalus ") 134 | } 135 | //log.Trace("nalus : \n", nalus) 136 | 137 | for _, v := range nalus { 138 | rps := rtpPacket.ParserNaluToRtpPayload(v) 139 | 140 | rtpPacket.SetTimeStamp(rtpPacket.TimeStamp() + 3000) 141 | 142 | for _, q := range rps { 143 | 144 | { 145 | if parser.ParserToInternalSlice(q) == true { 146 | log.Debug(hex.EncodeToString(parser.GetInternalBuffer())) 147 | parser.ClearInternalBuffer() 148 | } 149 | } 150 | 151 | 152 | rtpPacket.SetPayload(q) 153 | rtpPacket.SetSequence(rtpPacket.Sequence() + 1) 154 | 155 | r :=rtp.NewParser(1500) 156 | copy(r.Buffer(), rtpPacket.GetRtpBytes()) 157 | r.SetPacketLength(len(rtpPacket.GetRtpBytes())) 158 | r.Print("tag") 159 | //log.Trace("rps : ",p," : \n", hex.EncodeToString(rtpPacket.GetRtpBytes())) 160 | conn.WriteToUDP(rtpPacket.GetRtpBytes(), &net.UDPAddr{IP: net.ParseIP("192.168.0.78"), Port: 1236}) 161 | } 162 | // time.Sleep(5*time.Millisecond) 163 | } 164 | } 165 | 166 | func main(){ 167 | //testRtpPacket() 168 | testRtpSendH264() 169 | } 170 | -------------------------------------------------------------------------------- /redigo/redis/pubsub.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Gary Burd 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 | // not use this file except in compliance with the License. You may obtain 5 | // a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | // License for the specific language governing permissions and limitations 13 | // under the License. 14 | 15 | package redis 16 | 17 | import ( 18 | "errors" 19 | "time" 20 | ) 21 | 22 | // Subscription represents a subscribe or unsubscribe notification. 23 | type Subscription struct { 24 | // Kind is "subscribe", "unsubscribe", "psubscribe" or "punsubscribe" 25 | Kind string 26 | 27 | // The channel that was changed. 28 | Channel string 29 | 30 | // The current number of subscriptions for connection. 31 | Count int 32 | } 33 | 34 | // Message represents a message notification. 35 | type Message struct { 36 | // The originating channel. 37 | Channel string 38 | 39 | // The matched pattern, if any 40 | Pattern string 41 | 42 | // The message data. 43 | Data []byte 44 | } 45 | 46 | // Pong represents a pubsub pong notification. 47 | type Pong struct { 48 | Data string 49 | } 50 | 51 | // PubSubConn wraps a Conn with convenience methods for subscribers. 52 | type PubSubConn struct { 53 | Conn Conn 54 | } 55 | 56 | // Close closes the connection. 57 | func (c PubSubConn) Close() error { 58 | return c.Conn.Close() 59 | } 60 | 61 | // Subscribe subscribes the connection to the specified channels. 62 | func (c PubSubConn) Subscribe(channel ...interface{}) error { 63 | c.Conn.Send("SUBSCRIBE", channel...) 64 | return c.Conn.Flush() 65 | } 66 | 67 | // PSubscribe subscribes the connection to the given patterns. 68 | func (c PubSubConn) PSubscribe(channel ...interface{}) error { 69 | c.Conn.Send("PSUBSCRIBE", channel...) 70 | return c.Conn.Flush() 71 | } 72 | 73 | // Unsubscribe unsubscribes the connection from the given channels, or from all 74 | // of them if none is given. 75 | func (c PubSubConn) Unsubscribe(channel ...interface{}) error { 76 | c.Conn.Send("UNSUBSCRIBE", channel...) 77 | return c.Conn.Flush() 78 | } 79 | 80 | // PUnsubscribe unsubscribes the connection from the given patterns, or from all 81 | // of them if none is given. 82 | func (c PubSubConn) PUnsubscribe(channel ...interface{}) error { 83 | c.Conn.Send("PUNSUBSCRIBE", channel...) 84 | return c.Conn.Flush() 85 | } 86 | 87 | // Ping sends a PING to the server with the specified data. 88 | // 89 | // The connection must be subscribed to at least one channel or pattern when 90 | // calling this method. 91 | func (c PubSubConn) Ping(data string) error { 92 | c.Conn.Send("PING", data) 93 | return c.Conn.Flush() 94 | } 95 | 96 | // Receive returns a pushed message as a Subscription, Message, Pong or error. 97 | // The return value is intended to be used directly in a type switch as 98 | // illustrated in the PubSubConn example. 99 | func (c PubSubConn) Receive() interface{} { 100 | return c.receiveInternal(c.Conn.Receive()) 101 | } 102 | 103 | // ReceiveWithTimeout is like Receive, but it allows the application to 104 | // override the connection's default timeout. 105 | func (c PubSubConn) ReceiveWithTimeout(timeout time.Duration) interface{} { 106 | return c.receiveInternal(ReceiveWithTimeout(c.Conn, timeout)) 107 | } 108 | 109 | func (c PubSubConn) receiveInternal(replyArg interface{}, errArg error) interface{} { 110 | reply, err := Values(replyArg, errArg) 111 | if err != nil { 112 | return err 113 | } 114 | 115 | var kind string 116 | reply, err = Scan(reply, &kind) 117 | if err != nil { 118 | return err 119 | } 120 | 121 | switch kind { 122 | case "message": 123 | var m Message 124 | if _, err := Scan(reply, &m.Channel, &m.Data); err != nil { 125 | return err 126 | } 127 | return m 128 | case "pmessage": 129 | var m Message 130 | if _, err := Scan(reply, &m.Pattern, &m.Channel, &m.Data); err != nil { 131 | return err 132 | } 133 | return m 134 | case "subscribe", "psubscribe", "unsubscribe", "punsubscribe": 135 | s := Subscription{Kind: kind} 136 | if _, err := Scan(reply, &s.Channel, &s.Count); err != nil { 137 | return err 138 | } 139 | return s 140 | case "pong": 141 | var p Pong 142 | if _, err := Scan(reply, &p.Data); err != nil { 143 | return err 144 | } 145 | return p 146 | } 147 | return errors.New("redigo: unknown pubsub notification") 148 | } 149 | -------------------------------------------------------------------------------- /unit_test/decoder.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | log "github.com/astaxie/beego/logs" 5 | 6 | "github.com/giorgisio/goav/avcodec" 7 | //"github.com/giorgisio/goav/avdevice" 8 | "github.com/giorgisio/goav/avfilter" 9 | //"github.com/giorgisio/goav/avformat" 10 | "github.com/giorgisio/goav/avutil" 11 | //"github.com/giorgisio/goav/swresample" 12 | //"github.com/giorgisio/goav/swscale" 13 | "unsafe" 14 | "io/ioutil" 15 | "time" 16 | //"fmt" 17 | ) 18 | 19 | 20 | type Decoder struct { 21 | codec *avcodec.Codec 22 | context *avcodec.Context 23 | parserContext *avcodec.ParserContext 24 | pkt *avcodec.Packet 25 | frame *avutil.Frame 26 | } 27 | 28 | func AllocAll(codecId avcodec.CodecId) *Decoder{ 29 | pkt := avcodec.AvPacketAlloc() 30 | if pkt == nil { 31 | log.Critical("AvPacketAlloc failed.") 32 | } 33 | 34 | codec := avcodec.AvcodecFindDecoder(codecId) 35 | if codec == nil { 36 | log.Critical("AvcodecFindDecoder failed.") 37 | } 38 | 39 | context := codec.AvcodecAllocContext3() 40 | if context == nil { 41 | log.Critical("AvcodecAllocContext3 failed.") 42 | } 43 | 44 | parserContext := avcodec.AvParserInit(int(codecId)) 45 | if parserContext == nil { 46 | log.Critical("AvParserInit failed.") 47 | } 48 | 49 | frame := avutil.AvFrameAlloc() 50 | if frame == nil { 51 | log.Critical("AvFrameAlloc failed.") 52 | } 53 | 54 | err := context.AvcodecOpen2(codec, nil) 55 | if err < 0 { 56 | log.Critical("AvcodecOpen2 failed.") 57 | } 58 | 59 | return &Decoder{ 60 | codec, 61 | context, 62 | parserContext, 63 | pkt, 64 | frame, 65 | } 66 | } 67 | 68 | func (d *Decoder) parserPacket(buf []byte, size int) int { 69 | return d.context.AvParserParse2(d.parserContext, d.pkt, buf, 70 | size, avcodec.AV_NOPTS_VALUE, avcodec.AV_NOPTS_VALUE, 0) 71 | } 72 | 73 | // 0 success 74 | func (d *Decoder) generateFrame() int { 75 | ret := d.context.AvcodecSendPacket(d.pkt) 76 | if ret < 0 { 77 | log.Error("AvcodecSendPacket err ", avutil.ErrorFromCode(ret)) 78 | return ret 79 | } 80 | 81 | ret = d.context.AvcodecReceiveFrame((*avcodec.Frame)(unsafe.Pointer(d.frame))) 82 | if ret < 0 { 83 | log.Error("AvcodecReceiveFrame err ", avutil.ErrorFromCode(ret)) 84 | return ret 85 | } 86 | 87 | return ret 88 | } 89 | 90 | func (d *Decoder) FreeAll() { 91 | avutil.AvFrameFree(d.frame) 92 | d.pkt.AvFreePacket() 93 | avcodec.AvParserClose(d.parserContext) 94 | d.context.AvcodecClose() 95 | //d.context.AvcodecFreeContext() 96 | } 97 | 98 | func main() { 99 | log.Info("--------decoder init---------") 100 | log.Debug("AvFilter Version:\t%v", avfilter.AvfilterVersion()) 101 | log.Debug("AvCodec Version:\t%v", avcodec.AvcodecVersion()) 102 | // Register all formats and codecs 103 | //avformat.AvRegisterAll() 104 | //avcodec.AvcodecRegisterAll() 105 | 106 | data, err := ioutil.ReadFile("record.h264") 107 | if err != nil { 108 | log.Debug("File reading error", err) 109 | return 110 | } 111 | log.Debug("Open Success.") 112 | l := len(data) 113 | log.Debug("size of file:", l) 114 | 115 | decoder := AllocAll(avcodec.CodecId(avcodec.AV_CODEC_ID_H264)) 116 | 117 | b := make([]byte, 4096 + 64) 118 | 119 | sum := 0 120 | for sum < l { 121 | remain := 4096 122 | for remain > 0 { 123 | copy(b, data[sum:sum + 4096]) 124 | n := decoder.parserPacket(b, remain) 125 | log.Debug("parser ", n, "bytes") 126 | 127 | sum = sum + n 128 | remain = remain - n; 129 | 130 | log.Trace("--------", decoder.pkt.GetPacketSize()) 131 | if decoder.pkt.GetPacketSize() > 0 { 132 | log.Debug(*decoder.pkt) 133 | 134 | if decoder.generateFrame() == 0 { 135 | data0 := avutil.Data(decoder.frame)[0] 136 | buf := make([]byte, decoder.pkt.GetPacketSize()) 137 | startPos := uintptr(unsafe.Pointer(data0)) 138 | for i := 0; i < decoder.pkt.GetPacketSize(); i++ { 139 | element := *(*uint8)(unsafe.Pointer(startPos + uintptr(i))) 140 | buf[i] = element 141 | } 142 | } 143 | 144 | avutil.AvFrameUnref((*avutil.Frame)(unsafe.Pointer(decoder.frame))) 145 | time.Sleep(1*time.Second) 146 | decoder.FreeAll() 147 | return 148 | } 149 | } 150 | } 151 | 152 | for { 153 | time.Sleep(1*time.Second) 154 | } 155 | 156 | } 157 | 158 | 159 | 160 | /* 161 | func (p *Packet) GetPacketData() **uint8 { 162 | return (**uint8)(unsafe.Pointer(&p.data)) 163 | } 164 | 165 | func (p *Packet) GetPacketSize() *int { 166 | return (*int)(unsafe.Pointer(&p.size)) 167 | } 168 | */ -------------------------------------------------------------------------------- /redigo/redis/redis.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Gary Burd 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 | // not use this file except in compliance with the License. You may obtain 5 | // a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | // License for the specific language governing permissions and limitations 13 | // under the License. 14 | 15 | package redis 16 | 17 | import ( 18 | "errors" 19 | "time" 20 | ) 21 | 22 | // Error represents an error returned in a command reply. 23 | type Error string 24 | 25 | func (err Error) Error() string { return string(err) } 26 | 27 | // Conn represents a connection to a Redis server. 28 | type Conn interface { 29 | // Close closes the connection. 30 | Close() error 31 | 32 | // Err returns a non-nil value when the connection is not usable. 33 | Err() error 34 | 35 | // Do sends a command to the server and returns the received reply. 36 | Do(commandName string, args ...interface{}) (reply interface{}, err error) 37 | 38 | // Send writes the command to the client's output buffer. 39 | Send(commandName string, args ...interface{}) error 40 | 41 | // Flush flushes the output buffer to the Redis server. 42 | Flush() error 43 | 44 | // Receive receives a single reply from the Redis server 45 | Receive() (reply interface{}, err error) 46 | } 47 | 48 | // Argument is the interface implemented by an object which wants to control how 49 | // the object is converted to Redis bulk strings. 50 | type Argument interface { 51 | // RedisArg returns a value to be encoded as a bulk string per the 52 | // conversions listed in the section 'Executing Commands'. 53 | // Implementations should typically return a []byte or string. 54 | RedisArg() interface{} 55 | } 56 | 57 | // Scanner is implemented by an object which wants to control its value is 58 | // interpreted when read from Redis. 59 | type Scanner interface { 60 | // RedisScan assigns a value from a Redis value. The argument src is one of 61 | // the reply types listed in the section `Executing Commands`. 62 | // 63 | // An error should be returned if the value cannot be stored without 64 | // loss of information. 65 | RedisScan(src interface{}) error 66 | } 67 | 68 | // ConnWithTimeout is an optional interface that allows the caller to override 69 | // a connection's default read timeout. This interface is useful for executing 70 | // the BLPOP, BRPOP, BRPOPLPUSH, XREAD and other commands that block at the 71 | // server. 72 | // 73 | // A connection's default read timeout is set with the DialReadTimeout dial 74 | // option. Applications should rely on the default timeout for commands that do 75 | // not block at the server. 76 | // 77 | // All of the Conn implementations in this package satisfy the ConnWithTimeout 78 | // interface. 79 | // 80 | // Use the DoWithTimeout and ReceiveWithTimeout helper functions to simplify 81 | // use of this interface. 82 | type ConnWithTimeout interface { 83 | Conn 84 | 85 | // Do sends a command to the server and returns the received reply. 86 | // The timeout overrides the read timeout set when dialing the 87 | // connection. 88 | DoWithTimeout(timeout time.Duration, commandName string, args ...interface{}) (reply interface{}, err error) 89 | 90 | // Receive receives a single reply from the Redis server. The timeout 91 | // overrides the read timeout set when dialing the connection. 92 | ReceiveWithTimeout(timeout time.Duration) (reply interface{}, err error) 93 | } 94 | 95 | var errTimeoutNotSupported = errors.New("redis: connection does not support ConnWithTimeout") 96 | 97 | // DoWithTimeout executes a Redis command with the specified read timeout. If 98 | // the connection does not satisfy the ConnWithTimeout interface, then an error 99 | // is returned. 100 | func DoWithTimeout(c Conn, timeout time.Duration, cmd string, args ...interface{}) (interface{}, error) { 101 | cwt, ok := c.(ConnWithTimeout) 102 | if !ok { 103 | return nil, errTimeoutNotSupported 104 | } 105 | return cwt.DoWithTimeout(timeout, cmd, args...) 106 | } 107 | 108 | // ReceiveWithTimeout receives a reply with the specified read timeout. If the 109 | // connection does not satisfy the ConnWithTimeout interface, then an error is 110 | // returned. 111 | func ReceiveWithTimeout(c Conn, timeout time.Duration) (interface{}, error) { 112 | cwt, ok := c.(ConnWithTimeout) 113 | if !ok { 114 | return nil, errTimeoutNotSupported 115 | } 116 | return cwt.ReceiveWithTimeout(timeout) 117 | } 118 | -------------------------------------------------------------------------------- /goav/avutil/memory.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a MIT license that can be found in the LICENSE file. 2 | // Giorgis (habtom@giorgis.io) 3 | 4 | package avutil 5 | 6 | /* 7 | #cgo pkg-config: libavutil 8 | #include 9 | #include 10 | #include 11 | */ 12 | import "C" 13 | import ( 14 | "unsafe" 15 | ) 16 | 17 | //Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if available on the CPU). 18 | func AvMalloc(s uintptr) unsafe.Pointer { 19 | return unsafe.Pointer(C.av_malloc(C.size_t(s))) 20 | } 21 | 22 | func AvMallocArray(n, s uintptr) unsafe.Pointer { 23 | return C.av_malloc_array(C.size_t(n), C.size_t(s)) 24 | } 25 | 26 | //Allocate or reallocate a block of memory. 27 | func AvRealloc(p *int, s uintptr) unsafe.Pointer { 28 | return C.av_realloc(unsafe.Pointer(&p), C.size_t(s)) 29 | } 30 | 31 | //Allocate or reallocate a block of memory. 32 | func AvReallocF(p int, n, e uintptr) unsafe.Pointer { 33 | return C.av_realloc_f(unsafe.Pointer(&p), C.size_t(n), C.size_t(e)) 34 | } 35 | 36 | //Allocate or reallocate a block of memory. 37 | func AvReallocp(p int, s uintptr) int { 38 | return int(C.av_reallocp(unsafe.Pointer(&p), C.size_t(s))) 39 | } 40 | 41 | func AvReallocArray(p int, n, s uintptr) unsafe.Pointer { 42 | return C.av_realloc_array(unsafe.Pointer(&p), C.size_t(n), C.size_t(s)) 43 | } 44 | 45 | func AvReallocpArray(p int, n, s uintptr) int { 46 | return int(C.av_reallocp_array(unsafe.Pointer(&p), C.size_t(n), C.size_t(s))) 47 | } 48 | 49 | //Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). 50 | func AvFree(p unsafe.Pointer) { 51 | C.av_free(p) 52 | } 53 | 54 | //Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if available on the CPU) and zero all the bytes of the block. 55 | func AvMallocz(s uintptr) unsafe.Pointer { 56 | return C.av_mallocz(C.size_t(s)) 57 | } 58 | 59 | //Allocate a block of nmemb * size bytes with alignment suitable for all memory accesses (including vectors if available on the CPU) and zero all the bytes of the block. 60 | func AvCalloc(n, s uintptr) unsafe.Pointer { 61 | return C.av_calloc(C.size_t(n), C.size_t(s)) 62 | } 63 | 64 | func AvMalloczArray(n, s uintptr) unsafe.Pointer { 65 | return C.av_mallocz_array(C.size_t(n), C.size_t(s)) 66 | } 67 | 68 | //Duplicate the string s. 69 | func AvStrdup(s string) string { 70 | return C.GoString(C.av_strdup(C.CString(s))) 71 | } 72 | 73 | //char * av_strndup (const char *s, size_t len) av_malloc_attrib 74 | //Duplicate a substring of the string s. 75 | func AvStrndup(s string, l uintptr) string { 76 | return C.GoString(C.av_strndup(C.CString(s), C.size_t(l))) 77 | } 78 | 79 | //Duplicate the buffer p. 80 | func AvMemdup(p *int, s uintptr) unsafe.Pointer { 81 | return C.av_memdup(unsafe.Pointer(p), C.size_t(s)) 82 | } 83 | 84 | //Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer pointing to it to NULL. 85 | func AvFreep(p unsafe.Pointer) { 86 | C.av_freep(p) 87 | } 88 | 89 | //Add an element to a dynamic array. 90 | func AvDynarrayAdd(t unsafe.Pointer, n *int, e unsafe.Pointer) { 91 | C.av_dynarray_add(t, (*C.int)(unsafe.Pointer(n)), e) 92 | } 93 | 94 | //Add an element to a dynamic array. 95 | func AvDynarrayAddNofree(p unsafe.Pointer, n *int, e unsafe.Pointer) int { 96 | return int(C.av_dynarray_add_nofree(p, (*C.int)(unsafe.Pointer(&n)), e)) 97 | } 98 | 99 | //Add an element of size elem_size to a dynamic array. 100 | func AvDynarray2Add(t *unsafe.Pointer, n *int, e uintptr, d uint8) unsafe.Pointer { 101 | return C.av_dynarray2_add(t, (*C.int)(unsafe.Pointer(&n)), (C.size_t)(e), (*C.uint8_t)(unsafe.Pointer(&d))) 102 | } 103 | 104 | //Multiply two size_t values checking for overflow. 105 | func AvSizeMult(a, b uintptr, r *uintptr) int { 106 | return int(C.av_size_mult((C.size_t)(a), (C.size_t)(b), (*C.size_t)(unsafe.Pointer(r)))) 107 | } 108 | 109 | //Set the maximum size that may me allocated in one block. 110 | func AvMaxAlloc(m uintptr) { 111 | C.av_max_alloc(C.size_t(m)) 112 | } 113 | 114 | //deliberately overlapping memcpy implementation 115 | func AvMemcpyBackptr(d *uintptr, b, c int) { 116 | C.av_memcpy_backptr((*C.uint8_t)(unsafe.Pointer(d)), C.int(b), C.int(c)) 117 | } 118 | 119 | //Reallocate the given block if it is not large enough, otherwise do nothing. 120 | func AvFastRealloc(p unsafe.Pointer, s *uint, m uintptr) unsafe.Pointer { 121 | return C.av_fast_realloc(p, (*C.uint)(unsafe.Pointer(s)), (C.size_t)(m)) 122 | } 123 | 124 | //Allocate a buffer, reusing the given one if large enough. 125 | func AvFastMalloc(p unsafe.Pointer, s *uint, m uintptr) { 126 | C.av_fast_malloc(p, (*C.uint)(unsafe.Pointer(s)), (C.size_t)(m)) 127 | } 128 | -------------------------------------------------------------------------------- /unit_test/encoder.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | log "github.com/astaxie/beego/logs" 5 | 6 | "github.com/giorgisio/goav/avcodec" 7 | //"github.com/giorgisio/goav/avdevice" 8 | //"github.com/giorgisio/goav/avfilter" 9 | //"github.com/giorgisio/goav/avformat" 10 | "github.com/giorgisio/goav/avutil" 11 | //"github.com/giorgisio/goav/swresample" 12 | //"github.com/giorgisio/goav/swscale" 13 | "unsafe" 14 | "io/ioutil" 15 | "time" 16 | "./decoder" 17 | "os" 18 | //"fmt" 19 | ) 20 | 21 | 22 | type Encoder struct { 23 | codec *avcodec.Codec 24 | context *avcodec.Context 25 | pkt *avcodec.Packet 26 | } 27 | 28 | func AllocAll(codecId avcodec.CodecId) *Encoder{ 29 | pkt := avcodec.AvPacketAlloc() 30 | if pkt == nil { 31 | log.Critical("AvPacketAlloc failed.") 32 | } 33 | 34 | codec := avcodec.AvcodecFindEncoder(codecId) 35 | if codec == nil { 36 | log.Critical("AvcodecFindDecoder failed.") 37 | } 38 | 39 | context := codec.AvcodecAllocContext3() 40 | if context == nil { 41 | log.Critical("AvcodecAllocContext3 failed.") 42 | } 43 | 44 | return &Encoder{ 45 | codec, 46 | context, 47 | pkt, 48 | } 49 | } 50 | 51 | func (d *Encoder) Packet() *avcodec.Packet { 52 | return d.pkt 53 | } 54 | 55 | func (e *Encoder) SetEncodeParams(width int, height int, pxlFmt avcodec.PixelFormat, hasBframes bool, gopSize, num, den int) { 56 | e.context.SetEncodeParams2(width, height, pxlFmt, hasBframes, gopSize) 57 | e.context.SetTimebase(num, den) 58 | 59 | err := e.context.AvcodecOpen2(e.codec, nil) 60 | if err < 0 { 61 | log.Critical("AvcodecOpen2 failed.") 62 | } 63 | } 64 | 65 | // 0 success 66 | func (e *Encoder) GeneratePacket(frame *avutil.Frame) int { 67 | ret := e.context.AvcodecSendFrame((*avcodec.Frame)(unsafe.Pointer(frame))) 68 | if ret < 0 { 69 | log.Trace("AvcodecSendPacket err ", avutil.ErrorFromCode(ret)) 70 | return ret 71 | } 72 | 73 | ret = e.context.AvcodecReceivePacket(e.pkt) 74 | if ret < 0 { 75 | log.Trace("AvcodecReceiveFrame err ", avutil.ErrorFromCode(ret)) 76 | return ret 77 | } 78 | 79 | return ret 80 | } 81 | 82 | func (e *Encoder) ToBytes() []byte { 83 | data0 := e.Packet().Data() 84 | buf := make([]byte, e.Packet().GetPacketSize()) 85 | start := uintptr(unsafe.Pointer(data0)) 86 | for i := 0; i < e.Packet().GetPacketSize(); i++ { 87 | elem := *(*uint8)(unsafe.Pointer(start + uintptr(i))) 88 | buf[i] = elem 89 | } 90 | 91 | e.Packet().AvPacketUnref() 92 | return buf 93 | } 94 | 95 | func main() { 96 | log.Info("--------decoder init---------") 97 | //log.Debug("AvFilter Version:\t%v", avfilter.AvfilterVersion()) 98 | log.Debug("AvCodec Version:\t%v", avcodec.AvcodecVersion()) 99 | // Register all formats and codecs 100 | //avformat.AvRegisterAll() 101 | //avcodec.AvcodecRegisterAll() 102 | 103 | data, err := ioutil.ReadFile("record.h264") 104 | if err != nil { 105 | log.Debug("File reading error", err) 106 | return 107 | } 108 | log.Debug("Open Success.") 109 | l := len(data) 110 | log.Debug("size of file:", l) 111 | 112 | dec := decoder.AllocAll(avcodec.CodecId(avcodec.AV_CODEC_ID_H264)) 113 | 114 | enc := AllocAll(avcodec.CodecId(avcodec.AV_CODEC_ID_MPEG4)) 115 | enc.SetEncodeParams(1104, 622, 116 | avcodec.AV_PIX_FMT_YUV420P, 117 | true, 2, 118 | 1, 30) 119 | 120 | b := make([]byte, 4096 + 64) 121 | 122 | file, err := os.Create("./out.mp4") 123 | if err != nil { 124 | log.Critical("Error Reading") 125 | } 126 | defer file.Close() 127 | 128 | sum := 0 129 | for sum < l { 130 | remain := 4096 131 | for remain > 0 { 132 | copy(b, data[sum:sum + 4096]) 133 | n := dec.ParserPacket(b, remain) 134 | log.Debug("parser ", n, "bytes") 135 | 136 | sum = sum + n 137 | remain = remain - n; 138 | 139 | log.Trace("--------", dec.Packet().GetPacketSize()) 140 | if dec.Packet().GetPacketSize() > 0 { 141 | log.Debug(*dec.Packet()) 142 | 143 | if dec.GenerateFrame() == 0 { 144 | /*data0 := avutil.Data(dec.Frame())[0] 145 | buf := make([]byte, dec.Packet().GetPacketSize()) 146 | startPos := uintptr(unsafe.Pointer(data0)) 147 | for i := 0; i < dec.Packet().GetPacketSize(); i++ { 148 | element := *(*uint8)(unsafe.Pointer(startPos + uintptr(i))) 149 | buf[i] = element 150 | }*/ 151 | 152 | if enc.GeneratePacket(dec.Frame()) == 0 { 153 | cache := enc.ToBytes() 154 | file.Write(cache) 155 | } 156 | } 157 | 158 | avutil.AvFrameUnref(dec.Frame()) 159 | //time.Sleep(1*time.Second) 160 | } 161 | } 162 | } 163 | 164 | for { 165 | time.Sleep(1*time.Second) 166 | } 167 | 168 | } -------------------------------------------------------------------------------- /decoder/decoder.go: -------------------------------------------------------------------------------- 1 | package decoder 2 | 3 | import ( 4 | log "github.com/astaxie/beego/logs" 5 | 6 | "../goav/avcodec" 7 | "../goav/avutil" 8 | "unsafe" 9 | ) 10 | 11 | 12 | type Decoder struct { 13 | codec *avcodec.Codec 14 | context *avcodec.Context 15 | parserContext *avcodec.ParserContext 16 | pkt *avcodec.Packet 17 | frame *avutil.Frame 18 | ibpFrameCount int64 19 | } 20 | 21 | func AllocAll(codecId avcodec.CodecId) *Decoder{ 22 | pkt := avcodec.AvPacketAlloc() 23 | if pkt == nil { 24 | log.Critical("AvPacketAlloc failed.") 25 | } 26 | 27 | codec := avcodec.AvcodecFindDecoder(codecId) 28 | if codec == nil { 29 | log.Critical("AvcodecFindDecoder failed.") 30 | } 31 | 32 | context := codec.AvcodecAllocContext3() 33 | if context == nil { 34 | log.Critical("AvcodecAllocContext3 failed.") 35 | } 36 | 37 | parserContext := avcodec.AvParserInit(int(codecId)) 38 | if parserContext == nil { 39 | log.Critical("AvParserInit failed.") 40 | } 41 | 42 | frame := avutil.AvFrameAlloc() 43 | if frame == nil { 44 | log.Critical("AvFrameAlloc failed.") 45 | } 46 | 47 | err := context.AvcodecOpen2(codec, nil) 48 | if err < 0 { 49 | log.Critical("AvcodecOpen2 failed.") 50 | } 51 | 52 | return &Decoder{ 53 | codec, 54 | context, 55 | parserContext, 56 | pkt, 57 | frame, 58 | 0, 59 | } 60 | } 61 | 62 | func (d *Decoder) Packet() *avcodec.Packet { 63 | return d.pkt 64 | } 65 | 66 | func (d *Decoder) Frame() *avutil.Frame { 67 | return d.frame 68 | } 69 | 70 | func (d *Decoder) IncrIbpFrameCount() { 71 | d.ibpFrameCount++ 72 | } 73 | 74 | func (d *Decoder) IbpFrameCount() int64 { 75 | return d.ibpFrameCount 76 | } 77 | 78 | func (d *Decoder) ParserPacket(buf []byte, size int) int { 79 | return d.context.AvParserParse2(d.parserContext, d.pkt, buf, 80 | size, avcodec.AV_NOPTS_VALUE, avcodec.AV_NOPTS_VALUE, 0) 81 | } 82 | 83 | // 0 success 84 | func (d *Decoder) GenerateFrame() int { 85 | ret := d.context.AvcodecSendPacket(d.pkt) 86 | if ret < 0 { 87 | log.Error("AvcodecSendPacket err ", avutil.ErrorFromCode(ret)) 88 | return ret 89 | } 90 | 91 | ret = d.context.AvcodecReceiveFrame((*avcodec.Frame)(unsafe.Pointer(d.frame))) 92 | if ret < 0 { 93 | log.Error("AvcodecReceiveFrame err ", avutil.ErrorFromCode(ret)) 94 | return ret 95 | } 96 | 97 | return ret 98 | } 99 | 100 | func (d *Decoder) FreeAll() { 101 | avcodec.AvParserClose(d.parserContext) 102 | d.context.AvcodecFreeContext() 103 | avutil.AvFrameFree(d.frame) 104 | d.pkt.AvFreePacket() 105 | //d.context.AvcodecClose() 106 | } 107 | 108 | 109 | func (d *Decoder)Context() *avcodec.Context { 110 | return d.context 111 | } 112 | 113 | /*func main() { 114 | log.Info("--------decoder init---------") 115 | log.Debug("AvFilter Version:\t%v", avfilter.AvfilterVersion()) 116 | log.Debug("AvCodec Version:\t%v", avcodec.AvcodecVersion()) 117 | // Register all formats and codecs 118 | //avformat.AvRegisterAll() 119 | //avcodec.AvcodecRegisterAll() 120 | 121 | data, err := ioutil.ReadFile("record.h264") 122 | if err != nil { 123 | log.Debug("File reading error", err) 124 | return 125 | } 126 | log.Debug("Open Success.") 127 | l := len(data) 128 | log.Debug("size of file:", l) 129 | 130 | decoder := AllocAll(avcodec.CodecId(avcodec.AV_CODEC_ID_H264)) 131 | 132 | b := make([]byte, 4096 + 64) 133 | 134 | sum := 0 135 | for sum < l { 136 | remain := 4096 137 | for remain > 0 { 138 | copy(b, data[sum:sum + 4096]) 139 | n := decoder.parserPacket(b, remain) 140 | log.Debug("parser ", n, "bytes") 141 | 142 | sum = sum + n 143 | remain = remain - n; 144 | 145 | log.Trace("--------", decoder.pkt.GetPacketSize()) 146 | if decoder.pkt.GetPacketSize() > 0 { 147 | log.Debug(*decoder.pkt) 148 | 149 | if decoder.generateFrame() == 0 { 150 | data0 := avutil.Data(decoder.frame)[0] 151 | buf := make([]byte, decoder.pkt.GetPacketSize()) 152 | startPos := uintptr(unsafe.Pointer(data0)) 153 | for i := 0; i < decoder.pkt.GetPacketSize(); i++ { 154 | element := *(*uint8)(unsafe.Pointer(startPos + uintptr(i))) 155 | buf[i] = element 156 | } 157 | } 158 | 159 | avutil.AvFrameUnref((*avutil.Frame)(unsafe.Pointer(decoder.frame))) 160 | //time.Sleep(1*time.Second) 161 | } 162 | } 163 | } 164 | 165 | for { 166 | time.Sleep(1*time.Second) 167 | } 168 | 169 | }*/ 170 | 171 | 172 | 173 | /* 174 | func (p *Packet) GetPacketData() **uint8 { 175 | return (**uint8)(unsafe.Pointer(&p.data)) 176 | } 177 | 178 | func (p *Packet) GetPacketSize() *int { 179 | return (*int)(unsafe.Pointer(&p.size)) 180 | } 181 | */ -------------------------------------------------------------------------------- /redigo/redis/pubsub_example_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Gary Burd 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 | // not use this file except in compliance with the License. You may obtain 5 | // a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | // License for the specific language governing permissions and limitations 13 | // under the License. 14 | 15 | // +build go1.7 16 | 17 | package redis_test 18 | 19 | import ( 20 | "context" 21 | "fmt" 22 | "time" 23 | 24 | "github.com/gomodule/redigo/redis" 25 | ) 26 | 27 | // listenPubSubChannels listens for messages on Redis pubsub channels. The 28 | // onStart function is called after the channels are subscribed. The onMessage 29 | // function is called for each message. 30 | func listenPubSubChannels(ctx context.Context, redisServerAddr string, 31 | onStart func() error, 32 | onMessage func(channel string, data []byte) error, 33 | channels ...string) error { 34 | // A ping is set to the server with this period to test for the health of 35 | // the connection and server. 36 | const healthCheckPeriod = time.Minute 37 | 38 | c, err := redis.Dial("tcp", redisServerAddr, 39 | // Read timeout on server should be greater than ping period. 40 | redis.DialReadTimeout(healthCheckPeriod+10*time.Second), 41 | redis.DialWriteTimeout(10*time.Second)) 42 | if err != nil { 43 | return err 44 | } 45 | defer c.Close() 46 | 47 | psc := redis.PubSubConn{Conn: c} 48 | 49 | if err := psc.Subscribe(redis.Args{}.AddFlat(channels)...); err != nil { 50 | return err 51 | } 52 | 53 | done := make(chan error, 1) 54 | 55 | // Start a goroutine to receive notifications from the server. 56 | go func() { 57 | for { 58 | switch n := psc.Receive().(type) { 59 | case error: 60 | done <- n 61 | return 62 | case redis.Message: 63 | if err := onMessage(n.Channel, n.Data); err != nil { 64 | done <- err 65 | return 66 | } 67 | case redis.Subscription: 68 | switch n.Count { 69 | case len(channels): 70 | // Notify application when all channels are subscribed. 71 | if err := onStart(); err != nil { 72 | done <- err 73 | return 74 | } 75 | case 0: 76 | // Return from the goroutine when all channels are unsubscribed. 77 | done <- nil 78 | return 79 | } 80 | } 81 | } 82 | }() 83 | 84 | ticker := time.NewTicker(healthCheckPeriod) 85 | defer ticker.Stop() 86 | loop: 87 | for err == nil { 88 | select { 89 | case <-ticker.C: 90 | // Send ping to test health of connection and server. If 91 | // corresponding pong is not received, then receive on the 92 | // connection will timeout and the receive goroutine will exit. 93 | if err = psc.Ping(""); err != nil { 94 | break loop 95 | } 96 | case <-ctx.Done(): 97 | break loop 98 | case err := <-done: 99 | // Return error from the receive goroutine. 100 | return err 101 | } 102 | } 103 | 104 | // Signal the receiving goroutine to exit by unsubscribing from all channels. 105 | psc.Unsubscribe() 106 | 107 | // Wait for goroutine to complete. 108 | return <-done 109 | } 110 | 111 | func publish() { 112 | c, err := dial() 113 | if err != nil { 114 | fmt.Println(err) 115 | return 116 | } 117 | defer c.Close() 118 | 119 | c.Do("PUBLISH", "c1", "hello") 120 | c.Do("PUBLISH", "c2", "world") 121 | c.Do("PUBLISH", "c1", "goodbye") 122 | } 123 | 124 | // This example shows how receive pubsub notifications with cancelation and 125 | // health checks. 126 | func ExamplePubSubConn() { 127 | redisServerAddr, err := serverAddr() 128 | if err != nil { 129 | fmt.Println(err) 130 | return 131 | } 132 | 133 | ctx, cancel := context.WithCancel(context.Background()) 134 | 135 | err = listenPubSubChannels(ctx, 136 | redisServerAddr, 137 | func() error { 138 | // The start callback is a good place to backfill missed 139 | // notifications. For the purpose of this example, a goroutine is 140 | // started to send notifications. 141 | go publish() 142 | return nil 143 | }, 144 | func(channel string, message []byte) error { 145 | fmt.Printf("channel: %s, message: %s\n", channel, message) 146 | 147 | // For the purpose of this example, cancel the listener's context 148 | // after receiving last message sent by publish(). 149 | if string(message) == "goodbye" { 150 | cancel() 151 | } 152 | return nil 153 | }, 154 | "c1", "c2") 155 | 156 | if err != nil { 157 | fmt.Println(err) 158 | return 159 | } 160 | 161 | // Output: 162 | // channel: c1, message: hello 163 | // channel: c2, message: world 164 | // channel: c1, message: goodbye 165 | } 166 | -------------------------------------------------------------------------------- /goav/swscale/swscale.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a MIT license that can be found in the LICENSE file. 2 | // Giorgis (habtom@giorgis.io) 3 | 4 | //Package swscale performs highly optimized image scaling and colorspace and pixel format conversion operations. 5 | //Rescaling: is the process of changing the video size. Several rescaling options and algorithms are available. 6 | //Pixel format conversion: is the process of converting the image format and colorspace of the image. 7 | package swscale 8 | 9 | //#cgo pkg-config: libswscale libavutil 10 | //#include 11 | //#include 12 | //#include 13 | //#include 14 | //#include 15 | //#include 16 | import "C" 17 | import ( 18 | "unsafe" 19 | ) 20 | 21 | type ( 22 | Context C.struct_SwsContext 23 | Filter C.struct_SwsFilter 24 | Vector C.struct_SwsVector 25 | Class C.struct_AVClass 26 | PixelFormat C.enum_AVPixelFormat 27 | ) 28 | 29 | //Return the LIBSWSCALE_VERSION_INT constant. 30 | func SwscaleVersion() uint { 31 | return uint(C.swscale_version()) 32 | } 33 | 34 | //Return the libswscale build-time configuration. 35 | func SwscaleConfiguration() string { 36 | return C.GoString(C.swscale_configuration()) 37 | } 38 | 39 | //Return the libswscale license. 40 | func SwscaleLicense() string { 41 | return C.GoString(C.swscale_license()) 42 | } 43 | 44 | //Return a pointer to yuv<->rgb coefficients for the given colorspace suitable for sws_setColorspaceDetails(). 45 | func SwsGetcoefficients(c int) *int { 46 | return (*int)(unsafe.Pointer(C.sws_getCoefficients(C.int(c)))) 47 | } 48 | 49 | //Return a positive value if pix_fmt is a supported input format, 0 otherwise. 50 | func SwsIssupportedinput(p PixelFormat) int { 51 | return int(C.sws_isSupportedInput((C.enum_AVPixelFormat)(p))) 52 | } 53 | 54 | //Return a positive value if pix_fmt is a supported output format, 0 otherwise. 55 | func SwsIssupportedoutput(p PixelFormat) int { 56 | return int(C.sws_isSupportedOutput((C.enum_AVPixelFormat)(p))) 57 | } 58 | 59 | func SwsIssupportedendiannessconversion(p PixelFormat) int { 60 | return int(C.sws_isSupportedEndiannessConversion((C.enum_AVPixelFormat)(p))) 61 | } 62 | 63 | ////Scale the image slice in srcSlice and put the resulting scaled slice in the image in dst. 64 | func SwsScale(ctxt *Context, src *uint8, str int, y, h int, d *uint8, ds int) int { 65 | cctxt := (*C.struct_SwsContext)(unsafe.Pointer(ctxt)) 66 | csrc := (*C.uint8_t)(unsafe.Pointer(src)) 67 | cstr := (*C.int)(unsafe.Pointer(&str)) 68 | cd := (*C.uint8_t)(unsafe.Pointer(d)) 69 | cds := (*C.int)(unsafe.Pointer(&ds)) 70 | return int(C.sws_scale(cctxt, &csrc, cstr, C.int(y), C.int(h), &cd, cds)) 71 | } 72 | 73 | func SwsScale2(ctxt *Context, srcData [8]*uint8, srcStride [8]int32, y, h int, dstData [8]*uint8, dstStride [8]int32) int { 74 | cctxt := (*C.struct_SwsContext)(unsafe.Pointer(ctxt)) 75 | csrc := (**C.uint8_t)(unsafe.Pointer(&srcData[0])) 76 | cstr := (*C.int)(unsafe.Pointer(&srcStride[0])) 77 | cd := (**C.uint8_t)(unsafe.Pointer(&dstData[0])) 78 | cds := (*C.int)(unsafe.Pointer(&dstStride)) 79 | return int(C.sws_scale(cctxt, csrc, cstr, C.int(y), C.int(h), cd, cds)) 80 | } 81 | 82 | func SwsSetcolorspacedetails(ctxt *Context, it *int, sr int, t *int, dr, b, c, s int) int { 83 | cit := (*C.int)(unsafe.Pointer(it)) 84 | ct := (*C.int)(unsafe.Pointer(t)) 85 | return int(C.sws_setColorspaceDetails((*C.struct_SwsContext)(ctxt), cit, C.int(sr), ct, C.int(dr), C.int(b), C.int(c), C.int(s))) 86 | } 87 | 88 | func SwsGetcolorspacedetails(ctxt *Context, it, sr, t, dr, b, c, s *int) int { 89 | cit := (**C.int)(unsafe.Pointer(it)) 90 | csr := (*C.int)(unsafe.Pointer(sr)) 91 | ct := (**C.int)(unsafe.Pointer(t)) 92 | cdr := (*C.int)(unsafe.Pointer(dr)) 93 | cb := (*C.int)(unsafe.Pointer(b)) 94 | cc := (*C.int)(unsafe.Pointer(c)) 95 | cs := (*C.int)(unsafe.Pointer(s)) 96 | return int(C.sws_getColorspaceDetails((*C.struct_SwsContext)(ctxt), cit, csr, ct, cdr, cb, cc, cs)) 97 | } 98 | 99 | func SwsGetdefaultfilter(lb, cb, ls, cs, chs, cvs float32, v int) *Filter { 100 | return (*Filter)(unsafe.Pointer(C.sws_getDefaultFilter(C.float(lb), C.float(cb), C.float(ls), C.float(cs), C.float(chs), C.float(cvs), C.int(v)))) 101 | } 102 | 103 | func SwsFreefilter(f *Filter) { 104 | C.sws_freeFilter((*C.struct_SwsFilter)(f)) 105 | } 106 | 107 | //Convert an 8-bit paletted frame into a frame with a color depth of 32 bits. 108 | func SwsConvertpalette8topacked32(s, d *uint8, px int, p *uint8) { 109 | C.sws_convertPalette8ToPacked32((*C.uint8_t)(s), (*C.uint8_t)(d), C.int(px), (*C.uint8_t)(p)) 110 | } 111 | 112 | //Convert an 8-bit paletted frame into a frame with a color depth of 24 bits. 113 | func SwsConvertpalette8topacked24(s, d *uint8, px int, p *uint8) { 114 | C.sws_convertPalette8ToPacked24((*C.uint8_t)(s), (*C.uint8_t)(d), C.int(px), (*C.uint8_t)(p)) 115 | } 116 | 117 | //Get the Class for swsContext. 118 | func SwsGetClass() *Class { 119 | return (*Class)(C.sws_get_class()) 120 | } 121 | -------------------------------------------------------------------------------- /redigo/redis/test_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Gary Burd 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 | // not use this file except in compliance with the License. You may obtain 5 | // a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | // License for the specific language governing permissions and limitations 13 | // under the License. 14 | 15 | package redis 16 | 17 | import ( 18 | "bufio" 19 | "errors" 20 | "flag" 21 | "fmt" 22 | "io" 23 | "io/ioutil" 24 | "os" 25 | "os/exec" 26 | "strconv" 27 | "strings" 28 | "sync" 29 | "testing" 30 | "time" 31 | ) 32 | 33 | func SetNowFunc(f func() time.Time) { 34 | nowFunc = f 35 | } 36 | 37 | var ( 38 | ErrNegativeInt = errNegativeInt 39 | 40 | serverPath = flag.String("redis-server", "redis-server", "Path to redis server binary") 41 | serverAddress = flag.String("redis-address", "127.0.0.1", "The address of the server") 42 | serverBasePort = flag.Int("redis-port", 16379, "Beginning of port range for test servers") 43 | serverLogName = flag.String("redis-log", "", "Write Redis server logs to `filename`") 44 | serverLog = ioutil.Discard 45 | 46 | defaultServerMu sync.Mutex 47 | defaultServer *Server 48 | defaultServerErr error 49 | ) 50 | 51 | type Server struct { 52 | name string 53 | cmd *exec.Cmd 54 | done chan struct{} 55 | } 56 | 57 | func NewServer(name string, args ...string) (*Server, error) { 58 | s := &Server{ 59 | name: name, 60 | cmd: exec.Command(*serverPath, args...), 61 | done: make(chan struct{}), 62 | } 63 | 64 | r, err := s.cmd.StdoutPipe() 65 | if err != nil { 66 | return nil, err 67 | } 68 | 69 | err = s.cmd.Start() 70 | if err != nil { 71 | return nil, err 72 | } 73 | 74 | ready := make(chan error, 1) 75 | go s.watch(r, ready) 76 | 77 | select { 78 | case err = <-ready: 79 | case <-time.After(time.Second * 10): 80 | err = errors.New("timeout waiting for server to start") 81 | } 82 | 83 | if err != nil { 84 | s.Stop() 85 | return nil, err 86 | } 87 | 88 | return s, nil 89 | } 90 | 91 | func (s *Server) watch(r io.Reader, ready chan error) { 92 | fmt.Fprintf(serverLog, "%d START %s \n", s.cmd.Process.Pid, s.name) 93 | var listening bool 94 | var text string 95 | scn := bufio.NewScanner(r) 96 | for scn.Scan() { 97 | text = scn.Text() 98 | fmt.Fprintf(serverLog, "%s\n", text) 99 | if !listening { 100 | if strings.Contains(text, " * Ready to accept connections") || 101 | strings.Contains(text, " * The server is now ready to accept connections on port") { 102 | listening = true 103 | ready <- nil 104 | } 105 | } 106 | } 107 | if !listening { 108 | ready <- fmt.Errorf("server exited: %s", text) 109 | } 110 | s.cmd.Wait() 111 | fmt.Fprintf(serverLog, "%d STOP %s \n", s.cmd.Process.Pid, s.name) 112 | close(s.done) 113 | } 114 | 115 | func (s *Server) Stop() { 116 | s.cmd.Process.Signal(os.Interrupt) 117 | <-s.done 118 | } 119 | 120 | // stopDefaultServer stops the server created by DialDefaultServer. 121 | func stopDefaultServer() { 122 | defaultServerMu.Lock() 123 | defer defaultServerMu.Unlock() 124 | if defaultServer != nil { 125 | defaultServer.Stop() 126 | defaultServer = nil 127 | } 128 | } 129 | 130 | // DefaultServerAddr starts the test server if not already started and returns 131 | // the address of that server. 132 | func DefaultServerAddr() (string, error) { 133 | defaultServerMu.Lock() 134 | defer defaultServerMu.Unlock() 135 | addr := fmt.Sprintf("%v:%d", *serverAddress, *serverBasePort) 136 | if defaultServer != nil || defaultServerErr != nil { 137 | return addr, defaultServerErr 138 | } 139 | defaultServer, defaultServerErr = NewServer( 140 | "default", 141 | "--port", strconv.Itoa(*serverBasePort), 142 | "--bind", *serverAddress, 143 | "--save", "", 144 | "--appendonly", "no") 145 | return addr, defaultServerErr 146 | } 147 | 148 | // DialDefaultServer starts the test server if not already started and dials a 149 | // connection to the server. 150 | func DialDefaultServer(options ...DialOption) (Conn, error) { 151 | addr, err := DefaultServerAddr() 152 | if err != nil { 153 | return nil, err 154 | } 155 | c, err := Dial("tcp", addr, append([]DialOption{DialReadTimeout(1 * time.Second), DialWriteTimeout(1 * time.Second)}, options...)...) 156 | if err != nil { 157 | return nil, err 158 | } 159 | c.Do("FLUSHDB") 160 | return c, nil 161 | } 162 | 163 | func TestMain(m *testing.M) { 164 | os.Exit(func() int { 165 | flag.Parse() 166 | 167 | var f *os.File 168 | if *serverLogName != "" { 169 | var err error 170 | f, err = os.OpenFile(*serverLogName, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0600) 171 | if err != nil { 172 | fmt.Fprintf(os.Stderr, "Error opening redis-log: %v\n", err) 173 | return 1 174 | } 175 | defer f.Close() 176 | serverLog = f 177 | } 178 | 179 | defer stopDefaultServer() 180 | 181 | return m.Run() 182 | }()) 183 | } 184 | -------------------------------------------------------------------------------- /cron/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package cron implements a cron spec parser and job runner. 3 | 4 | Usage 5 | 6 | Callers may register Funcs to be invoked on a given schedule. Cron will run 7 | them in their own goroutines. 8 | 9 | c := cron.New() 10 | c.AddFunc("0 30 * * * *", func() { fmt.Println("Every hour on the half hour") }) 11 | c.AddFunc("@hourly", func() { fmt.Println("Every hour") }) 12 | c.AddFunc("@every 1h30m", func() { fmt.Println("Every hour thirty") }) 13 | c.Start() 14 | .. 15 | // Funcs are invoked in their own goroutine, asynchronously. 16 | ... 17 | // Funcs may also be added to a running Cron 18 | c.AddFunc("@daily", func() { fmt.Println("Every day") }) 19 | .. 20 | // Inspect the cron job entries' next and previous run times. 21 | inspect(c.Entries()) 22 | .. 23 | c.Stop() // Stop the scheduler (does not stop any jobs already running). 24 | 25 | CRON Expression Format 26 | 27 | A cron expression represents a set of times, using 6 space-separated fields. 28 | 29 | Field name | Mandatory? | Allowed values | Allowed special characters 30 | ---------- | ---------- | -------------- | -------------------------- 31 | Seconds | Yes | 0-59 | * / , - 32 | Minutes | Yes | 0-59 | * / , - 33 | Hours | Yes | 0-23 | * / , - 34 | Day of month | Yes | 1-31 | * / , - ? 35 | Month | Yes | 1-12 or JAN-DEC | * / , - 36 | Day of week | Yes | 0-6 or SUN-SAT | * / , - ? 37 | 38 | Note: Month and Day-of-week field values are case insensitive. "SUN", "Sun", 39 | and "sun" are equally accepted. 40 | 41 | Special Characters 42 | 43 | Asterisk ( * ) 44 | 45 | The asterisk indicates that the cron expression will match for all values of the 46 | field; e.g., using an asterisk in the 5th field (month) would indicate every 47 | month. 48 | 49 | Slash ( / ) 50 | 51 | Slashes are used to describe increments of ranges. For example 3-59/15 in the 52 | 1st field (minutes) would indicate the 3rd minute of the hour and every 15 53 | minutes thereafter. The form "*\/..." is equivalent to the form "first-last/...", 54 | that is, an increment over the largest possible range of the field. The form 55 | "N/..." is accepted as meaning "N-MAX/...", that is, starting at N, use the 56 | increment until the end of that specific range. It does not wrap around. 57 | 58 | Comma ( , ) 59 | 60 | Commas are used to separate items of a list. For example, using "MON,WED,FRI" in 61 | the 5th field (day of week) would mean Mondays, Wednesdays and Fridays. 62 | 63 | Hyphen ( - ) 64 | 65 | Hyphens are used to define ranges. For example, 9-17 would indicate every 66 | hour between 9am and 5pm inclusive. 67 | 68 | Question mark ( ? ) 69 | 70 | Question mark may be used instead of '*' for leaving either day-of-month or 71 | day-of-week blank. 72 | 73 | Predefined schedules 74 | 75 | You may use one of several pre-defined schedules in place of a cron expression. 76 | 77 | Entry | Description | Equivalent To 78 | ----- | ----------- | ------------- 79 | @yearly (or @annually) | Run once a year, midnight, Jan. 1st | 0 0 0 1 1 * 80 | @monthly | Run once a month, midnight, first of month | 0 0 0 1 * * 81 | @weekly | Run once a week, midnight between Sat/Sun | 0 0 0 * * 0 82 | @daily (or @midnight) | Run once a day, midnight | 0 0 0 * * * 83 | @hourly | Run once an hour, beginning of hour | 0 0 * * * * 84 | 85 | Intervals 86 | 87 | You may also schedule a job to execute at fixed intervals, starting at the time it's added 88 | or cron is run. This is supported by formatting the cron spec like this: 89 | 90 | @every 91 | 92 | where "duration" is a string accepted by time.ParseDuration 93 | (http://golang.org/pkg/time/#ParseDuration). 94 | 95 | For example, "@every 1h30m10s" would indicate a schedule that activates after 96 | 1 hour, 30 minutes, 10 seconds, and then every interval after that. 97 | 98 | Note: The interval does not take the job runtime into account. For example, 99 | if a job takes 3 minutes to run, and it is scheduled to run every 5 minutes, 100 | it will have only 2 minutes of idle time between each run. 101 | 102 | Time zones 103 | 104 | All interpretation and scheduling is done in the machine's local time zone (as 105 | provided by the Go time package (http://www.golang.org/pkg/time). 106 | 107 | Be aware that jobs scheduled during daylight-savings leap-ahead transitions will 108 | not be run! 109 | 110 | Thread safety 111 | 112 | Since the Cron service runs concurrently with the calling code, some amount of 113 | care must be taken to ensure proper synchronization. 114 | 115 | All cron methods are designed to be correctly synchronized as long as the caller 116 | ensures that invocations have a clear happens-before ordering between them. 117 | 118 | Implementation 119 | 120 | Cron entries are stored in an array, sorted by their next activation time. Cron 121 | sleeps until the next job is due to be run. 122 | 123 | Upon waking: 124 | - it runs each entry that is active on that second 125 | - it calculates the next run times for the jobs that were run 126 | - it re-sorts the array of entries by next activation time. 127 | - it goes to sleep until the soonest job. 128 | */ 129 | package cron 130 | -------------------------------------------------------------------------------- /goav/avfilter/avfilter.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a MIT license that can be found in the LICENSE file. 2 | // Giorgis (habtom@giorgis.io) 3 | 4 | //Package avfilter contains methods that deal with ffmpeg filters 5 | //filters in the same linear chain are separated by commas, and distinct linear chains of filters are separated by semicolons. 6 | //FFmpeg is enabled through the "C" libavfilter library 7 | package avfilter 8 | 9 | /* 10 | #cgo pkg-config: libavfilter 11 | #include 12 | #include 13 | #include 14 | #include 15 | */ 16 | import "C" 17 | import ( 18 | "unsafe" 19 | ) 20 | 21 | type ( 22 | Filter C.struct_AVFilter 23 | Context C.struct_AVFilterContext 24 | Link C.struct_AVFilterLink 25 | Graph C.struct_AVFilterGraph 26 | Input C.struct_AVFilterInOut 27 | Pad C.struct_AVFilterPad 28 | Dictionary C.struct_AVDictionary 29 | Class C.struct_AVClass 30 | Frame C.struct_AVFrame 31 | MediaType C.enum_AVMediaType 32 | ) 33 | 34 | //Return the LIBAvFILTER_VERSION_INT constant. 35 | func AvfilterVersion() uint { 36 | return uint(C.avfilter_version()) 37 | } 38 | 39 | //Return the libavfilter build-time configuration. 40 | func AvfilterConfiguration() string { 41 | return C.GoString(C.avfilter_configuration()) 42 | } 43 | 44 | //Return the libavfilter license. 45 | func AvfilterLicense() string { 46 | return C.GoString(C.avfilter_license()) 47 | } 48 | 49 | //Get the number of elements in a NULL-terminated array of Pads (e.g. 50 | func AvfilterPadCount(p *Pad) int { 51 | return int(C.avfilter_pad_count((*C.struct_AVFilterPad)(p))) 52 | } 53 | 54 | //Get the name of an Pad. 55 | func AvfilterPadGetName(p *Pad, pi int) string { 56 | return C.GoString(C.avfilter_pad_get_name((*C.struct_AVFilterPad)(p), C.int(pi))) 57 | } 58 | 59 | //Get the type of an Pad. 60 | func AvfilterPadGetType(p *Pad, pi int) MediaType { 61 | return (MediaType)(C.avfilter_pad_get_type((*C.struct_AVFilterPad)(p), C.int(pi))) 62 | } 63 | 64 | //Link two filters together. 65 | func AvfilterLink(s *Context, sp uint, d *Context, dp uint) int { 66 | return int(C.avfilter_link((*C.struct_AVFilterContext)(s), C.uint(sp), (*C.struct_AVFilterContext)(d), C.uint(dp))) 67 | } 68 | 69 | //Free the link in *link, and set its pointer to NULL. 70 | func AvfilterLinkFree(l **Link) { 71 | C.avfilter_link_free((**C.struct_AVFilterLink)(unsafe.Pointer(l))) 72 | } 73 | 74 | //Get the number of channels of a link. 75 | func AvfilterLinkGetChannels(l *Link) int { 76 | return int(C.avfilter_link_get_channels((*C.struct_AVFilterLink)(l))) 77 | } 78 | 79 | //Set the closed field of a link. 80 | func AvfilterLinkSetClosed(l *Link, c int) { 81 | C.avfilter_link_set_closed((*C.struct_AVFilterLink)(l), C.int(c)) 82 | } 83 | 84 | //Negotiate the media format, dimensions, etc of all inputs to a filter. 85 | func AvfilterConfigLinks(f *Context) int { 86 | return int(C.avfilter_config_links((*C.struct_AVFilterContext)(f))) 87 | } 88 | 89 | //Make the filter instance process a command. 90 | func AvfilterProcessCommand(f *Context, cmd, arg, res string, l, fl int) int { 91 | return int(C.avfilter_process_command((*C.struct_AVFilterContext)(f), C.CString(cmd), C.CString(arg), C.CString(res), C.int(l), C.int(fl))) 92 | } 93 | 94 | //Initialize the filter system. 95 | func AvfilterRegisterAll() { 96 | C.avfilter_register_all() 97 | } 98 | 99 | //Initialize a filter with the supplied parameters. 100 | func (ctx *Context) AvfilterInitStr(args string) int { 101 | return int(C.avfilter_init_str((*C.struct_AVFilterContext)(ctx), C.CString(args))) 102 | } 103 | 104 | //Initialize a filter with the supplied dictionary of options. 105 | func (ctx *Context) AvfilterInitDict(o **Dictionary) int { 106 | return int(C.avfilter_init_dict((*C.struct_AVFilterContext)(ctx), (**C.struct_AVDictionary)(unsafe.Pointer(o)))) 107 | } 108 | 109 | //Free a filter context. 110 | func (ctx *Context) AvfilterFree() { 111 | C.avfilter_free((*C.struct_AVFilterContext)(ctx)) 112 | } 113 | 114 | //Insert a filter in the middle of an existing link. 115 | func AvfilterInsertFilter(l *Link, f *Context, fsi, fdi uint) int { 116 | return int(C.avfilter_insert_filter((*C.struct_AVFilterLink)(l), (*C.struct_AVFilterContext)(f), C.uint(fsi), C.uint(fdi))) 117 | } 118 | 119 | //avfilter_get_class 120 | func AvfilterGetClass() *Class { 121 | return (*Class)(C.avfilter_get_class()) 122 | } 123 | 124 | //Allocate a single Input entry. 125 | func AvfilterInoutAlloc() *Input { 126 | return (*Input)(C.avfilter_inout_alloc()) 127 | } 128 | 129 | //Free the supplied list of Input and set *inout to NULL. 130 | func AvfilterInoutFree(i *Input) { 131 | C.avfilter_inout_free((**C.struct_AVFilterInOut)(unsafe.Pointer(i))) 132 | } 133 | 134 | func (i *Input)FilterContext() *Context { 135 | return (*Context)(i.filter_ctx) 136 | } 137 | 138 | func (i *Input)Next() *Input { 139 | return (*Input)(i.next) 140 | } 141 | 142 | func (i *Input)PadIdx() uint { 143 | return (uint)(i.pad_idx) 144 | } 145 | 146 | func AvBufferSinkGetFrame(c *Context, f *Frame) int { 147 | return (int)(C.av_buffersink_get_frame((*C.struct_AVFilterContext)(c), (*C.struct_AVFrame)(f))) 148 | } 149 | 150 | // keep ref 151 | func AvBuffersrcWriteFrame(c *Context, f *Frame) int { 152 | return (int)(C.av_buffersrc_write_frame((*C.struct_AVFilterContext)(c), (*C.struct_AVFrame)(f))) 153 | } 154 | 155 | // copy 156 | func AvBuffersrcAddFrame(c *Context, f *Frame) int { 157 | return (int)(C.av_buffersrc_add_frame((*C.struct_AVFilterContext)(c), (*C.struct_AVFrame)(f))) 158 | } -------------------------------------------------------------------------------- /redigo/redis/reply_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Gary Burd 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 | // not use this file except in compliance with the License. You may obtain 5 | // a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | // License for the specific language governing permissions and limitations 13 | // under the License. 14 | 15 | package redis_test 16 | 17 | import ( 18 | "fmt" 19 | "reflect" 20 | "testing" 21 | 22 | "github.com/gomodule/redigo/redis" 23 | ) 24 | 25 | type valueError struct { 26 | v interface{} 27 | err error 28 | } 29 | 30 | func ve(v interface{}, err error) valueError { 31 | return valueError{v, err} 32 | } 33 | 34 | var replyTests = []struct { 35 | name interface{} 36 | actual valueError 37 | expected valueError 38 | }{ 39 | { 40 | "ints([[]byte, []byte])", 41 | ve(redis.Ints([]interface{}{[]byte("4"), []byte("5")}, nil)), 42 | ve([]int{4, 5}, nil), 43 | }, 44 | { 45 | "ints([nt64, int64])", 46 | ve(redis.Ints([]interface{}{int64(4), int64(5)}, nil)), 47 | ve([]int{4, 5}, nil), 48 | }, 49 | { 50 | "ints([[]byte, nil, []byte])", 51 | ve(redis.Ints([]interface{}{[]byte("4"), nil, []byte("5")}, nil)), 52 | ve([]int{4, 0, 5}, nil), 53 | }, 54 | { 55 | "ints(nil)", 56 | ve(redis.Ints(nil, nil)), 57 | ve([]int(nil), redis.ErrNil), 58 | }, 59 | { 60 | "int64s([[]byte, []byte])", 61 | ve(redis.Int64s([]interface{}{[]byte("4"), []byte("5")}, nil)), 62 | ve([]int64{4, 5}, nil), 63 | }, 64 | { 65 | "int64s([int64, int64])", 66 | ve(redis.Int64s([]interface{}{int64(4), int64(5)}, nil)), 67 | ve([]int64{4, 5}, nil), 68 | }, 69 | { 70 | "strings([[]byte, []bytev2])", 71 | ve(redis.Strings([]interface{}{[]byte("v1"), []byte("v2")}, nil)), 72 | ve([]string{"v1", "v2"}, nil), 73 | }, 74 | { 75 | "strings([string, string])", 76 | ve(redis.Strings([]interface{}{"v1", "v2"}, nil)), 77 | ve([]string{"v1", "v2"}, nil), 78 | }, 79 | { 80 | "byteslices([v1, v2])", 81 | ve(redis.ByteSlices([]interface{}{[]byte("v1"), []byte("v2")}, nil)), 82 | ve([][]byte{[]byte("v1"), []byte("v2")}, nil), 83 | }, 84 | { 85 | "float64s([v1, v2])", 86 | ve(redis.Float64s([]interface{}{[]byte("1.234"), []byte("5.678")}, nil)), 87 | ve([]float64{1.234, 5.678}, nil), 88 | }, 89 | { 90 | "values([v1, v2])", 91 | ve(redis.Values([]interface{}{[]byte("v1"), []byte("v2")}, nil)), 92 | ve([]interface{}{[]byte("v1"), []byte("v2")}, nil), 93 | }, 94 | { 95 | "values(nil)", 96 | ve(redis.Values(nil, nil)), 97 | ve([]interface{}(nil), redis.ErrNil), 98 | }, 99 | { 100 | "float64(1.0)", 101 | ve(redis.Float64([]byte("1.0"), nil)), 102 | ve(float64(1.0), nil), 103 | }, 104 | { 105 | "float64(nil)", 106 | ve(redis.Float64(nil, nil)), 107 | ve(float64(0.0), redis.ErrNil), 108 | }, 109 | { 110 | "uint64(1)", 111 | ve(redis.Uint64(int64(1), nil)), 112 | ve(uint64(1), nil), 113 | }, 114 | { 115 | "uint64(-1)", 116 | ve(redis.Uint64(int64(-1), nil)), 117 | ve(uint64(0), redis.ErrNegativeInt), 118 | }, 119 | { 120 | "positions([[1, 2], nil, [3, 4]])", 121 | ve(redis.Positions([]interface{}{[]interface{}{[]byte("1"), []byte("2")}, nil, []interface{}{[]byte("3"), []byte("4")}}, nil)), 122 | ve([]*[2]float64{{1.0, 2.0}, nil, {3.0, 4.0}}, nil), 123 | }, 124 | } 125 | 126 | func TestReply(t *testing.T) { 127 | for _, rt := range replyTests { 128 | if rt.actual.err != rt.expected.err { 129 | t.Errorf("%s returned err %v, want %v", rt.name, rt.actual.err, rt.expected.err) 130 | continue 131 | } 132 | if !reflect.DeepEqual(rt.actual.v, rt.expected.v) { 133 | t.Errorf("%s=%+v, want %+v", rt.name, rt.actual.v, rt.expected.v) 134 | } 135 | } 136 | } 137 | 138 | // dial wraps DialDefaultServer() with a more suitable function name for examples. 139 | func dial() (redis.Conn, error) { 140 | return redis.DialDefaultServer() 141 | } 142 | 143 | // serverAddr wraps DefaultServerAddr() with a more suitable function name for examples. 144 | func serverAddr() (string, error) { 145 | return redis.DefaultServerAddr() 146 | } 147 | 148 | func ExampleBool() { 149 | c, err := dial() 150 | if err != nil { 151 | fmt.Println(err) 152 | return 153 | } 154 | defer c.Close() 155 | 156 | c.Do("SET", "foo", 1) 157 | exists, _ := redis.Bool(c.Do("EXISTS", "foo")) 158 | fmt.Printf("%#v\n", exists) 159 | // Output: 160 | // true 161 | } 162 | 163 | func ExampleInt() { 164 | c, err := dial() 165 | if err != nil { 166 | fmt.Println(err) 167 | return 168 | } 169 | defer c.Close() 170 | 171 | c.Do("SET", "k1", 1) 172 | n, _ := redis.Int(c.Do("GET", "k1")) 173 | fmt.Printf("%#v\n", n) 174 | n, _ = redis.Int(c.Do("INCR", "k1")) 175 | fmt.Printf("%#v\n", n) 176 | // Output: 177 | // 1 178 | // 2 179 | } 180 | 181 | func ExampleInts() { 182 | c, err := dial() 183 | if err != nil { 184 | fmt.Println(err) 185 | return 186 | } 187 | defer c.Close() 188 | 189 | c.Do("SADD", "set_with_integers", 4, 5, 6) 190 | ints, _ := redis.Ints(c.Do("SMEMBERS", "set_with_integers")) 191 | fmt.Printf("%#v\n", ints) 192 | // Output: 193 | // []int{4, 5, 6} 194 | } 195 | 196 | func ExampleString() { 197 | c, err := dial() 198 | if err != nil { 199 | fmt.Println(err) 200 | return 201 | } 202 | defer c.Close() 203 | 204 | c.Do("SET", "hello", "world") 205 | s, err := redis.String(c.Do("GET", "hello")) 206 | fmt.Printf("%#v\n", s) 207 | // Output: 208 | // "world" 209 | } 210 | -------------------------------------------------------------------------------- /goav/avcodec/pixel.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a MIT license that can be found in the LICENSE file. 2 | // Giorgis (habtom@giorgis.io) 3 | 4 | //Package avcodec contains the codecs (decoders and encoders) provided by the libavcodec library 5 | //Provides some generic global options, which can be set on all the encoders and decoders. 6 | package avcodec 7 | 8 | //#cgo pkg-config: libavformat libavcodec libavutil 9 | //#include 10 | //#include 11 | //#include 12 | //#include 13 | //#include 14 | //#include 15 | //#include 16 | //#include 17 | //#include 18 | import "C" 19 | 20 | const ( 21 | AV_PIX_FMT_YUV420P = 0 22 | AV_PIX_FMT_YUV420P9 = C.AV_PIX_FMT_YUV420P9 23 | AV_PIX_FMT_YUV422P9 = C.AV_PIX_FMT_YUV422P9 24 | AV_PIX_FMT_YUV444P9 = C.AV_PIX_FMT_YUV444P9 25 | AV_PIX_FMT_YUV420P10 = C.AV_PIX_FMT_YUV420P10 26 | AV_PIX_FMT_YUV422P10 = C.AV_PIX_FMT_YUV422P10 27 | AV_PIX_FMT_YUV440P10 = C.AV_PIX_FMT_YUV440P10 28 | AV_PIX_FMT_YUV444P10 = C.AV_PIX_FMT_YUV444P10 29 | AV_PIX_FMT_YUV420P12 = C.AV_PIX_FMT_YUV420P12 30 | AV_PIX_FMT_YUV422P12 = C.AV_PIX_FMT_YUV422P12 31 | AV_PIX_FMT_YUV440P12 = C.AV_PIX_FMT_YUV440P12 32 | AV_PIX_FMT_YUV444P12 = C.AV_PIX_FMT_YUV444P12 33 | AV_PIX_FMT_YUV420P14 = C.AV_PIX_FMT_YUV420P14 34 | AV_PIX_FMT_YUV422P14 = C.AV_PIX_FMT_YUV422P14 35 | AV_PIX_FMT_YUV444P14 = C.AV_PIX_FMT_YUV444P14 36 | AV_PIX_FMT_YUV420P16 = C.AV_PIX_FMT_YUV420P16 37 | AV_PIX_FMT_YUV422P16 = C.AV_PIX_FMT_YUV422P16 38 | AV_PIX_FMT_YUV444P16 = C.AV_PIX_FMT_YUV444P16 39 | AV_PIX_FMT_YUVA420P9 = C.AV_PIX_FMT_YUVA420P9 40 | AV_PIX_FMT_YUVA422P9 = C.AV_PIX_FMT_YUVA422P9 41 | AV_PIX_FMT_YUVA444P9 = C.AV_PIX_FMT_YUVA444P9 42 | AV_PIX_FMT_YUVA420P10 = C.AV_PIX_FMT_YUVA420P10 43 | AV_PIX_FMT_YUVA422P10 = C.AV_PIX_FMT_YUVA422P10 44 | AV_PIX_FMT_YUVA444P10 = C.AV_PIX_FMT_YUVA444P10 45 | AV_PIX_FMT_YUVA420P16 = C.AV_PIX_FMT_YUVA420P16 46 | AV_PIX_FMT_YUVA422P16 = C.AV_PIX_FMT_YUVA422P16 47 | AV_PIX_FMT_YUVA444P16 = C.AV_PIX_FMT_YUVA444P16 48 | AV_PIX_FMT_RGB24 = C.AV_PIX_FMT_RGB24 49 | AV_PIX_FMT_RGBA = C.AV_PIX_FMT_RGBA 50 | 51 | SWS_FAST_BILINEAR = C.SWS_FAST_BILINEAR 52 | SWS_BILINEAR = C.SWS_BILINEAR 53 | SWS_BICUBIC = C.SWS_BICUBIC 54 | SWS_X = C.SWS_X 55 | SWS_POINT = C.SWS_POINT 56 | SWS_AREA = C.SWS_AREA 57 | SWS_BICUBLIN = C.SWS_BICUBLIN 58 | SWS_GAUSS = C.SWS_GAUSS 59 | SWS_SINC = C.SWS_SINC 60 | SWS_LANCZOS = C.SWS_LANCZOS 61 | SWS_SPLINE = C.SWS_SPLINE 62 | SWS_SRC_V_CHR_DROP_MASK = C.SWS_SRC_V_CHR_DROP_MASK 63 | SWS_SRC_V_CHR_DROP_SHIFT = C.SWS_SRC_V_CHR_DROP_SHIFT 64 | SWS_PARAM_DEFAULT = C.SWS_PARAM_DEFAULT 65 | SWS_PRINT_INFO = C.SWS_PRINT_INFO 66 | SWS_FULL_CHR_H_INT = C.SWS_FULL_CHR_H_INT 67 | SWS_FULL_CHR_H_INP = C.SWS_FULL_CHR_H_INP 68 | SWS_DIRECT_BGR = C.SWS_DIRECT_BGR 69 | SWS_ACCURATE_RND = C.SWS_ACCURATE_RND 70 | SWS_BITEXACT = C.SWS_BITEXACT 71 | SWS_ERROR_DIFFUSION = C.SWS_ERROR_DIFFUSION 72 | SWS_MAX_REDUCE_CUTOFF = C.SWS_MAX_REDUCE_CUTOFF 73 | SWS_CS_ITU709 = C.SWS_CS_ITU709 74 | SWS_CS_FCC = C.SWS_CS_FCC 75 | SWS_CS_ITU601 = C.SWS_CS_ITU601 76 | SWS_CS_ITU624 = C.SWS_CS_ITU624 77 | SWS_CS_SMPTE170M = C.SWS_CS_SMPTE170M 78 | SWS_CS_SMPTE240M = C.SWS_CS_SMPTE240M 79 | SWS_CS_DEFAULT = C.SWS_CS_DEFAULT 80 | SWS_CS_BT2020 = C.SWS_CS_BT2020 81 | ) 82 | 83 | const ( 84 | AV_SAMPLE_FMT_NONE = C.AV_SAMPLE_FMT_NONE 85 | AV_SAMPLE_FMT_U8 = C.AV_SAMPLE_FMT_U8 86 | AV_SAMPLE_FMT_S16 = C.AV_SAMPLE_FMT_S16 87 | AV_SAMPLE_FMT_S32 = C.AV_SAMPLE_FMT_S32 88 | AV_SAMPLE_FMT_FLT = C.AV_SAMPLE_FMT_FLT 89 | AV_SAMPLE_FMT_DBL = C.AV_SAMPLE_FMT_DBL 90 | 91 | AV_SAMPLE_FMT_U8P = C.AV_SAMPLE_FMT_U8P 92 | AV_SAMPLE_FMT_S16P = C.AV_SAMPLE_FMT_S16P 93 | AV_SAMPLE_FMT_S32P = C.AV_SAMPLE_FMT_S32P 94 | AV_SAMPLE_FMT_FLTP = C.AV_SAMPLE_FMT_FLTP 95 | AV_SAMPLE_FMT_DBLP = C.AV_SAMPLE_FMT_DBLP 96 | AV_SAMPLE_FMT_S64 = C.AV_SAMPLE_FMT_S64 97 | AV_SAMPLE_FMT_S64P = C.AV_SAMPLE_FMT_S64P 98 | 99 | AV_SAMPLE_FMT_NB = C.AV_SAMPLE_FMT_NB 100 | ) 101 | 102 | const ( 103 | AV_CH_LAYOUT_STEREO = C.AV_CH_LAYOUT_STEREO 104 | ) 105 | 106 | func (pf PixelFormat) String() string { 107 | switch int(pf) { 108 | case AV_PIX_FMT_YUV420P9: 109 | return "YUV420P9" 110 | 111 | case AV_PIX_FMT_YUV422P9: 112 | return "YUV422P9" 113 | 114 | case AV_PIX_FMT_YUV444P9: 115 | return "YUV444P9" 116 | 117 | case AV_PIX_FMT_YUV420P10: 118 | return "YUV420P10" 119 | 120 | case AV_PIX_FMT_YUV422P10: 121 | return "YUV422P10" 122 | 123 | case AV_PIX_FMT_YUV440P10: 124 | return "YUV440P10" 125 | 126 | case AV_PIX_FMT_YUV444P10: 127 | return "YUV444P10" 128 | 129 | case AV_PIX_FMT_YUV420P12: 130 | return "YUV420P12" 131 | 132 | case AV_PIX_FMT_YUV422P12: 133 | return "YUV422P12" 134 | 135 | case AV_PIX_FMT_YUV440P12: 136 | return "YUV440P12" 137 | 138 | case AV_PIX_FMT_YUV444P12: 139 | return "YUV444P12" 140 | 141 | case AV_PIX_FMT_YUV420P14: 142 | return "YUV420P14" 143 | 144 | case AV_PIX_FMT_YUV422P14: 145 | return "YUV422P14" 146 | 147 | case AV_PIX_FMT_YUV444P14: 148 | return "YUV444P14" 149 | 150 | case AV_PIX_FMT_YUV420P16: 151 | return "YUV420P16" 152 | 153 | case AV_PIX_FMT_YUV422P16: 154 | return "YUV422P16" 155 | 156 | case AV_PIX_FMT_YUV444P16: 157 | return "YUV444P16" 158 | 159 | case AV_PIX_FMT_YUVA420P9: 160 | return "YUVA420P9" 161 | 162 | case AV_PIX_FMT_YUVA422P9: 163 | return "YUVA422P9" 164 | 165 | case AV_PIX_FMT_YUVA444P9: 166 | return "YUVA444P9" 167 | 168 | case AV_PIX_FMT_YUVA420P10: 169 | return "YUVA420P10" 170 | 171 | case AV_PIX_FMT_YUVA422P10: 172 | return "YUVA422P10" 173 | 174 | case AV_PIX_FMT_YUVA444P10: 175 | return "YUVA444P10" 176 | 177 | case AV_PIX_FMT_YUVA420P16: 178 | return "YUVA420P16" 179 | 180 | case AV_PIX_FMT_YUVA422P16: 181 | return "YUVA422P16" 182 | 183 | case AV_PIX_FMT_YUVA444P16: 184 | return "YUVA444P16" 185 | 186 | case AV_PIX_FMT_RGB24: 187 | return "RGB24" 188 | 189 | case AV_PIX_FMT_RGBA: 190 | return "RGBA" 191 | } 192 | 193 | return "{UNKNOWN}" 194 | } 195 | -------------------------------------------------------------------------------- /goav/avformat/stream_struct.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a MIT license that can be found in the LICENSE file. 2 | // Giorgis (habtom@giorgis.io) 3 | 4 | package avformat 5 | 6 | //#cgo pkg-config: libavformat 7 | //#include 8 | import "C" 9 | import ( 10 | "unsafe" 11 | 12 | "github.com/giorgisio/goav/avcodec" 13 | "github.com/giorgisio/goav/avutil" 14 | ) 15 | 16 | func (avs *Stream) CodecParameters() *avcodec.AvCodecParameters { 17 | return (*avcodec.AvCodecParameters)(unsafe.Pointer(avs.codecpar)) 18 | } 19 | 20 | func (avs *Stream) Codec() *CodecContext { 21 | return (*CodecContext)(unsafe.Pointer(avs.codec)) 22 | } 23 | 24 | func (avs *Stream) Metadata() *avutil.Dictionary { 25 | return (*avutil.Dictionary)(unsafe.Pointer(avs.metadata)) 26 | } 27 | 28 | func (avs *Stream) IndexEntries() *AvIndexEntry { 29 | return (*AvIndexEntry)(unsafe.Pointer(avs.index_entries)) 30 | } 31 | 32 | func (avs *Stream) AttachedPic() avcodec.Packet { 33 | return *fromCPacket(&avs.attached_pic) 34 | } 35 | 36 | func (avs *Stream) SideData() *AvPacketSideData { 37 | return (*AvPacketSideData)(unsafe.Pointer(avs.side_data)) 38 | } 39 | 40 | func (avs *Stream) ProbeData() AvProbeData { 41 | return AvProbeData(avs.probe_data) 42 | } 43 | 44 | func (avs *Stream) AvgFrameRate() avcodec.Rational { 45 | return newRational(avs.avg_frame_rate) 46 | } 47 | 48 | // func (avs *Stream) DisplayAspectRatio() *Rational { 49 | // return (*Rational)(unsafe.Pointer(avs.display_aspect_ratio)) 50 | // } 51 | 52 | func (avs *Stream) RFrameRate() avcodec.Rational { 53 | return newRational(avs.r_frame_rate) 54 | } 55 | 56 | func (avs *Stream) SampleAspectRatio() avcodec.Rational { 57 | return newRational(avs.sample_aspect_ratio) 58 | } 59 | 60 | func (avs *Stream) TimeBase() avcodec.Rational { 61 | return newRational(avs.time_base) 62 | } 63 | 64 | // func (avs *Stream) RecommendedEncoderConfiguration() string { 65 | // return C.GoString(avs.recommended_encoder_configuration) 66 | // } 67 | 68 | func (avs *Stream) Discard() AvDiscard { 69 | return AvDiscard(avs.discard) 70 | } 71 | 72 | func (avs *Stream) NeedParsing() AvStreamParseType { 73 | return AvStreamParseType(avs.need_parsing) 74 | } 75 | 76 | func (avs *Stream) CodecInfoNbFrames() int { 77 | return int(avs.codec_info_nb_frames) 78 | } 79 | 80 | func (avs *Stream) Disposition() int { 81 | return int(avs.disposition) 82 | } 83 | 84 | func (avs *Stream) EventFlags() int { 85 | return int(avs.event_flags) 86 | } 87 | 88 | func (avs *Stream) Id() int { 89 | return int(avs.id) 90 | } 91 | 92 | func (avs *Stream) Index() int { 93 | return int(avs.index) 94 | } 95 | 96 | func (avs *Stream) InjectGlobalSideData() int { 97 | return int(avs.inject_global_side_data) 98 | } 99 | 100 | func (avs *Stream) LastIpDuration() int { 101 | return int(avs.last_IP_duration) 102 | } 103 | 104 | func (avs *Stream) NbDecodedFrames() int { 105 | return int(avs.nb_decoded_frames) 106 | } 107 | 108 | func (avs *Stream) NbIndexEntries() int { 109 | return int(avs.nb_index_entries) 110 | } 111 | 112 | func (avs *Stream) NbSideData() int { 113 | return int(avs.nb_side_data) 114 | } 115 | 116 | func (avs *Stream) ProbePackets() int { 117 | return int(avs.probe_packets) 118 | } 119 | 120 | func (avs *Stream) PtsWrapBehavior() int { 121 | return int(avs.pts_wrap_behavior) 122 | } 123 | 124 | func (avs *Stream) RequestProbe() int { 125 | return int(avs.request_probe) 126 | } 127 | 128 | func (avs *Stream) SkipSamples() int { 129 | return int(avs.skip_samples) 130 | } 131 | 132 | func (avs *Stream) SkipToKeyframe() int { 133 | return int(avs.skip_to_keyframe) 134 | } 135 | 136 | func (avs *Stream) StreamIdentifier() int { 137 | return int(avs.stream_identifier) 138 | } 139 | 140 | func (avs *Stream) UpdateInitialDurationsDone() int { 141 | return int(avs.update_initial_durations_done) 142 | } 143 | 144 | func (avs *Stream) CurDts() int64 { 145 | return int64(avs.cur_dts) 146 | } 147 | 148 | func (avs *Stream) Duration() int64 { 149 | return int64(avs.duration) 150 | } 151 | 152 | // func (avs *Stream) FirstDiscardSample() int64 { 153 | // return int64(avs.first_discard_sample) 154 | // } 155 | 156 | func (avs *Stream) FirstDts() int64 { 157 | return int64(avs.first_dts) 158 | } 159 | 160 | func (avs *Stream) InterleaverChunkDuration() int64 { 161 | return int64(avs.interleaver_chunk_duration) 162 | } 163 | 164 | func (avs *Stream) InterleaverChunkSize() int64 { 165 | return int64(avs.interleaver_chunk_size) 166 | } 167 | 168 | // func (avs *Stream) LastDiscardSample() int64 { 169 | // return int64(avs.last_discard_sample) 170 | // } 171 | 172 | func (avs *Stream) LastDtsForOrderCheck() int64 { 173 | return int64(avs.last_dts_for_order_check) 174 | } 175 | 176 | func (avs *Stream) LastIpPts() int64 { 177 | return int64(avs.last_IP_pts) 178 | } 179 | 180 | func (avs *Stream) MuxTsOffset() int64 { 181 | return int64(avs.mux_ts_offset) 182 | } 183 | 184 | func (avs *Stream) NbFrames() int64 { 185 | return int64(avs.nb_frames) 186 | } 187 | 188 | func (avs *Stream) PtsBuffer() int64 { 189 | return int64(avs.pts_buffer[0]) 190 | } 191 | 192 | func (avs *Stream) PtsReorderError() int64 { 193 | return int64(avs.pts_reorder_error[0]) 194 | } 195 | 196 | func (avs *Stream) PtsWrapReference() int64 { 197 | return int64(avs.pts_wrap_reference) 198 | } 199 | 200 | // func (avs *Stream) StartSkipSamples() int64 { 201 | // return int64(avs.start_skip_samples) 202 | // } 203 | 204 | func (avs *Stream) StartTime() int64 { 205 | return int64(avs.start_time) 206 | } 207 | 208 | func (avs *Stream) Parser() *CodecParserContext { 209 | return (*CodecParserContext)(unsafe.Pointer(avs.parser)) 210 | } 211 | 212 | func (avs *Stream) LastInPacketBuffer() *AvPacketList { 213 | return (*AvPacketList)(unsafe.Pointer(avs.last_in_packet_buffer)) 214 | } 215 | 216 | // func (avs *Stream) PrivPts() *FFFrac { 217 | // return (*FFFrac)(unsafe.Pointer(avs.priv_pts)) 218 | // } 219 | 220 | func (avs *Stream) DtsMisordered() uint8 { 221 | return uint8(avs.dts_misordered) 222 | } 223 | 224 | func (avs *Stream) DtsOrdered() uint8 { 225 | return uint8(avs.dts_ordered) 226 | } 227 | 228 | func (avs *Stream) PtsReorderErrorCount() uint8 { 229 | return uint8(avs.pts_reorder_error_count[0]) 230 | } 231 | 232 | func (avs *Stream) IndexEntriesAllocatedSize() uint { 233 | return uint(avs.index_entries_allocated_size) 234 | } 235 | 236 | func (avs *Stream) Free() { 237 | C.av_freep(unsafe.Pointer(avs)) 238 | } 239 | -------------------------------------------------------------------------------- /cron/parser_test.go: -------------------------------------------------------------------------------- 1 | package cron 2 | 3 | import ( 4 | "reflect" 5 | "strings" 6 | "testing" 7 | "time" 8 | ) 9 | 10 | func TestRange(t *testing.T) { 11 | zero := uint64(0) 12 | ranges := []struct { 13 | expr string 14 | min, max uint 15 | expected uint64 16 | err string 17 | }{ 18 | {"5", 0, 7, 1 << 5, ""}, 19 | {"0", 0, 7, 1 << 0, ""}, 20 | {"7", 0, 7, 1 << 7, ""}, 21 | 22 | {"5-5", 0, 7, 1 << 5, ""}, 23 | {"5-6", 0, 7, 1<<5 | 1<<6, ""}, 24 | {"5-7", 0, 7, 1<<5 | 1<<6 | 1<<7, ""}, 25 | 26 | {"5-6/2", 0, 7, 1 << 5, ""}, 27 | {"5-7/2", 0, 7, 1<<5 | 1<<7, ""}, 28 | {"5-7/1", 0, 7, 1<<5 | 1<<6 | 1<<7, ""}, 29 | 30 | {"*", 1, 3, 1<<1 | 1<<2 | 1<<3 | starBit, ""}, 31 | {"*/2", 1, 3, 1<<1 | 1<<3 | starBit, ""}, 32 | 33 | {"5--5", 0, 0, zero, "Too many hyphens"}, 34 | {"jan-x", 0, 0, zero, "Failed to parse int from"}, 35 | {"2-x", 1, 5, zero, "Failed to parse int from"}, 36 | {"*/-12", 0, 0, zero, "Negative number"}, 37 | {"*//2", 0, 0, zero, "Too many slashes"}, 38 | {"1", 3, 5, zero, "below minimum"}, 39 | {"6", 3, 5, zero, "above maximum"}, 40 | {"5-3", 3, 5, zero, "beyond end of range"}, 41 | {"*/0", 0, 0, zero, "should be a positive number"}, 42 | } 43 | 44 | for _, c := range ranges { 45 | actual, err := getRange(c.expr, bounds{c.min, c.max, nil}) 46 | if len(c.err) != 0 && (err == nil || !strings.Contains(err.Error(), c.err)) { 47 | t.Errorf("%s => expected %v, got %v", c.expr, c.err, err) 48 | } 49 | if len(c.err) == 0 && err != nil { 50 | t.Errorf("%s => unexpected error %v", c.expr, err) 51 | } 52 | if actual != c.expected { 53 | t.Errorf("%s => expected %d, got %d", c.expr, c.expected, actual) 54 | } 55 | } 56 | } 57 | 58 | func TestField(t *testing.T) { 59 | fields := []struct { 60 | expr string 61 | min, max uint 62 | expected uint64 63 | }{ 64 | {"5", 1, 7, 1 << 5}, 65 | {"5,6", 1, 7, 1<<5 | 1<<6}, 66 | {"5,6,7", 1, 7, 1<<5 | 1<<6 | 1<<7}, 67 | {"1,5-7/2,3", 1, 7, 1<<1 | 1<<5 | 1<<7 | 1<<3}, 68 | } 69 | 70 | for _, c := range fields { 71 | actual, _ := getField(c.expr, bounds{c.min, c.max, nil}) 72 | if actual != c.expected { 73 | t.Errorf("%s => expected %d, got %d", c.expr, c.expected, actual) 74 | } 75 | } 76 | } 77 | 78 | func TestAll(t *testing.T) { 79 | allBits := []struct { 80 | r bounds 81 | expected uint64 82 | }{ 83 | {minutes, 0xfffffffffffffff}, // 0-59: 60 ones 84 | {hours, 0xffffff}, // 0-23: 24 ones 85 | {dom, 0xfffffffe}, // 1-31: 31 ones, 1 zero 86 | {months, 0x1ffe}, // 1-12: 12 ones, 1 zero 87 | {dow, 0x7f}, // 0-6: 7 ones 88 | } 89 | 90 | for _, c := range allBits { 91 | actual := all(c.r) // all() adds the starBit, so compensate for that.. 92 | if c.expected|starBit != actual { 93 | t.Errorf("%d-%d/%d => expected %b, got %b", 94 | c.r.min, c.r.max, 1, c.expected|starBit, actual) 95 | } 96 | } 97 | } 98 | 99 | func TestBits(t *testing.T) { 100 | bits := []struct { 101 | min, max, step uint 102 | expected uint64 103 | }{ 104 | {0, 0, 1, 0x1}, 105 | {1, 1, 1, 0x2}, 106 | {1, 5, 2, 0x2a}, // 101010 107 | {1, 4, 2, 0xa}, // 1010 108 | } 109 | 110 | for _, c := range bits { 111 | actual := getBits(c.min, c.max, c.step) 112 | if c.expected != actual { 113 | t.Errorf("%d-%d/%d => expected %b, got %b", 114 | c.min, c.max, c.step, c.expected, actual) 115 | } 116 | } 117 | } 118 | 119 | func TestParse(t *testing.T) { 120 | entries := []struct { 121 | expr string 122 | expected Schedule 123 | err string 124 | }{ 125 | { 126 | expr: "* 5 * * * *", 127 | expected: &SpecSchedule{ 128 | Second: all(seconds), 129 | Minute: 1 << 5, 130 | Hour: all(hours), 131 | Dom: all(dom), 132 | Month: all(months), 133 | Dow: all(dow), 134 | }, 135 | }, 136 | { 137 | expr: "* 5 j * * *", 138 | err: "Failed to parse int from", 139 | }, 140 | { 141 | expr: "@every 5m", 142 | expected: ConstantDelaySchedule{Delay: time.Duration(5) * time.Minute}, 143 | }, 144 | { 145 | expr: "@every Xm", 146 | err: "Failed to parse duration", 147 | }, 148 | { 149 | expr: "@yearly", 150 | expected: &SpecSchedule{ 151 | Second: 1 << seconds.min, 152 | Minute: 1 << minutes.min, 153 | Hour: 1 << hours.min, 154 | Dom: 1 << dom.min, 155 | Month: 1 << months.min, 156 | Dow: all(dow), 157 | }, 158 | }, 159 | { 160 | expr: "@annually", 161 | expected: &SpecSchedule{ 162 | Second: 1 << seconds.min, 163 | Minute: 1 << minutes.min, 164 | Hour: 1 << hours.min, 165 | Dom: 1 << dom.min, 166 | Month: 1 << months.min, 167 | Dow: all(dow), 168 | }, 169 | }, 170 | { 171 | expr: "@unrecognized", 172 | err: "Unrecognized descriptor", 173 | }, 174 | { 175 | expr: "* * * *", 176 | err: "Expected 5 to 6 fields", 177 | }, 178 | { 179 | expr: "", 180 | err: "Empty spec string", 181 | }, 182 | } 183 | 184 | for _, c := range entries { 185 | actual, err := Parse(c.expr) 186 | if len(c.err) != 0 && (err == nil || !strings.Contains(err.Error(), c.err)) { 187 | t.Errorf("%s => expected %v, got %v", c.expr, c.err, err) 188 | } 189 | if len(c.err) == 0 && err != nil { 190 | t.Errorf("%s => unexpected error %v", c.expr, err) 191 | } 192 | if !reflect.DeepEqual(actual, c.expected) { 193 | t.Errorf("%s => expected %b, got %b", c.expr, c.expected, actual) 194 | } 195 | } 196 | } 197 | 198 | func TestStandardSpecSchedule(t *testing.T) { 199 | entries := []struct { 200 | expr string 201 | expected Schedule 202 | err string 203 | }{ 204 | { 205 | expr: "5 * * * *", 206 | expected: &SpecSchedule{1 << seconds.min, 1 << 5, all(hours), all(dom), all(months), all(dow)}, 207 | }, 208 | { 209 | expr: "@every 5m", 210 | expected: ConstantDelaySchedule{time.Duration(5) * time.Minute}, 211 | }, 212 | { 213 | expr: "5 j * * *", 214 | err: "Failed to parse int from", 215 | }, 216 | { 217 | expr: "* * * *", 218 | err: "Expected exactly 5 fields", 219 | }, 220 | } 221 | 222 | for _, c := range entries { 223 | actual, err := ParseStandard(c.expr) 224 | if len(c.err) != 0 && (err == nil || !strings.Contains(err.Error(), c.err)) { 225 | t.Errorf("%s => expected %v, got %v", c.expr, c.err, err) 226 | } 227 | if len(c.err) == 0 && err != nil { 228 | t.Errorf("%s => unexpected error %v", c.expr, err) 229 | } 230 | if !reflect.DeepEqual(actual, c.expected) { 231 | t.Errorf("%s => expected %b, got %b", c.expr, c.expected, actual) 232 | } 233 | } 234 | } 235 | -------------------------------------------------------------------------------- /goav/example/tutorial01.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // tutorial01.c 4 | // Code based on a tutorial at http://dranger.com/ffmpeg/tutorial01.html 5 | 6 | // A small sample program that shows how to use libavformat and libavcodec to 7 | // read video from a file. 8 | // 9 | // Use 10 | // 11 | // gcc -o tutorial01 tutorial01.c -lavformat -lavcodec -lswscale -lz 12 | // 13 | // to build (assuming libavformat and libavcodec are correctly installed 14 | // your system). 15 | // 16 | // Run using 17 | // 18 | // tutorial01 myvideofile.mpg 19 | // 20 | // to write the first five frames from "myvideofile.mpg" to disk in PPM 21 | // format. 22 | import ( 23 | "fmt" 24 | "log" 25 | "os" 26 | "unsafe" 27 | 28 | "github.com/giorgisio/goav/swscale" 29 | 30 | "github.com/giorgisio/goav/avcodec" 31 | "github.com/giorgisio/goav/avformat" 32 | "github.com/giorgisio/goav/avutil" 33 | ) 34 | 35 | // SaveFrame writes a single frame to disk as a PPM file 36 | func SaveFrame(frame *avutil.Frame, width, height, frameNumber int) { 37 | // Open file 38 | fileName := fmt.Sprintf("frame%d.ppm", frameNumber) 39 | file, err := os.Create(fileName) 40 | if err != nil { 41 | log.Println("Error Reading") 42 | } 43 | defer file.Close() 44 | 45 | // Write header 46 | header := fmt.Sprintf("P6\n%d %d\n255\n", width, height) 47 | file.Write([]byte(header)) 48 | 49 | // Write pixel data 50 | for y := 0; y < height; y++ { 51 | data0 := avutil.Data(frame)[0] 52 | buf := make([]byte, width*3) 53 | startPos := uintptr(unsafe.Pointer(data0)) + uintptr(y)*uintptr(avutil.Linesize(frame)[0]) 54 | for i := 0; i < width*3; i++ { 55 | element := *(*uint8)(unsafe.Pointer(startPos + uintptr(i))) 56 | buf[i] = element 57 | } 58 | file.Write(buf) 59 | } 60 | } 61 | 62 | func main() { 63 | if len(os.Args) < 2 { 64 | fmt.Println("Please provide a movie file") 65 | os.Exit(1) 66 | } 67 | 68 | // Open video file 69 | pFormatContext := avformat.AvformatAllocContext() 70 | if avformat.AvformatOpenInput(&pFormatContext, os.Args[1], nil, nil) != 0 { 71 | fmt.Printf("Unable to open file %s\n", os.Args[1]) 72 | os.Exit(1) 73 | } 74 | 75 | // Retrieve stream information 76 | if pFormatContext.AvformatFindStreamInfo(nil) < 0 { 77 | fmt.Println("Couldn't find stream information") 78 | os.Exit(1) 79 | } 80 | 81 | // Dump information about file onto standard error 82 | pFormatContext.AvDumpFormat(0, os.Args[1], 0) 83 | 84 | // Find the first video stream 85 | for i := 0; i < int(pFormatContext.NbStreams()); i++ { 86 | switch pFormatContext.Streams()[i].CodecParameters().AvCodecGetType() { 87 | case avformat.AVMEDIA_TYPE_VIDEO: 88 | 89 | // Get a pointer to the codec context for the video stream 90 | pCodecCtxOrig := pFormatContext.Streams()[i].Codec() 91 | // Find the decoder for the video stream 92 | pCodec := avcodec.AvcodecFindDecoder(avcodec.CodecId(pCodecCtxOrig.GetCodecId())) 93 | if pCodec == nil { 94 | fmt.Println("Unsupported codec!") 95 | os.Exit(1) 96 | } 97 | // Copy context 98 | pCodecCtx := pCodec.AvcodecAllocContext3() 99 | if pCodecCtx.AvcodecCopyContext((*avcodec.Context)(unsafe.Pointer(pCodecCtxOrig))) != 0 { 100 | fmt.Println("Couldn't copy codec context") 101 | os.Exit(1) 102 | } 103 | 104 | // Open codec 105 | if pCodecCtx.AvcodecOpen2(pCodec, nil) < 0 { 106 | fmt.Println("Could not open codec") 107 | os.Exit(1) 108 | } 109 | 110 | // Allocate video frame 111 | pFrame := avutil.AvFrameAlloc() 112 | 113 | // Allocate an AVFrame structure 114 | pFrameRGB := avutil.AvFrameAlloc() 115 | if pFrameRGB == nil { 116 | fmt.Println("Unable to allocate RGB Frame") 117 | os.Exit(1) 118 | } 119 | 120 | // Determine required buffer size and allocate buffer 121 | numBytes := uintptr(avcodec.AvpictureGetSize(avcodec.AV_PIX_FMT_RGB24, pCodecCtx.Width(), 122 | pCodecCtx.Height())) 123 | buffer := avutil.AvMalloc(numBytes) 124 | 125 | // Assign appropriate parts of buffer to image planes in pFrameRGB 126 | // Note that pFrameRGB is an AVFrame, but AVFrame is a superset 127 | // of AVPicture 128 | avp := (*avcodec.Picture)(unsafe.Pointer(pFrameRGB)) 129 | avp.AvpictureFill((*uint8)(buffer), avcodec.AV_PIX_FMT_RGB24, pCodecCtx.Width(), pCodecCtx.Height()) 130 | 131 | // initialize SWS context for software scaling 132 | swsCtx := swscale.SwsGetcontext( 133 | pCodecCtx.Width(), 134 | pCodecCtx.Height(), 135 | (swscale.PixelFormat)(pCodecCtx.PixFmt()), 136 | pCodecCtx.Width(), 137 | pCodecCtx.Height(), 138 | avcodec.AV_PIX_FMT_RGB24, 139 | avcodec.SWS_BILINEAR, 140 | nil, 141 | nil, 142 | nil, 143 | ) 144 | 145 | // Read frames and save first five frames to disk 146 | frameNumber := 1 147 | packet := avcodec.AvPacketAlloc() 148 | for pFormatContext.AvReadFrame(packet) >= 0 { 149 | // Is this a packet from the video stream? 150 | if packet.StreamIndex() == i { 151 | // Decode video frame 152 | response := pCodecCtx.AvcodecSendPacket(packet) 153 | if response < 0 { 154 | fmt.Printf("Error while sending a packet to the decoder: %s\n", avutil.ErrorFromCode(response)) 155 | } 156 | for response >= 0 { 157 | response = pCodecCtx.AvcodecReceiveFrame((*avcodec.Frame)(unsafe.Pointer(pFrame))) 158 | if response == avutil.AvErrorEAGAIN || response == avutil.AvErrorEOF { 159 | break 160 | } else if response < 0 { 161 | fmt.Printf("Error while receiving a frame from the decoder: %s\n", avutil.ErrorFromCode(response)) 162 | return 163 | } 164 | 165 | if frameNumber <= 5 { 166 | // Convert the image from its native format to RGB 167 | swscale.SwsScale2(swsCtx, avutil.Data(pFrame), 168 | avutil.Linesize(pFrame), 0, pCodecCtx.Height(), 169 | avutil.Data(pFrameRGB), avutil.Linesize(pFrameRGB)) 170 | 171 | // Save the frame to disk 172 | fmt.Printf("Writing frame %d\n", frameNumber) 173 | SaveFrame(pFrameRGB, pCodecCtx.Width(), pCodecCtx.Height(), frameNumber) 174 | } else { 175 | return 176 | } 177 | frameNumber++ 178 | } 179 | } 180 | 181 | // Free the packet that was allocated by av_read_frame 182 | packet.AvFreePacket() 183 | } 184 | 185 | // Free the RGB image 186 | avutil.AvFree(buffer) 187 | avutil.AvFrameFree(pFrameRGB) 188 | 189 | // Free the YUV frame 190 | avutil.AvFrameFree(pFrame) 191 | 192 | // Close the codecs 193 | pCodecCtx.AvcodecClose() 194 | (*avcodec.Context)(unsafe.Pointer(pCodecCtxOrig)).AvcodecClose() 195 | 196 | // Close the video file 197 | pFormatContext.AvformatCloseInput() 198 | 199 | // Stop after saving frames of first video straem 200 | break 201 | 202 | default: 203 | fmt.Println("Didn't find a video stream") 204 | os.Exit(1) 205 | } 206 | } 207 | } 208 | -------------------------------------------------------------------------------- /cron/cron.go: -------------------------------------------------------------------------------- 1 | package cron 2 | 3 | import ( 4 | "log" 5 | "runtime" 6 | "sort" 7 | "time" 8 | ) 9 | 10 | // Cron keeps track of any number of entries, invoking the associated func as 11 | // specified by the schedule. It may be started, stopped, and the entries may 12 | // be inspected while running. 13 | type Cron struct { 14 | entries []*Entry 15 | stop chan struct{} 16 | add chan *Entry 17 | snapshot chan []*Entry 18 | running bool 19 | ErrorLog Logger 20 | location *time.Location 21 | } 22 | 23 | // Job is an interface for submitted cron jobs. 24 | type Job interface { 25 | Run() 26 | } 27 | 28 | // The Schedule describes a job's duty cycle. 29 | type Schedule interface { 30 | // Return the next activation time, later than the given time. 31 | // Next is invoked initially, and then each time the job is run. 32 | Next(time.Time) time.Time 33 | } 34 | 35 | // Logger is a Logger interface. 36 | type Logger interface { 37 | Printf(format string, v ...interface{}) 38 | } 39 | 40 | // Entry consists of a schedule and the func to execute on that schedule. 41 | type Entry struct { 42 | // The schedule on which this job should be run. 43 | Schedule Schedule 44 | 45 | // The next time the job will run. This is the zero time if Cron has not been 46 | // started or this entry's schedule is unsatisfiable 47 | Next time.Time 48 | 49 | // The last time this job was run. This is the zero time if the job has never 50 | // been run. 51 | Prev time.Time 52 | 53 | // The Job to run. 54 | Job Job 55 | } 56 | 57 | // byTime is a wrapper for sorting the entry array by time 58 | // (with zero time at the end). 59 | type byTime []*Entry 60 | 61 | func (s byTime) Len() int { return len(s) } 62 | func (s byTime) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 63 | func (s byTime) Less(i, j int) bool { 64 | // Two zero times should return false. 65 | // Otherwise, zero is "greater" than any other time. 66 | // (To sort it at the end of the list.) 67 | if s[i].Next.IsZero() { 68 | return false 69 | } 70 | if s[j].Next.IsZero() { 71 | return true 72 | } 73 | return s[i].Next.Before(s[j].Next) 74 | } 75 | 76 | // New returns a new Cron job runner, in the Local time zone. 77 | func New() *Cron { 78 | return NewWithLocation(time.Now().Location()) 79 | } 80 | 81 | // NewWithLocation returns a new Cron job runner. 82 | func NewWithLocation(location *time.Location) *Cron { 83 | return &Cron{ 84 | entries: nil, 85 | add: make(chan *Entry), 86 | stop: make(chan struct{}), 87 | snapshot: make(chan []*Entry), 88 | running: false, 89 | ErrorLog: nil, 90 | location: location, 91 | } 92 | } 93 | 94 | // A wrapper that turns a func() into a cron.Job 95 | type FuncJob func() 96 | 97 | func (f FuncJob) Run() { f() } 98 | 99 | // AddFunc adds a func to the Cron to be run on the given schedule. 100 | func (c *Cron) AddFunc(spec string, cmd func()) error { 101 | return c.AddJob(spec, FuncJob(cmd)) 102 | } 103 | 104 | // AddJob adds a Job to the Cron to be run on the given schedule. 105 | func (c *Cron) AddJob(spec string, cmd Job) error { 106 | schedule, err := Parse(spec) 107 | if err != nil { 108 | return err 109 | } 110 | c.Schedule(schedule, cmd) 111 | return nil 112 | } 113 | 114 | // Schedule adds a Job to the Cron to be run on the given schedule. 115 | func (c *Cron) Schedule(schedule Schedule, cmd Job) { 116 | entry := &Entry{ 117 | Schedule: schedule, 118 | Job: cmd, 119 | } 120 | if !c.running { 121 | c.entries = append(c.entries, entry) 122 | return 123 | } 124 | 125 | c.add <- entry 126 | } 127 | 128 | // Entries returns a snapshot of the cron entries. 129 | func (c *Cron) Entries() []*Entry { 130 | if c.running { 131 | c.snapshot <- nil 132 | x := <-c.snapshot 133 | return x 134 | } 135 | return c.entrySnapshot() 136 | } 137 | 138 | // Location gets the time zone location 139 | func (c *Cron) Location() *time.Location { 140 | return c.location 141 | } 142 | 143 | // Start the cron scheduler in its own go-routine, or no-op if already started. 144 | func (c *Cron) Start() { 145 | if c.running { 146 | return 147 | } 148 | c.running = true 149 | go c.run() 150 | } 151 | 152 | // Run the cron scheduler, or no-op if already running. 153 | func (c *Cron) Run() { 154 | if c.running { 155 | return 156 | } 157 | c.running = true 158 | c.run() 159 | } 160 | 161 | func (c *Cron) runWithRecovery(j Job) { 162 | defer func() { 163 | if r := recover(); r != nil { 164 | const size = 64 << 10 165 | buf := make([]byte, size) 166 | buf = buf[:runtime.Stack(buf, false)] 167 | c.logf("cron: panic running job: %v\n%s", r, buf) 168 | } 169 | }() 170 | j.Run() 171 | } 172 | 173 | // Run the scheduler. this is private just due to the need to synchronize 174 | // access to the 'running' state variable. 175 | func (c *Cron) run() { 176 | // Figure out the next activation times for each entry. 177 | now := c.now() 178 | for _, entry := range c.entries { 179 | entry.Next = entry.Schedule.Next(now) 180 | } 181 | 182 | for { 183 | // Determine the next entry to run. 184 | sort.Sort(byTime(c.entries)) 185 | 186 | var timer *time.Timer 187 | if len(c.entries) == 0 || c.entries[0].Next.IsZero() { 188 | // If there are no entries yet, just sleep - it still handles new entries 189 | // and stop requests. 190 | timer = time.NewTimer(100000 * time.Hour) 191 | } else { 192 | timer = time.NewTimer(c.entries[0].Next.Sub(now)) 193 | } 194 | 195 | for { 196 | select { 197 | case now = <-timer.C: 198 | now = now.In(c.location) 199 | // Run every entry whose next time was less than now 200 | for _, e := range c.entries { 201 | if e.Next.After(now) || e.Next.IsZero() { 202 | break 203 | } 204 | go c.runWithRecovery(e.Job) 205 | e.Prev = e.Next 206 | e.Next = e.Schedule.Next(now) 207 | } 208 | 209 | case newEntry := <-c.add: 210 | timer.Stop() 211 | now = c.now() 212 | newEntry.Next = newEntry.Schedule.Next(now) 213 | c.entries = append(c.entries, newEntry) 214 | 215 | case <-c.snapshot: 216 | c.snapshot <- c.entrySnapshot() 217 | continue 218 | 219 | case <-c.stop: 220 | timer.Stop() 221 | return 222 | } 223 | 224 | break 225 | } 226 | } 227 | } 228 | 229 | // Logs an error to stderr or to the configured error log 230 | func (c *Cron) logf(format string, args ...interface{}) { 231 | if c.ErrorLog != nil { 232 | c.ErrorLog.Printf(format, args...) 233 | } else { 234 | log.Printf(format, args...) 235 | } 236 | } 237 | 238 | // Stop stops the cron scheduler if it is running; otherwise it does nothing. 239 | func (c *Cron) Stop() { 240 | if !c.running { 241 | return 242 | } 243 | c.stop <- struct{}{} 244 | c.running = false 245 | } 246 | 247 | // entrySnapshot returns a copy of the current cron entry list. 248 | func (c *Cron) entrySnapshot() []*Entry { 249 | entries := []*Entry{} 250 | for _, e := range c.entries { 251 | entries = append(entries, &Entry{ 252 | Schedule: e.Schedule, 253 | Next: e.Next, 254 | Prev: e.Prev, 255 | Job: e.Job, 256 | }) 257 | } 258 | return entries 259 | } 260 | 261 | // now returns current time in c location 262 | func (c *Cron) now() time.Time { 263 | return time.Now().In(c.location) 264 | } 265 | -------------------------------------------------------------------------------- /goav/avformat/context_struct.go: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a MIT license that can be found in the LICENSE file. 2 | // Giorgis (habtom@giorgis.io) 3 | 4 | package avformat 5 | 6 | //#cgo pkg-config: libavformat 7 | //#include 8 | import "C" 9 | import ( 10 | "reflect" 11 | "unsafe" 12 | 13 | "github.com/giorgisio/goav/avutil" 14 | ) 15 | 16 | func (ctxt *Context) Chapters() **AvChapter { 17 | return (**AvChapter)(unsafe.Pointer(ctxt.chapters)) 18 | } 19 | 20 | func (ctxt *Context) AudioCodec() *AvCodec { 21 | return (*AvCodec)(unsafe.Pointer(ctxt.audio_codec)) 22 | } 23 | 24 | func (ctxt *Context) SubtitleCodec() *AvCodec { 25 | return (*AvCodec)(unsafe.Pointer(ctxt.subtitle_codec)) 26 | } 27 | 28 | func (ctxt *Context) VideoCodec() *AvCodec { 29 | return (*AvCodec)(unsafe.Pointer(ctxt.video_codec)) 30 | } 31 | 32 | func (ctxt *Context) Metadata() *avutil.Dictionary { 33 | return (*avutil.Dictionary)(unsafe.Pointer(ctxt.metadata)) 34 | } 35 | 36 | func (ctxt *Context) Internal() *AvFormatInternal { 37 | return (*AvFormatInternal)(unsafe.Pointer(ctxt.internal)) 38 | } 39 | 40 | func (ctxt *Context) Pb() *AvIOContext { 41 | return (*AvIOContext)(unsafe.Pointer(ctxt.pb)) 42 | } 43 | 44 | func (ctxt *Context) InterruptCallback() AvIOInterruptCB { 45 | return AvIOInterruptCB(ctxt.interrupt_callback) 46 | } 47 | 48 | func (ctxt *Context) Programs() []*AvProgram { 49 | header := reflect.SliceHeader{ 50 | Data: uintptr(unsafe.Pointer(ctxt.programs)), 51 | Len: int(ctxt.NbPrograms()), 52 | Cap: int(ctxt.NbPrograms()), 53 | } 54 | 55 | return *((*[]*AvProgram)(unsafe.Pointer(&header))) 56 | } 57 | 58 | func (ctxt *Context) Streams() []*Stream { 59 | header := reflect.SliceHeader{ 60 | Data: uintptr(unsafe.Pointer(ctxt.streams)), 61 | Len: int(ctxt.NbStreams()), 62 | Cap: int(ctxt.NbStreams()), 63 | } 64 | 65 | return *((*[]*Stream)(unsafe.Pointer(&header))) 66 | } 67 | 68 | func (ctxt *Context) Filename() string { 69 | return C.GoString((*C.char)(unsafe.Pointer(&ctxt.filename[0]))) 70 | } 71 | 72 | // func (ctxt *Context) CodecWhitelist() string { 73 | // return C.GoString(ctxt.codec_whitelist) 74 | // } 75 | 76 | // func (ctxt *Context) FormatWhitelist() string { 77 | // return C.GoString(ctxt.format_whitelist) 78 | // } 79 | 80 | func (ctxt *Context) AudioCodecId() CodecId { 81 | return CodecId(ctxt.audio_codec_id) 82 | } 83 | 84 | func (ctxt *Context) SubtitleCodecId() CodecId { 85 | return CodecId(ctxt.subtitle_codec_id) 86 | } 87 | 88 | func (ctxt *Context) VideoCodecId() CodecId { 89 | return CodecId(ctxt.video_codec_id) 90 | } 91 | 92 | func (ctxt *Context) DurationEstimationMethod() AvDurationEstimationMethod { 93 | return AvDurationEstimationMethod(ctxt.duration_estimation_method) 94 | } 95 | 96 | func (ctxt *Context) AudioPreload() int { 97 | return int(ctxt.audio_preload) 98 | } 99 | 100 | func (ctxt *Context) AvioFlags() int { 101 | return int(ctxt.avio_flags) 102 | } 103 | 104 | func (ctxt *Context) AvoidNegativeTs() int { 105 | return int(ctxt.avoid_negative_ts) 106 | } 107 | 108 | func (ctxt *Context) BitRate() int { 109 | return int(ctxt.bit_rate) 110 | } 111 | 112 | func (ctxt *Context) CtxFlags() int { 113 | return int(ctxt.ctx_flags) 114 | } 115 | 116 | func (ctxt *Context) Debug() int { 117 | return int(ctxt.debug) 118 | } 119 | 120 | func (ctxt *Context) ErrorRecognition() int { 121 | return int(ctxt.error_recognition) 122 | } 123 | 124 | func (ctxt *Context) EventFlags() int { 125 | return int(ctxt.event_flags) 126 | } 127 | 128 | func (ctxt *Context) Flags() int { 129 | return int(ctxt.flags) 130 | } 131 | 132 | func (ctxt *Context) FlushPackets() int { 133 | return int(ctxt.flush_packets) 134 | } 135 | 136 | func (ctxt *Context) FormatProbesize() int { 137 | return int(ctxt.format_probesize) 138 | } 139 | 140 | func (ctxt *Context) FpsProbeSize() int { 141 | return int(ctxt.fps_probe_size) 142 | } 143 | 144 | func (ctxt *Context) IoRepositioned() int { 145 | return int(ctxt.io_repositioned) 146 | } 147 | 148 | func (ctxt *Context) Keylen() int { 149 | return int(ctxt.keylen) 150 | } 151 | 152 | func (ctxt *Context) MaxChunkDuration() int { 153 | return int(ctxt.max_chunk_duration) 154 | } 155 | 156 | func (ctxt *Context) MaxChunkSize() int { 157 | return int(ctxt.max_chunk_size) 158 | } 159 | 160 | func (ctxt *Context) MaxDelay() int { 161 | return int(ctxt.max_delay) 162 | } 163 | 164 | func (ctxt *Context) MaxTsProbe() int { 165 | return int(ctxt.max_ts_probe) 166 | } 167 | 168 | func (ctxt *Context) MetadataHeaderPadding() int { 169 | return int(ctxt.metadata_header_padding) 170 | } 171 | 172 | func (ctxt *Context) ProbeScore() int { 173 | return int(ctxt.probe_score) 174 | } 175 | 176 | func (ctxt *Context) Seek2any() int { 177 | return int(ctxt.seek2any) 178 | } 179 | 180 | func (ctxt *Context) StrictStdCompliance() int { 181 | return int(ctxt.strict_std_compliance) 182 | } 183 | 184 | func (ctxt *Context) TsId() int { 185 | return int(ctxt.ts_id) 186 | } 187 | 188 | func (ctxt *Context) UseWallclockAsTimestamps() int { 189 | return int(ctxt.use_wallclock_as_timestamps) 190 | } 191 | 192 | func (ctxt *Context) Duration() int64 { 193 | return int64(ctxt.duration) 194 | } 195 | 196 | func (ctxt *Context) MaxAnalyzeDuration2() int64 { 197 | return int64(ctxt.max_analyze_duration) 198 | } 199 | 200 | func (ctxt *Context) MaxInterleaveDelta() int64 { 201 | return int64(ctxt.max_interleave_delta) 202 | } 203 | 204 | func (ctxt *Context) OutputTsOffset() int64 { 205 | return int64(ctxt.output_ts_offset) 206 | } 207 | 208 | func (ctxt *Context) Probesize2() int64 { 209 | return int64(ctxt.probesize) 210 | } 211 | 212 | func (ctxt *Context) SkipInitialBytes() int64 { 213 | return int64(ctxt.skip_initial_bytes) 214 | } 215 | 216 | func (ctxt *Context) StartTime() int64 { 217 | return int64(ctxt.start_time) 218 | } 219 | 220 | func (ctxt *Context) StartTimeRealtime() int64 { 221 | return int64(ctxt.start_time_realtime) 222 | } 223 | 224 | func (ctxt *Context) Iformat() *InputFormat { 225 | return (*InputFormat)(unsafe.Pointer(ctxt.iformat)) 226 | } 227 | 228 | func (ctxt *Context) Oformat() *OutputFormat { 229 | return (*OutputFormat)(unsafe.Pointer(ctxt.oformat)) 230 | } 231 | 232 | // func (ctxt *Context) DumpSeparator() uint8 { 233 | // return uint8(ctxt.dump_separator) 234 | // } 235 | 236 | func (ctxt *Context) CorrectTsOverflow() int { 237 | return int(ctxt.correct_ts_overflow) 238 | } 239 | 240 | func (ctxt *Context) MaxIndexSize() uint { 241 | return uint(ctxt.max_index_size) 242 | } 243 | 244 | func (ctxt *Context) MaxPictureBuffer() uint { 245 | return uint(ctxt.max_picture_buffer) 246 | } 247 | 248 | func (ctxt *Context) NbChapters() uint { 249 | return uint(ctxt.nb_chapters) 250 | } 251 | 252 | func (ctxt *Context) NbPrograms() uint { 253 | return uint(ctxt.nb_programs) 254 | } 255 | 256 | func (ctxt *Context) NbStreams() uint { 257 | return uint(ctxt.nb_streams) 258 | } 259 | 260 | func (ctxt *Context) PacketSize() uint { 261 | return uint(ctxt.packet_size) 262 | } 263 | 264 | func (ctxt *Context) Probesize() uint { 265 | return uint(ctxt.probesize) 266 | } 267 | 268 | func (ctxt *Context) SetPb(pb *AvIOContext) { 269 | ctxt.pb = (*C.struct_AVIOContext)(unsafe.Pointer(pb)) 270 | } 271 | 272 | func (ctxt *Context) Pb2() **AvIOContext { 273 | return (**AvIOContext)(unsafe.Pointer(&ctxt.pb)) 274 | } 275 | --------------------------------------------------------------------------------