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:
@@ -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 (
|
||||
|
||||
Reference in New Issue
Block a user