Menu

IBasicVideo2.GetCurrentImage returns black fr

Yuan Shi
2009-09-23
2012-10-29
  • Yuan Shi

    Yuan Shi - 2009-09-23

    I want to extract frames from video files without playing them. I used the
    GetCurrentImage of IBasicVideo2 to extract frames of videos as thumbnails of
    them. I Successfully extracted frames from video files of the format of WMV,
    AVI, DAT, ASF except MPG and VOB. When I extract frames of MPG and VOB files,
    It returns black frames. Why??

    Here is my code:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.Runtime.InteropServices;
    using System.Drawing;
    using System.Drawing.Imaging;
    using DShowNet;
    using QuartzTypeLib;

    namespace test2
    {
    /// <summary>
    /// Window1.xaml 的交互逻辑
    /// </summary>
    public partial class Window1 : Window
    {

    public Window1()
    {
    InitializeComponent();
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
    string videoFileName = "d:\aaaa\《OVER IT》MV.MPG";
    string bitmapFileName = "d:\《OVER IT》MV.MPG.bmp";
    GetThumbnail(videoFileName, bitmapFileName);
    }

    private bool GetThumbnail(string videoFileName, string bitmapFileName)
    {

    FilgraphManagerClass filgraph = new FilgraphManagerClass();

    try
    {

    filgraph.RenderFile(videoFileName);

    filgraph.CurrentPosition = filgraph.Duration / 2;

    int width = filgraph.SourceWidth;

    int height = filgraph.SourceHeight;

    // BITMAPINFOHEADER.biSize + 4 * BITMAPINFOHEADER.biWidth *
    BITMAPINFOHEADER.biHeight
    int pBufferSize = 40 + 4 * width * height;

    DShowNet.IBasicVideo2 video = (DShowNet.IBasicVideo2)filgraph;

    IntPtr pDIBImage = Marshal.AllocHGlobal(pBufferSize);

    video.GetCurrentImage(ref pBufferSize, pDIBImage);

    int stride = -4 * width;

    System.Drawing.Imaging.PixelFormat format =
    System.Drawing.Imaging.PixelFormat.Format32bppRgb;

    IntPtr scan0 = (IntPtr)(((int)pDIBImage) + (pBufferSize - (4 * width)));

    Bitmap bmp = new Bitmap(width, height, stride, format, scan0);

    bmp.Save(bitmapFileName);

    Marshal.FreeHGlobal(pDIBImage);
    }
    catch
    {

    return false;
    }

    while (Marshal.ReleaseComObject(filgraph) > 0) ;

    return true;

    }

    }
    }

     
  • snarfle

    snarfle - 2009-09-23

    It doesn't appear that you are checking the return code from your method
    calls. That might give you some idea of what is going wrong.

     
  • Yuan Shi

    Yuan Shi - 2009-09-23

    video.GetCurrentImage(ref pBufferSize, pDIBImage);

    The return code is always zero of all the format of videos I test. And the
    frames could be saved to bmp image files.

     
  • Yuan Shi

    Yuan Shi - 2009-09-23

    video.GetCurrentImage(ref pBufferSize, pDIBImage);

    It seems that this method can't extract frames from mpg and vob files. The
    frames are all black frames. Why? The limitation of format ?
    Any ideas?

     
  • Eric

    Eric - 2009-09-23

    MPEG files and VOB files produce interlaced video and there is perhaps a
    limitation in IBasicVideo.GetCurrentImage.

    http://msdn.microsoft.com/en-
    us/library/dd389570%28VS.85%29.aspx

    From the docs:
    "This method fails if the renderer is using DirectDraw acceleration.
    Unfortunately, this depends on the end-user's hardware configuration, so in
    practice this method is not reliable."

    "To obtain the required buffer size to hold the image, call this method
    with a NULL pointer in the pDIBImage parameter. The method returns the
    required buffer size in the pBufferSize parameter. Allocate a buffer of that
    size and call the method again, with pDIBImage pointing to the buffer."

    Finally, since you don't use our lib, don't expect much support. The typelib
    import you use never return any return value (void). So this make the
    interface unusable...

     
  • Yuan Shi

    Yuan Shi - 2009-09-24

    nowinskie,
    Thank you~~
    "Finally, since you don't use our lib, don't expect much support. The
    typelib import you use never return any return value (void). So this make the
    interface unusable..."
    What do you mean? What lib?

     
  • snarfle

    snarfle - 2009-09-24

    You are kidding, right? Have you even looked to see what forum you are posting
    in?

    :
    http://directshownet.sourceforge.net/

     
  • Yuan Shi

    Yuan Shi - 2009-09-24

    I add the interface IMediaControl to play the video, then I sucessfully
    extracted the frames of videos with format of mpg and vob. However, I don't
    want to play the videos. I just want to get the frames as thubnails. So what
    should I do?

    mediaCtrl.Run();

    filgraph.CurrentPosition = filgraph.Duration / 2;

    mediaCtrl.Stop();

     
  • Yuan Shi

    Yuan Shi - 2009-09-24

    To snarfle,

    Thank you. I know that lib, but I don't know it's yours. I apologize for that.
    I post my question in this forum because someone told me that it's better to
    post questions of Directshow and C# in this forum.
    The lib is too large for me. I just want to get a thubnail of a video without
    playing it.

     

Log in to post a comment.