Akai

Hi all

anyone have any windows executable sample code where i can extract frames from MPEG-2 clips. I guess we will have to use DirectShow API to fulfill this.

DirectShowSamples can be found here: http://sourceforge.net/project/showfiles.php group_id=136334

Actually i have found the VMR9Snapper which is a C# windows form and it is able to extract frames from MPEG-2. But i got some problems implementing it to a windows executable code. Will be glad if someone can help me out.

I post my C# codes as follows:

using System;

using System.Drawing;

using System.Drawing.Imaging;

using System.Data;

using System.Collections;

using System.ComponentModel;

using System.Runtime.InteropServices;

using System.IO;

using System.Threading;

using DirectShowLib;

using Microsoft.Win32;

namespace ConsoleApp

{

class Program

{

// DirectShow stuff

private static IFilterGraph2 graphBuilder = null;

private static IMediaControl mediaControl = null;

private static IMediaPosition mediaPosition = null;

private static IBaseFilter vmr9 = null;

private static IVMRWindowlessControl9 windowlessCtrl = null;

private static void openFile()

{

BuildGraph(@"C:\MK Projects\ConsoleApp\ch5.mpg");

RunGraph();

Console.WriteLine("Opened successfully");

}

private static void BuildGraph(string fileName)

{

int hr = 0;

try

{

graphBuilder = (IFilterGraph2)new FilterGraph();

mediaControl = (IMediaControl)graphBuilder;

mediaPosition = (IMediaPosition)graphBuilder;

vmr9 = (IBaseFilter)new VideoMixingRenderer9();

ConfigureVMR9InWindowlessMode();

//Open window with movie

hr = graphBuilder.AddFilter(vmr9, "Video Mixing Renderer 9");

DsError.ThrowExceptionForHR(hr);

hr = graphBuilder.RenderFile(fileName, null);

DsError.ThrowExceptionForHR(hr);

Console.WriteLine("Opening graph");

}

catch (Exception e)

{

//CloseInterfaces();

Console.WriteLine("Error opening graph");

}

}

private static void RunGraph()

{

if (mediaControl != null)

{

int hr = mediaControl.Run();

DsError.ThrowExceptionForHR(hr);

}

Console.WriteLine("Running graph");

}

//Capturing frame

private static void snapImage()

{

//mediaPosition.put_CurrentPosition(tsp.TotalSeconds);

mediaControl.Run();

mediaControl.Pause();

Console.WriteLine("hello");

//Console.WriteLine(windowlessCtrl.ToString());

if (true) //windowlessCtrl != null) --------------------> windowlessCtrl is always null in my code here

{

IntPtr currentImage = IntPtr.Zero;

Bitmap bmp = null;

try

{

//error occurred here

int hr = windowlessCtrl.GetCurrentImage(out currentImage);

Console.WriteLine("end here ");

DsError.ThrowExceptionForHR(hr);

if (currentImage != IntPtr.Zero)

{

BitmapInfoHeader structure = new BitmapInfoHeader();

Marshal.PtrToStructure(currentImage, structure);

string FileName = @"C:\MK Projects\ConsoleApp\Captured.jpg";

bmp.Save(FileName, System.Drawing.Imaging.ImageFormat.Jpeg);

Console.WriteLine("Image saved");

}

else

Console.WriteLine("Image not saved");

}

catch (Exception anyException)

{

Console.WriteLine("Image saving failed");

}

finally

{

if (bmp != null)

{

bmp.Dispose();

}

Marshal.FreeCoTaskMem(currentImage);

Console.WriteLine("Image saving failed1");

}

}

}

private static void ConfigureVMR9InWindowlessMode()

{

int hr = 0;

IVMRFilterConfig9 filterConfig = (IVMRFilterConfig9)vmr9;

// Not really needed for VMR9 but don't forget calling it with VMR7

hr = filterConfig.SetNumberOfStreams(1);

DsError.ThrowExceptionForHR(hr);

// Change VMR9 mode to Windowless

hr = filterConfig.SetRenderingMode(VMR9Mode.Windowless);

DsError.ThrowExceptionForHR(hr);

windowlessCtrl = (IVMRWindowlessControl9)vmr9;

// Set "Parent" window

//hr = windowlessCtrl.SetVideoClippingWindow(panel1.Handle);

//DsError.ThrowExceptionForHR(hr);

// Set Aspect-Ratio

hr = windowlessCtrl.SetAspectRatioMode(VMR9AspectRatioMode.LetterBox);

DsError.ThrowExceptionForHR(hr);

// Add delegates for Windowless operations

//AddHandlers();

// Call the resize handler to configure the output size

//MainForm_ResizeMove(null, null);

}

public static void Main()

{

openFile();

System.Threading.Thread.Sleep(4000);

snapImage();

}

}

}



Re: DirectShow Development DirectShow to extract frames from MPEG-2 clips in win32 format

Michel Roujansky

Have a look at the VMRPlayer sample in the VMR9 folder (it implements a bitmap grabbing function using VMRBitmap). In the code, you should find the C++ equivalent to your C# code (and much more).