IStreamBufferMediaSeeking setPosition doesn't seem to render - c#

I have created two DirectShow graphs. One captures from a Hauppauge HD-PVR and stores it in a StreamBufferSink. The second one uses a StreamBufferSource, sends the output to an MPEG-2 Demultiplexer, sending the video to the ArcSoft Video Decoder and on to a Video Mixing Renderer 9 set up in windowless mode.
This all works fine for previewing the data. When I use the IStreamBufferMediaSeeking.SetPositions method (getting the interface from the StreamBufferSource) to change the playback position, if I set it anywhere but at the beginning of the stream, the video freezes and stops updating. Calling GetCurrentPosition on IStreamBufferMediaSeeking shows the position is moving on the stream, but the video just doesn't follow along.
I am using C# and DirectShowLib-2005 for programming things.
Any ideas on what is wrong or how to figure out what is going wrong?

What I have discovered is the StreamBufferSink/StreamBufferSource only understand MPEG-2 or DV video. H.264 is not supported so it doesn't know how to seek within the stream and thus I cannot use this component for what I want to do unless I transcode my stream to MPEG-2 which defeats the purpose for having an H.264 stream in the first place.

Further information: This actually will work under Windows 7 with the updates to the Streaming Buffer Engine. To get rewind, I had to demux the stream and add the MPEG-2 Video Stream Analyzer filter before putting the data into the Stream Buffer Sink.

Related

IP Camera continuous snapshots vs. video

I'm making a project using c# 2013, windows forms and this project will use an IP camera to display a video for a long time using CGI Commands.
I know from the articles I've read that the return of the streaming video of the IP camera is a continuous multi-part stream. and I found some samples to display the video like this one Writing an IP Camera Viewer in C# 5.0
but I see a lot of code to extract the single part that represents a single image and displays it and so on.
Also I tried to take continuous snap shots from the camera using the following code.
HttpWebRequest req=(HttpWebRequest)WebRequest.Create("http://192.168.1.200/snap1080");
HttpWebResponse res = (HttpWebResponse)req.GetResponse();
Stream strm = res.GetResponseStream();
image.Image = Image.FromStream(strm);
and I repeated this code in a loop that remains for a second and counts the no. of snapshots that were taken in a second and it gives me a number between 88 and 114 snapshots per second
IMHO the first example that displays the video makes a lot of processing to extract the single part of the multi-part response and displays it which may be as slow as the other method of taking a continuous snapshots.
So I ask for other developers' experiences in this issue if they see other difference between the 2 methods of displaying the video. Also I want to know the effect of receiving a continuous multi-part stream on the memory is it safe or will generate an out of memory errors.
Thanks in advance
If you are taking more than 1 jpeg per 1-3 seconds, better capture H264 video stream, it will take less bandwidth and cpu.
Usually mjpeg stream is 10-20 times bigger than the same h264 stream. So 80 snapshots per second is a really big amount.
As long as you dispose of the image and stream correctly, you should not have memory issues. I have done a similar thing in the past with an IP Camera, even converting all the images that I take as a snapshot back into a video using ffmpeg (I think it was).

Audio Streaming from Microphone

