revid: added PCM and ADPCM codecs

This commit is contained in:
Trek H 2019-04-23 16:20:47 +09:30
parent a60c65a6cf
commit 20c9e6c409
5 changed files with 27 additions and 5 deletions

View File

@ -108,7 +108,7 @@ func handleFlags() revid.Config {
cpuprofile = flag.String("cpuprofile", "", "write cpu profile to `file`") cpuprofile = flag.String("cpuprofile", "", "write cpu profile to `file`")
inputPtr = flag.String("Input", "", "The input type: Raspivid, File, v4l, Audio") 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") rtmpMethodPtr = flag.String("RtmpMethod", "", "The method used to send over rtmp: Ffmpeg, Librtmp")
quantizePtr = flag.Bool("Quantize", false, "Quantize input (non-variable bitrate)") quantizePtr = flag.Bool("Quantize", false, "Quantize input (non-variable bitrate)")
verbosityPtr = flag.String("Verbosity", "Info", "Verbosity: Debug, Info, Warning, Error, Fatal") verbosityPtr = flag.String("Verbosity", "Info", "Verbosity: Debug, Info, Warning, Error, Fatal")
@ -194,12 +194,16 @@ func handleFlags() revid.Config {
case "Audio": case "Audio":
cfg.Rate = float64(*sampleRatePtr*sampleSize) / float64(blockSize) cfg.Rate = float64(*sampleRatePtr*sampleSize) / float64(blockSize)
default: default:
cfg.Rate = *frameRatePtr cfg.Rate = float64(*frameRatePtr)
} }
switch *inputCodecPtr { switch *inputCodecPtr {
case "H264": case "H264":
cfg.InputCodec = revid.H264 cfg.InputCodec = revid.H264
case "PCM":
cfg.InputCodec = revid.PCM
case "ADPCM":
cfg.InputCodec = revid.ADPCM
case "": case "":
default: default:
log.Log(logger.Error, pkg+"bad input codec argument") log.Log(logger.Error, pkg+"bad input codec argument")

View File

@ -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 { func PCM(dst io.Writer, src io.Reader, delay time.Duration) error {
var tick <-chan time.Time var tick <-chan time.Time
if delay == 0 { 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
}

View File

@ -202,7 +202,7 @@ func (e *Encoder) TimeBasedPsi(b bool, sendCount int) {
e.pktCount = e.psiSendCount 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. // then sending it to the encoder's io.Writer destination.
func (e *Encoder) Write(data []byte) (int, error) { func (e *Encoder) Write(data []byte) (int, error) {
if len(data) > pes.MaxPesSize { if len(data) > pes.MaxPesSize {

View File

@ -119,6 +119,8 @@ const (
Http Http
H264 H264
Mjpeg Mjpeg
PCM
ADPCM
None None
Mpegts Mpegts
Ffmpeg Ffmpeg

View File

@ -263,6 +263,12 @@ func (r *Revid) setupPipeline(mtsEnc, flvEnc func(dst io.Writer, rate int) (io.W
case Mjpeg: case Mjpeg:
r.config.Logger.Log(logger.Info, pkg+"using MJPEG lexer") r.config.Logger.Log(logger.Info, pkg+"using MJPEG lexer")
r.lexTo = lex.MJPEG 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 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. // startAudioInput is used to start capturing audio from an audio device and processing it.
func (r *Revid) startAudioInput() error { func (r *Revid) startAudioInput() error {
ai := NewAudioInput(audioParams)
ai := NewAudioInput()
go r.processFrom(ai, time.Second/time.Duration(r.config.Rate)) go r.processFrom(ai, time.Second/time.Duration(r.config.Rate))
return nil return nil