h264.py 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. from .lib import Decoder, RtpData
  2. from .rtp import RTP
  3. __all__ = ["H264Decoder"]
  4. class FuIndicator:
  5. def __init__(self, pack: "int"):
  6. self.F = (pack >> 7) > 0
  7. self.NRI = (pack >> 6) & 0x03
  8. self.Type = pack & 0x1F
  9. self.ft = pack & 0xE0 # first three bytes
  10. class FuHeader:
  11. def __init__(self, pack: "int"):
  12. self.S = (pack & 0x80) > 0
  13. self.E = (pack & 0x40) > 0
  14. self.S = (pack & 0x20) > 0
  15. self.Type = pack & 0x1F
  16. class H264Decoder(Decoder):
  17. def __init__(self):
  18. super(H264Decoder, self).__init__()
  19. def parse(self, rtp: "RTP"):
  20. indicator = FuIndicator(rtp.payload[0])
  21. rtpData = RtpData(data=rtp.payload[2:], pts=rtp.header.timestamp, seq=rtp.header.SN, isFrameEnd=rtp.header.M)
  22. if indicator.Type == 28: # 分片包: FU-A
  23. header = FuHeader(rtp.payload[1])
  24. if header.S: # first
  25. rtpData.packType, rtpData.naluType = 0, header.Type
  26. rtpData.data = self.Prefix + bytes([indicator.ft | header.Type]) + rtp.payload[2:]
  27. elif header.E:
  28. rtpData.packType = 2
  29. else:
  30. rtpData.packType = 1
  31. elif indicator.Type in [1, 5, 6, 7, 8]: # 单包: !IDR, IDR, SEI, SPS, PPS
  32. rtpData.data = self.Prefix + rtp.payload
  33. else:
  34. raise TypeError(f"not support h264 packType: {indicator.Type}")
  35. self.Manager.lock.acquire()
  36. self.Manager.packs.append(rtpData)
  37. self.Manager.lock.release()