From 236d2c5f4819bdc06871fe882539b8b28e76d71e Mon Sep 17 00:00:00 2001 From: Trek H Date: Tue, 22 Dec 2020 12:51:20 +1030 Subject: [PATCH] pes/codecutils: move SID functionality to pes from codecutils, add PCM and ADPCM encoding options --- container/mts/encoder.go | 13 +++-------- container/mts/encoder_test.go | 2 +- container/mts/mpegts_test.go | 4 ++-- container/mts/options.go | 22 ++++++++++++------- container/mts/payload_test.go | 3 ++- .../mts/pes}/helpers.go | 4 ++-- revid/pipeline.go | 19 ++++++++++++---- 7 files changed, 39 insertions(+), 28 deletions(-) rename {codec/codecutil => container/mts/pes}/helpers.go (92%) diff --git a/container/mts/encoder.go b/container/mts/encoder.go index b0ce5035..3eef00d0 100644 --- a/container/mts/encoder.go +++ b/container/mts/encoder.go @@ -39,14 +39,6 @@ import ( "bitbucket.org/ausocean/utils/realtime" ) -// Stream IDs as per ITU-T Rec. H.222.0 / ISO/IEC 13818-1 [1], tables 2-22 and 2-34. -const ( - streamIDH264 = 27 - streamIDH265 = 36 - streamIDMJPEG = 28 - streamIDAudio = 0xc0 // ADPCM audio stream ID. -) - // These three constants are used to select between the three different // methods of when the PSI is sent. const ( @@ -60,7 +52,8 @@ const ( EncodeH264 = iota EncodeH265 EncodeMJPEG - EncodeAudio + EncodePCM + EncodeADPCM ) // The program IDs we assign to different types of media. @@ -102,7 +95,7 @@ const ( const ( defaultRate = 25 // FPS defaultPSIMethod = psiMethodNAL - defaultStreamID = streamIDH264 + defaultStreamID = pes.H264SID defaultMediaPID = PIDVideo ) diff --git a/container/mts/encoder_test.go b/container/mts/encoder_test.go index 3c9c5dd5..f3bd1cc0 100644 --- a/container/mts/encoder_test.go +++ b/container/mts/encoder_test.go @@ -191,7 +191,7 @@ func TestEncodePcm(t *testing.T) { sampleSize := 2 blockSize := 16000 writeFreq := float64(sampleRate*sampleSize) / float64(blockSize) - e, err := NewEncoder(nopCloser{&buf}, (*testLogger)(t), PacketBasedPSI(10), Rate(writeFreq), MediaType(EncodeAudio)) + e, err := NewEncoder(nopCloser{&buf}, (*testLogger)(t), PacketBasedPSI(10), Rate(writeFreq), MediaType(EncodePCM)) if err != nil { t.Fatalf("could not create MTS encoder, failed with error: %v", err) } diff --git a/container/mts/mpegts_test.go b/container/mts/mpegts_test.go index e31106ce..e1249aae 100644 --- a/container/mts/mpegts_test.go +++ b/container/mts/mpegts_test.go @@ -134,7 +134,7 @@ func writePSI(b *bytes.Buffer) error { func writeFrame(b *bytes.Buffer, frame []byte, pts uint64) error { // Prepare PES data. pesPkt := pes.Packet{ - StreamID: streamIDH264, + StreamID: pes.H264SID, PDI: hasPTS, PTS: pts, Data: frame, @@ -210,7 +210,7 @@ func TestGetPTSRange2(t *testing.T) { clip.Reset() for j := 0; j < nPackets; j++ { pesPkt := pes.Packet{ - StreamID: streamIDH264, + StreamID: pes.H264SID, PDI: hasPTS, PTS: test.pts[j], Data: []byte{}, diff --git a/container/mts/options.go b/container/mts/options.go index 0d46692f..599e324c 100644 --- a/container/mts/options.go +++ b/container/mts/options.go @@ -29,6 +29,8 @@ package mts import ( "errors" "time" + + "bitbucket.org/ausocean/av/container/mts/pes" ) var ( @@ -65,26 +67,30 @@ func TimeBasedPSI(dur time.Duration) func(*Encoder) error { // MediaType is an option that can be passed to NewEncoder. It is used to // specifiy the media type/codec of the data we are packetising using the -// encoder. Currently supported options are EncodeH264, EncodeH265, EncodeMJPEG -// and EncodeAudio. +// encoder. Currently supported options are EncodeH264, EncodeH265, EncodeMJPEG, EncodePCM +// and EncodeADPCM. func MediaType(mt int) func(*Encoder) error { return func(e *Encoder) error { switch mt { - case EncodeAudio: + case EncodePCM: e.mediaPID = PIDAudio - e.streamID = streamIDAudio - e.log.Debug("configured for audio packetisation") + e.streamID = pes.PCMSID + e.log.Debug("configured for PCM packetisation") + case EncodeADPCM: + e.mediaPID = PIDAudio + e.streamID = pes.ADPCMSID + e.log.Debug("configured for ADPCM packetisation") case EncodeH265: e.mediaPID = PIDVideo - e.streamID = streamIDH265 + e.streamID = pes.H265SID e.log.Debug("configured for h.265 packetisation") case EncodeH264: e.mediaPID = PIDVideo - e.streamID = streamIDH264 + e.streamID = pes.H264SID e.log.Debug("configured for h.264 packetisation") case EncodeMJPEG: e.mediaPID = PIDVideo - e.streamID = streamIDMJPEG + e.streamID = pes.MJPEGSID e.log.Debug("configured for MJPEG packetisation") default: return ErrUnsupportedMedia diff --git a/container/mts/payload_test.go b/container/mts/payload_test.go index d3974a99..f940c68f 100644 --- a/container/mts/payload_test.go +++ b/container/mts/payload_test.go @@ -36,6 +36,7 @@ import ( "time" "bitbucket.org/ausocean/av/container/mts/meta" + "bitbucket.org/ausocean/av/container/mts/pes" "bitbucket.org/ausocean/av/container/mts/psi" ) @@ -94,7 +95,7 @@ func TestExtract(t *testing.T) { want.frames = append(want.frames, Frame{ Media: frame, PTS: nextPTS, - ID: streamIDH264, + ID: pes.H264SID, Meta: metaMap, }) } diff --git a/codec/codecutil/helpers.go b/container/mts/pes/helpers.go similarity index 92% rename from codec/codecutil/helpers.go rename to container/mts/pes/helpers.go index d17fca2d..e41a4ab7 100644 --- a/codec/codecutil/helpers.go +++ b/container/mts/pes/helpers.go @@ -22,11 +22,11 @@ LICENSE in gpl.txt. If not, see http://www.gnu.org/licenses. */ -package codecutil +package pes import "errors" -// Stream types +// Stream types AKA stream IDs as per ITU-T Rec. H.222.0 / ISO/IEC 13818-1 [1], tables 2-22 and 2-34. const ( H264SID = 27 H265SID = 36 diff --git a/revid/pipeline.go b/revid/pipeline.go index e5c69758..f55ac02c 100644 --- a/revid/pipeline.go +++ b/revid/pipeline.go @@ -95,14 +95,25 @@ func (r *Revid) reset(c config.Config) error { encOptions = append(encOptions, mts.TimeBasedPSI(time.Duration(r.cfg.PSITime)*time.Second)) r.cfg.CBR = true case codecutil.PCM, codecutil.ADPCM: - return nil, errors.New(fmt.Sprintf("invalid input codec: %v for input: %v", r.cfg.InputCodec, r.cfg.Input)) + return nil, fmt.Errorf("invalid input codec: %v for input: %v", r.cfg.InputCodec, r.cfg.Input) default: panic("unknown input codec") } case config.InputAudio: - st = mts.EncodeAudio - encOptions = append(encOptions, mts.TimeBasedPSI(time.Duration(r.cfg.PSITime)*time.Second)) - rate = 1 / r.cfg.RecPeriod + switch r.cfg.InputCodec { + case codecutil.PCM: + st = mts.EncodePCM + encOptions = append(encOptions, mts.TimeBasedPSI(time.Duration(r.cfg.PSITime)*time.Second)) + rate = 1 / r.cfg.RecPeriod + case codecutil.ADPCM: + st = mts.EncodeADPCM + encOptions = append(encOptions, mts.TimeBasedPSI(time.Duration(r.cfg.PSITime)*time.Second)) + rate = 1 / r.cfg.RecPeriod + case codecutil.H264, codecutil.H265, codecutil.MJPEG: + return nil, fmt.Errorf("invalid input codec: %v for input: %v", r.cfg.InputCodec, r.cfg.Input) + default: + panic("unknown input codec") + } default: panic("unknown input type") }