mirror of
				https://github.com/aler9/gortsplib
				synced 2025-10-31 02:26:57 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			144 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			144 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Package format contains RTP format definitions, decoders and encoders.
 | |
| package format
 | |
| 
 | |
| import (
 | |
| 	"strings"
 | |
| 
 | |
| 	"github.com/pion/rtp"
 | |
| )
 | |
| 
 | |
| func getCodecAndClock(rtpMap string) (string, string) {
 | |
| 	parts2 := strings.SplitN(rtpMap, "/", 2)
 | |
| 	if len(parts2) != 2 {
 | |
| 		return "", ""
 | |
| 	}
 | |
| 
 | |
| 	return strings.ToLower(parts2[0]), parts2[1]
 | |
| }
 | |
| 
 | |
| type unmarshalContext struct {
 | |
| 	mediaType   string
 | |
| 	payloadType uint8
 | |
| 	clock       string
 | |
| 	codec       string
 | |
| 	rtpMap      string
 | |
| 	fmtp        map[string]string
 | |
| }
 | |
| 
 | |
| // Format is a media format.
 | |
| // It defines the payload type of RTP packets and how to encode/decode them.
 | |
| type Format interface {
 | |
| 	unmarshal(ctx *unmarshalContext) error
 | |
| 
 | |
| 	// Codec returns the codec name.
 | |
| 	Codec() string
 | |
| 
 | |
| 	// ClockRate returns the clock rate.
 | |
| 	ClockRate() int
 | |
| 
 | |
| 	// PayloadType returns the payload type.
 | |
| 	PayloadType() uint8
 | |
| 
 | |
| 	// RTPMap returns the rtpmap attribute.
 | |
| 	RTPMap() string
 | |
| 
 | |
| 	// FMTP returns the fmtp attribute.
 | |
| 	FMTP() map[string]string
 | |
| 
 | |
| 	// PTSEqualsDTS checks whether PTS is equal to DTS in RTP packets.
 | |
| 	PTSEqualsDTS(*rtp.Packet) bool
 | |
| }
 | |
| 
 | |
| // Unmarshal decodes a format from a media description.
 | |
| func Unmarshal(mediaType string, payloadType uint8, rtpMap string, fmtp map[string]string) (Format, error) {
 | |
| 	codec, clock := getCodecAndClock(rtpMap)
 | |
| 
 | |
| 	format := func() Format {
 | |
| 		switch {
 | |
| 		// video
 | |
| 
 | |
| 		case payloadType == 26:
 | |
| 			return &MJPEG{}
 | |
| 
 | |
| 		case payloadType == 32:
 | |
| 			return &MPEG1Video{}
 | |
| 
 | |
| 		case payloadType == 33:
 | |
| 			return &MPEGTS{}
 | |
| 
 | |
| 		case codec == "mp4v-es" && clock == "90000":
 | |
| 			return &MPEG4Video{}
 | |
| 
 | |
| 		case codec == "h264" && clock == "90000":
 | |
| 			return &H264{}
 | |
| 
 | |
| 		case codec == "h265" && clock == "90000":
 | |
| 			return &H265{}
 | |
| 
 | |
| 		case codec == "vp8" && clock == "90000":
 | |
| 			return &VP8{}
 | |
| 
 | |
| 		case codec == "vp9" && clock == "90000":
 | |
| 			return &VP9{}
 | |
| 
 | |
| 		case codec == "av1" && clock == "90000":
 | |
| 			return &AV1{}
 | |
| 
 | |
| 		// audio
 | |
| 
 | |
| 		case payloadType == 0, payloadType == 8:
 | |
| 			return &G711{}
 | |
| 
 | |
| 		case payloadType == 9:
 | |
| 			return &G722{}
 | |
| 
 | |
| 		case (codec == "g726-16" ||
 | |
| 			codec == "g726-24" ||
 | |
| 			codec == "g726-32" ||
 | |
| 			codec == "g726-40" ||
 | |
| 			codec == "aal2-g726-16" ||
 | |
| 			codec == "aal2-g726-24" ||
 | |
| 			codec == "aal2-g726-32" ||
 | |
| 			codec == "aal2-g726-40") && clock == "8000":
 | |
| 			return &G726{}
 | |
| 
 | |
| 		case payloadType == 14:
 | |
| 			return &MPEG1Audio{}
 | |
| 
 | |
| 		case codec == "l8", codec == "l16", codec == "l24":
 | |
| 			return &LPCM{}
 | |
| 
 | |
| 		case codec == "mpeg4-generic":
 | |
| 			return &MPEG4AudioGeneric{}
 | |
| 
 | |
| 		case codec == "mp4a-latm":
 | |
| 			return &MPEG4AudioLATM{}
 | |
| 
 | |
| 		case codec == "speex":
 | |
| 			return &Speex{}
 | |
| 
 | |
| 		case codec == "vorbis":
 | |
| 			return &Vorbis{}
 | |
| 
 | |
| 		case codec == "opus":
 | |
| 			return &Opus{}
 | |
| 		}
 | |
| 
 | |
| 		return &Generic{}
 | |
| 	}()
 | |
| 
 | |
| 	err := format.unmarshal(&unmarshalContext{
 | |
| 		mediaType:   mediaType,
 | |
| 		payloadType: payloadType,
 | |
| 		clock:       clock,
 | |
| 		codec:       codec,
 | |
| 		rtpMap:      rtpMap,
 | |
| 		fmtp:        fmtp,
 | |
| 	})
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	return format, nil
 | |
| }
 | 