I'm creating an video chat application but I'm having issues streaming microphone audio. I have video streams working already but I was hoping to find out the best method of capturing a laptop's built in microphone and stream it. At the moment I'm using a NetworkStream for sending the video. I have limited experience with NAudio (http://naudio.codeplex.com/) but every example of microphone capture doesn't seem to include a New Audio Frame event (which is my method for sending video frames).
I've been looking at http://voicerecorder.codeplex.com/ but it seems to be more than I need and doesn't cover streaming.
How do I capture microphone audio and stream it, if possible without the overhead of saving the audio to a file? I'd appreciate a simple example.
Create a new WaveIn object
call StartRecording
in the DataAvailable event handler, transmit args.BytesRecorded bytes from args.Buffer across the network.
Note that this will mean you are transmitting PCM, which is not very efficient. Normally for network streaming you would use a codec. In the NAudioDemo source code there is a Network Chat demo showing this in action.

Audio Sync problems using DirectShow.NET

I have started a thread on this at DirectShow.NET's forum, here is the link http://sourceforge.net/projects/directshownet/forums/forum/460697/topic/5194414/index/page/1
but unfortunately the problem still persists...
I have an application that captures video from a webcam and audio from the microphone and save it to a file, for some reason the audio and video are never in-sync, i tried the following:
1. Started with ffdshow encoder and changed to AVI Mux - problem persists, audio is delayed and at the end of the video the picture remains frozen and the audio continues
2. Changed from AVI Mux to WM ASF Writer - video is frozen at the beginning (2 seconds) and rest of video is in-sync (but the two first seconds are not usable)
3. create SampleGrabber that prints the timestamp for both audio and video - saw that the audio timestamp is 500ms earlier but I have no idea what to do with this fact...
4. tried manually setting the ReferenceClock to one of the capture filters (audio/video) but both won't cast to IReferenceClock
5. Created a SystemClock and set it has the ReferenceClock - made no difference
6. Set SyncUsingStreamOffset(true) on the grap - timestamps are much closer now but the final result is the same
7. Tried saving the audio and video to two different files and used VirtualDub to see if they match, they still dont...
Oh i forgot to mention I also tried building the graph in GraphEditPlus but the problem still remains, here's a link to the graph: http://www2.picturepush.com/photo/a/8030745/img/8030745.png
Currently I am testing all my changes on the CapWMV sample from DirectShow.NET's samples.
Please any advice would be highly appreciated, I am hopeless :/
Thanks,
Eran.
Update:
It seems there's a constant 500ms gap between the audio and video, if I use virtualDub to delay the audio by 500ms it looks fine, how can set this in the graph?
You are having latency on the audio stream equal to size of capture buffer. That is, you obtain the full buffer which started being captured 0.5 seconds away. You need to use smaller buffers and/or apply offset on the buffers to adjust the latency.
See:
Minimizing audio capture latency in DirectShow
How to eliminate 1 second delay in DirectShow filter chain? (Using Delphi and DSPACK)
IAMBufferNegotiation is the keyword.
Just wanted to add the solution for my situation, maybe it will help someone.
I was trying to record video from a webcam together with audio from a microphone, video is HD (1080p) so I wanted to save an AVI file encoded in MPEG4, so I used ffshow-tryous (free Mpeg4 encoder) together with an Avi Mux Filter, the problem was that some (well most of them :) ) of my videos had sync issues.
What I discovered was that Avi Mux does not handle synchronization, it assumes the data arrives at the appropriate time (written here - http://msdn.microsoft.com/en-us/library/dd407208(v=vs.85).aspx), so I tried using WMAsfWriter which does handle synchronization and it worked fine (The 2 seconds freeze I mentioned above was just a glitch with VLC Player) but it doesn't work good with high resolutions and I had trouble using it with custom profiles (filters won't get connected).
I also tried Roman's suggestion and although the links were very interesting and promising (I really recommend reading them - can't give +1 to a post yet...) it just didn't made any difference :/
My final solution was to give up on MPEG4 and just use MPEG2, I switched from Avi Mux to Microsoft MPEG2 Encoder which works great, should have thought about that long time ago :)
Hopefully this will help someone else.
Thanks,
Eran.
I had the same problem rendering video from WMV to AVI using Xvid MPEG-4 decoder.
My final solution without giving up MPEG-4 was to configure the AviMuxer setting ConfigAviMux::SetMasterStream property
As explained in the Capturing Video to an AVI File article from MSDN configuration:
If you are capturing audio and video from two separate devices, it is a
good idea to make the audio stream the master stream. This helps to
prevent drift between the two streams, because the AVI Mux filter
adjust the playback rate on the video stream to match the audio
stream.
Example Code :
IConfigAviMux _filterAVIMuxerCfg = (IConfigAviMux)_filterAVIMuxer;
_filterAVIMuxerCfg.SetMasterStream(0); // I've add first audio ;)

Get Stream and save as jpeg (image) file from IP Camera using ffmpeg

