revid: added chunkSize to audioInput and bufferSize to lex functions

The audio lexers need to know how much data they will be receiving unlike video which has a fixed buffer size.
This means that all the lex function will need to be given a buffer size since they are used as a function pointer with the same signature.
This commit is contained in:
Trek H 2019-05-05 17:56:14 +09:30
parent 09db8907a5
commit a3c7cb5616
3 changed files with 20 additions and 23 deletions

View File

@ -135,6 +135,8 @@ func handleFlags() revid.Config {
saturationPtr = flag.Int("Saturation", 0, "Set Saturation. (100-100)")
exposurePtr = flag.String("Exposure", "auto", "Set exposure mode. ("+strings.Join(revid.ExposureModes[:], ",")+")")
autoWhiteBalancePtr = flag.String("Awb", "auto", "Set automatic white balance mode. ("+strings.Join(revid.AutoWhiteBalanceModes[:], ",")+")")
// Audio specific flags.
sampleRatePtr = flag.Int("SampleRate", 48000, "Sample rate of recorded audio")
channelsPtr = flag.Int("Channels", 1, "Record in Mono or Stereo (1 or 2)")
recPeriodPtr = flag.Int("recPeriod", 5, "How many seconds to record at a time")

View File

@ -36,10 +36,6 @@ import (
"time"
)
const (
audioChunkSize = 16000
)
var noDelay = make(chan time.Time)
func init() {
@ -52,7 +48,7 @@ var h264Prefix = [...]byte{0x00, 0x00, 0x01, 0x09, 0xf0}
// successive writes being performed not earlier than the specified delay.
// NAL units are split after type 1 (Coded slice of a non-IDR picture), 5
// (Coded slice of a IDR picture) and 8 (Picture parameter set).
func H264(dst io.Writer, src io.Reader, delay time.Duration) error {
func H264(dst io.Writer, src io.Reader, delay time.Duration, bufSize int) error {
var tick <-chan time.Time
if delay == 0 {
tick = noDelay
@ -62,7 +58,7 @@ func H264(dst io.Writer, src io.Reader, delay time.Duration) error {
tick = ticker.C
}
const bufSize = 8 << 10
bufSize = 8 << 10 //TODO(Trek): Pass this in rather than set it in here.
c := newScanner(src, make([]byte, 4<<10)) // Standard file buffer size.
@ -207,7 +203,7 @@ func (c *scanner) reload() error {
// MJPEG parses MJPEG frames read from src into separate writes to dst with
// successive writes being performed not earlier than the specified delay.
func MJPEG(dst io.Writer, src io.Reader, delay time.Duration) error {
func MJPEG(dst io.Writer, src io.Reader, delay time.Duration, bufSize int) error {
var tick <-chan time.Time
if delay == 0 {
tick = noDelay
@ -252,7 +248,7 @@ 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, bufSize int) error {
var tick <-chan time.Time
if delay == 0 {
tick = noDelay
@ -263,7 +259,7 @@ func PCM(dst io.Writer, src io.Reader, delay time.Duration) error {
}
for {
buf := make([]byte, 0, audioChunkSize)
buf := make([]byte, 0, bufSize)
_, err := src.Read(buf)
if err != nil {
return err
@ -281,7 +277,7 @@ func PCM(dst io.Writer, src io.Reader, delay time.Duration) error {
// 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)
func ADPCM(dst io.Writer, src io.Reader, delay time.Duration, bufSize int) error {
err := PCM(dst, src, delay, bufSize)
return err
}

View File

@ -103,7 +103,7 @@ type Revid struct {
cmd *exec.Cmd
// lexTo, encoder and packer handle transcoding the input stream.
lexTo func(dest io.Writer, src io.Reader, delay time.Duration) error
lexTo func(dest io.Writer, src io.Reader, delay time.Duration, bufSize int) error
// buffer handles passing frames from the transcoder
// to the target destination.
@ -620,7 +620,7 @@ func (r *Revid) startRaspivid() error {
}
r.wg.Add(1)
go r.processFrom(stdout, 0)
go r.processFrom(stdout, 0, 0)
return nil
}
@ -662,7 +662,7 @@ func (r *Revid) startV4L() error {
}
r.wg.Add(1)
go r.processFrom(stdout, time.Duration(0))
go r.processFrom(stdout, time.Duration(0), 0)
return nil
}
@ -678,21 +678,20 @@ func (r *Revid) setupInputForFile() error {
// TODO(kortschak): Maybe we want a context.Context-aware parser that we can stop.
r.wg.Add(1)
go r.processFrom(f, time.Second/time.Duration(r.config.FrameRate))
go r.processFrom(f, time.Second/time.Duration(r.config.FrameRate), 0)
return nil
}
// startAudioInput is used to start capturing audio from an audio device and processing it.
func (r *Revid) startAudioInput() error {
ai := NewAudioInput(&r.config)
go r.processFrom(ai, time.Second/time.Duration(r.config.WriteRate))
go r.processFrom(ai, time.Second/time.Duration(r.config.WriteRate), ai.ChunkSize())
return nil
}
func (r *Revid) processFrom(read io.Reader, delay time.Duration) {
func (r *Revid) processFrom(read io.Reader, delay time.Duration, bufSize int) {
r.config.Logger.Log(logger.Info, pkg+"reading input data")
r.err <- r.lexTo(r.buffer, read, delay)
r.err <- r.lexTo(r.buffer, read, delay, bufSize)
r.config.Logger.Log(logger.Info, pkg+"finished reading input data")
r.wg.Done()
}