fix: demuxer mp4 one more time

This commit is contained in:
langhuihui
2025-02-13 14:02:55 +08:00
parent 942eeb11b0
commit a5399ed11f
5 changed files with 64 additions and 34 deletions
+5 -5
View File
@@ -15,7 +15,7 @@ type (
BoxHeader interface {
Type() BoxType
HeaderSize() uint32
Size() uint32
Size() uint64
Header() BoxHeader
HeaderWriteTo(w io.Writer) (n int64, err error)
}
@@ -85,7 +85,7 @@ func CreateContainerBox(typ BoxType, children ...IBox) *ContainerBox {
if reflect.ValueOf(child).IsNil() {
continue
}
size += child.Size()
size += uint32(child.Size())
realChildren = append(realChildren, child)
}
return &ContainerBox{
@@ -101,9 +101,9 @@ func (b *BigBox) HeaderSize() uint32 { return BasicBoxLen + 8 }
func (b *BaseBox) Header() BoxHeader { return b }
func (b *BaseBox) HeaderSize() uint32 { return BasicBoxLen }
func (b *BaseBox) Size() uint32 { return b.size }
func (b *BaseBox) Type() BoxType { return b.typ }
func (b *BaseBox) Size() uint64 { return uint64(b.size) }
func (b *BigBox) Size() uint64 { return uint64(b.size) }
func (b *BaseBox) Type() BoxType { return b.typ }
func (b *BaseBox) HeaderWriteTo(w io.Writer) (n int64, err error) {
var tmp [4]byte
+14
View File
@@ -16,6 +16,20 @@ type MediaDataBox struct {
net.Buffers
}
func (box *MediaDataBox) HeaderSize() uint32 {
if box.size == 1 {
return BasicBoxLen + 8
}
return BasicBoxLen
}
func (box *MediaDataBox) Size() uint64 {
if box.size == 1 {
return uint64(len(box.Data)) + 8 + 8
}
return uint64(box.size)
}
func (box *MediaDataBox) WriteTo(w io.Writer) (n int64, err error) {
var tmp [8]byte
var buffers net.Buffers
+7
View File
@@ -144,6 +144,13 @@ func (t *TrakBox) ParseSamples() (samplelist []Sample) {
}
}
}
if stbl.STSS != nil {
for _, keyIndex := range stbl.STSS.Entries {
samplelist[keyIndex-1].KeyFrame = true
}
}
return samplelist
}
+7 -3
View File
@@ -49,9 +49,10 @@ type (
ReadSampleIdx []uint32
IsFragment bool
// pssh []*PsshBox
moov *MoovBox
mdat *MediaDataBox
QuicTime bool
moov *MoovBox
mdat *MediaDataBox
mdatOffset uint64
QuicTime bool
}
)
@@ -96,6 +97,7 @@ func (d *Demuxer) Demux() (err error) {
// return
// }
var b IBox
var offset uint64
for {
b, err = box.ReadFrom(d.reader)
if err != nil {
@@ -104,6 +106,7 @@ func (d *Demuxer) Demux() (err error) {
}
return err
}
offset += b.Size()
switch box := b.(type) {
case *FileTypeBox:
if slices.Contains(box.CompatibleBrands, [4]byte{'q', 't', ' ', ' '}) {
@@ -112,6 +115,7 @@ func (d *Demuxer) Demux() (err error) {
case *FreeBox:
case *MediaDataBox:
d.mdat = box
d.mdatOffset = offset - b.Size() + uint64(box.HeaderSize())
case *MoovBox:
if box.MVEX != nil {
d.IsFragment = true
+31 -26
View File
@@ -1,7 +1,6 @@
package mp4
import (
"io"
"os"
"strings"
"time"
@@ -40,10 +39,10 @@ func NewPuller(conf config.Pull) m7s.IPuller {
func (p *RecordReader) Run() (err error) {
pullJob := &p.PullJob
publisher := pullJob.Publisher
allocator := util.NewScalableMemoryAllocator(1 << 10)
// allocator := util.NewScalableMemoryAllocator(1 << 10)
var ts, tsOffset int64
var realTime time.Time
defer allocator.Recycle()
// defer allocator.Recycle()
publisher.OnGetPosition = func() time.Time {
return realTime
}
@@ -67,17 +66,17 @@ func (p *RecordReader) Run() (err error) {
switch track.Cid {
case box.MP4_CODEC_H264:
var sequence rtmp.RTMPVideo
sequence.SetAllocator(allocator)
// sequence.SetAllocator(allocator)
sequence.Append([]byte{0x17, 0x00, 0x00, 0x00, 0x00}, track.ExtraData)
err = publisher.WriteVideo(&sequence)
case box.MP4_CODEC_H265:
var sequence rtmp.RTMPVideo
sequence.SetAllocator(allocator)
// sequence.SetAllocator(allocator)
sequence.Append([]byte{0b1001_0000 | rtmp.PacketTypeSequenceStart}, codec.FourCC_H265[:], track.ExtraData)
err = publisher.WriteVideo(&sequence)
case box.MP4_CODEC_AAC:
var sequence rtmp.RTMPAudio
sequence.SetAllocator(allocator)
// sequence.SetAllocator(allocator)
sequence.Append([]byte{0xaf, 0x00}, track.ExtraData)
err = publisher.WriteAudio(&sequence)
}
@@ -109,14 +108,19 @@ func (p *RecordReader) Run() (err error) {
goto nextStream
}
if _, err = p.demuxer.reader.Seek(sample.Offset, io.SeekStart); err != nil {
return
}
sample.Data = allocator.Malloc(sample.Size)
if _, err = io.ReadFull(p.demuxer.reader, sample.Data); err != nil {
allocator.Free(sample.Data)
// if _, err = p.demuxer.reader.Seek(sample.Offset, io.SeekStart); err != nil {
// return
// }
sampleOffset := int(sample.Offset) - int(p.demuxer.mdatOffset)
if sampleOffset < 0 || sampleOffset+sample.Size > len(p.demuxer.mdat.Data) {
return
}
sample.Data = p.demuxer.mdat.Data[sampleOffset : sampleOffset+sample.Size]
// sample.Data = allocator.Malloc(sample.Size)
// if _, err = io.ReadFull(p.demuxer.reader, sample.Data); err != nil {
// allocator.Free(sample.Data)
// return
// }
ts = int64(sample.DTS + uint64(tsOffset))
realTime = stream.StartTime.Add(time.Duration(sample.DTS) * time.Millisecond)
if p.MaxTS > 0 && ts > p.MaxTS {
@@ -125,15 +129,15 @@ func (p *RecordReader) Run() (err error) {
switch track.Cid {
case box.MP4_CODEC_H264:
var videoFrame rtmp.RTMPVideo
videoFrame.SetAllocator(allocator)
// videoFrame.SetAllocator(allocator)
videoFrame.CTS = uint32(sample.PTS - sample.DTS)
videoFrame.Timestamp = uint32(ts)
videoFrame.AppendOne([]byte{util.Conditional[byte](sample.KeyFrame, 0x17, 0x27), 0x01, byte(videoFrame.CTS >> 24), byte(videoFrame.CTS >> 8), byte(videoFrame.CTS)})
videoFrame.AddRecycleBytes(sample.Data)
videoFrame.Append([]byte{util.Conditional[byte](sample.KeyFrame, 0x17, 0x27), 0x01, byte(videoFrame.CTS >> 24), byte(videoFrame.CTS >> 8), byte(videoFrame.CTS)}, sample.Data)
// videoFrame.AddRecycleBytes(sample.Data)
err = publisher.WriteVideo(&videoFrame)
case box.MP4_CODEC_H265:
var videoFrame rtmp.RTMPVideo
videoFrame.SetAllocator(allocator)
// videoFrame.SetAllocator(allocator)
videoFrame.CTS = uint32(sample.PTS - sample.DTS)
videoFrame.Timestamp = uint32(ts)
var head []byte
@@ -150,28 +154,29 @@ func (p *RecordReader) Run() (err error) {
util.PutBE(head[5:8], videoFrame.CTS) // cts
}
copy(head[1:], codec.FourCC_H265[:])
videoFrame.AddRecycleBytes(sample.Data)
videoFrame.Append(head, sample.Data)
// videoFrame.AddRecycleBytes(sample.Data)
err = publisher.WriteVideo(&videoFrame)
case box.MP4_CODEC_AAC:
var audioFrame rtmp.RTMPAudio
audioFrame.SetAllocator(allocator)
// audioFrame.SetAllocator(allocator)
audioFrame.Timestamp = uint32(ts)
audioFrame.AppendOne([]byte{0xaf, 0x01})
audioFrame.AddRecycleBytes(sample.Data)
audioFrame.Append([]byte{0xaf, 0x01}, sample.Data)
// audioFrame.AddRecycleBytes(sample.Data)
err = publisher.WriteAudio(&audioFrame)
case box.MP4_CODEC_G711A:
var audioFrame rtmp.RTMPAudio
audioFrame.SetAllocator(allocator)
// audioFrame.SetAllocator(allocator)
audioFrame.Timestamp = uint32(ts)
audioFrame.AppendOne([]byte{0x72})
audioFrame.AddRecycleBytes(sample.Data)
audioFrame.Append([]byte{0x72}, sample.Data)
// audioFrame.AddRecycleBytes(sample.Data)
err = publisher.WriteAudio(&audioFrame)
case box.MP4_CODEC_G711U:
var audioFrame rtmp.RTMPAudio
audioFrame.SetAllocator(allocator)
// audioFrame.SetAllocator(allocator)
audioFrame.Timestamp = uint32(ts)
audioFrame.AppendOne([]byte{0x82})
audioFrame.AddRecycleBytes(sample.Data)
audioFrame.Append([]byte{0x82}, sample.Data)
// audioFrame.AddRecycleBytes(sample.Data)
err = publisher.WriteAudio(&audioFrame)
}
}