fmtp.go 2.0 KB

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