Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lal support opus #349

Merged
merged 1 commit into from
Apr 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions pkg/base/avpacket.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@ type AvPacketPt int

const (
AvPacketPtUnknown AvPacketPt = -1
AvPacketPtG711U AvPacketPt = 0 // g711u
AvPacketPtG711A AvPacketPt = 8 // g711a
AvPacketPtAvc AvPacketPt = 96 // h264
AvPacketPtHevc AvPacketPt = 98 // h265
AvPacketPtAac AvPacketPt = 97 // aac
AvPacketPtG711U AvPacketPt = 0 // g711u
AvPacketPtG711A AvPacketPt = 8 // g711a
AvPacketPtAvc AvPacketPt = 96 // h264
AvPacketPtHevc AvPacketPt = 98 // h265
AvPacketPtAac AvPacketPt = 97 // aac
AvPacketPtOpus AvPacketPt = 101 // opus
)

func (a AvPacketPt) ReadableString() string {
Expand Down
1 change: 1 addition & 0 deletions pkg/base/t_http_an__.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const (
AudioCodecAac = "AAC"
AudioCodecG711U = "PCMU"
AudioCodecG711A = "PCMA"
AudioCodecOpus = "OPUS"

// VideoCodecAvc StatGroup.VideoCodec
VideoCodecAvc = "H264"
Expand Down
2 changes: 2 additions & 0 deletions pkg/base/t_rtmp.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ package base
import (
"encoding/hex"
"fmt"

"github.com/q191201771/naza/pkg/bele"
"github.com/q191201771/naza/pkg/nazabytes"
)
Expand Down Expand Up @@ -117,6 +118,7 @@ const (
RtmpSoundFormatG711A uint8 = 7
RtmpSoundFormatG711U uint8 = 8
RtmpSoundFormatAac uint8 = 10
RtmpSoundFormatOpus uint8 = 13

RtmpAacPacketTypeSeqHeader = 0
RtmpAacPacketTypeRaw = 1
Expand Down
5 changes: 4 additions & 1 deletion pkg/logic/group__core_streaming.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
package logic

import (
"github.com/q191201771/lal/pkg/rtsp"
"net"

"github.com/q191201771/lal/pkg/rtsp"

"github.com/q191201771/lal/pkg/rtmp"
"github.com/q191201771/naza/pkg/nazalog"

Expand Down Expand Up @@ -409,6 +410,8 @@ func (group *Group) broadcastByRtmpMsg(msg base.RtmpMsg) {
group.stat.AudioCodec = base.AudioCodecG711U
case base.RtmpSoundFormatG711A:
group.stat.AudioCodec = base.AudioCodecG711A
case base.RtmpSoundFormatOpus:
group.stat.AudioCodec = base.AudioCodecOpus
}
}
}
Expand Down
1 change: 1 addition & 0 deletions pkg/mpegts/mpegts.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ const (
// 0x24 HEVC (HEVC video stream as defined in Rec. ITU-T H.265 | ISO/IEC 23008-2 MPEG-H Part 2)
// -----------------------------------------------------------------------------
StreamTypeUnknown uint8 = 0x00
StreamTypePrivate uint8 = 0x06
StreamTypeAac uint8 = 0x0F
StreamTypeAvc uint8 = 0x1B
StreamTypeHevc uint8 = 0x24
Expand Down
52 changes: 46 additions & 6 deletions pkg/mpegts/pmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
package mpegts

import (
"github.com/q191201771/lal/pkg/base"
"github.com/q191201771/naza/pkg/nazabits"
)

Expand Down Expand Up @@ -57,9 +58,10 @@ type Pmt struct {
}

type PmtProgramElement struct {
StreamType uint8
Pid uint16
Length uint16
StreamType uint8
Pid uint16
Length uint16
Descriptors []Descriptor
}

func ParsePmt(b []byte) (pmt Pmt) {
Expand Down Expand Up @@ -110,7 +112,7 @@ func (pmt *Pmt) SearchPid(pid uint16) *PmtProgramElement {
return nil
}

func PackPmt(videoStreamType, audioStreamType uint8) []byte {
func PackPmt(videoCodecId, audioCodecId int) []byte {
ts := make([]byte, 188)
tsheader := []byte{0x47, 0x50, 0x01, 0x10}
copy(ts, tsheader)
Expand All @@ -122,18 +124,56 @@ func PackPmt(videoStreamType, audioStreamType uint8) []byte {
psi.sectionData.section.currentNextIndicator = 1
psi.sectionData.pmtData.pcrPid = 0x100

videoStreamType := StreamTypeUnknown
if videoCodecId == int(base.RtmpCodecIdAvc) {
videoStreamType = StreamTypeAvc
} else if videoCodecId == int(base.RtmpCodecIdHevc) {
videoStreamType = StreamTypeHevc
}

if videoStreamType != StreamTypeUnknown {
psi.sectionData.pmtData.pes = append(psi.sectionData.pmtData.pes, PmtProgramElement{
StreamType: videoStreamType,
Pid: PidVideo,
})
}

audioStreamType := StreamTypeUnknown
if audioCodecId == int(base.RtmpSoundFormatAac) {
audioStreamType = StreamTypeAac
} else if audioCodecId == int(base.RtmpSoundFormatOpus) {
audioStreamType = StreamTypePrivate
}

if audioStreamType != StreamTypeUnknown {
psi.sectionData.pmtData.pes = append(psi.sectionData.pmtData.pes, PmtProgramElement{
pmtEle := PmtProgramElement{
StreamType: audioStreamType,
Pid: PidAudio,
})
}

if audioCodecId == int(base.RtmpSoundFormatOpus) {
descriptor := []Descriptor{
{
Length: 4,
Tag: DescriptorTagRegistration,
Registration: DescriptorRegistration{
FormatIdentifier: opusIdentifier,
},
},
{
Length: 2,
Tag: DescriptorTagExtension,
Extension: DescriptorExtension{
Tag: 0x80,
Unknown: []uint8{0x02},
},
},
}

pmtEle.Descriptors = append(pmtEle.Descriptors, descriptor...)
}

psi.sectionData.pmtData.pes = append(psi.sectionData.pmtData.pes, pmtEle)
}

psilen, psiData := psi.Pack()
Expand Down
154 changes: 150 additions & 4 deletions pkg/mpegts/psi.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,36 @@ const (
TsPsiIdForbidden = 0xFF // forbidden
)

const (
DescriptorTagAC3 = 0x6a
DescriptorTagAVCVideo = 0x28
DescriptorTagComponent = 0x50
DescriptorTagContent = 0x54
DescriptorTagDataStreamAlignment = 0x6
DescriptorTagEnhancedAC3 = 0x7a
DescriptorTagExtendedEvent = 0x4e
DescriptorTagExtension = 0x7f
DescriptorTagISO639LanguageAndAudioType = 0xa
DescriptorTagLocalTimeOffset = 0x58
DescriptorTagMaximumBitrate = 0xe
DescriptorTagNetworkName = 0x40
DescriptorTagParentalRating = 0x55
DescriptorTagPrivateDataIndicator = 0xf
DescriptorTagPrivateDataSpecifier = 0x5f
DescriptorTagRegistration = 0x5
DescriptorTagService = 0x48
DescriptorTagShortEvent = 0x4d
DescriptorTagStreamIdentifier = 0x52
DescriptorTagSubtitling = 0x59
DescriptorTagTeletext = 0x56
DescriptorTagVBIData = 0x45
DescriptorTagVBITeletext = 0x46
)

const (
opusIdentifier = 0x4f707573 // Opus
)

type PsiSection struct {
pointerFileld uint8
sectionData PsiSectionData
Expand Down Expand Up @@ -152,13 +182,58 @@ func (psi *PsiSection) calaPatSectionLength() (length uint16) {
}

func (psi *PsiSection) calaPmtSectionLength() (length uint16) {
// 暂不考虑Program descriptors
// Reserved bits(3 bits)+PCR PID(13 bits)+Reserved bits(4 bits)+Program info length(12 bits)
length = 4
length += uint16(5 * len(psi.sectionData.pmtData.pes))

for _, pe := range psi.sectionData.pmtData.pes {
length += 5

if len(pe.Descriptors) > 0 {
length += psi.calcDescriptorsLength(pe.Descriptors)
}
}

return
}

func (psi *PsiSection) calcDescriptorsLength(ds []Descriptor) uint16 {
length := uint16(0)
for _, d := range ds {
length += 2 // tag and length
length += uint16(psi.calcDescriptorLength(d))
}
return length
}

func (psi *PsiSection) calcDescriptorLength(d Descriptor) uint8 {
if d.Length == 0 {
return 0
}

switch d.Tag {
case DescriptorTagRegistration:
return psi.calcDescriptorRegistrationLength(d.Registration)
case DescriptorTagExtension:
return psi.calcDescriptorExtensionLength(d.Extension)
}

return 0
}

func (psi *PsiSection) calcDescriptorRegistrationLength(d DescriptorRegistration) uint8 {
return uint8(4 + len(d.AdditionalIdentificationInfo))
}

func (psi *PsiSection) calcDescriptorExtensionLength(d DescriptorExtension) uint8 {
// tag
ret := 1
if d.Unknown != nil {
ret += len(d.Unknown)
}

return uint8(ret)
}

func (psi *PsiSection) writePatSection(bw *nazabits.BitWriter) {
for _, pe := range psi.sectionData.patData.pes {
bw.WriteBits16(16, pe.pn)
Expand All @@ -179,8 +254,79 @@ func (psi *PsiSection) writePmtSection(bw *nazabits.BitWriter) {
bw.WriteBits8(8, pe.StreamType)
bw.WriteBits8(3, 0xff)
bw.WriteBits16(13, pe.Pid)
bw.WriteBits8(4, 0xff)
bw.WriteBits16(12, 0)
psi.writeDescriptorsWithLength(bw, pe.Descriptors)
}
return
}

func (psi *PsiSection) writeDescriptorsWithLength(bw *nazabits.BitWriter, dps []Descriptor) {
bw.WriteBits8(4, 0xff)

infolen := psi.calcDescriptorsLength(dps)
bw.WriteBits16(12, infolen)

for _, dp := range dps {
psi.writeDescriptor(bw, dp)
}
}

func (psi *PsiSection) writeDescriptor(bw *nazabits.BitWriter, d Descriptor) {
length := psi.calcDescriptorLength(d)

bw.WriteBits8(8, d.Tag)
bw.WriteBits8(8, length)

switch d.Tag {
case DescriptorTagRegistration:
psi.writeDescriptorRegistration(bw, d.Registration)
case DescriptorTagExtension:
psi.writeDescriptorExtension(bw, d.Extension)
}
}

func (psi *PsiSection) writeDescriptorRegistration(bw *nazabits.BitWriter, d DescriptorRegistration) {
bw.WriteBits16(16, uint16((d.FormatIdentifier>>16)&0xFFFF))
bw.WriteBits16(16, uint16(d.FormatIdentifier&0xFFFF))

if len(d.AdditionalIdentificationInfo) > 0 {
for _, b := range d.AdditionalIdentificationInfo {
bw.WriteBits8(8, b)
}
}
}

func (psi *PsiSection) writeDescriptorExtension(bw *nazabits.BitWriter, d DescriptorExtension) {
bw.WriteBits8(8, d.Tag)

if len(d.Unknown) > 0 {
for _, b := range d.Unknown {
bw.WriteBits8(8, b)
}
}
}

type Descriptor struct {
Length uint8
Tag uint8
Registration DescriptorRegistration
Extension DescriptorExtension
}

type DescriptorRegistration struct {
AdditionalIdentificationInfo []byte
FormatIdentifier uint32
}

type DescriptorExtension struct {
SupplementaryAudio DescriptorExtensionSupplementaryAudio
Tag uint8
Unknown []byte
}

type DescriptorExtensionSupplementaryAudio struct {
EditorialClassification uint8
HasLanguageCode bool
LanguageCode []byte
MixType bool
PrivateData []byte
}
8 changes: 8 additions & 0 deletions pkg/remux/avpacket2rtmp.go
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,14 @@ func (r *AvPacket2RtmpRemuxer) FeedAvPacket(pkt base.AvPacket) {
copy(payload[1:], pkt.Payload)
r.emitRtmpAvMsg(true, payload, pkt.Timestamp)

case base.AvPacketPtOpus:
length := len(pkt.Payload) + 1
payload := make([]byte, length)
// codecid=13, 44kHz、16bits、Stereo
payload[0] = 0xdf
copy(payload[1:], pkt.Payload)
r.emitRtmpAvMsg(true, payload, pkt.Timestamp)

default:
Log.Warnf("unsupported packet. type=%d", pkt.PayloadType)
}
Expand Down
5 changes: 4 additions & 1 deletion pkg/remux/remux.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@ package remux

var _ iRtmp2MpegtsFilterObserver = &Rtmp2MpegtsRemuxer{}

const pcmDefaultSampleRate = 8000
const (
pcmDefaultSampleRate = 8000
opusDefaultSampleRate = 48000
)
Loading
Loading