How i can get stream from Ip Camera, Its using RTP, stream is MPEG4, i have multicast address and port,and i have ip camera's IP address and Port Number. And I cant reach via http forexample (http://ip/jpeg) And I cant reach stream with VLC Player too. forexample (rtp://ipadressofcam:port) and (rtp://multicastaddress:port)
So What is ffmpeg command of that?
I have windows OS, I only write code with C# right now.
But producer created their own ocx which used for viewing cam,that plugin can work on .net but i dont want to use it becouse it doesnt have much funcionality, I mean you cant get current picture or snapshot of cams, thats why i have to do it myself.
Are you sure the stream is not password-protected?
Try to see why your camera rejects VLC requests. And this is how to do it: Install Wireshark, start it, and put a filter for the camera address, like: ip.addr == camera_ip (xxxx.xxxx.xxxx.xxxx). Then, try to connect with VLC, and look there at the messages exchanged. If you see a DROP, UNAUTH, or something that tells you to use a passwd, introduce it. (VLC will first try to connect using an unauthenticated procedure, and if it fails, will ask for a passwd.)
Wireshark will give you clues if the failure reason is something different.
And keep in mind that if VLC can't access it, the chance to find some other way to do it is almost zero. Unless you're a video guru.
Hope it helps!
You can use VLC for such a thing ,and it's ActiveX control which is available for .NET also ,just need to install VLC Media Player and you can set it's control on VS toolbox
http://forum.videolan.org/viewtopic.php?f=32&t=54969
UPDATE
If you are ready to pay for this stuff you can use http://www.mainconcept.com/products/sdks/video.html this Company product's to advance with Decoding and Encoding ,where you can find a huge Library .
So you want to receive video stream from camera and convert individual frame into JPEG file. This sounds good and actually sounds natural: why not? there is a video feed being sent on network and we don't need much, just to pick individual frame.
The original stream is MPEG-4 (Part 2) and desired target encoding is JPEG. This breaks the task into parts of getting MPEG-4 video feed, decoding it into uncompressed images, and encoding into JPEG. Let us go through these from the last one backwards.
JPEG is a popular encoding and there are various codecs with different interface capable of compressing into JPEG. Options include GDI+ API, IJG JPEG library libjpeg, JPEG libraries and codecs for video with DirectShow and other interfaces.
MPEG-4 decoder is a complicated component, however is luckily well standardized and available in different interfaces and from several sources. In particular MPEG-4 Part 2 Video Decoder is shipped as DMO (and also through ) with Windows 7. Decoder is also available as DirectShow filter in ffdshow, Intel Media SDK.
Back to the first step, you need to reach MPEG-4 stream from network. First of all you indicated that the camera is available on multi-cast UDP address. This makes you open a socket and put into onto multi-cast group in order to start receiving RTP data. The data you would receive is not pure MPEG-4 yet, and is formatted according to RTP Payload Format for MPEG-4 Audio/Visual Streams and as you receive RTP stream of messages you will have to be prepared to receive out of order fragments, packet losses etc. You are supposed to receive what you can receive, check the RTP headers, and do your best in reconstructing MPEG-4 feed.
Eventually you need to cover these steps (not necessarily directly, you would rather use third party libraries including those mentioned in other answers) from your application and build a pipeline which stitches together receiving from network and transcoding.
So until now, I saw VLC cant open it but if we create .sdp file and play it with ffplay only a black screen appears.
vlc -vvv dshow:// --sout-keep --sout-all --sout=#rtp{dst=multicastaddress,port=portNo,sdp=file:///C:/test/my.sdp}
Of course this is not pure solution but there is little bit hope.
But obsolute solution can be like that;
There is no way to use just c# to achive what i intend. There are few c++ library components that i can use, but i can use it along with Managed c++ to write interop services and use those dlls in my c# code.Here is what i need:
1-I need an RTP Library, http://research.edm.uhasselt.be/~jori/page/index.php?n=CS.Jrtplib or live555 but live555 has certain limitations.
2-RTP Library is the transport for the MPEG4 stream i pull from my encoder. But i need ways to control the stream, those are provided producer's WSDLs.
3-After that i need a decoder; Libavcodec, I can use libavcodec to convert an Iframe to a jpeg image in .net.

Capture a DVB-T Stream to a movie-file

I have a form with a liveview of the tv-signal (from dvb-t stick). I've the sampleproject "DTViewer" from http://directshownet.sourceforge.net/about.html.
Now I try to capture the stream to a movie-file by clicking a button, but how?
I use C# and DirectShow.NET.
I tried to search in many sampleprojcets but these are made for videoinputs not a dvb-t stick with a BDA (Broadcast Driver Architecture) interface.
Help!
Don’t really know what exactly do you mean by a “movie-file”, but I can tell you how to capture the entire MUX (transport stream). Create a graph with a Microsoft DVBT Network Provider, You_Name_It BDA DVBT Tuner, You_Name_It BDA Digital Capture and MPEG-2 Demultiplexer filters. Once you connect them, enumerate all output pins on the MPEG-2 Demultiplexer and render them. Tune the frequency of your choice (put_TuneRequest). At this point everything is ready to run the graph, but don’t run it! Enumerate all filters in the graph. Disconnect all filters except Microsoft DVBT Network Provider, You_Name_It BDA DVBT Tuner and You_Name_It BDA Digital Capture. Remove all these disconnected filters from the graph except the MPEG-2 Demultiplexer (it has to be in the graph although it is not connected). Add Sample Grabber filter and NULL Renderer filter. Connect Digital Capture filter to Sample Grabber and Sample Grabber to NULL Renderer. You can run the graph now. Through the callback in Sample Grabber filter you will receive the entire MUX. Of course, there is still some work to demux the data, but once you do that, you can capture all TV programs in one MUX at once. The easiest way is to capture it in a TS format because the TS is being broadcasted (188 bytes long packets).
It seems to me VLC has BDA support (BDA.c file reference), maybe you can snoop up something from their code?
There is no simple answer to your question. I have started one such project and have found out that there is very little I know about it, so here is little something from my research.
First, you'll have to understand that dvb-t tuner card or stick doesn't give video frames in the classical sense, but the decoding is done in the pc, on the cpu. External card will provide you with compressed data only, as it fetches it from the air.
Next - data that is delivered to you will be in MPEG2 or MPEG4 Transport Stream format. Which is suitable for streaming or broadcasting, not for saving to file. VLC is able to play TS written to the file, but to record a proper video file, you'll have to either transcode the file or repack it to Program Stream. Google it a little, you'll find the differences.
More - one frequency on the air consists of many channels, and that channel packing is called 'mux'. So - from the BDA tuner/capturer you'll get ALL data, and you'll have to demux it manually or let BDA demuxer do it for you.
Hope that's enough info to get you started, I can post you some interesting links when I get to the real keyboard.

Categories