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/pion/rtp" "image" ) // FindVP8Format finds the VP8 media and format. func FindVP8Format(desc *description.Session) (*format.VP8, *description.Media, error) { var vp8Format *format.VP8 vp8Media := desc.FindFormat(&vp8Format) if vp8Media == nil { return nil, nil, errors.New("media VP8 not found") } return vp8Format, vp8Media, nil } // ProcessVP8RGBA processes VP8 flow and returns PTS and IMG. func ProcessVP8RGBA( c *gortsplib.Client, vp8Media *description.Media, vp8RTPDec *rtpvp8.Decoder, vp8Dec *VPDecoder, pkt *rtp.Packet, ) ( int64, *image.RGBA, error) { // Decode timestamp. pts, ok := c.PacketPTS2(vp8Media, pkt) if !ok { return 0, nil, fmt.Errorf("waiting for timestamp\n") } // Extract access units from RTP packets. au, err := vp8RTPDec.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 := vp8Dec.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 }