예제 #1
0
파일: main.go 프로젝트: ziutek/dvb
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))
	}
}
예제 #2
0
파일: main.go 프로젝트: ziutek/dvb
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)
	}
}