Hello! I’m receiving raw h264 i- and p-frames from RTSP stream using RtspClientSharp (C# library). I’m trying to push that frames to appsrc and convert them into JPEG, but something goes wrong and appsink doesn’t emit new-sample signal. Here is my code:
using System.Net;
using Gst;
using Gst.App;
using RtspClientSharp;
using RtspClientSharp.RawFrames;
using Format = Gst.Format;
using Task = System.Threading.Tasks.Task;
using Uri = System.Uri;
Application.Init();
var uri = new Uri("rtsp://x.x.x.x/onvif/media?profile=Profile1");
var credentials = new NetworkCredential("xxx", "xxx");
var rtspClient = new RtspClient(new ConnectionParameters(uri, credentials));
using var pipeline = new Pipeline("ppl");
using var source = ElementFactory.Make("appsrc", "source");
using var h264parse = ElementFactory.Make("h264parse", "h264parse");
using var avdec_h264 = ElementFactory.Make("avdec_h264", "avdec_h264");
using var jpegenc = ElementFactory.Make("jpegenc", "jpegenc");
using var sink = new AppSink("sink");
pipeline.Add(source, h264parse, avdec_h264, jpegenc, sink);
source.Link(h264parse);
h264parse.Link(avdec_h264);
avdec_h264.Link(jpegenc);
jpegenc.Link(sink);
rtspClient.FrameReceived += async (sender, frame) =>
{
if (frame.Type != FrameType.Video) return;
using var gstBuffer = new Gst.Buffer(frame.FrameSegment.Array!);
using var caps = Caps.FromString("video/x-h264");
var segment = new Segment();
using var structure = new Structure("frame");
structure.SetValue("width", new GLib.Value(1280));
structure.SetValue("height", new GLib.Value(720));
using var gstSample = new Sample(gstBuffer, caps, segment, structure);
source.Emit("push-sample", gstSample);
if (pipeline.CurrentState is not State.Playing)
pipeline.SetState(State.Playing);
await Task.CompletedTask;
};
sink.NewSample += (object sender, NewSampleArgs args) =>
{
var sink = sender as AppSink;
using var sample = sink!.PullSample();
using var buffer = sample.Buffer;
var size = buffer.Size;
// Read the JPEG image from the buffer
var jpegData = new byte[size];
buffer.Extract(0, ref jpegData);
Console.WriteLine("Received JPEG image data.");
};
await rtspClient.ConnectAsync(CancellationToken.None);
await rtspClient.ReceiveAsync(CancellationToken.None);
while (true)
{
await Task.Delay(1000);
}
If I set GST_DEBUG to 2 I get following output:
0:00:00.302714100 8860 0000029AFA55E180 WARN h264parse gsth264parse.c:4072:gst_h264_parse_set_caps:<h264parse> video/x-h264 caps without codec_data or stream-format
0:00:00.304448000 8860 0000029AFA55E180 WARN codecparsers_h264 gsth264parser.c:2474:gst_h264_parser_parse_slice_hdr: couldn't find associated picture parameter set with id: 0
0:00:00.304749700 8860 0000029AFA55E180 WARN h264parse gsth264parse.c:2028:gst_h264_parse_handle_frame:<h264parse> Failed to update backlog
0:00:00.305084200 8860 0000029AFA55E180 WARN codecparsers_h264 gsth264parser.c:2474:gst_h264_parser_parse_slice_hdr: couldn't find associated picture parameter set with id: 0
0:00:00.305365700 8860 0000029AFA55E180 WARN h264parse gsth264parse.c:2028:gst_h264_parse_handle_frame:<h264parse> Failed to update backlog
0:00:00.305703600 8860 0000029AFA55E180 WARN codecparsers_h264 gsth264parser.c:2474:gst_h264_parser_parse_slice_hdr: couldn't find associated picture parameter set with id: 0
0:00:00.305973300 8860 0000029AFA55E180 WARN h264parse gsth264parse.c:2028:gst_h264_parse_handle_frame:<h264parse> Failed to update backlog
What am I doing wrong?