[Windows Mobile] Changing still image resolution or DirectShow.NETCF part IV

Most of us who was trying to use DirectShowNETCF found that resolution of stilled image smaller that it could be, for example my device (Samsung i710) got default resolution on still pin 320×240, but i know that it supports resolutions up to 2Mpx. So that should be fixed :)

What do we need to change resolution?
1. We need Enum supported:

2. Using IAMStreamConfig set required mediatype to required pin (STILL pin in our case)

here is interfaces:

[ComVisible(true), ComImport,
Guid("89C31040-846B-11CE-97D3-00AA0055595A"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IEnumMediaTypes
{
[PreserveSig]
int Next(
[In] int cMediaTypes,
[Out] out IntPtr ppMediaTypes,
[Out] out int pcFetched
);

[PreserveSig]
int Skip([In] int cMediaTypes);

[PreserveSig]
int Reset();

[PreserveSig]
int Clone([Out] out IEnumMediaTypes ppEnum);
}

[ComVisible(true), ComImport,
Guid("C6E13340-30AC-11D0-A18C-00A0C9118956"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IAMStreamConfig
{
[PreserveSig]
int SetFormat([In, MarshalAs(UnmanagedType.LPStruct)] AMMediaType pmt);

[PreserveSig]
int GetFormat([Out] out IntPtr pmt);

[PreserveSig]
int GetNumberOfCapabilities(
[Out] out int piCount,
[Out] out int piSize);

[PreserveSig]
int GetStreamCaps(
[In] int iIndex,
[Out] out IntPtr ppmt,
[In] IntPtr pSCC
);
}

Also was created useful class CEnumMediatypes (as in DSPack)

public class CEnumMediaTypes
{
private List<AMMediaType> FList;
private IEnumMediaTypes EnumMediaTypes;
private IntPtr Mt;
public void Free()
{
Clear();
}

public CEnumMediaTypes()
{
FList = new List<AMMediaType>();
}

private void Clear()
{
for (int i = 0; i < FList.Count; i++)
{
DirectShowEx.FreeMediaType(FList[i]);
FList[0] = null;
FList.RemoveAt(0);
}

FList.Clear();
}

public int Count
{
get
{
return FList.Count;
}
}

public void Assign(ICaptureGraphBuilder2 capGraph, IBaseFilter filter, Guid category)
{
Clear();

IPin pin_ = null;
CGuid guid = new CGuid(category);
CGuid guid2 = new CGuid(CLSID_.MEDIATYPE_Video);
int res = capGraph.FindPin(filter, PinDirection.Output, guid, guid2, true, 0, out pin_);

if (res > -1)
{
pin_.EnumMediaTypes(out EnumMediaTypes);
if (EnumMediaTypes == null)
{
return;
}

int fetched = 0;

int hr = EnumMediaTypes.Next(1, out Mt, out fetched);
while (hr == 0)
{
fetched = 0;
hr = EnumMediaTypes.Next(1, out Mt, out fetced);
AMMediaType mt = (AMMediaType)Marshal.PtrToStructure(Mt, typeof(AMMediaType));
FList.Add(mt);
}

Marshal.ReleaseComObject(EnumMediaTypes);
Marshal.ReleaseComObject(pin_);
}
}

private string getFourCC(int value)
{
IntPtr ptr = Marshal.AllocHGlobal(4);
Marshal.WriteInt32(ptr, value);
byte[] bt = new byte[4];
Marshal.Copy(ptr, bt, 0, 4);
Marshal.FreeHGlobal(ptr);
char[] ch = new char[4];
for (int i = 0; i < 4; i++)
{
ch[i] = (char)bt[i];
}
bt = null;
return new string(ch);
}

public string GetMediaDescription(int index)
{
string result = "";

AMMediaType tempType = FList[index];
if (tempType.formatType == CLSID_.VideoInfo)
{
result += ((VideoInfoHeader)Marshal.PtrToStructure(tempType.formatPtr, typeof(VideoInfoHeader))).BmiHeader.Width.ToString();
result += 'X';
result += ((VideoInfoHeader)Marshal.PtrToStructure(tempType.formatPtr, typeof(VideoInfoHeader))).BmiHeader.Height.ToString();
}
else
{
if (tempType.formatType == CLSID_.VideoInfo2)
{
result += ((VideoInfoHeader2)Marshal.PtrToStructure(tempType.formatPtr, typeof(VideoInfoHeader2))).BmiHeader.Width.ToString();
result += 'X';
result += ((VideoInfoHeader2)Marshal.PtrToStructure(tempType.formatPtr, typeof(VideoInfoHeader2))).BmiHeader.Height.ToString();
}
}

tempType = null;
return result;
}

public AMMediaType this[int index]
{
get
{
return FList[index];
}
}

}

Exaple how to set/change resolution is here

13 Responses to “[Windows Mobile] Changing still image resolution or DirectShow.NETCF part IV”

  1. 1
    Charlie Says:

    Great :)
    When video capture?
    You are the best!

  2. 2
    eric Says:

    This example code has been overwrited by 06/18 ’s example
    Can you Update it?

    thank

  3. 3
    admin Says:

    Done :)

  4. 4
    Markov Says:

    Hi thanks for your code!
    When i try to change reslution to 320×240 and save as jpg but image have noise, so much noise!

  5. 5
    Toyin Says:

    I’m using the HTC 8925 (Tilt). I am getting the “Cannot start camera” error message when I click on the start button. Is there anything else I needed to have done, before clicking on the Init and Start buttons?

  6. 6
    grapeot Says:

    Hi, Alex:

    Thanks very much for this library!

    But in this sample code, it seems all the “” as “>”. I don’t know whether this is caused by my browser (IE 8.0), but you’d better check it. :-)

    Thanks again! BTW, if i want to use this library, need i get a license?

  7. 7
    grapeot Says:

    hi, Alex:

    I don’t understand how to find STILL pins… the Camera class provides no access to internal ICaptureGraph2. And when I try to subclass it, the ICaptureGraph2 interface still seems inaccessible.

    And in the example named Camera, i didn’t find any statements related to CEnumMediaTypes, while my HTC Touch HD can only get a 240 * 320 resolution when directly calling Camera.getMediaTypes().

    So, does this article only offer a motivation, but we still need to implement them such as building the graph by ourselves? Or there are actually practical solutions in DirectShow.NET CF library?

    Thanks very much for your work, it is really fantastic! :-)

    Thanks,
    grapeot

  8. 8
    admin Says:

    2grapeot if you need to still image then camera class already has still method, regarding resolution that seems problem of HTC directshow driver.

    if you need something more than you need to build graph by yourself

  9. 9
    grapeot Says:

    Thanks for the explanation :-)

  10. 10
    robo Says:

    i think, the low resolution is because we grab frames from a video stream.
    and in video mode, the camera will not allow a resolution of 2MP :-(

    so to get a 2MP still image, we might have to use another interace :-/

    roland,
    new here, still looking for the lib to build the examples :’(

  11. 11
    admin Says:

    2robo, you are not right. in Camera class i do enumerating of still pin and it returns resolutions up to max supported on most devices, but HTC does not.

    in AMCamera and AMCameraEx use video pin to grab frames.

    P.S. lib you can find here:
    http://alexmogurenko.com/blog/directshownetcf/

  12. 12
    Abito Says:

    Hi Alex, did you manage to find a solution for HTC devices? mine only gives 320 X 240 resolution, even though it has a 3.2MP camera

  13. 13
    admin Says:

    this is directshow driver problem and its impossible to resolve it using directshow

Leave a Reply