admin管理员组

文章数量:1123702

I’m implementing a packet loss counter based on the PTS from the av_packet, and it works fine when using RTSP/TCP as the transport mode. However, when I switched to RTSP/UDP, two packets consistently share the same PTS. This puzzled me because I assumed that av_read_frame would parse the stream and provide "valid" packets.

In both cases, the stream is FU-A H.264, and I expected FFmpeg to handle reassembly in both transport modes identically. My understanding was that if UDP packets were splitted, FFmpeg would reassemble them into a single av_packet, similar to how it handles reassembly for TCP packets split due to MTU and FU-A.

I could adapt my packet loss calculation by simply ignoring packets with the same PTS as the previous one, but I want to understand what’s happening here.

TCP

packet pts: -9223372036854775808, dts: -9223372036854775808, size: 52672, key-frame: true, discard: false, corrupt: false
packet pts: 3598, dts: 3598, size: 6034, key-frame: false, discard: false, corrupt: false
packet pts: 7196, dts: 7196, size: 5730, key-frame: false, discard: false, corrupt: false
packet pts: 10794, dts: 10794, size: 6153, key-frame: false, discard: false, corrupt: false
packet pts: 14392, dts: 14392, size: 2269, key-frame: false, discard: false, corrupt: false
packet pts: 17989, dts: 17989, size: 2656, key-frame: false, discard: false, corrupt: false
packet pts: 21587, dts: 21587, size: 2659, key-frame: false, discard: false, corrupt: false

UDP

packet pts: -9223372036854775808, dts: -9223372036854775808, size: 1391, key-frame: true, discard: false, corrupt: false
packet pts: 0, dts: 0, size: 109265, key-frame: true, discard: false, corrupt: false
packet pts: 3598, dts: 3598, size: 878, key-frame: false, discard: false, corrupt: false
packet pts: -> 3598, dts: 3598, size: 7728, key-frame: false, discard: false, corrupt: false
packet pts: 7195, dts: 7195, size: 887, key-frame: false, discard: false, corrupt: false
packet pts: -> 7195, dts: 7195, size: 7149, key-frame: false, discard: false, corrupt: false
packet pts: 10793, dts: 10793, size: 795, key-frame: false, discard: false, corrupt: false
packet pts: -> 10793, dts: 10793, size: 7777, key-frame: false, discard: false, corrupt: false
packet pts: 14391, dts: 14391, size: 119, key-frame: false, discard: false, corrupt: false
packet pts: -> 14391, dts: 14391, size: 2075, key-frame: false, discard: false, corrupt: false

For reference here my code

// PackageLossDetection detects possible packet loss based on PTS (Presentation Time Stamp) values.
// It compares the PTS of the packet with the expected PTS, calculated using the stream's time base and average frame rate.
// If the deviation between the expected and actual PTS exceeds a defined tolerance.
//
// Parameters:
//   - pkt: incoming packet whose PTS is to be checked.
//   - stream: the stream containing time base and average frame rate information.
func (s *AvSource) PackageLossDetection(pkt *astiav.Packet, stream *astiav.Stream) {

    // When using UDP as RTSP Transport packages in tuple has same PTS
    // TODO: Maybe we should invest more time to find a better solution
    if s.lastPts == pkt.Pts() {
        return
    }

    if pkt.Pts() > 0 {

        const tolerance = 4 // Allowable deviation in PTS steps
        if stream.AvgFrameRate().Num() == 0 {
            s.log.Warn().Str("stream", s.stream.Name).Msg("PackageLossDetection, no frame rate information available")
            return
        }

        var ptsBetween = stream.TimeBase().Den() * stream.TimeBase().Num() / stream.AvgFrameRate().Num()
        if math.Abs(float64(pkt.Pts()-(s.lastPts+int64(ptsBetween)))) > tolerance {
            s.log.Warn().Str("stream", s.stream.Name).Msgf("PackageLossDetection, PTS steps: %d, expected: %d, got: %d", int(ptsBetween), s.lastPts+int64(ptsBetween), pkt.Pts())
            utils.SafeIncrementInt64(&s.metrics.LossCount)
        }

        s.lastPts = pkt.Pts()
    }
}

本文标签: ffmpegDuplicated PTS value when using rtsp transport UDP (H264 FUA)Stack Overflow