package formats import ( "errors" "fmt" "github.com/bluenviron/gortsplib/v4" "github.com/bluenviron/gortsplib/v4/pkg/description" "github.com/bluenviron/gortsplib/v4/pkg/format" "github.com/bluenviron/gortsplib/v4/pkg/format/rtpvp8" "github.com/bluenviron/gortsplib/v4/pkg/format/rtpvp9" "github.com/pion/rtp" "image" ) // FindVP9Format finds the VP9 media and format. func FindVP9Format(desc *description.Session) (*format.VP9, *description.Media, error) { var vp9Format *format.VP9 vp9Media := desc.FindFormat(&vp9Format) if vp9Media == nil { return nil, nil, errors.New("media VP9 not found") } return vp9Format, vp9Media, nil } // ProcessVP9RGBA processes VP9 flow and returns PTS and IMG. func ProcessVP9RGBA( c *gortsplib.Client, vp9Media *description.Media, vp9RTPDec *rtpvp9.Decoder, vp9Dec *VPDecoder, pkt *rtp.Packet, ) ( int64, *image.RGBA, error) { // Decode timestamp. pts, ok := c.PacketPTS2(vp9Media, pkt) if !ok { return 0, nil, fmt.Errorf("waiting for timestamp\n") } // Extract access units from RTP packets. au, err := vp9RTPDec.Decode(pkt) if err != rtpvp8.ErrNonStartingPacketAndNoPrevious && err != rtpvp8.ErrMorePacketsNeeded { return 0, nil, fmt.Errorf("decoding RTP packet error: %w", err) } // Convert VP8 access units into RGBA frames. img, err := vp9Dec.Decode(au) if err != nil { return 0, nil, fmt.Errorf("convert into RGBA frames error\n") } // Wait for a frame. if img == nil { return 0, nil, fmt.Errorf("frame not found\n") } return pts, img, nil }