func main() { src := flag.String( "src", "rf", "source: rf, udp, mcast", ) laddr := flag.String( "laddr", "0.0.0.0:1234", "listen IP address and port or multicast GROUP:PORT@INTERFACE", ) fpath := flag.String( "front", "/dev/dvb/adapter0/frontend0", "path to the frontend device", ) dmxpath := flag.String( "demux", "/dev/dvb/adapter0/demux0", "path to the demux device", ) dvrpath := flag.String( "dvr", "", "path to the dvr device (defaul use demux to read packets)", ) sys := flag.String( "sys", "t", "delivery system type: t, s, s2, ca, cb, cc", ) freq := flag.Float64( "freq", 0, "frequency [Mhz]", ) sr := flag.Uint( "sr", 0, "symbol rate [kBd]", ) pol := flag.String( "pol", "h", "polarization: h, v", ) count := flag.Uint64( "count", 0, "number of MPEG-TS packets to process (default 0 means infinity)", ) bw := flag.Uint( "bw", 0, "bandwidth [MHz] (default 0 means automatic)", ) out := flag.String( "out", "", "output to the specified file or UDP address and port (default read and discard all packets)", ) flag.Usage = usage flag.Parse() if flag.NArg() == 0 { usage() } pids := make([]int16, flag.NArg()) for i, a := range flag.Args() { pid, err := strconv.ParseInt(a, 0, 64) checkErr(err) if uint64(pid) > 8192 { die(a + " isn't in valid PID range [0, 8192]") } pids[i] = int16(pid) } var w ts.PktWriter switch { case *out == "": w = outputDiscard{} case strings.IndexByte(*out, ':') != -1: w = newOutputUDP("", *out) default: w = newOutputFile(*out) } var ( r ts.PktReader err error ) switch *src { case "rf": fe, err = internal.Tune(*fpath, *sys, *pol, int64(*freq*1e6), int(*bw*1e6), *sr*1e3) checkErr(err) checkErr(internal.WaitForTune(fe, time.Now().Add(5*time.Second), true)) r, filter = setFilter(*dmxpath, *dvrpath, pids) case "udp": r, err = internal.ListenUDP(*laddr, pids...) checkErr(err) case "mcast": r, err = internal.ListenMulticastUDP(*laddr, pids...) checkErr(err) default: die("Unknown source: " + *src) } pkt := new(ts.ArrayPkt) if *count == 0 { for { checkErr(r.ReadPkt(pkt)) checkErr(w.WritePkt(pkt)) } } for n := *count; n != 0; n-- { checkErr(r.ReadPkt(pkt)) checkErr(w.WritePkt(pkt)) } }
func main() { fpath := flag.String( "front", "/dev/dvb/adapter0/frontend0", "path to the frontend device", ) dmxpath := flag.String( "demux", "/dev/dvb/adapter0/demux0", "path to the demux device", ) sys := flag.String( "sys", "t", "delivery system type: t, s, s2, ca, cb, cc", ) freq := flag.Float64( "freq", 0, "frequency [Mhz]", ) sr := flag.Uint( "sr", 0, "symbol rate [kBd]", ) pol := flag.String( "pol", "h", "polarization: h, v", ) bw := flag.Uint( "bw", 0, "bandwidth [MHz] (default 0 means automatic - not supported by many tuners)", ) flag.Usage = usage flag.Parse() if flag.NArg() == 0 { usage() } pids := make([]int16, flag.NArg()) for i, a := range flag.Args() { pid, err := strconv.ParseInt(a, 0, 64) checkErr(err) if uint64(pid) > 8192 { die(a + " isn't in valid PID range [0, 8192]") } pids[i] = int16(pid) } fe, err := internal.Tune(*fpath, *sys, *pol, int64(*freq*1e6), int(*bw*1e6), *sr*1e3) checkErr(err) checkErr(internal.WaitForTune(fe, time.Now().Add(15*time.Second), true)) filterParam := demux.StreamFilterParam{ Pid: pids[0], In: demux.InFrontend, Out: demux.OutTSTap, Type: demux.Other, } filter, err = demux.Device(*dmxpath).NewStreamFilter(&filterParam) for _, pid := range pids[1:] { checkErr(filter.AddPid(pid)) } checkErr(err) checkErr(filter.Start()) var rssi, snr, ber, ublk string for { fe3 := frontend.API3{fe} if rssi != "-" { val, err := fe3.SignalStrength() if err != nil { if e, ok := err.(frontend.Error); ok && e.What == "rssi" { rssi = "-" } else { die(err.Error()) } } else { rssi = strconv.FormatInt(int64(val), 10) } } if snr != "-" { val, err := fe3.SNR() if err != nil { if e, ok := err.(frontend.Error); ok && e.What == "snr" { snr = "-" } else { die(err.Error()) } } else { snr = strconv.FormatInt(int64(val), 10) } } if ber != "-" { val, err := fe3.BER() if err != nil { if e, ok := err.(frontend.Error); ok && e.What == "ber" { ber = "-" } else { die(err.Error()) } } else { ber = strconv.FormatInt(int64(val), 10) } } if ublk != "-" { val, err := fe3.UncorrectedBlocks() if err != nil { if e, ok := err.(frontend.Error); ok && e.What == "uncorrected_blocks" { ublk = "-" } else { die(err.Error()) } } else { ublk = strconv.FormatUint(uint64(val), 10) } } log.Printf("API3 RSSI: %s SNR: %s BER: %s UBLK: %s", rssi, snr, ber, ublk) s, err := fe.Stat() checkErr(err) log.Printf( "API5 Sig: %v CNR: %v PreIFEC: %v/%v bit/bit PostIFEC: %v/%v bit/bit PostOFEC %v/%v blk/blk\n", s.Signal, s.CNR, s.PreErrBit, s.PreTotBit, s.PostErrBit, s.PostTotBit, s.ErrBlk, s.TotBlk) time.Sleep(2 * time.Second) } }