-
Notifications
You must be signed in to change notification settings - Fork 104
Convering the Stored Encoded Stream to Mpeg #276
Hey PSI community,
A PSI newbie here.
I have a set of psi stores containing both video and audio streams from a study conducted by a former student of my Advisor. Now I am trying to convert them to some standard format (MPEG) to be able to use in another tool.
Based on my naive understanding of PSI, I wrote the following code to first decode the Image stream and use MPEGWriter to write them as MPEG files. The code works as expected however its runtime is a disaster (it takes 14 minutes to convert a 30-second video).
Basically, I am asking if this is the expected behavior of the system. I'd appreciate any pointers to help me speed up this code.
`
IProducer<Shared> participant_feed = store.OpenStream<Shared>("Video");
var writer = new Mpeg4Writer(pipeline, "output.mp4", 640, 480, PixelFormat.BGR_24bpp);
participant_feed.Out.Decode().PipeTo(writer.ImageIn, DeliveryPolicy.Unlimited);
var replay_fast = new ReplayDescriptor(
new TimeInterval(leftPoint:start_date, rightPoint: end_date), // I set this so there is ~30 seconds between start and end date
replaySpeedFactor: 100f,
useOriginatingTime: false,
enforceReplayClock: false
);
pipeline.Run(replay_fast);
`
Any help would be greatly appreciated.
All reactions
Replies: 2 comments
Same problem here. +1
All reactions
Thanks for your question. We have also observed finicky behavior in runtime speed when exporting outside of \psi to mpeg. It seems the underlying Windows media technology used by our component does a lot of aggressive locking and throttling, and it's easy to get into a state where all messages get queued up in front of it for a long time before being slowly processed.
There are a couple changes to your code that I can suggest, which should hopefully help:
- Create your pipeline with a default delivery policy of
DeliveryPolicy.Throttle, and don't useDeliveryPolicy.Unlimited. This ensures that the store reader delivers all messages, but only as fast as the mpeg writer can process them. Otherwise all messages will be pushed into a huge queue at infinite speed, and you might run out of memory if processing larger files. This is good practice for all pipelines that are intended to process existing data, rather than instantiate a live system. - If your mpeg doesn't have audio, make sure to specify that in its configuration.
- You can simply run the pipeline with the
ReplayAllreplay descriptor to have it run as fast as possible.
Try something like the code below, and please let us know if the observed execution time improves or stays about the same.
using var pipeline = Pipeline.Create(deliveryPolicy: DeliveryPolicy.Throttle); IProducer<Shared> participant_feed = store.OpenStream<Shared>("Video"); var writer = new Mpeg4Writer(pipeline, "output.mp4", new Mpeg4WriterConfiguration() { ImageWidth = 640, ImageHeight = 480, PixelFormat = PixelFormat.BGR_24bpp, ContainsAudio = false, }); participant_feed.Out.Decode().PipeTo(writer.ImageIn); var startTime = DateTime.Now; pipeline.RunAsync(ReplayDescriptor.ReplayAll, progress: new Progress<double>(p => Console.Write($"Progress: {p:P} Time elapsed: {DateTime.Now - startTime}\r"))); pipeline.WaitAll(); Console.WriteLine($"Done in {DateTime.Now - startTime}.");
All reactions
-
👍 1