mirror of
https://github.com/aler9/gortsplib
synced 2025-10-05 23:26:54 +08:00
improve h264.PTSEqualsDTS, h265.PTSEqualsDTS
This commit is contained in:
@@ -14,61 +14,6 @@ import (
|
|||||||
"github.com/bluenviron/mediacommon/pkg/codecs/h264"
|
"github.com/bluenviron/mediacommon/pkg/codecs/h264"
|
||||||
)
|
)
|
||||||
|
|
||||||
// check whether a RTP/H264 packet contains a IDR, without decoding the packet.
|
|
||||||
func rtpH264ContainsIDR(pkt *rtp.Packet) bool {
|
|
||||||
if len(pkt.Payload) == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
typ := h264.NALUType(pkt.Payload[0] & 0x1F)
|
|
||||||
|
|
||||||
switch typ {
|
|
||||||
case h264.NALUTypeIDR:
|
|
||||||
return true
|
|
||||||
|
|
||||||
case 24: // STAP-A
|
|
||||||
payload := pkt.Payload[1:]
|
|
||||||
|
|
||||||
for len(payload) > 0 {
|
|
||||||
if len(payload) < 2 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
size := uint16(payload[0])<<8 | uint16(payload[1])
|
|
||||||
payload = payload[2:]
|
|
||||||
|
|
||||||
if size == 0 || int(size) > len(payload) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
var nalu []byte
|
|
||||||
nalu, payload = payload[:size], payload[size:]
|
|
||||||
|
|
||||||
typ = h264.NALUType(nalu[0] & 0x1F)
|
|
||||||
if typ == h264.NALUTypeIDR {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case 28: // FU-A
|
|
||||||
if len(pkt.Payload) < 2 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
start := pkt.Payload[1] >> 7
|
|
||||||
if start != 1 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
typ := h264.NALUType(pkt.Payload[1] & 0x1F)
|
|
||||||
if typ == h264.NALUTypeIDR {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// H264 is a RTP format for the H264 codec, defined in MPEG-4 part 10.
|
// H264 is a RTP format for the H264 codec, defined in MPEG-4 part 10.
|
||||||
// Specification: https://datatracker.ietf.org/doc/html/rfc6184
|
// Specification: https://datatracker.ietf.org/doc/html/rfc6184
|
||||||
type H264 struct {
|
type H264 struct {
|
||||||
@@ -172,7 +117,59 @@ func (f *H264) FMTP() map[string]string {
|
|||||||
|
|
||||||
// PTSEqualsDTS implements Format.
|
// PTSEqualsDTS implements Format.
|
||||||
func (f *H264) PTSEqualsDTS(pkt *rtp.Packet) bool {
|
func (f *H264) PTSEqualsDTS(pkt *rtp.Packet) bool {
|
||||||
return rtpH264ContainsIDR(pkt)
|
if len(pkt.Payload) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
typ := h264.NALUType(pkt.Payload[0] & 0x1F)
|
||||||
|
|
||||||
|
switch typ {
|
||||||
|
case h264.NALUTypeIDR, h264.NALUTypeSPS, h264.NALUTypePPS:
|
||||||
|
return true
|
||||||
|
|
||||||
|
case 24: // STAP-A
|
||||||
|
payload := pkt.Payload[1:]
|
||||||
|
|
||||||
|
for len(payload) > 0 {
|
||||||
|
if len(payload) < 2 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
size := uint16(payload[0])<<8 | uint16(payload[1])
|
||||||
|
payload = payload[2:]
|
||||||
|
|
||||||
|
if size == 0 || int(size) > len(payload) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var nalu []byte
|
||||||
|
nalu, payload = payload[:size], payload[size:]
|
||||||
|
|
||||||
|
typ = h264.NALUType(nalu[0] & 0x1F)
|
||||||
|
switch typ {
|
||||||
|
case h264.NALUTypeIDR, h264.NALUTypeSPS, h264.NALUTypePPS:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case 28: // FU-A
|
||||||
|
if len(pkt.Payload) < 2 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
start := pkt.Payload[1] >> 7
|
||||||
|
if start != 1 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
typ := h264.NALUType(pkt.Payload[1] & 0x1F)
|
||||||
|
switch typ {
|
||||||
|
case h264.NALUTypeIDR, h264.NALUTypeSPS, h264.NALUTypePPS:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateDecoder creates a decoder able to decode the content of the format.
|
// CreateDecoder creates a decoder able to decode the content of the format.
|
||||||
|
@@ -12,61 +12,6 @@ import (
|
|||||||
"github.com/bluenviron/gortsplib/v3/pkg/formats/rtph265"
|
"github.com/bluenviron/gortsplib/v3/pkg/formats/rtph265"
|
||||||
)
|
)
|
||||||
|
|
||||||
// check whether a RTP/H265 packet is random access, without decoding the packet.
|
|
||||||
func rtpH265IsRandomAccess(pkt *rtp.Packet) bool {
|
|
||||||
if len(pkt.Payload) == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
typ := h265.NALUType((pkt.Payload[0] >> 1) & 0b111111)
|
|
||||||
|
|
||||||
switch typ {
|
|
||||||
case h265.NALUType_IDR_W_RADL, h265.NALUType_IDR_N_LP, h265.NALUType_CRA_NUT:
|
|
||||||
return true
|
|
||||||
|
|
||||||
case h265.NALUType_AggregationUnit:
|
|
||||||
payload := pkt.Payload[2:]
|
|
||||||
|
|
||||||
for len(payload) > 0 {
|
|
||||||
if len(payload) < 2 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
size := uint16(payload[0])<<8 | uint16(payload[1])
|
|
||||||
payload = payload[2:]
|
|
||||||
|
|
||||||
if size == 0 || int(size) > len(payload) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
var nalu []byte
|
|
||||||
nalu, payload = payload[:size], payload[size:]
|
|
||||||
|
|
||||||
typ = h265.NALUType((nalu[0] >> 1) & 0b111111)
|
|
||||||
if typ == h265.NALUType_IDR_W_RADL || typ == h265.NALUType_IDR_N_LP || typ == h265.NALUType_CRA_NUT {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case h265.NALUType_FragmentationUnit:
|
|
||||||
if len(pkt.Payload) < 3 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
start := pkt.Payload[1] >> 7
|
|
||||||
if start != 1 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
typ := h265.NALUType(pkt.Payload[2] & 0b111111)
|
|
||||||
if typ == h265.NALUType_IDR_W_RADL || typ == h265.NALUType_IDR_N_LP || typ == h265.NALUType_CRA_NUT {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// H265 is a RTP format for the H265 codec.
|
// H265 is a RTP format for the H265 codec.
|
||||||
// Specification: https://datatracker.ietf.org/doc/html/rfc7798
|
// Specification: https://datatracker.ietf.org/doc/html/rfc7798
|
||||||
type H265 struct {
|
type H265 struct {
|
||||||
@@ -168,7 +113,62 @@ func (f *H265) FMTP() map[string]string {
|
|||||||
|
|
||||||
// PTSEqualsDTS implements Format.
|
// PTSEqualsDTS implements Format.
|
||||||
func (f *H265) PTSEqualsDTS(pkt *rtp.Packet) bool {
|
func (f *H265) PTSEqualsDTS(pkt *rtp.Packet) bool {
|
||||||
return rtpH265IsRandomAccess(pkt)
|
if len(pkt.Payload) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
typ := h265.NALUType((pkt.Payload[0] >> 1) & 0b111111)
|
||||||
|
|
||||||
|
switch typ {
|
||||||
|
case h265.NALUType_IDR_W_RADL, h265.NALUType_IDR_N_LP, h265.NALUType_CRA_NUT,
|
||||||
|
h265.NALUType_VPS_NUT, h265.NALUType_SPS_NUT, h265.NALUType_PPS_NUT:
|
||||||
|
return true
|
||||||
|
|
||||||
|
case h265.NALUType_AggregationUnit:
|
||||||
|
payload := pkt.Payload[2:]
|
||||||
|
|
||||||
|
for len(payload) > 0 {
|
||||||
|
if len(payload) < 2 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
size := uint16(payload[0])<<8 | uint16(payload[1])
|
||||||
|
payload = payload[2:]
|
||||||
|
|
||||||
|
if size == 0 || int(size) > len(payload) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var nalu []byte
|
||||||
|
nalu, payload = payload[:size], payload[size:]
|
||||||
|
|
||||||
|
typ = h265.NALUType((nalu[0] >> 1) & 0b111111)
|
||||||
|
switch typ {
|
||||||
|
case h265.NALUType_IDR_W_RADL, h265.NALUType_IDR_N_LP, h265.NALUType_CRA_NUT,
|
||||||
|
h265.NALUType_VPS_NUT, h265.NALUType_SPS_NUT, h265.NALUType_PPS_NUT:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case h265.NALUType_FragmentationUnit:
|
||||||
|
if len(pkt.Payload) < 3 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
start := pkt.Payload[1] >> 7
|
||||||
|
if start != 1 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
typ := h265.NALUType(pkt.Payload[2] & 0b111111)
|
||||||
|
switch typ {
|
||||||
|
case h265.NALUType_IDR_W_RADL, h265.NALUType_IDR_N_LP, h265.NALUType_CRA_NUT,
|
||||||
|
h265.NALUType_VPS_NUT, h265.NALUType_SPS_NUT, h265.NALUType_PPS_NUT:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateDecoder creates a decoder able to decode the content of the format.
|
// CreateDecoder creates a decoder able to decode the content of the format.
|
||||||
|
Reference in New Issue
Block a user