Context: I'm looking at the effects of down sampling, then up sampling video files. I'm using Media Foundation .NET to expose MF in C#. Program currently goes through following process:
Take a high res video and read in each frame (SourceReader & ReadSample)
Down sample using custom code that manipulates at the byte level
Write the down sampled data to a new, lower res video file (using SinkWriter)
Repeat for a range of resolutions supported by Media Foundation
Read down sampled videos back in and up sample to the next higher resolution in the list below, again using custom code that manipulates each byte
Write the new data to a higher res file (again using SinkWriter)
Resolutions I'm using are:
2560,1440
2346,1320
2134,1200
1920,1080
1706,960
1494,840
1280,720
1068,600
854,480
640,360
428,240
214,120
Current situation: This works almost perfectly. I run through the down sample process and have 11 down sampled video files (one at each resolution in the list above), plus the original 1440p video. I then read in each of those 11 videos and up sample. It works for 10 of them.
The problem: when I try to take the (1280,720) video to up sample to (1494,840), I get:
System.AccessViolationException: 'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.'
... when I try to read in the first frame. I can't figure out why. The SourceReader configures fine (at least, no error returns). I do things like Marshal.Copy to get the sampled frame data into managed memory space, which I initially assumed was the problem. Code doesn't get that far though - just errors as soon as I try to read the first frame sample. ReadSample is in a Try...Catch block, but exception remains unhandled, so no other error information returned.
I don't want to just start pasting in unhelpful code, so please let me know what is useful to see and I'll add to the question. Most of the code has been taken from MS tutorials for SourceReader and SinkWriter. Also worth keeping in mind that this works in most situations, so code isn't 'broken' as such.
I've tried compiling in Release and Debug, x86 and x64. Also tried Suppressing JIT Optimisation in Visual Studio options.
Any ideas on where to look next?
Turns out this is a problem with the Media Foundation .NET interface, not the underlying MF framework. I built a small test program in C++ that implemented key parts of the code and it went through fine.
Not sure why Media Foundation .NET was causing problems, but the solution was just to set attribute:
MF_SOURCE_READER_ENABLE_ADVANCED_VIDEO_PROCESSING
rather than
MF_SOURCE_READER_ENABLE_VIDEO_PROCESSING
With advanced processing on, it behaves properly.
Related
I was successful on training and evaluate networks based on the CIFAR-10 samples. I'm using my own images with specific size . The networks were trained with GPU and able to evaluate with CPU. However, I'm not able to evaluate it with with GPU. The evaluation is using C# EvalDLL Wrapper. The deviceID is change from -1 to 0 to indicate the GPU # as shown below:
model0.CreateNetwork(string.Format("modelPath=\"{0}\"", modelFilePath), deviceId: 0);
Did I missed something?
Can anyone run GPU on C# EvalDLL Wrapper program ?
I'm using binary version of the CNTK (not CPU_Only).
I'm able to run the EvalWrapper on a GPU, using exactly the code you posted below. I just tested via CsEvalClient:
When running my CNN through EvalWrapper on a GPU box, the logs say that it used the cuDNN convolution engine, which is GPU-only. I take that as a sign that it really ran on the GPU.
When running the code on a CPU-only box, it screams that it can't find a CUDA driver, as I would expect.
When switching back to deviceId:-1 and run on the CPU-only box, the logs say that is uses the GEMM convolution engine, and that engine is CPU-only.
What do you see in the logs when CNTK loads the model?
I'm not sure this is the right procedure. Here is what I did.
Instead of using the binary vision, install the source code follow the installation instruction and compile the source code.
Copy the DLLs from "x64.release" directory to the directory where the "exe" file located (flowing https://github.com/Microsoft/CNTK/issues/394).
Note: for multiple projects in solution, make sure the configuration is the same (eg. release mode at x64).
With GTX 960, the processing speed to from 770ms to 1 ms for an image.
I am building a multistream video player. I am currently having issues trying to close a file. Effectively I may have 1 to 4 video files playing at any one time. When I am playing 4 files, then the next sequence only has one, I can't seem to repaint the video panel correctly after removing the source file filter.
I must say that I am building and managing the graph manually (to get some extra speed), including connecting all filters/renderers etc. I have looked into GMFBridge, but ultimately I ran into issues keeping the render graph and file graph in sync all the time (issues such as fast playback (catching up due to timecoding) and having to run/pause/stop/step the mediacontrol on both render and file graphs simultaneously (failed playback sometimes)). From memory the render graph needs to be configured correctly and my scenario didn't fit in exactly with the sample provided (need to playback seemlessly but still required the individual time coding for each file - not merged into one large file).
I reuse the IFilterGraph2/VMR/DirectSound objects throughout the lifetime of the application. The only thing that changes is the SourceFilter and neccessary decoders/demuxes.
So the process is:
Build graph
Add Renderer
Attempt to play a file - according to file type, add the source filter and demux/decoders etc (remove any obsolete filters)
Connect the filters together (manually connect the pins)
Seek/play etc
Once done, unload the current source file by calling Graph.RemoveFilter(), but leave the renderers in the graph and disconnect all pins.
I have experienced the following error:
COM+ exception when closing the file (and calling VMR.RepaintVideo())
EDIT: The error is this:
COM+ is required for this operation, but is not installed (Exception from HRESULT: 0x8004020C)
I do call VMR.SetVideoClippingWindow() once when adding the renderer to the graph.
Is there any way to unload the file, without disposing the filtergraph, and repaint/clear the video window? for that matter, is there any way to repaint the video when there is no source file filter in the graph?
I don't think you have any significant speed gain if you stop the graph and even disconnect pins
The error is not really COM+, the codes overlap and this error has a different meaning (what is the code exactly?)
The only way to eliminate all artifacts and smoothly swap the files and make it quick is to split the pipeline into parts and have video renderer in the filter graph you never stop and disconnect. This takes you back to bridging, or instead to similar technique of synchronization streams between upstream file graph and downstream presentation graph.
UPD. The error is 0x8004020C VFW_E_BUFFER_NOTSET "No buffer space has been set.", use ShowHresult to decode codes, this tool has in particular priority to DirectShow codes when it hits overlapped code blocks.
I'm trying to use the DirectShot.Net wrapper from "http://directshownet.sourceforge.net/" to extract frames from a number of video files.
Whenever I run the DxScan sample app. I get a "No combination of intermediate filters could be found to make the connection." This happens for WMV files, MP4 files, AVI files. Any media I point at the sample app.
If I open any of the videos using the GSpot codec tool and ask it to render the graph, it does so without problem. So the machine is definitely capable of playing the content.
I'm on Win 7 64 bit. The same error is thrown targeting x64, x86 or Auto. Including running Visual Studio as an Administrator.
I've modified the sample code to try and find the correct pin containing the video media type as suggested by Romain R below.
I'm using:
IEnumPins epins;
capFilter.EnumPins(out epins);
IntPtr fetched = Marshal.AllocCoTaskMem(4);
IPin[] pins = new IPin[1];
while (epins.Next(1, pins, fetched) == 0)
{
PinInfo pinfo;
pins[0].QueryPinInfo(out pinfo);
IEnumMediaTypes mtypes;
pins[0].EnumMediaTypes(out mtypes);
AMMediaType[] types = new AMMediaType[1];
while(mtypes.Next(1, types, new IntPtr()) == 0){
var majorType = types[0].majorType;
if (majorType == MediaType.Video)
{
//This is never reached
}
}
}
For MP4 files, it's never hitting the commented line above. However for WMV files, the demo will now run correctly.
Presumably, this is because it isn't finding an appropriate MP4 file filter. Which is obscure as the content will play fine in windows media player.
Is this a likely cause?
DxScan sample is building a filter graph in an unreliable way, in particular is makes an assumption that the first pin it grabs from the source filter supplied for a media file is a video pin. It is not always the case. A better graph building approach should be working out fine. You might want to step through to find out at what line you have an error. Most likely, it is going to be connection of Sample Grabber Filter input pin.
UPD. Note that it might so happen that original filter has no input pins, it requires additional filters in between, so called parser/demultiplexer filters which convert streams into video frames and audio samples. DirectShow API offers Render* methods to assist in graph building in terms of suggesting required links of this chain and direct connection DxScan is doing might or might not work out.
That is, DxScan might be not the best sample to start from, MSDN samples/reference for native API are perhaps better for taking off the ground with DirectShow.
Your playground and primary research and API exploration tool should be GraphEdit from Windows SDK (GraphStudio, or GraphStudioNext as alternate improved options), not a DirectShow.NET wrapper library sample.
Which is obscure as the content will play fine in windows media player.
WMP does not use DirectShow for playback.
Recently stumbled upon this post whilst trying to decide on the best way of getting a VLC player into C#.
Does VLC media player have a C# interface?
I downloaded the dll files and imported them into my project, but then realised I had no real idea of how to use them. Has anyone got a Windows Forms example of this code that works? The code have tried is shown below -
Vlc.DotNet.Core.Medias.MediaBase media = new
Vlc.DotNet.Core.Medias.PathMedia(#"C:\Users\...\SampleVideos\Wildlife.wmv");
Vlc.DotNet.Forms.VlcControl vlcControl1 = new Vlc.DotNet.Forms.VlcControl();
vlcControl1.Play(media);
I am also using the code in this link in the main program.cs of my project.
http://vlcdotnet.codeplex.com/wikipage?title=Forms
The current problem I experience is that upon starting the project it throws a NullReferenceException when it gets to ->
vlcControl1.Play(media)
The problem seems to be with the vlcControl but I am unsure why. The documentation seems to rather thin and I couldn't find any working examples on the codeplex site. If anyone has a working forms example or knows what I might have missed please let me know!
Here is the call stack present when the error occurs ->
RTSPViewer_Test.exe!RTSPViewer_Test.Form1.Form1_Load(object sender,
System.EventArgs e) Line 31 + 0xd bytes C#
RTSPViewer_Test.exe!RTSPViewer_Test.Program.Main() Line 30 + 0x1d bytes C#
When debugging it appears that the Media and Medias attribute of the VLC control are both null. When trying to set the Media of the control to the media object created above a
NullReferenceException
Checking the VLC control object Media does indeed equal null, but I am not sure why it hasn't been initialised properly.
I was unable to get the program to work using the latest version of the Vlc.dotnet libraries but instead used the alpha 2 version which was posted by Raj. I used VLC version 1.1.5 with this library to get the basic example to function properly. My end objective was to stream from an rtsp device, however this library does not appear to support this functionality yet.
For anyone looking to use a good C# wrapper for using VLC then this is a great example -
http://www.codeproject.com/Articles/109639/nVLC
Used the library files from VLC 1.1.1 with this project and works fine. Supports pretty much all the features that you would usually use in VLC but gives you much more control over what you use them for.
Many of the issues that arise when using these DLL wrappers arose from incorrect versions of the source DLL files. The VLC libraries are only 32 bit at this time, so you need to make sure to compile using x86 mode otherwise the libvlc.dll will not load properly and the application will crash. Using the above example you must also make sure that the libvlc.dll, libvlccore.dll and the plugins folder are included in the build folder.
Does anybody have a known reliable way to create a video from a series of image files? Before you mod me down for not searching for the answer before posting the question, and before you fire off a simple message like "use FFMPEG," read the rest of this message.
I'm trying to create a video, it doesn't matter too much what format as long as it's widely supported, from a series of images (.jpg, .bmp, etc.). My platform is Windows Server 2008, 64-bit. If I can make the video from within my C# program, that's great, but I'm not averse to writing a series of image files to a directory and then firing off an external program to make a video from those images.
The only constraints are: it must work on my Windows Server 2008 system, and be scriptable. That is, no GUI programs that require operator intervention.
I found a number of similar questions on StackOverflow, and have tried several of the solutions, all with varying degrees of frustration and none with anything like success.
FFMPEG looks like a great program. Maybe it is, on Linux. The two Windows builds I downloaded are broken. Given this command line:
ffmpeg -r 1 -f image2 -i jpeg\*.jpg video.avi
One of the builds reads the images and then crashes due to data execution prevention. The other reads the first file and then spits out an error message that says "cannot find suitable codec for file jpeg/image2.jpg". Helpful, that. In any case, FFMPEG looks like a non-starter under Windows.
One answer to a previous posting recommended Splicer . It looks like pretty good code. I compiled the samples and tried to run, but got some cryptic error message about a file not found. It looks like a COM class isn't registered. I suppose I need to install something (DirectShow, maybe, although I thought that was already installed?). Depending on what's required, I might have a difficult time justifying its installation on a server. ("What? Why do you need that on a server?")
Another answer suggested the AviFile library from Code Project. That looks simple enough: a wrapper around the Windows AviFile subsystem. Except that the AVI files the package creates appear to have all of the frames, but only the first frame shows when I play the AVI in Windows Media Player. Well, that and if you try to create a compressed video, the program throws an exception.
So, I'm left wondering if there is a good, reliable way to do what I want: on a Windows system, create an AVI or other common video file format from a series of images, either through a .NET API or using an external program. Any help?
After working with it a while and taking a look at x264 and VideoLan, I went back to Splicer. It turns out that the cryptic error message was due to an error in my code.
It looks like Splicer will do what I want: programmatically create videos from a series of images.
Thanks to all who responded.
You can use VideoLan and I'd recommend it.
I've had direct experience in a C# application with VideoLan doing these two things:
Embedding a VLC viewer in my C# application (there are 3-4 C# "wrappers" for the VLC veiwer).
Using vlc.exe in a separate Process by sending it command-line arguments.
The fact that VideoLan has a command-line interface is a great thing. And VLC supports a command-line option that disables any visual element; so the VLC GUI doesn't pop up and neither does a command-line window. Thus, in a C# application you can farm out the video-related work to the VLC client. C# has the Process class which can manage your vlc.exe instances for you. It ends up being a pretty neat solution.
The handling of video on Windows (encoding and playback) is a real quagmire. And .NET isn't going to help you at all - you're always going to be either PInvoking/COM-interoping native APIs or using a .NET wrapper that someone else has built to do the same.
Anyway, I can't say I've used it, but a good bet seems to be the x264 library that is part of the videolan project. That gives you a self-contained C library that you can PInvoke and you don't have to worry about installing and DirectShow garbage on your server. It'll generate H.264 format video which is playable in Flash as I understand it.
I've used mplayer's mencoder to create AVI (with codecs msmpeg4/mp3, readable by default with Windows Media Player) from TGA files on linux like this:
mencoder mf://*.tga -mf fps=25:type=tga \
-audiofile /tmp/test.mp3 -oac copy \
-of lavf -ovc lavc \
-lavcopts vcodec=msmpeg4v2:mbd=2:mv0:trell:cbp:last_pred=3:vbitrate=3000 \
-o /tmp/test.avi
I know mplayer does have a Windows version.
Instead of just going through all the hassle, you could coppy all the images that you want to be included in your video to the clipboard and have it imported into Windows Live Movie Maker (dynamically, of course!) and have it compile for you!
All of this CAN be done through code, but this way, you don't have to create it yourself. As you said that the platform was Windows, and ALL Windows comps have Windows Live Movie Maker installed, so it shouldn't be a problem for anyone using your application unless
a) They uninstalled Windows Live Movie Maker
b) They are using a computer running on a Windows Version more than 8 or 9 years old...