move rtp.Frame to av.Frame

This commit is contained in:
notch
2020-12-24 15:27:39 +08:00
parent aa501595f1
commit 8ace21c630
6 changed files with 62 additions and 69 deletions

23
av/frame.go Normal file
View File

@@ -0,0 +1,23 @@
// Copyright (c) 2019,CAOHONGJU All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package av
// 帧类型
const (
FrameVideo = byte(iota)
FrameAudio
)
// Frame 音视频完整帧
type Frame struct {
FrameType byte // 帧类型
AbsTimestamp int64 // 绝对时间戳(主要用于表示 pts),单位为 ms 的 UNIX 时间
Payload []byte // 媒体数据载荷
}
// FrameWriter 包装 WriteFrame 方法的接口
type FrameWriter interface {
WriteFrame(frame *Frame) error
}

View File

@@ -102,19 +102,19 @@ func (muxer *flvMuxer) prepareTemplate() {
muxer.audioDataTemplate = audioData
}
func (muxer *flvMuxer) WriteFrame(frame *rtp.Frame) error {
func (muxer *flvMuxer) WriteFrame(frame *av.Frame) error {
if muxer.baseNtp == 0 {
muxer.baseNtp = frame.NTPTime
muxer.baseNtp = frame.AbsTimestamp
}
if frame.FrameType == rtp.FrameVideo {
if frame.FrameType == av.FrameVideo {
return muxer.muxVideoTag(frame)
} else {
return muxer.muxAudioTag(frame)
}
}
func (muxer *flvMuxer) muxVideoTag(frame *rtp.Frame) error {
func (muxer *flvMuxer) muxVideoTag(frame *av.Frame) error {
if frame.Payload[0]&0x1F == h264.NalSps {
if len(muxer.videoMeta.Sps) == 0 {
muxer.videoMeta.Sps = frame.Payload
@@ -130,7 +130,7 @@ func (muxer *flvMuxer) muxVideoTag(frame *rtp.Frame) error {
}
dts := time.Now().UnixNano()/int64(time.Millisecond) - muxer.baseTs
pts := frame.NTPTime - muxer.baseNtp + ptsDelay
pts := frame.AbsTimestamp - muxer.baseNtp + ptsDelay
if dts > pts {
pts = dts
}
@@ -159,7 +159,7 @@ func (muxer *flvMuxer) muxVideoTag(frame *rtp.Frame) error {
return muxer.tagWriter.WriteTag(tag)
}
func (muxer *flvMuxer) muxAudioTag(frame *rtp.Frame) error {
func (muxer *flvMuxer) muxAudioTag(frame *av.Frame) error {
audioData := *muxer.audioDataTemplate
audioData.Body = frame.Payload
data, _ := audioData.Marshal()
@@ -167,7 +167,7 @@ func (muxer *flvMuxer) muxAudioTag(frame *rtp.Frame) error {
tag := &flv.Tag{
TagType: flv.TagTypeAudio,
DataSize: uint32(len(data)),
Timestamp: uint32(frame.NTPTime-muxer.baseNtp) + ptsDelay,
Timestamp: uint32(frame.AbsTimestamp-muxer.baseNtp) + ptsDelay,
StreamID: 0,
Data: data,
}

View File

@@ -1,33 +0,0 @@
// Copyright (c) 2019,CAOHONGJU All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package rtp
// 帧类型
const (
FrameVideo = byte(iota)
FrameAudio
)
// Frame 音视频完整帧
type Frame struct {
FrameType byte // 帧类型
NTPTime int64 // 绝对时间戳,单位 ms
RTPTime uint32 // rtp time
Payload []byte // 媒体数据载荷
}
// FrameWriter 包装 WriteFrame 方法的接口
type FrameWriter interface {
WriteFrame(frame *Frame) error
}
// FrameExtractor 帧提取器
type FrameExtractor interface {
Control(p *Packet) error
Extract(p *Packet) error
}
// CreateFrameExtractor 帧提取器创建方式
type CreateFrameExtractor func(w FrameWriter) FrameExtractor

View File

@@ -11,6 +11,12 @@ import (
"github.com/cnotch/xlog"
)
// FrameExtractor 帧提取器
type FrameExtractor interface {
Control(p *Packet) error
Extract(p *Packet) error
}
// FrameConverter 帧转换器
type FrameConverter struct {
closed bool

View File

@@ -7,18 +7,19 @@ package rtp
import (
"fmt"
"github.com/cnotch/ipchub/av"
"github.com/cnotch/ipchub/av/h264"
)
type h264FrameExtractor struct {
fragments []*Packet // 分片包
w FrameWriter
w av.FrameWriter
syncClock SyncClock
rtpTimeUnit int
}
// NewH264FrameExtractor 实例化 H264 帧提取器
func NewH264FrameExtractor(w FrameWriter) FrameExtractor {
func NewH264FrameExtractor(w av.FrameWriter) FrameExtractor {
return &h264FrameExtractor{
fragments: make([]*Packet, 0, 16),
w: w,
@@ -62,11 +63,10 @@ func (fe *h264FrameExtractor) Extract(packet *Packet) (err error) {
// | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | :...OPTIONAL RTP padding |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
frame := &Frame{
FrameType: FrameVideo,
NTPTime: fe.rtp2ntp(packet.Timestamp),
RTPTime: packet.Timestamp,
Payload: payload,
frame := &av.Frame{
FrameType: av.FrameVideo,
AbsTimestamp: fe.rtp2ntp(packet.Timestamp),
Payload: payload,
}
err = fe.w.WriteFrame(frame)
case naluType == h264.NalStapaInRtp:
@@ -108,11 +108,10 @@ func (fe *h264FrameExtractor) extractStapa(packet *Packet) (err error) {
}
off += 2
frame := &Frame{
FrameType: FrameVideo,
NTPTime: fe.rtp2ntp(packet.Timestamp),
RTPTime: packet.Timestamp,
Payload: make([]byte, nalSize),
frame := &av.Frame{
FrameType: av.FrameVideo,
AbsTimestamp: fe.rtp2ntp(packet.Timestamp),
Payload: make([]byte, nalSize),
}
copy(frame.Payload, payload[off:])
frame.Payload[0] = 0 | (header & 0x60) | (frame.Payload[0] & 0x1F)
@@ -168,11 +167,10 @@ func (fe *h264FrameExtractor) extractFuA(packet *Packet) (err error) {
frameLen += len(fragment.Payload()) - 2
}
frame := &Frame{
FrameType: FrameVideo,
NTPTime: fe.rtp2ntp(packet.Timestamp),
RTPTime: packet.Timestamp,
Payload: make([]byte, frameLen)}
frame := &av.Frame{
FrameType: av.FrameVideo,
AbsTimestamp: fe.rtp2ntp(packet.Timestamp),
Payload: make([]byte, frameLen)}
frame.Payload[0] = (header & 0x60) | (fuHeader & 0x1F)
offset := 1

View File

@@ -5,11 +5,12 @@
package rtp
import (
"github.com/cnotch/ipchub/av"
"github.com/cnotch/ipchub/av/aac"
)
type mpesFrameExtractor struct {
w FrameWriter
w av.FrameWriter
sizeLength int
indexLength int
// extractFunc func(packet *Packet) error
@@ -18,7 +19,7 @@ type mpesFrameExtractor struct {
}
// NewMPESFrameExtractor 实例化 MPES 帧提取器
func NewMPESFrameExtractor(w FrameWriter, rtpTimeUnit int) FrameExtractor {
func NewMPESFrameExtractor(w av.FrameWriter, rtpTimeUnit int) FrameExtractor {
fe := &mpesFrameExtractor{
w: w,
sizeLength: 13,
@@ -74,11 +75,10 @@ func (fe *mpesFrameExtractor) extractFor2ByteAUHeader(packet *Packet) (err error
for i := 0; i < int(auHeadersCount); i++ {
auHeader := uint16(0) | (uint16(auHeaders[0]) << 8) | uint16(auHeaders[1])
frameSize := auHeader >> fe.indexLength
frame := &Frame{
FrameType: FrameAudio,
NTPTime: fe.rtp2ntp(frameTimeStamp),
RTPTime: frameTimeStamp,
Payload: framesPayload[:frameSize],
frame := &av.Frame{
FrameType: av.FrameAudio,
AbsTimestamp: fe.rtp2ntp(frameTimeStamp),
Payload: framesPayload[:frameSize],
}
if err = fe.w.WriteFrame(frame); err != nil {
return
@@ -109,11 +109,10 @@ func (fe *mpesFrameExtractor) extractFor1ByteAUHeader(packet *Packet) (err error
for i := 0; i < int(auHeadersCount); i++ {
auHeader := auHeaders[0]
frameSize := auHeader >> fe.indexLength
frame := &Frame{
FrameType: FrameAudio,
NTPTime: fe.rtp2ntp(frameTimeStamp),
RTPTime: frameTimeStamp,
Payload: framesPayload[:frameSize],
frame := &av.Frame{
FrameType: av.FrameAudio,
AbsTimestamp: fe.rtp2ntp(frameTimeStamp),
Payload: framesPayload[:frameSize],
}
if err = fe.w.WriteFrame(frame); err != nil {
return