Пример видео захвата QuickTime для Windows - PullRequest
0 голосов
/ 01 декабря 2019

Знаете ли вы какой-нибудь рабочий пример того, как захватывать кадры из видео с помощью QuickTime в Windows? Мне нужно воспроизвести видео в памяти и получить доступ к каждому отрендеренному кадру попиксельно. Мое приложение WPF вызывает код dll из библиотеки C ++.

У меня есть старый код, использующий SetMovieDrawingCompleteProc и доступ к визуализированным кадрам с помощью GetGWorldPixMap. Но есть некоторые утечки памяти, а также код перестает работать иногда из-за незапланированного исключения внутри Quicktime - и я не могу заставить его работать правильно.

Это код захвата:

    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);

Вот как я открываю фильм:

    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);

Перед вами какие-либо предложения по использованию DirectShow, DirectX, некоторого материала для Windows Media - нет, я не могу его использовать, так как мне нужен точный контроль скорости видео(и нет, эти технологии плохо работают).

...