Page 1 of 1
SetVideoCallbacks
Posted: 30 Jun 2020 21:25
by burnerx
I have now used 2 days to try get video frames from stream. By samples it should be easy but I dont find proper documentation for SetVideoCallbacks and something goes wrong.
I can get those frames to files with PreviewThumbnailExtractor example. But problems come when I try get it to memory stream of bitmap without writing it to disk. Is there any possibility that someone who know that lib properly will write modified version from that PreviewThumbnailExtractor what are just simplified version what just return bitmap object or bytearray of data.
Re: SetVideoCallbacks
Posted: 01 Jul 2020 09:00
by chubinou
I have an old sample showing the use of libvlc_video_set_callbacks
https://code.videolan.org/chub/vlc-demo ... stream.cpp
PreviewThumbnailExtractor, is not the right tool to get video frame by frames
Re: SetVideoCallbacks
Posted: 01 Jul 2020 09:23
by burnerx
Oh I forgot mention that I speak c# samples.
My need is do operations for live video feed at realtime. In case that our post processor code cannot handle all frames it should start drop frames. Anyway goal is to get almost all frames processed from 30fps stream. So in that case it is right tool to do it?
Re: SetVideoCallbacks
Posted: 01 Jul 2020 11:14
by mfkl
[..] and something goes wrong.
Yeah, we're gonna need a whole lot more of details here. Start with your full code and full verbose logs.
Vlc.DotNet WPF's control has something similar to what you want:
https://github.com/ZeBobo5/Vlc.DotNet/b ... rovider.cs You could adapt the code to LibVLCSharp's API quite easily.
Re: SetVideoCallbacks
Posted: 01 Jul 2020 11:15
by mfkl
My need is do operations for live video feed at realtime.
What kind of operations?
Re: SetVideoCallbacks
Posted: 01 Jul 2020 11:31
by burnerx
[..] and something goes wrong.
Yeah, we're gonna need a whole lot more of details here. Start with your full code and full verbose logs.
Vlc.DotNet WPF's control has something similar to what you want:
https://github.com/ZeBobo5/Vlc.DotNet/b ... rovider.cs You could adapt the code to LibVLCSharp's API quite easily.
Yes that is one of samples what I have try modify. Thing is that all those samples use MemoryMappedFile to create memory allocation. Probably I just did not get right kind memory allocation or pointer out from Bitmap or array. Or is there some spesific reason why those all samples use that same MemoryMappedFile?
About question what error I got. None. I dont get any error or exception. Not even I enable them all. It will just exit process with code -1073741819.
Re: SetVideoCallbacks
Posted: 01 Jul 2020 11:45
by mfkl
Or is there some spesific reason why those all samples use that same MemoryMappedFile?
Because it seems to be the right tool for the job, see
https://docs.microsoft.com/en-us/dotnet ... etcore-3.1. You didn't mention why MemoryMappedFile isn't right for your use case, nor what you're trying to achieve.
About question what error I got. None. I dont get any error or exception. Not even I enable them all. It will just exit process with code -1073741819.
Have you enabled verbose logs? Again, share your code...
Re: SetVideoCallbacks
Posted: 01 Jul 2020 12:13
by burnerx
My need is do operations for live video feed at realtime.
What kind of operations?
pixel & byte remapping, bitwise transpose and cutting & sending it to multiple devices with proprietary protocol. Currently I manage do that with 30fps from local frames but thing is that I try get live video source from udp multicast h264 stream what offers frames instead of reading them from disk. One way to do that is receive packets with c# and then decode data with ffmpeg lib but another hand vlc can receive and decode stream so if I manage to get those decoded raw RV24 frames out from memory at decent rate then rest is easy.
Code: Select all
using LibVLCSharp.Shared;
using System;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Drawing;
using System.Drawing.Imaging;
namespace PreviewThumbnailExtractor
{
class Program
{
private const uint Width = 1920;
private const uint Height = 1080;
/// <summary>
/// RGBA is used, so 4 byte per pixel, or 32 bits.
/// </summary>
private const uint BytePerPixel = 24;
/// <summary>
/// the number of bytes per "line"
/// For performance reasons inside the core of VLC, it must be aligned to multiples of 32.
/// </summary>
private static readonly uint Pitch;
/// <summary>
/// The number of lines in the buffer.
/// For performance reasons inside the core of VLC, it must be aligned to multiples of 32.
/// </summary>
private static readonly uint Lines;
static Program()
{
Pitch = Align(Width * BytePerPixel);
Lines = Align(Height);
uint Align(uint size)
{
if (size % 32 == 0)
{
return size;
}
return ((size / 32) + 1) * 32;// Align on the next multiple of 32
}
}
static Bitmap bmp;
static BitmapData data;
private static long FrameCounter = 0;
static async Task Main(string[] args)
{
bmp = new Bitmap(1920, 1080);
data = bmp.LockBits(new System.Drawing.Rectangle(0, 0, Convert.ToInt32( Width), Convert.ToInt32(Height)), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
// Extract thumbnails in the "preview" folder next to the app
var currentDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
var destination = Path.Combine(currentDirectory, "preview");
Directory.CreateDirectory(destination);
// Load native libvlc library
Core.Initialize();
using (var libvlc = new LibVLC())
using (var mediaPlayer = new MediaPlayer(libvlc))
{
// Listen to events
var processingCancellationTokenSource = new CancellationTokenSource();
//mediaPlayer.Stopped += (s, e) => processingCancellationTokenSource.CancelAfter(1);
mediaPlayer.Stopped += MediaPlayer_Stopped;
// Create new media
var media = new Media(libvlc, new Uri("udp://@238.0.0.1:1234"));
media.AddOption(":no-audio");
// Set the size and format of the video here.
mediaPlayer.SetVideoFormat("RV24", Width, Height, Pitch);
//mediaPlayer.SetVideoFormatCallbacks(this.VideoFormat, this.CleanupVideo);
mediaPlayer.SetVideoCallbacks(Lock, null, Display);
// Start recording
mediaPlayer.Play(media);
// Waits for the processing to stop
try
{
await ProcessThumbnailsAsync(destination, processingCancellationTokenSource.Token);
}
catch (OperationCanceledException e)
{
Console.WriteLine("something went wrong :(");
}
Console.WriteLine("Done. Press any key to exit.");
Console.ReadKey();
}
}
private static void MediaPlayer_Stopped(object sender, EventArgs e)
{
Console.WriteLine("Stopped");
}
private static async Task ProcessThumbnailsAsync(string destination, CancellationToken token)
{
while (!token.IsCancellationRequested)
{
await Task.Delay(TimeSpan.FromSeconds(1), token);
}
}
private static IntPtr Lock(IntPtr opaque, IntPtr planes)
{
planes = data.Scan0;
Marshal.WriteIntPtr(planes, opaque);
return IntPtr.Zero;
}
private static void Display(IntPtr opaque, IntPtr picture)
{
FrameCounter++;
Console.WriteLine("FrameCounter");
}
}
}
Re: SetVideoCallbacks
Posted: 01 Jul 2020 12:28
by mfkl
Should be possible. Enabling verbose logs is your first step
https://code.videolan.org/videolan/LibV ... ibvlc-logs
Then join us on discord maybe, would be easier to talk.
https://discord.gg/XjYc2k