github.com/pion/webrtc/v3@v3.2.24/internal/fmtp/fmtp.go (about) 1 // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly> 2 // SPDX-License-Identifier: MIT 3 4 // Package fmtp implements per codec parsing of fmtp lines 5 package fmtp 6 7 import ( 8 "strings" 9 ) 10 11 // FMTP interface for implementing custom 12 // FMTP parsers based on MimeType 13 type FMTP interface { 14 // MimeType returns the MimeType associated with 15 // the fmtp 16 MimeType() string 17 // Match compares two fmtp descriptions for 18 // compatibility based on the MimeType 19 Match(f FMTP) bool 20 // Parameter returns a value for the associated key 21 // if contained in the parsed fmtp string 22 Parameter(key string) (string, bool) 23 } 24 25 // Parse parses an fmtp string based on the MimeType 26 func Parse(mimetype, line string) FMTP { 27 var f FMTP 28 29 parameters := make(map[string]string) 30 31 for _, p := range strings.Split(line, ";") { 32 pp := strings.SplitN(strings.TrimSpace(p), "=", 2) 33 key := strings.ToLower(pp[0]) 34 var value string 35 if len(pp) > 1 { 36 value = pp[1] 37 } 38 parameters[key] = value 39 } 40 41 switch { 42 case strings.EqualFold(mimetype, "video/h264"): 43 f = &h264FMTP{ 44 parameters: parameters, 45 } 46 default: 47 f = &genericFMTP{ 48 mimeType: mimetype, 49 parameters: parameters, 50 } 51 } 52 53 return f 54 } 55 56 type genericFMTP struct { 57 mimeType string 58 parameters map[string]string 59 } 60 61 func (g *genericFMTP) MimeType() string { 62 return g.mimeType 63 } 64 65 // Match returns true if g and b are compatible fmtp descriptions 66 // The generic implementation is used for MimeTypes that are not defined 67 func (g *genericFMTP) Match(b FMTP) bool { 68 c, ok := b.(*genericFMTP) 69 if !ok { 70 return false 71 } 72 73 if !strings.EqualFold(g.mimeType, c.MimeType()) { 74 return false 75 } 76 77 for k, v := range g.parameters { 78 if vb, ok := c.parameters[k]; ok && !strings.EqualFold(vb, v) { 79 return false 80 } 81 } 82 83 for k, v := range c.parameters { 84 if va, ok := g.parameters[k]; ok && !strings.EqualFold(va, v) { 85 return false 86 } 87 } 88 89 return true 90 } 91 92 func (g *genericFMTP) Parameter(key string) (string, bool) { 93 v, ok := g.parameters[key] 94 return v, ok 95 }