fix duration fps

This commit is contained in:
Lidashuang 2024-03-29 12:05:52 +08:00
parent 960ca7eac5
commit 823f870b68
3 changed files with 96 additions and 35 deletions

View File

@ -255,7 +255,8 @@ type Packet struct {
Time time.Duration // packet decode time Time time.Duration // packet decode time
Duration time.Duration // packet duration Duration time.Duration // packet duration
Data []byte // packet data Data []byte // packet data
RealTimestamp int64 // packet real timestamp (ms) RealTimestamp int64 // packet real time (ms)
RealTs int64 // packet real time (s)
} }
// Raw audio frame. // Raw audio frame.

View File

@ -90,6 +90,8 @@ type RTSPClient struct {
PreAudioTS int64 PreAudioTS int64
PreVideoTS int64 PreVideoTS int64
PreSequenceNumber int PreSequenceNumber int
PrePacket []*av.Packet
PreDuration time.Duration
FPS int FPS int
WaitCodec bool WaitCodec bool
chTMP int chTMP int
@ -98,9 +100,9 @@ type RTSPClient struct {
end int end int
offset int offset int
realVideoTs int64 realVideoTs int64
keyFrameRealVideoTs int64 preKeyRealVideoTs int64
keyFrameIterateDrua int64 preRealVideoMs int64
preDuration time.Duration iterateDruation time.Duration
status string status string
lastPausedTime time.Time lastPausedTime time.Time
} }
@ -538,6 +540,7 @@ func (client *RTSPClient) Seek(customHeaders map[string]string, target int64) er
} }
client.status = PLAY client.status = PLAY
client.PreVideoTS = 0 client.PreVideoTS = 0
client.PrePacket = nil
return nil return nil
} }
@ -706,7 +709,7 @@ func (client *RTSPClient) CodecUpdateVPS(val []byte) {
// Println mini logging functions // Println mini logging functions
func (client *RTSPClient) Println(v ...interface{}) { func (client *RTSPClient) Println(v ...interface{}) {
if client.options.Debug { if client.options.Debug {
log.Println(v) log.Println(v...)
} }
} }

View File

@ -26,14 +26,14 @@ func (client *RTSPClient) containsPayloadType(pt int) bool {
return exist return exist
} }
func (client *RTSPClient) durationFromSDP() time.Duration { // func (client *RTSPClient) durationFromSDP() time.Duration {
for _, sdp := range client.mediaSDP { // for _, sdp := range client.mediaSDP {
if sdp.AVType == VIDEO && sdp.FPS != 0 { // if sdp.AVType == VIDEO && sdp.FPS != 0 {
return time.Duration((int(1000) / sdp.FPS) * int(time.Millisecond)) // return time.Duration((int(1000) / sdp.FPS) * int(time.Millisecond))
} // }
} // }
return 0 // return 0
} // }
func (client *RTSPClient) RTPDemuxer(payloadRAW *[]byte) ([]*av.Packet, bool) { func (client *RTSPClient) RTPDemuxer(payloadRAW *[]byte) ([]*av.Packet, bool) {
content := *payloadRAW content := *payloadRAW
@ -299,34 +299,91 @@ func (client *RTSPClient) appendAudioPacket(retmap []*av.Packet, nal []byte, dur
} }
func (client *RTSPClient) appendVideoPacket(retmap []*av.Packet, nal []byte, isKeyFrame bool) []*av.Packet { func (client *RTSPClient) appendVideoPacket(retmap []*av.Packet, nal []byte, isKeyFrame bool) []*av.Packet {
var realVideoMs int64 // Playback has real video ts
duration := time.Duration(float32(client.timestamp-client.PreVideoTS)/TimeBaseFactor) * time.Millisecond
sdpDuration := client.durationFromSDP()
if sdpDuration != 0 && duration > sdpDuration {
duration = sdpDuration
}
if duration == 0 {
duration = client.preDuration
}
client.preDuration = duration
if isKeyFrame {
client.keyFrameRealVideoTs = client.realVideoTs
client.keyFrameIterateDrua = 0
} else {
client.keyFrameIterateDrua += duration.Milliseconds()
}
if client.realVideoTs != 0 { if client.realVideoTs != 0 {
realVideoMs = client.keyFrameRealVideoTs * 1000 return client.appendPlaybackVideoPacket(retmap, nal, isKeyFrame)
realVideoMs += client.keyFrameIterateDrua } else {
// LiveView
return client.appendLiveViewVideoPacket(retmap, nal, isKeyFrame)
} }
}
return append(retmap, &av.Packet{ func (client *RTSPClient) appendPlaybackVideoPacket(retmap []*av.Packet, nal []byte, isKeyFrame bool) []*av.Packet {
prePkt := client.PrePacket
curPkt := &av.Packet{
Data: append(binSize(len(nal)), nal...), Data: append(binSize(len(nal)), nal...),
CompositionTime: time.Duration(TimeDelay) * time.Millisecond, CompositionTime: time.Duration(TimeDelay) * time.Millisecond,
Idx: client.videoIDX, Idx: client.videoIDX,
IsKeyFrame: isKeyFrame, IsKeyFrame: isKeyFrame,
Duration: duration, Duration: client.PreDuration,
Time: time.Duration(client.timestamp/TimeBaseFactor) * time.Millisecond, Time: time.Duration(client.timestamp/TimeBaseFactor) * time.Millisecond,
RealTimestamp: realVideoMs, RealTimestamp: 0,
}) RealTs: client.realVideoTs,
}
client.PrePacket = append(retmap, curPkt)
if len(prePkt) == 0 {
return nil
} else {
var prePktTime time.Duration
lenPrePkt := len(prePkt)
for i := lenPrePkt - 1; i >= 0; i-- {
prePktTime = prePkt[i].Time
if i+1 == lenPrePkt {
prePkt[i].Duration = time.Duration(client.timestamp/TimeBaseFactor)*time.Millisecond - prePkt[i].Time
} else {
prePkt[i].Duration = (prePkt[i].Time - prePktTime) * time.Millisecond
}
client.PreDuration = prePkt[i].Duration
if prePkt[i].IsKeyFrame {
if prePkt[i].RealTs == client.preRealVideoMs/1000 {
client.iterateDruation += prePkt[i].Duration
} else {
client.iterateDruation = 0
client.preKeyRealVideoTs = prePkt[i].RealTs
}
} else {
client.iterateDruation += prePkt[i].Duration
}
prePkt[i].RealTimestamp = client.preKeyRealVideoTs*1000 + client.iterateDruation.Milliseconds()
client.preRealVideoMs = prePkt[i].RealTimestamp
// fmt.Println("playback duration", prePkt[i].IsKeyFrame, prePkt[i].RealTs, client.preRealVideoMs, prePkt[i].Duration, client.iterateDruation)
}
return prePkt
}
}
func (client *RTSPClient) appendLiveViewVideoPacket(retmap []*av.Packet, nal []byte, isKeyFrame bool) []*av.Packet {
prePkt := client.PrePacket
client.PrePacket = append(retmap, &av.Packet{
Data: append(binSize(len(nal)), nal...),
CompositionTime: time.Duration(TimeDelay) * time.Millisecond,
Idx: client.videoIDX,
IsKeyFrame: isKeyFrame,
Duration: client.PreDuration,
Time: time.Duration(client.timestamp/TimeBaseFactor) * time.Millisecond,
})
if len(prePkt) == 0 {
return nil
} else {
var prePktTime time.Duration
lenPrePkt := len(prePkt)
for i := lenPrePkt - 1; i >= 0; i-- {
if isKeyFrame {
prePkt[i].Duration = client.PreDuration
} else {
prePktTime = prePkt[i].Time
if i+1 == lenPrePkt {
prePkt[i].Duration = time.Duration(client.timestamp/TimeBaseFactor)*time.Millisecond - prePkt[i].Time
} else {
prePkt[i].Duration = (prePkt[i].Time - prePktTime) * time.Millisecond
}
client.PreDuration = prePkt[i].Duration
}
// fmt.Println("liveview duration", prePkt[i].IsKeyFrame, prePkt[i].Time.Milliseconds(), prePkt[i].Duration)
}
return prePkt
}
} }