Tuesday 13 March 2012

Surface project - part 5 (video capture by using .net DirectShow)

After showing my first demo to supervisors, they were pleased with the user interface and wanted me to move on to the next scenario, the indigenous people want to record the video media by themselves through the web camera and pin these videos onto the map at custom defined locations.

Thus, the first task would be how to capture video stream from camera. There is a great article and a open source project, which wraps the native direct show code into .net platform.

However, after look into the project, I found that if you want to preview the live video from camera, you need use a windows form control. Thus, how to use windows form control in a WPF project. There is a tutorial provided by MSDN.

Following code is to make a simple WPF application, which capture video from camera and display on the screen as well.

1. add two rows into the grid, put the preview control on the first row, and a stack panel, which contains operation buttons, on the second row

<Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="480"/>
            <RowDefinition Height="50"/>
        </Grid.RowDefinitions>
        <WindowsFormsHost Grid.Row="0">
            <wf:Panel x:Name="ThePreviewControl" Width="640" Height="480"/>
        </WindowsFormsHost>
       
        <StackPanel Orientation="Horizontal" Grid.Row="1" HorizontalAlignment="Center"  VerticalAlignment="Center">
            <Button Name="StartBtn" Width="100" Click="StartBtn_Click" Margin="0,0,50,0" Content="Start" HorizontalAlignment="Center" VerticalAlignment="Center" />
            <Button Name="StopBtn"  Width="100" Click="StopBtn_Click" Content="Stop" Margin="0,0,50,0"/>
            <TextBox Name="FileTxt" Width="200" Text="c:\test.avi"/>
        </StackPanel>
       
    </Grid>


2. In the code behind file, add two fields for capture the video

        private Capture capture = null;
        private Filters filters = new Filters();


3. Inside the constructor, intitalize the capture object, and start preview
   
            capture = new Capture(filters.VideoInputDevices[0], filters.AudioInputDevices[0]);
            capture.VideoCompressor = filters.VideoCompressors[2]; //DV encode
            capture.AudioCompressor = filters.AudioCompressors[6]; // mp3

            //start preview
            capture.PreviewWindow = ThePreviewControl;


Now, when you start the application, you should see the image captured from camera displayed on the screen.



However, it has not finished yet. If you try to preview the video in a Surface project it won't work, as windows form control does not support move, scale or rotation. Thinking about the wrap class, it is some kind of restrict to windows form, but what I only need to preview is the raw image data for each frame. Here is an article, the author extended the wrap class by adding a callback after each frame. The limitation is that you still need to attach the preview control, otherwise, the callback won't work.

No comments:

Post a Comment