vp8.go 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. package codec
  2. import "errors"
  3. type VP8FrameTag struct {
  4. FrameType uint32 //0: I frame , 1: P frame
  5. Version uint32
  6. Display uint32
  7. FirstPartSize uint32
  8. }
  9. type VP8KeyFrameHead struct {
  10. Width int
  11. Height int
  12. HorizScale int
  13. VertScale int
  14. }
  15. func DecodeFrameTag(frame []byte) (*VP8FrameTag, error) {
  16. if len(frame) < 3 {
  17. return nil, errors.New("frame bytes < 3")
  18. }
  19. var tmp uint32 = (uint32(frame[2]) << 16) | (uint32(frame[1]) << 8) | uint32(frame[0])
  20. tag := &VP8FrameTag{}
  21. tag.FrameType = tmp & 0x01
  22. tag.Version = (tmp >> 1) & 0x07
  23. tag.Display = (tmp >> 4) & 0x01
  24. tag.FirstPartSize = (tmp >> 5) & 0x7FFFF
  25. return tag, nil
  26. }
  27. func DecodeKeyFrameHead(frame []byte) (*VP8KeyFrameHead, error) {
  28. if len(frame) < 7 {
  29. return nil, errors.New("frame bytes < 3")
  30. }
  31. if frame[0] != 0x9d || frame[1] != 0x01 || frame[2] != 0x2a {
  32. return nil, errors.New("not find Start code")
  33. }
  34. head := &VP8KeyFrameHead{}
  35. head.Width = int(uint16(frame[4]&0x3f)<<8 | uint16(frame[3]))
  36. head.HorizScale = int(frame[4] >> 6)
  37. head.Height = int(uint16(frame[6]&0x3f)<<8 | uint16(frame[5]))
  38. head.VertScale = int(frame[6] >> 6)
  39. return head, nil
  40. }
  41. func IsKeyFrame(frame []byte) bool {
  42. tag, err := DecodeFrameTag(frame)
  43. if err != nil {
  44. return false
  45. }
  46. if tag.FrameType == 0 {
  47. return true
  48. } else {
  49. return false
  50. }
  51. }
  52. func GetResloution(frame []byte) (width int, height int, err error) {
  53. if !IsKeyFrame(frame) {
  54. return 0, 0, errors.New("the frame is not Key frame")
  55. }
  56. head, err := DecodeKeyFrameHead(frame[3:])
  57. if err != nil {
  58. return 0, 0, err
  59. }
  60. return head.Width, head.Height, nil
  61. }