Feature: Implement H.264 and AV1 hardware encoding for remote control

Remark: Need to update FFmpeg static libraries to take effort
This commit is contained in:
yuanyuanxiang
2026-05-28 11:41:33 +02:00
parent d1aa7a2c02
commit 8c7f612449
30 changed files with 2113 additions and 68 deletions

View File

@@ -350,6 +350,69 @@ func IsH264Keyframe(data []byte) bool {
return false
}
// IsAnyKeyframe sniffs the codec from the first byte then dispatches to the
// matching keyframe detector. H.264 Annex B always starts with 0x00 (start
// code prefix); AV1 OBU headers have bit7=0 and bits[3:6]=obu_type in [1,15]
// so the first byte is in [0x08,0x78] and never 0x00. Lets the server stay
// codec-agnostic so the browser can run H.264 and AV1 sessions side by side.
func IsAnyKeyframe(data []byte) bool {
if len(data) == 0 {
return false
}
if data[0] == 0x00 {
return IsH264Keyframe(data)
}
return IsAv1Keyframe(data)
}
// IsAv1Keyframe walks the OBU chain and returns true on the first
// OBU_SEQUENCE_HEADER (type 1). FFmpeg's AV1 encoders prepend SEQ HDR to
// every IDR, so seeing one is equivalent to "this packet contains a key
// frame". Mirrors the C++ IsAv1Keyframe helper in ScreenSpyDlg.cpp.
//
// AV1 OBU header byte layout: 0|type:4|ext:1|size:1|reserved:1
func IsAv1Keyframe(data []byte) bool {
n := len(data)
pos := 0
for pos < n {
hdr := data[pos]
obuType := (hdr >> 3) & 0x0F
hasExt := hdr&0x04 != 0
hasSize := hdr&0x02 != 0
if obuType == 1 { // OBU_SEQUENCE_HEADER
return true
}
pos++
if hasExt {
if pos >= n {
return false
}
pos++
}
if !hasSize {
return false // unsized OBU runs to end of packet
}
// LEB128 size
var sz uint64
for i := range 8 {
if pos >= n {
return false
}
b := data[pos]
pos++
sz |= uint64(b&0x7F) << (7 * i)
if b&0x80 == 0 {
break
}
}
if uint64(pos)+sz > uint64(n) {
return false
}
pos += int(sz)
}
return false
}
// LOGIN_INFOR structure size and offsets (matching C++ struct with default alignment)
// Note: C++ struct uses default alignment (4-byte for uint32/int)
const (