package fmtp
import (
"strings"
)
func defaultClockRate(mimeType string ) uint32 {
defaults := map [string ]uint32 {
"audio/opus" : 48000 ,
"audio/pcmu" : 8000 ,
"audio/pcma" : 8000 ,
}
if def , ok := defaults [strings .ToLower (mimeType )]; ok {
return def
}
return 90000
}
func defaultChannels(mimeType string ) uint16 {
defaults := map [string ]uint16 {
"audio/opus" : 2 ,
}
if def , ok := defaults [strings .ToLower (mimeType )]; ok {
return def
}
return 0
}
func parseParameters(line string ) map [string ]string {
parameters := make (map [string ]string )
for _ , p := range strings .Split (line , ";" ) {
pp := strings .SplitN (strings .TrimSpace (p ), "=" , 2 )
key := strings .ToLower (pp [0 ])
var value string
if len (pp ) > 1 {
value = pp [1 ]
}
parameters [key ] = value
}
return parameters
}
func ClockRateEqual (mimeType string , valA , valB uint32 ) bool {
if valA == 0 {
valA = defaultClockRate (mimeType )
}
if valB == 0 {
valB = defaultClockRate (mimeType )
}
return valA == valB
}
func ChannelsEqual (mimeType string , valA , valB uint16 ) bool {
if valA == 0 {
valA = defaultChannels (mimeType )
}
if valB == 0 {
valB = defaultChannels (mimeType )
}
if valA == 0 {
valA = 1
}
if valB == 0 {
valB = 1
}
return valA == valB
}
func paramsEqual(valA , valB map [string ]string ) bool {
for k , v := range valA {
if vb , ok := valB [k ]; ok && !strings .EqualFold (vb , v ) {
return false
}
}
for k , v := range valB {
if va , ok := valA [k ]; ok && !strings .EqualFold (va , v ) {
return false
}
}
return true
}
type FMTP interface {
MimeType () string
Match (f FMTP ) bool
Parameter (key string ) (string , bool )
}
func Parse (mimeType string , clockRate uint32 , channels uint16 , line string ) FMTP {
var fmtp FMTP
parameters := parseParameters (line )
switch {
case strings .EqualFold (mimeType , "video/h264" ):
fmtp = &h264FMTP {
parameters : parameters ,
}
case strings .EqualFold (mimeType , "video/vp9" ):
fmtp = &vp9FMTP {
parameters : parameters ,
}
case strings .EqualFold (mimeType , "video/av1" ):
fmtp = &av1FMTP {
parameters : parameters ,
}
default :
fmtp = &genericFMTP {
mimeType : mimeType ,
clockRate : clockRate ,
channels : channels ,
parameters : parameters ,
}
}
return fmtp
}
type genericFMTP struct {
mimeType string
clockRate uint32
channels uint16
parameters map [string ]string
}
func (g *genericFMTP ) MimeType () string {
return g .mimeType
}
func (g *genericFMTP ) Match (b FMTP ) bool {
fmtp , ok := b .(*genericFMTP )
if !ok {
return false
}
return strings .EqualFold (g .mimeType , fmtp .MimeType ()) &&
ClockRateEqual (g .mimeType , g .clockRate , fmtp .clockRate ) &&
ChannelsEqual (g .mimeType , g .channels , fmtp .channels ) &&
paramsEqual (g .parameters , fmtp .parameters )
}
func (g *genericFMTP ) Parameter (key string ) (string , bool ) {
v , ok := g .parameters [key ]
return v , ok
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .