From: qydysky Date: Sun, 18 May 2025 15:44:38 +0000 (+0800) Subject: Fix 优化 (#208) X-Git-Tag: v0.18.2~2 X-Git-Url: http://127.0.0.1:8081/?a=commitdiff_plain;h=3916234a3f7e88557d955896e3c060b92fc82fde;p=bili_danmu%2F.git Fix 优化 (#208) * Fix 优化 * Fix 优化 --- diff --git a/Reply/flvDecode.go b/Reply/flvDecode.go index 881f0f1..76071d0 100644 --- a/Reply/flvDecode.go +++ b/Reply/flvDecode.go @@ -288,7 +288,6 @@ func (t *FlvDecoder) Cut(reader io.Reader, startT, duration time.Duration, w io. } func (t *FlvDecoder) CutSeed(reader io.Reader, startT, duration time.Duration, w io.Writer, seeker io.Seeker, getIndex func(seedTo time.Duration) (int64, error)) (err error) { - bufSize := humanize.KByte * 1100 buf := make([]byte, humanize.KByte*500) buff := slice.New[byte]() over := false @@ -310,14 +309,11 @@ func (t *FlvDecoder) CutSeed(reader io.Reader, startT, duration time.Duration, w } for c := 0; err == nil && !over; c++ { - if buff.Size() < bufSize { - n, e := reader.Read(buf) - if n == 0 && errors.Is(e, io.EOF) { - return io.EOF - } - err = buff.Append(buf[:n]) - continue + n, e := reader.Read(buf) + if n == 0 && errors.Is(e, io.EOF) { + return io.EOF } + err = buff.Append(buf[:n]) if !t.init { if frontBuf, dropOffset, e := t.InitFlv(buff.GetPureBuf()); e != nil { @@ -325,8 +321,6 @@ func (t *FlvDecoder) CutSeed(reader io.Reader, startT, duration time.Duration, w } else { if dropOffset != 0 { _ = buff.RemoveFront(dropOffset) - } else { - bufSize *= 2 } if len(frontBuf) == 0 { continue @@ -345,15 +339,17 @@ func (t *FlvDecoder) CutSeed(reader io.Reader, startT, duration time.Duration, w } seek = true startTM = 0 - buff.Clear() + buff.Reset() } - if dropOffset, e := t.oneF(buff.GetPureBuf(), wf); e != nil { - return perrors.New(e.Error(), ActionOneFFlv) - } else { - if dropOffset != 0 { - _ = buff.RemoveFront(dropOffset) + for { + if dropOffset, e := t.oneF(buff.GetPureBuf(), wf); e != nil { + return perrors.New(e.Error(), ActionOneFFlv) } else { - bufSize *= 2 + if dropOffset != 0 { + _ = buff.RemoveFront(dropOffset) + } else { + break + } } } } @@ -362,7 +358,6 @@ func (t *FlvDecoder) CutSeed(reader io.Reader, startT, duration time.Duration, w } func (t *FlvDecoder) GenFastSeed(reader io.Reader, save func(seedTo time.Duration, cuIndex int64) error) (err error) { - bufSize := humanize.KByte * 1100 totalRead := 0 buf := make([]byte, humanize.KByte*500) buff := slice.New[byte]() @@ -370,15 +365,12 @@ func (t *FlvDecoder) GenFastSeed(reader io.Reader, save func(seedTo time.Duratio firstFT := -1 for c := 0; err == nil && !over; c++ { - if buff.Size() < bufSize { - n, e := reader.Read(buf) - if n == 0 && errors.Is(e, io.EOF) { - return io.EOF - } - totalRead += n - err = buff.Append(buf[:n]) - continue + n, e := reader.Read(buf) + if n == 0 && errors.Is(e, io.EOF) { + return io.EOF } + totalRead += n + err = buff.Append(buf[:n]) if !t.init { if frontBuf, dropOffset, e := t.InitFlv(buff.GetPureBuf()); e != nil { @@ -386,29 +378,29 @@ func (t *FlvDecoder) GenFastSeed(reader io.Reader, save func(seedTo time.Duratio } else { if dropOffset != 0 { _ = buff.RemoveFront(dropOffset) - } else { - bufSize *= 2 } if len(frontBuf) == 0 { continue } } } else { - if dropOffset, e := t.oneF(buff.GetPureBuf(), func(t, index int, buf []byte) error { - if firstFT == -1 { - firstFT = t - } - if e := save(time.Millisecond*time.Duration(t-firstFT), int64(totalRead-buff.Size()+index)); e != nil { - return perrors.Join(ActionGenFastSeedFlv, e) - } - return nil - }); e != nil { - return perrors.Join(ActionGenFastSeedFlv, ActionOneFFlv, e) - } else { - if dropOffset != 0 { - _ = buff.RemoveFront(dropOffset) + for { + if dropOffset, e := t.oneF(buff.GetPureBuf(), func(t, index int, buf []byte) error { + if firstFT == -1 { + firstFT = t + } + if e := save(time.Millisecond*time.Duration(t-firstFT), int64(totalRead-buff.Size()+index)); e != nil { + return perrors.Join(ActionGenFastSeedFlv, e) + } + return nil + }); e != nil { + return perrors.Join(ActionGenFastSeedFlv, ActionOneFFlv, e) } else { - bufSize *= 2 + if dropOffset != 0 { + _ = buff.RemoveFront(dropOffset) + } else { + break + } } } } diff --git a/Reply/fmp4Decode.go b/Reply/fmp4Decode.go index f45c017..69f5507 100644 --- a/Reply/fmp4Decode.go +++ b/Reply/fmp4Decode.go @@ -414,7 +414,7 @@ func (t *Fmp4Decoder) Search_stream_fmp4(buf []byte, keyframe *slice.Buf[byte]) return } -type dealFMp4 func(t float64, index int, buf *slice.Buf[byte]) error +type dealFMp4 func(t float64, index int, re io.Reader) error func (t *Fmp4Decoder) oneF(buf []byte, w ...dealFMp4) (cu int, err error) { if len(buf) > humanize.MByte*100 { @@ -424,10 +424,7 @@ func (t *Fmp4Decoder) oneF(buf []byte, w ...dealFMp4) (cu int, err error) { return 0, ErrMisTraks } - t.buflock.Lock() - defer t.buflock.Unlock() - - t.buf.Reset() + sbuf := slice.NewSliceIndexNoLock(buf) defer func() { if err != nil { @@ -437,7 +434,7 @@ func (t *Fmp4Decoder) oneF(buf []byte, w ...dealFMp4) (cu int, err error) { var ( haveKeyframe bool - bufModified = t.buf.GetModified() + bufModified = sbuf.GetModified() // maxSequenceNumber int //有时并不是单调增加 maxVT float64 maxAT float64 @@ -519,7 +516,7 @@ func (t *Fmp4Decoder) oneF(buf []byte, w ...dealFMp4) (cu int, err error) { } dropKeyFrame = func(index int) { - t.buf.Reset() + sbuf.Reset() haveKeyframe = false cu = index } @@ -562,13 +559,11 @@ func (t *Fmp4Decoder) oneF(buf []byte, w ...dealFMp4) (cu int, err error) { } } - // fmt.Println(ts.getT(), "frame0", keyframeMoof, t.buf.size(), m[0].i, m[6].n, m[6].e) - //deal frame if keyframeMoof { - if v, e := t.buf.HadModified(bufModified); e == nil && v && !t.buf.IsEmpty() { + if v, e := sbuf.HadModified(bufModified); e == nil && v && !sbuf.IsEmpty() { if haveKeyframe && len(w) > 0 { - err = w[0](video.getT(), cu, t.buf) + err = w[0](video.getT(), cu, sbuf) dropKeyFrame(m[0].i) return ErrNormal } @@ -579,9 +574,7 @@ func (t *Fmp4Decoder) oneF(buf []byte, w ...dealFMp4) (cu int, err error) { cu = m[6].e } if haveKeyframe { - if e := t.buf.Append(buf[m[0].i:m[6].e]); e != nil { - return e - } + sbuf.Append(m[0].i, m[6].e) } return nil }, @@ -648,9 +641,9 @@ func (t *Fmp4Decoder) oneF(buf []byte, w ...dealFMp4) (cu int, err error) { //deal frame if keyframeMoof { - if v, e := t.buf.HadModified(bufModified); e == nil && v && !t.buf.IsEmpty() { + if v, e := sbuf.HadModified(bufModified); e == nil && v && !sbuf.IsEmpty() { if haveKeyframe && len(w) > 0 { - err = w[0](video.getT(), cu, t.buf) + err = w[0](video.getT(), cu, sbuf) dropKeyFrame(m[0].i) return ErrNormal } @@ -661,251 +654,7 @@ func (t *Fmp4Decoder) oneF(buf []byte, w ...dealFMp4) (cu int, err error) { cu = m[10].e } if haveKeyframe { - if e := t.buf.Append(buf[m[0].i:m[10].e]); e != nil { - return e - } - } - return nil - }, - }, - }, - ) - - if errors.Is(err, ErrNormal) { - err = nil - } - - return -} - -func (t *Fmp4Decoder) oneFNoBuf(buf []byte, w ...dealFMp4) (cu int, err error) { - if len(buf) > humanize.MByte*100 { - return 0, ErrBufTooLarge - } - if len(t.traks) == 0 { - return 0, ErrMisTraks - } - - defer func() { - if err != nil { - cu = 0 - } - }() - - var ( - haveKeyframe bool - // bufModified bool - // maxSequenceNumber int //有时并不是单调增加 - maxVT float64 - maxAT float64 - - //get timeStamp - get_timeStamp = func(tfdt int) (ts timeStamp) { - switch buf[tfdt+8] { - case 0: - ts.data = buf[tfdt+16 : tfdt+20] - ts.timeStamp = int(F.Btoi32(buf, tfdt+16)) - case 1: - ts.data = buf[tfdt+12 : tfdt+20] - ts.timeStamp = int(F.Btoi64(buf, tfdt+12)) - } - return - } - - //get track type - get_track_type = func(tfhd, tfdt int) (ts timeStamp, handlerType byte) { - track, ok := t.traks[int(F.Btoi(buf, tfhd+12, 4))] - if ok { - ts := get_timeStamp(tfdt) - // if track.firstTimeStamp == -1 { - // track.firstTimeStamp = ts.timeStamp - // } - - // ts.firstTimeStamp = track.firstTimeStamp - ts.handlerType = track.handlerType - ts.timescale = track.timescale - - // if ts.timeStamp > track.lastTimeStamp { - // track.lastTimeStamp = ts.timeStamp - // ts.resetTs() - // } - - return ts, track.handlerType - } - return - } - - //is SampleEntries error? - checkSampleEntries = func(trun, mdat int) error { - if buf[trun+11] == 'b' { - for i := trun + 24; i < mdat; i += 12 { - if F.Btoi(buf, i+4, 4) < 1000 { - return errors.New("find sample size less then 1000") - } - } - } - return nil - } - - //is t error? - checkAndSetMaxT = func(ts timeStamp) (err error) { - switch ts.handlerType { - case 'v': - if maxVT == 0 { - maxVT = ts.getT() - } else if maxVT == ts.getT() { - err = ActionCheckTFail.New("equal VT detect") - } else if maxVT > ts.getT() { - err = ActionCheckTFail.New("lower VT detect") - } else { - maxVT = ts.getT() - } - case 'a': - if maxAT == 0 { - maxAT = ts.getT() - } else if maxAT == ts.getT() { - err = ActionCheckTFail.New("equal AT detect") - } else if maxAT > ts.getT() { - err = ActionCheckTFail.New("lower AT detect") - } else { - maxAT = ts.getT() - } - default: - } - return - } - - dropKeyFrame = func(index int) { - haveKeyframe = false - cu = index - } - ) - - ies, recycle, e := decode(buf, "moof") - defer recycle(ies) - if e != nil { - return 0, e - } - - var ErrNormal pe.Action = "ErrNormal" - - err = deals(ies, - []dealIE{ - { - boxNames: []string{"moof", "mfhd", "traf", "tfhd", "tfdt", "trun", "mdat"}, - fs: func(m []ie) error { - var ( - keyframeMoof = buf[m[5].i+20] == byte(0x02) - // moofSN = int(F.Btoi(buf, m[1].i+12, 4)) - video timeStamp - ) - - { - ts, handlerType := get_track_type(m[3].i, m[4].i) - if ts.handlerType == 'v' { - if e := checkSampleEntries(m[5].i, m[6].i); e != nil { - //skip - dropKeyFrame(m[0].e) - return pe.Join(ErrDecode, e) - } - } - if handlerType == 'v' { - video = ts - } - if e := checkAndSetMaxT(ts); e != nil { - dropKeyFrame(m[0].e) - return pe.Join(ErrDecode, e) - } - } - - // fmt.Println(ts.getT(), "frame0", keyframeMoof, t.buf.size(), m[0].i, m[6].n, m[6].e) - - //deal frame - if keyframeMoof { - if haveKeyframe && len(w) > 0 { - err = w[0](video.getT(), cu, nil) - dropKeyFrame(m[0].i) - return ErrNormal - } - dropKeyFrame(m[0].i) - haveKeyframe = true - } else if !haveKeyframe { - cu = m[6].e - } - return nil - }, - }, - { - boxNames: []string{"moof", "mfhd", "traf", "tfhd", "tfdt", "trun", "traf", "tfhd", "tfdt", "trun", "mdat"}, - fs: func(m []ie) error { - var ( - keyframeMoof = buf[m[5].i+20] == byte(0x02) || buf[m[9].i+20] == byte(0x02) - // moofSN = int(F.Btoi(buf, m[1].i+12, 4)) - video timeStamp - audio timeStamp - ) - - { - ts, handlerType := get_track_type(m[3].i, m[4].i) - if handlerType == 'v' { - if e := checkSampleEntries(m[5].i, m[6].i); e != nil { - //skip - dropKeyFrame(m[0].e) - return pe.Join(ErrDecode, e) - } - } - switch handlerType { - case 'v': - video = ts - case 's': - audio = ts - } - if e := checkAndSetMaxT(ts); e != nil { - dropKeyFrame(m[0].e) - return pe.Join(ErrDecode, e) - } - } - { - ts, handlerType := get_track_type(m[7].i, m[8].i) - if handlerType == 'v' { - if e := checkSampleEntries(m[9].i, m[10].i); e != nil { - //skip - dropKeyFrame(m[0].e) - return pe.Join(ErrDecode, e) - } - } - switch handlerType { - case 'v': - video = ts - case 's': - audio = ts - } - if e := checkAndSetMaxT(ts); e != nil { - dropKeyFrame(m[0].e) - return pe.Join(ErrDecode, e) - } - } - - //sync audio timeStamp - if t.AVTDiff <= 0.1 { - t.AVTDiff = 0.1 - } - if diff := math.Abs(video.getT() - audio.getT()); diff > t.AVTDiff { - return pe.Join(ErrDecode, fmt.Errorf("时间戳不匹配 %v %v (或许应调整fmp4音视频时间戳容差s>%.2f)", video.timeStamp, audio.timeStamp, diff)) - // copy(video.data, F.Itob64(int64(audio.getT()*float64(video.timescale)))) - } - - //deal frame - if keyframeMoof { - if haveKeyframe && len(w) > 0 { - err = w[0](video.getT(), cu, nil) - dropKeyFrame(m[0].i) - return ErrNormal - } - dropKeyFrame(m[0].i) - haveKeyframe = true - } else if !haveKeyframe { - cu = m[10].e + sbuf.Append(m[0].i, m[10].e) } return nil }, @@ -927,7 +676,6 @@ func (t *Fmp4Decoder) Cut(reader io.Reader, startT, duration time.Duration, w io func (t *Fmp4Decoder) CutSeed(reader io.Reader, startT, duration time.Duration, w io.Writer, seeker io.Seeker, getIndex func(seedTo time.Duration) (int64, error)) (err error) { buf := make([]byte, humanize.MByte*3) - buff := slice.New[byte]() init := false seek := false over := false @@ -935,14 +683,18 @@ func (t *Fmp4Decoder) CutSeed(reader io.Reader, startT, duration time.Duration, durationM := duration.Seconds() firstFT := -1.0 - wf := func(t float64, index int, buf *slice.Buf[byte]) (e error) { + t.buflock.Lock() + defer t.buflock.Unlock() + t.buf.Reset() + + wf := func(t float64, index int, re io.Reader) (e error) { if firstFT == -1 { firstFT = t } cu := t - firstFT over = duration != 0 && cu > durationM+startTM if startTM <= cu && !over { - _, e = w.Write(buf.GetPureBuf()) + _, e = io.Copy(w, re) } return } @@ -955,10 +707,10 @@ func (t *Fmp4Decoder) CutSeed(reader io.Reader, startT, duration time.Duration, if n == 0 && errors.Is(e, io.EOF) { return io.EOF } - err = buff.Append(buf[:n]) + err = t.buf.Append(buf[:n]) if !init { - if frontBuf, e := t.Init_fmp4(buff.GetPureBuf()); e != nil { + if frontBuf, e := t.Init_fmp4(t.buf.GetPureBuf()); e != nil { return pe.New(e.Error(), ActionInitFmp4) } else { if len(frontBuf) == 0 { @@ -982,14 +734,14 @@ func (t *Fmp4Decoder) CutSeed(reader io.Reader, startT, duration time.Duration, } seek = true startTM = 0 - buff.Clear() + t.buf.Reset() } for { - if dropOffset, e := t.oneF(buff.GetPureBuf(), wf); e != nil { + if dropOffset, e := t.oneF(t.buf.GetPureBuf(), wf); e != nil { return pe.New(e.Error(), ActionOneFFmp4) } else { if dropOffset != 0 { - _ = buff.RemoveFront(dropOffset) + _ = t.buf.RemoveFront(dropOffset) } else { break } @@ -1028,7 +780,7 @@ func (t *Fmp4Decoder) GenFastSeed(reader io.Reader, save func(seedTo time.Durati } } else { for { - if dropOffset, e := t.oneFNoBuf(t.buf.GetPureBuf(), func(ts float64, index int, _ *slice.Buf[byte]) error { + if dropOffset, e := t.oneF(t.buf.GetPureBuf(), func(ts float64, index int, _ io.Reader) error { if firstFT == -1 { firstFT = ts } diff --git a/go.mod b/go.mod index 29a2dfa..d9ab673 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.24 require ( github.com/gotk3/gotk3 v0.6.4 github.com/mdp/qrterminal/v3 v3.2.0 - github.com/qydysky/part v0.28.20250514163050 + github.com/qydysky/part v0.28.20250518084643 github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 golang.org/x/text v0.24.0 // indirect diff --git a/go.sum b/go.sum index 70d831f..e036c9d 100644 --- a/go.sum +++ b/go.sum @@ -46,8 +46,8 @@ github.com/qydysky/biliApi v0.0.0-20250509210314-8407d638b123 h1:YXqqrwvzFwfs8Lo github.com/qydysky/biliApi v0.0.0-20250509210314-8407d638b123/go.mod h1:1FbgCj+aOwIvuRRuX/l5uTLb3JIwWyJSa0uEfwpYV/8= github.com/qydysky/brotli v0.0.0-20240828134800-e9913a6e7ed9 h1:k451T+bpsLr+Dq9Ujo+Qtx0iomRA1XXS5ttlEojvfuQ= github.com/qydysky/brotli v0.0.0-20240828134800-e9913a6e7ed9/go.mod h1:cI8/gy/wjy2Eb+p2IUj2ZuDnC8R5Vrx3O0VMPvMvphA= -github.com/qydysky/part v0.28.20250514163050 h1:BQ7pNQWmXkW/sP2wQchORO3L0cGW6cX8jqvlQVGm5G4= -github.com/qydysky/part v0.28.20250514163050/go.mod h1:wp71PQdKYcg9jn9yDDvqC4shS/kzejyvFqbfUxuHocY= +github.com/qydysky/part v0.28.20250518084643 h1:6hhY+O/pe4ynY7tL21VDZ9kVMr+i0bBAD4F5TfNHRA8= +github.com/qydysky/part v0.28.20250518084643/go.mod h1:wp71PQdKYcg9jn9yDDvqC4shS/kzejyvFqbfUxuHocY= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=