package astiav import ( "strings" "testing" "github.com/stretchr/testify/require" ) func TestFormatContext(t *testing.T) { fc1, err := globalHelper.inputFormatContext("video.mp4", nil) require.NoError(t, err) ss := fc1.Streams() require.Len(t, ss, 2) s1 := ss[0] require.Equal(t, int64(607664), fc1.BitRate()) require.Equal(t, NewFormatContextCtxFlags(0), fc1.CtxFlags()) require.Equal(t, int64(5013333), fc1.Duration()) require.True(t, fc1.EventFlags().Has(FormatEventFlagMetadataUpdated)) require.True(t, fc1.Flags().Has(FormatContextFlagAutoBsf)) require.Equal(t, NewRational(24, 1), fc1.GuessFrameRate(s1, nil)) require.Equal(t, NewRational(1, 1), fc1.GuessSampleAspectRatio(s1, nil)) require.True(t, fc1.InputFormat().Flags().Has(IOFormatFlagNoByteSeek)) require.Equal(t, IOContextFlags(0), fc1.IOFlags()) require.Equal(t, int64(0), fc1.MaxAnalyzeDuration()) require.Equal(t, "isom", fc1.Metadata().Get("major_brand", nil, NewDictionaryFlags()).Value()) require.Equal(t, int64(0), fc1.StartTime()) require.Equal(t, 2, fc1.NbStreams()) require.Len(t, fc1.Streams(), 2) cl := fc1.Class() require.NotNil(t, cl) require.Equal(t, "AVFormatContext", cl.Name()) sdp, err := fc1.SDPCreate() require.NoError(t, err) require.Equal(t, "v=0\r\no=- 0 0 IN IP4 127.0.0.1\r\ns=Big Buck Bunny\r\nt=0 0\r\na=tool:libavformat 61.1.100\r\nm=video 0 RTP/AVP 96\r\nb=AS:441\r\na=rtpmap:96 H264/90000\r\na=fmtp:96 packetization-mode=1; sprop-parameter-sets=Z0LADasgKDPz4CIAAAMAAgAAAwBhHihUkA==,aM48gA==; profile-level-id=42C00D\r\na=control:streamid=0\r\nm=audio 0 RTP/AVP 97\r\nb=AS:161\r\na=rtpmap:97 MPEG4-GENERIC/48000/2\r\na=fmtp:97 profile-level-id=1;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3; config=1190\r\na=control:streamid=1\r\n", sdp) SetLogLevel(LogLevelInfo) SetLogCallback(func(c Classer, l LogLevel, f, msg string) { msg = strings.TrimSpace(msg) if strings.HasPrefix(msg, "Stream") && strings.Contains(msg, "Video") { require.Equal(t, msg, `Stream #0:0[0x1](und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p(progressive), 320x180 [SAR 1:1 DAR 16:9], 441 kb/s, 24 fps, 24 tbr, 12288 tbn (default)`) } }) fc1.Dump(0, "video.mp4", false) _, _, err = fc1.FindBestStream(MediaTypeUnknown, -1, -1) require.Error(t, err) s2, c1, err := fc1.FindBestStream(MediaTypeVideo, -1, -1) require.NoError(t, err) require.Equal(t, s1.Index(), s2.Index()) require.Equal(t, s1.CodecParameters().CodecID(), c1.ID()) s2, c1, err = fc1.FindBestStream(MediaTypeAudio, 1, 0) require.NoError(t, err) require.Equal(t, 1, s2.Index()) fc2, err := AllocOutputFormatContext(nil, "mp4", "") require.NoError(t, err) defer fc2.Free() require.True(t, fc2.OutputFormat().Flags().Has(IOFormatFlagGlobalheader)) fc3 := AllocFormatContext() require.NotNil(t, fc3) defer fc3.Free() io, err := OpenIOContext("testdata/video.mp4", NewIOContextFlags(IOContextFlagRead)) require.NoError(t, err) defer io.Close() //nolint:errcheck fc3.SetPb(io) fc3.SetStrictStdCompliance(StrictStdComplianceExperimental) fc3.SetFlags(NewFormatContextFlags(FormatContextFlagAutoBsf)) require.NotNil(t, fc3.Pb()) require.Equal(t, StrictStdComplianceExperimental, fc3.StrictStdCompliance()) require.True(t, fc3.Flags().Has(FormatContextFlagAutoBsf)) s3 := fc3.NewStream(nil) require.NotNil(t, s3) s4 := fc3.NewStream(nil) require.NotNil(t, s4) require.Equal(t, 1, s4.Index()) d := NewDictionary() d.Set("k", "v", 0) fc3.SetMetadata(d) e := fc3.Metadata().Get("k", nil, 0) require.NotNil(t, e) require.Equal(t, "v", e.Value()) fc3.SetMetadata(nil) require.Nil(t, fc3.Metadata()) fc4 := AllocFormatContext() require.NotNil(t, fc4) defer fc4.Free() fc4.SetInterruptCallback().Interrupt() require.ErrorIs(t, fc4.OpenInput("testdata/video.mp4", nil, nil), ErrExit) fc5 := AllocFormatContext() require.NotNil(t, fc5) defer fc5.Free() require.NotNil(t, fc5.NewProgram(1)) require.Equal(t, 1, fc5.NbPrograms()) ps := fc5.Programs() require.Equal(t, 1, len(ps)) require.Equal(t, 1, ps[0].ID()) fc6 := AllocFormatContext() require.NotNil(t, fc6) defer fc6.Free() require.NoError(t, fc6.OpenInput("testdata/video.mp4", nil, nil)) require.NoError(t, fc6.FindStreamInfo(nil)) require.Equal(t, 2, fc6.NbStreams()) pkt1 := AllocPacket() require.NotNil(t, pkt1) defer pkt1.Free() require.NoError(t, fc6.ReadFrame(pkt1)) require.Equal(t, int64(48), pkt1.Pos()) pkt2 := AllocPacket() require.NotNil(t, pkt2) defer pkt2.Free() require.NoError(t, fc6.ReadFrame(pkt2)) require.Equal(t, int64(261), pkt2.Pos()) require.NoError(t, fc6.SeekFrame(0, 0, NewSeekFlags().Add(SeekFlagBackward))) require.NoError(t, fc6.ReadFrame(pkt1)) require.Equal(t, int64(48), pkt1.Pos()) const outputPath = "tmp/test-format-context-output.mp4" fc7, err := AllocOutputFormatContext(nil, "", outputPath) require.NoError(t, err) defer fc7.Free() for _, is := range fc6.Streams() { os := fc7.NewStream(nil) require.NotNil(t, os) require.NoError(t, is.CodecParameters().Copy(os.CodecParameters())) } ic, err := OpenIOContext(outputPath, NewIOContextFlags(IOContextFlagWrite)) require.NoError(t, err) fc7.SetPb(ic) require.NoError(t, fc7.WriteHeader(nil)) require.NoError(t, fc7.WriteFrame(pkt1)) require.NoError(t, fc7.WriteInterleavedFrame(pkt2)) require.NoError(t, fc7.WriteTrailer()) require.NoError(t, fc7.Flush()) fc8 := AllocFormatContext() require.NotNil(t, fc8) defer fc8.Free() require.NoError(t, fc8.OpenInput(outputPath, nil, nil)) require.NoError(t, fc8.FindStreamInfo(nil)) require.Equal(t, 2, fc8.NbStreams()) pkt3 := AllocPacket() require.NotNil(t, pkt3) defer pkt3.Free() require.NoError(t, fc8.ReadFrame(pkt3)) require.Equal(t, int64(48), pkt3.Pos()) pkt4 := AllocPacket() require.NotNil(t, pkt4) defer pkt4.Free() require.NoError(t, fc8.ReadFrame(pkt4)) require.Equal(t, int64(261), pkt4.Pos()) }