From 20c9e6c409473e109562ebfb77e8377b0c69f377 Mon Sep 17 00:00:00 2001 From: Trek H Date: Tue, 23 Apr 2019 16:20:47 +0930 Subject: [PATCH] revid: added PCM and ADPCM codecs --- cmd/revid-cli/main.go | 8 ++++++-- codec/lex/lex.go | 11 +++++++++++ container/mts/encoder.go | 2 +- revid/config.go | 2 ++ revid/revid.go | 9 +++++++-- 5 files changed, 27 insertions(+), 5 deletions(-) diff --git a/cmd/revid-cli/main.go b/cmd/revid-cli/main.go index 67b495b2..2a863680 100644 --- a/cmd/revid-cli/main.go +++ b/cmd/revid-cli/main.go @@ -108,7 +108,7 @@ func handleFlags() revid.Config { cpuprofile = flag.String("cpuprofile", "", "write cpu profile to `file`") inputPtr = flag.String("Input", "", "The input type: Raspivid, File, v4l, Audio") - inputCodecPtr = flag.String("InputCodec", "", "The codec of the input: H264, Mjpeg") + inputCodecPtr = flag.String("InputCodec", "", "The codec of the input: H264, Mjpeg, PCM, ADPCM") rtmpMethodPtr = flag.String("RtmpMethod", "", "The method used to send over rtmp: Ffmpeg, Librtmp") quantizePtr = flag.Bool("Quantize", false, "Quantize input (non-variable bitrate)") verbosityPtr = flag.String("Verbosity", "Info", "Verbosity: Debug, Info, Warning, Error, Fatal") @@ -194,12 +194,16 @@ func handleFlags() revid.Config { case "Audio": cfg.Rate = float64(*sampleRatePtr*sampleSize) / float64(blockSize) default: - cfg.Rate = *frameRatePtr + cfg.Rate = float64(*frameRatePtr) } switch *inputCodecPtr { case "H264": cfg.InputCodec = revid.H264 + case "PCM": + cfg.InputCodec = revid.PCM + case "ADPCM": + cfg.InputCodec = revid.ADPCM case "": default: log.Log(logger.Error, pkg+"bad input codec argument") diff --git a/codec/lex/lex.go b/codec/lex/lex.go index a3d05df5..ff1d4e4d 100644 --- a/codec/lex/lex.go +++ b/codec/lex/lex.go @@ -250,6 +250,8 @@ func MJPEG(dst io.Writer, src io.Reader, delay time.Duration) error { } } +// PCM reads from the given source and breaks the PCM into chunks that +// are an appropriate size for mts and pes packets. func PCM(dst io.Writer, src io.Reader, delay time.Duration) error { var tick <-chan time.Time if delay == 0 { @@ -274,3 +276,12 @@ func PCM(dst io.Writer, src io.Reader, delay time.Duration) error { } } } + +// ADPCM reads from the given source and breaks the ADPCM into chunks that +// are an appropriate size for mts and pes packets. +// Since PCM and ADPCM are not any different when it comes to how they are +// transmitted, ADPCM is just a wrapper for PCM. +func ADPCM(dst io.Writer, src io.Reader, delay time.Duration) error { + err := PCM(dst, src, delay) + return err +} diff --git a/container/mts/encoder.go b/container/mts/encoder.go index e72cfebf..2d7ce656 100644 --- a/container/mts/encoder.go +++ b/container/mts/encoder.go @@ -202,7 +202,7 @@ func (e *Encoder) TimeBasedPsi(b bool, sendCount int) { e.pktCount = e.psiSendCount } -// Write implements io.Writer. Write takes raw h264 and encodes into mpegts, +// Write implements io.Writer. Write takes raw video or audio data and encodes into mpegts, // then sending it to the encoder's io.Writer destination. func (e *Encoder) Write(data []byte) (int, error) { if len(data) > pes.MaxPesSize { diff --git a/revid/config.go b/revid/config.go index 75fc0e5d..ceeec5e8 100644 --- a/revid/config.go +++ b/revid/config.go @@ -119,6 +119,8 @@ const ( Http H264 Mjpeg + PCM + ADPCM None Mpegts Ffmpeg diff --git a/revid/revid.go b/revid/revid.go index 75424779..75be7ca4 100644 --- a/revid/revid.go +++ b/revid/revid.go @@ -263,6 +263,12 @@ func (r *Revid) setupPipeline(mtsEnc, flvEnc func(dst io.Writer, rate int) (io.W case Mjpeg: r.config.Logger.Log(logger.Info, pkg+"using MJPEG lexer") r.lexTo = lex.MJPEG + case PCM: + r.config.Logger.Log(logger.Info, pkg+"using PCM lexer") + r.lexTo = lex.PCM + case ADPCM: + r.config.Logger.Log(logger.Info, pkg+"using ADPCM lexer") + r.lexTo = lex.ADPCM } return nil } @@ -670,8 +676,7 @@ func (r *Revid) setupInputForFile() error { // startAudioInput is used to start capturing audio from an audio device and processing it. func (r *Revid) startAudioInput() error { - - ai := NewAudioInput() + ai := NewAudioInput(audioParams) go r.processFrom(ai, time.Second/time.Duration(r.config.Rate)) return nil