revid: fixed rtpPort and rtcpPort parsing and added H264 and H265 IDs

Added H264ID and H265ID consts and added logic to select this const for use in encoder based on mediaType param in NewEncoder. Also now
declaring PMT in NewEncoder so that we can set streamID correctly based on mediaType.
This commit is contained in:
Saxon 2019-05-16 13:57:10 +09:30
parent bd56e936a4
commit 548b7caa81
6 changed files with 54 additions and 40 deletions

View File

@ -55,30 +55,6 @@ var (
}, },
}, },
} }
// standardPmt is a minimal PMT, without descriptors for time and location.
standardPmt = psi.PSI{
Pf: 0x00,
Tid: 0x02,
Ssi: true,
Sl: 0x12,
Tss: &psi.TSS{
Tide: 0x01,
V: 0,
Cni: true,
Sn: 0,
Lsn: 0,
Sd: &psi.PMT{
Pcrpid: 0x0100,
Pil: 0,
Essd: &psi.ESSD{
St: 0x1b,
Epid: 0x0100,
Esil: 0x00,
},
},
},
}
) )
const ( const (
@ -94,7 +70,7 @@ var Meta *meta.Data
var ( var (
patTable = standardPat.Bytes() patTable = standardPat.Bytes()
pmtTable = standardPmt.Bytes() pmtTable []byte
) )
const ( const (
@ -103,14 +79,16 @@ const (
pmtPid = 4096 pmtPid = 4096
videoPid = 256 videoPid = 256
audioPid = 210 audioPid = 210
videoStreamID = 0xe0 // First video stream ID. H264ID = 27
H265ID = 36
audioStreamID = 0xc0 // First audio stream ID. audioStreamID = 0xc0 // First audio stream ID.
) )
// Video and Audio constants are used to communicate which media type will be encoded when creating a // Video and Audio constants are used to communicate which media type will be encoded when creating a
// new encoder with NewEncoder. // new encoder with NewEncoder.
const ( const (
Video = iota H264 = iota
H265
Audio Audio
) )
@ -158,11 +136,38 @@ func NewEncoder(dst io.WriteCloser, rate float64, mediaType int) *Encoder {
case Audio: case Audio:
mPid = audioPid mPid = audioPid
sid = audioStreamID sid = audioStreamID
case Video: case H265:
mPid = videoPid mPid = videoPid
sid = videoStreamID sid = H264ID
case H264:
mPid = videoPid
sid = H265ID
} }
// standardPmt is a minimal PMT, without descriptors for time and location.
pmtTable = (&psi.PSI{
Pf: 0x00,
Tid: 0x02,
Ssi: true,
Sl: 0x12,
Tss: &psi.TSS{
Tide: 0x01,
V: 0,
Cni: true,
Sn: 0,
Lsn: 0,
Sd: &psi.PMT{
Pcrpid: 0x0100,
Pil: 0,
Essd: &psi.ESSD{
St: byte(sid),
Epid: 0x0100,
Esil: 0x00,
},
},
},
}).Bytes()
return &Encoder{ return &Encoder{
dst: dst, dst: dst,
@ -219,7 +224,7 @@ func (e *Encoder) Write(data []byte) (int, error) {
// Prepare PES data. // Prepare PES data.
pesPkt := pes.Packet{ pesPkt := pes.Packet{
StreamID: e.streamID, StreamID: byte(36),
PDI: hasPTS, PDI: hasPTS,
PTS: e.pts(), PTS: e.pts(),
Data: data, Data: data,

View File

@ -99,7 +99,7 @@ func TestEncodeVideo(t *testing.T) {
// Create the dst and write the test data to encoder. // Create the dst and write the test data to encoder.
dst := &destination{} dst := &destination{}
_, err := NewEncoder(nopCloser{dst}, 25, Video).Write(data) _, err := NewEncoder(nopCloser{dst}, 25, H264).Write(data)
if err != nil { if err != nil {
t.Fatalf("could not write data to encoder, failed with err: %v\n", err) t.Fatalf("could not write data to encoder, failed with err: %v\n", err)
} }

View File

@ -48,7 +48,7 @@ const fps = 25
func TestMetaEncode1(t *testing.T) { func TestMetaEncode1(t *testing.T) {
Meta = meta.New() Meta = meta.New()
var buf bytes.Buffer var buf bytes.Buffer
e := NewEncoder(nopCloser{&buf}, fps, Video) e := NewEncoder(nopCloser{&buf}, fps, H264)
Meta.Add("ts", "12345678") Meta.Add("ts", "12345678")
if err := e.writePSI(); err != nil { if err := e.writePSI(); err != nil {
t.Errorf(errUnexpectedErr, err.Error()) t.Errorf(errUnexpectedErr, err.Error())
@ -76,7 +76,7 @@ func TestMetaEncode1(t *testing.T) {
func TestMetaEncode2(t *testing.T) { func TestMetaEncode2(t *testing.T) {
Meta = meta.New() Meta = meta.New()
var buf bytes.Buffer var buf bytes.Buffer
e := NewEncoder(nopCloser{&buf}, fps, Video) e := NewEncoder(nopCloser{&buf}, fps, H264)
Meta.Add("ts", "12345678") Meta.Add("ts", "12345678")
Meta.Add("loc", "1234,4321,1234") Meta.Add("loc", "1234,4321,1234")
if err := e.writePSI(); err != nil { if err := e.writePSI(); err != nil {

View File

@ -126,7 +126,7 @@ func writePSI(b *bytes.Buffer) error {
func writeFrame(b *bytes.Buffer, frame []byte, pts uint64) error { func writeFrame(b *bytes.Buffer, frame []byte, pts uint64) error {
// Prepare PES data. // Prepare PES data.
pesPkt := pes.Packet{ pesPkt := pes.Packet{
StreamID: videoStreamID, StreamID: H264ID,
PDI: hasPTS, PDI: hasPTS,
PTS: pts, PTS: pts,
Data: frame, Data: frame,

View File

@ -166,7 +166,14 @@ func (r *Revid) reset(config Config) error {
err = r.setupPipeline( err = r.setupPipeline(
func(dst io.WriteCloser, fps int) (io.WriteCloser, error) { func(dst io.WriteCloser, fps int) (io.WriteCloser, error) {
e := mts.NewEncoder(dst, float64(fps), mts.Video) var st int
switch r.config.Input {
case Raspivid, File, V4L:
st = mts.H264
case RTSPCamera:
st = mts.H265
}
e := mts.NewEncoder(dst, float64(fps), st)
return e, nil return e, nil
}, },
func(dst io.WriteCloser, fps int) (io.WriteCloser, error) { func(dst io.WriteCloser, fps int) (io.WriteCloser, error) {
@ -607,6 +614,7 @@ func (r *Revid) setupInputForFile() (func() error, error) {
func (r *Revid) startRTSPCamera() (func() error, error) { func (r *Revid) startRTSPCamera() (func() error, error) {
rtspClt, err := rtsp.NewClient(r.config.RTSPURL) rtspClt, err := rtsp.NewClient(r.config.RTSPURL)
fmt.Printf("RTSPURL: %v\n", r.config.RTSPURL)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -623,12 +631,12 @@ func (r *Revid) startRTSPCamera() (func() error, error) {
} }
r.config.Logger.Log(logger.Info, pkg+"RTSP server DESCRIBE response", "response", resp.String()) r.config.Logger.Log(logger.Info, pkg+"RTSP server DESCRIBE response", "response", resp.String())
rtpPort, err := strconv.Atoi(strings.Split(r.config.RTPRecvAddr, ":")[0]) rtpPort, err := strconv.Atoi(strings.Split(r.config.RTPRecvAddr, ":")[1])
if err != nil { if err != nil {
return nil, err return nil, err
} }
rtcpPort, err := strconv.Atoi(strings.Split(r.config.RTCPAddr, ":")[0]) rtcpPort, err := strconv.Atoi(strings.Split(r.config.RTCPAddr, ":")[1])
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -644,6 +652,7 @@ func (r *Revid) startRTSPCamera() (func() error, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
r.config.Logger.Log(logger.Info, pkg+"RTSP server PLAY response", "response", resp.String())
// TODO(saxon): use rtcp client to maintain rtp stream. // TODO(saxon): use rtcp client to maintain rtp stream.

View File

@ -134,7 +134,7 @@ func TestMtsSenderSegment(t *testing.T) {
const numberOfClips = 11 const numberOfClips = 11
dst := &destination{t: t, done: make(chan struct{}), doneAt: numberOfClips} dst := &destination{t: t, done: make(chan struct{}), doneAt: numberOfClips}
sender := newMtsSender(dst, (*dummyLogger)(t).log, rbSize, rbElementSize, 0) sender := newMtsSender(dst, (*dummyLogger)(t).log, rbSize, rbElementSize, 0)
encoder := mts.NewEncoder(sender, 25, mts.Video) encoder := mts.NewEncoder(sender, 25, mts.H264)
// Turn time based PSI writing off for encoder. // Turn time based PSI writing off for encoder.
const psiSendCount = 10 const psiSendCount = 10
@ -212,7 +212,7 @@ func TestMtsSenderFailedSend(t *testing.T) {
const clipToFailAt = 3 const clipToFailAt = 3
dst := &destination{t: t, testFails: true, failAt: clipToFailAt, done: make(chan struct{})} dst := &destination{t: t, testFails: true, failAt: clipToFailAt, done: make(chan struct{})}
sender := newMtsSender(dst, (*dummyLogger)(t).log, rbSize, rbElementSize, 0) sender := newMtsSender(dst, (*dummyLogger)(t).log, rbSize, rbElementSize, 0)
encoder := mts.NewEncoder(sender, 25, mts.Video) encoder := mts.NewEncoder(sender, 25, mts.H264)
// Turn time based PSI writing off for encoder and send PSI every 10 packets. // Turn time based PSI writing off for encoder and send PSI every 10 packets.
const psiSendCount = 10 const psiSendCount = 10
@ -292,7 +292,7 @@ func TestMtsSenderDiscontinuity(t *testing.T) {
const clipToDelay = 3 const clipToDelay = 3
dst := &destination{t: t, sendDelay: 10 * time.Millisecond, delayAt: clipToDelay, done: make(chan struct{})} dst := &destination{t: t, sendDelay: 10 * time.Millisecond, delayAt: clipToDelay, done: make(chan struct{})}
sender := newMtsSender(dst, (*dummyLogger)(t).log, 1, rbElementSize, 0) sender := newMtsSender(dst, (*dummyLogger)(t).log, 1, rbElementSize, 0)
encoder := mts.NewEncoder(sender, 25, mts.Video) encoder := mts.NewEncoder(sender, 25, mts.H264)
// Turn time based PSI writing off for encoder. // Turn time based PSI writing off for encoder.
const psiSendCount = 10 const psiSendCount = 10