mirror of
https://github.com/cnotch/ipchub.git
synced 2025-09-26 19:41:18 +08:00
move rtp.Frame to av.Frame
This commit is contained in:
23
av/frame.go
Normal file
23
av/frame.go
Normal 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
|
||||
}
|
@@ -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,
|
||||
}
|
||||
|
@@ -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
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user