You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
lal/pkg/sdp/parse_logic.go

167 lines
4.1 KiB
Go

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

// Copyright 2020, Chef. All rights reserved.
// https://github.com/q191201771/lal
//
// Use of this source code is governed by a MIT-style license
// that can be found in the License file.
//
// Author: Chef (191201771@qq.com)
package sdp
import (
"fmt"
"strings"
"github.com/q191201771/lal/pkg/base"
)
type LogicContext struct {
RawSdp []byte
AudioClockRate int
VideoClockRate int
Asc []byte
Vps []byte
Sps []byte
Pps []byte
audioPayloadTypeBase base.AvPacketPt // lal内部定义的类型
videoPayloadTypeBase base.AvPacketPt
audioPayloadTypeOrigin int // 原始类型sdp或rtp中的类型
videoPayloadTypeOrigin int
audioAControl string
videoAControl string
// 没有用上的
hasAudio bool
hasVideo bool
}
func (lc *LogicContext) IsAudioPayloadTypeOrigin(t int) bool {
return lc.audioPayloadTypeOrigin == t
}
func (lc *LogicContext) IsVideoPayloadTypeOrigin(t int) bool {
return lc.videoPayloadTypeOrigin == t
}
func (lc *LogicContext) IsPayloadTypeOrigin(t int) bool {
return lc.audioPayloadTypeOrigin == t || lc.videoPayloadTypeOrigin == t
}
func (lc *LogicContext) IsAudioUnpackable() bool {
return lc.audioPayloadTypeBase == base.AvPacketPtAac && lc.Asc != nil
}
func (lc *LogicContext) IsVideoUnpackable() bool {
return lc.videoPayloadTypeBase == base.AvPacketPtAvc ||
lc.videoPayloadTypeBase == base.AvPacketPtHevc
}
func (lc *LogicContext) IsAudioUri(uri string) bool {
return lc.audioAControl != "" && strings.HasSuffix(uri, lc.audioAControl)
}
func (lc *LogicContext) IsVideoUri(uri string) bool {
return lc.videoAControl != "" && strings.HasSuffix(uri, lc.videoAControl)
}
func (lc *LogicContext) HasAudioAControl() bool {
return lc.audioAControl != ""
}
func (lc *LogicContext) HasVideoAControl() bool {
return lc.videoAControl != ""
}
func (lc *LogicContext) MakeAudioSetupUri(uri string) string {
return lc.makeSetupUri(uri, lc.audioAControl)
}
func (lc *LogicContext) MakeVideoSetupUri(uri string) string {
return lc.makeSetupUri(uri, lc.videoAControl)
}
func (lc *LogicContext) GetAudioPayloadTypeBase() base.AvPacketPt {
return lc.audioPayloadTypeBase
}
func (lc *LogicContext) GetVideoPayloadTypeBase() base.AvPacketPt {
return lc.videoPayloadTypeBase
}
func (lc *LogicContext) makeSetupUri(uri string, aControl string) string {
if strings.HasPrefix(aControl, "rtsp://") {
return aControl
}
return fmt.Sprintf("%s/%s", uri, aControl)
}
func ParseSdp2LogicContext(b []byte) (LogicContext, error) {
var ret LogicContext
c, err := ParseSdp2RawContext(b)
if err != nil {
return ret, err
}
for _, md := range c.MediaDescList {
switch md.M.Media {
case "audio":
ret.hasAudio = true
ret.AudioClockRate = md.ARtpMap.ClockRate
ret.audioAControl = md.AControl.Value
ret.audioPayloadTypeOrigin = md.ARtpMap.PayloadType
if md.ARtpMap.EncodingName == ARtpMapEncodingNameAac {
ret.audioPayloadTypeBase = base.AvPacketPtAac
if md.AFmtPBase != nil {
ret.Asc, err = ParseAsc(md.AFmtPBase)
if err != nil {
Log.Warnf("parse asc from afmtp failed. err=%+v", err)
}
} else {
Log.Warnf("aac afmtp not exist.")
}
} else {
ret.audioPayloadTypeBase = base.AvPacketPtUnknown
}
case "video":
ret.hasVideo = true
ret.VideoClockRate = md.ARtpMap.ClockRate
ret.videoAControl = md.AControl.Value
ret.videoPayloadTypeOrigin = md.ARtpMap.PayloadType
switch md.ARtpMap.EncodingName {
case ARtpMapEncodingNameH264:
ret.videoPayloadTypeBase = base.AvPacketPtAvc
if md.AFmtPBase != nil {
ret.Sps, ret.Pps, err = ParseSpsPps(md.AFmtPBase)
if err != nil {
Log.Warnf("parse sps pps from afmtp failed. err=%+v", err)
}
} else {
Log.Warnf("avc afmtp not exist.")
}
case ARtpMapEncodingNameH265:
ret.videoPayloadTypeBase = base.AvPacketPtHevc
if md.AFmtPBase != nil {
ret.Vps, ret.Sps, ret.Pps, err = ParseVpsSpsPps(md.AFmtPBase)
if err != nil {
Log.Warnf("parse vps sps pps from afmtp failed. err=%+v", err)
}
} else {
Log.Warnf("hevc afmtp not exist.")
}
default:
ret.videoPayloadTypeBase = base.AvPacketPtUnknown
}
}
}
ret.RawSdp = b
return ret, nil
}