Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
4.5 kB · 137 lines
Go
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138package media
import ( "bytes" "context" "crypto/sha256" "encoding/hex" "os" "testing"
"github.com/go-gst/go-gst/gst" "github.com/go-gst/go-gst/gst/app" "github.com/stretchr/testify/require" "stream.place/streamplace/pkg/log")
// TestRandomAccessSrcBin_Passthrough verifies that the bin drains the// supplied ReaderAt end-to-end and the bytes arriving at an appsink// exactly match the source data, both byte-count and content.func TestRandomAccessSrcBin_Passthrough(t *testing.T) { withNoGSTLeaks(t, func() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() ctx = log.WithLogValues(ctx, "test", "TestRandomAccessSrcBin_Passthrough")
fixture, err := os.ReadFile(getFixture("sample-segment.mp4")) require.NoError(t, err) require.NotEmpty(t, fixture)
pipeline, err := gst.NewPipeline("ra-src-passthrough") require.NoError(t, err)
srcBin, err := RandomAccessSrcBin(ctx, "ra-src", bytes.NewReader(fixture), int64(len(fixture))) require.NoError(t, err) require.NoError(t, pipeline.Add(srcBin.Element))
sinkEle, err := gst.NewElementWithProperties("appsink", map[string]interface{}{ "name": "ra-sink", "sync": false, }) require.NoError(t, err) require.NoError(t, pipeline.Add(sinkEle))
ghostPad := srcBin.GetStaticPad("src") require.NotNil(t, ghostPad) sinkPad := sinkEle.GetStaticPad("sink") require.NotNil(t, sinkPad) require.Equal(t, gst.PadLinkOK, ghostPad.Link(sinkPad))
out := &bytes.Buffer{} sink := app.SinkFromElement(sinkEle) sink.SetCallbacks(&app.SinkCallbacks{ NewSampleFunc: WriterNewSample(ctx, out), })
errCh := make(chan error, 1) go func() { errCh <- HandleBusMessages(ctx, pipeline) }()
require.NoError(t, pipeline.SetState(gst.StatePlaying)) require.NoError(t, <-errCh) require.NoError(t, pipeline.BlockSetState(gst.StateNull))
require.Equal(t, fixture, out.Bytes()) })}
// TestRandomAccessSrcBin_Seek exercises the random-access path by having a// downstream identity element issue manual seek events. We hash the bytes// arriving at the appsink and compare against a known good full-file hash;// if any seek lands at the wrong offset or returns the wrong slice of// bytes, this catches it.func TestRandomAccessSrcBin_Seek(t *testing.T) { withNoGSTLeaks(t, func() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() ctx = log.WithLogValues(ctx, "test", "TestRandomAccessSrcBin_Seek")
fixture, err := os.ReadFile(getFixture("sample-segment.mp4")) require.NoError(t, err) require.GreaterOrEqual(t, len(fixture), 1024)
// Read three disjoint regions via two seeks. Compare to direct // fixture slices. reader := bytes.NewReader(fixture) size := int64(len(fixture))
check := func(name string, offset, length int64) { pipeline, err := gst.NewPipeline("ra-src-seek-" + name) require.NoError(t, err)
srcBin, err := RandomAccessSrcBin(ctx, "ra-src", reader, size) require.NoError(t, err) require.NoError(t, pipeline.Add(srcBin.Element))
sinkEle, err := gst.NewElementWithProperties("appsink", map[string]interface{}{ "name": "ra-sink", "sync": false, }) require.NoError(t, err) require.NoError(t, pipeline.Add(sinkEle))
require.Equal(t, gst.PadLinkOK, srcBin.GetStaticPad("src").Link(sinkEle.GetStaticPad("sink")))
out := &bytes.Buffer{} sink := app.SinkFromElement(sinkEle) sink.SetCallbacks(&app.SinkCallbacks{ NewSampleFunc: WriterNewSample(ctx, out), })
errCh := make(chan error, 1) go func() { errCh <- HandleBusMessages(ctx, pipeline) }() require.NoError(t, pipeline.SetState(gst.StatePaused))
// Issue a byte-format seek into the desired range. ok := pipeline.SeekSimple(offset, gst.FormatBytes, gst.SeekFlagFlush) require.True(t, ok, "%s: seek to %d failed", name, offset)
require.NoError(t, pipeline.SetState(gst.StatePlaying)) require.NoError(t, <-errCh) require.NoError(t, pipeline.BlockSetState(gst.StateNull))
got := out.Bytes() require.GreaterOrEqual(t, len(got), int(length), "%s: expected at least %d bytes, got %d", name, length, len(got))
wantH := sha256.Sum256(fixture[offset : offset+length]) gotH := sha256.Sum256(got[:length]) require.Equal(t, hex.EncodeToString(wantH[:]), hex.EncodeToString(gotH[:]), "%s: byte mismatch at offset %d len %d", name, offset, length) }
// Tail slice check("tail", size-1024, 1024) // Middle slice check("middle", size/2, 1024) // Head slice check("head", 0, 1024) })}