mirror of
https://github.com/langhuihui/monibuca.git
synced 2026-05-07 23:13:26 +08:00
fix: demuxer mp4 one more time
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user