首页 > 解决方案 > QuickTime video grabber example for Windows

问题描述

Do you know some working example of how to grab frames from video using QuickTime on Windows? I need to play the video in memory and access every rendered frame pixel by pixel. My app is WPF calling dll code from C++ library.

I have some old code using SetMovieDrawingCompleteProc and accessing the rendered frames using GetGWorldPixMap. But there are some memory leaks and also the code stops working sometimes by unhanded exception inside Quicktime - and I can't make it work correctly.

This is the grab code:

    CGrafPtr pOldWorld = nil;
    GDHandle pOldHandle = nil;
    GetGWorld(&pOldWorld, &pOldHandle);
    SetGWorld(m_offscreenWorld, NULL);

    PixMapHandle pixMapHandle = GetGWorldPixMap(m_offscreenWorld);

    SetGWorld(pOldWorld, pOldHandle);

    if (!LockPixels(pixMapHandle))
        return;

    UCHAR *pixBaseAddr = (UCHAR*)GetPixBaseAddr(pixMapHandle);

    // handle pixels...

    UnlockPixels(pixMapHandle);

    SetGWorld(pOldWorld, pOldHandle);

This is how I open the movie:

    qtErr = FSMakeFSSpec(0, 0, macFullPath, &m_sfFile);
    if (qtErr != noErr)
        throw "Can't convert filename to mac file struct";

    qtErr = OpenMovieFile(&m_sfFile, &theFile, fsRdPerm);
    if (qtErr != noErr)
        throw "Can't open file";


    qtErr = NewMovieFromFile(&m_movie, theFile, nil, nil, 0, nil);
    if (qtErr != noErr)
    {
        m_movie = nil;
        throw "Can't make new movie";
    }

    qtErr = CloseMovieFile(theFile);
    if (qtErr != noErr)
        throw "Can't close movie";

    SetMovieActive(m_movie, true);

    GetMovieBox(m_movie, &m_movieRect);

    qtErr = QTNewGWorld(
        &m_offscreenWorld, k32BGRAPixelFormat, &m_movieRect,
        NULL, NULL, NULL);
    if (qtErr != noErr)
        throw "Can't create off screen world";

    CGrafPtr pOldWorld = nil;
    GDHandle pOldHandle = nil;
    GetGWorld(&pOldWorld, &pOldHandle);
    SetGWorld(m_offscreenWorld, NULL);

    SetMovieGWorld(m_movie, m_offscreenWorld, NULL);

    SetGWorld(pOldWorld, pOldHandle);

    m_movieController = NewMovieController(m_movie,
        &m_movieRect, mcNotVisible | mcScaleMovieToFit | mcTopLeftMovie);
    if (m_movieController == nil)
        throw "Can't get movie controller";

    SetMovieDrawingCompleteProc(
        m_movie, movieDrawingCallWhenChanged,
        pContext->drawCompleteFunc, (long)this);

Before you any suggestions of using DirectShow, DirectX, some Windows media stuff - no, I can't use it, since I need precise speed control of the video (and no, it's not working well in these technologies).

标签: wpfwindowsquicktime

解决方案


不幸的是,Windows 10 不再支持 QuickTime,而且它确实无法正常工作。特别是当您尝试一次播放多个 mov 文件时。所以不再需要示例:) ...


推荐阅读