Мало кто заметил, что был задан вопрос. В BufferCB никто номер кадра не даст, их проще посчитать своим счетчиком или вычислять по таймстемпам сэмплов (если framerate равномерный).
Здравствуйте, DEMON HOOD, Вы писали:
DH>Здравствуйте, magician_g, Вы писали:
_>>Как из avi сделать последовательность bmp.
DH>
DH>//------------------------------------------------------------------------------
DH>// File: GrabBitmaps.cpp
DH>//
DH>// Desc: DirectShow sample code - GrabBitmaps sample
DH>// This console app will open a long AVI file in the parent directory,
DH>// create a filter graph with a sample grabber filter,
DH>// read frames out of it every second for a few seconds,
DH>// and write the frames to BMP files in the current directory.
DH>//
DH>// Copyright (c) Microsoft Corporation. All rights reserved.
DH>//------------------------------------------------------------------------------
DH>#include <windows.h>
DH>#include <streams.h>
DH>#include <stdio.h>
DH>#include <atlbase.h>
DH>#include <qedit.h>
DH>// Function prototypes
DH>int GrabBitmaps(TCHAR * szFile);
DH>HRESULT GetPin(IBaseFilter * pFilter, PIN_DIRECTION dirrequired, int iNum, IPin **ppPin);
DH>IPin * GetInPin ( IBaseFilter *pFilter, int Num );
DH>IPin * GetOutPin( IBaseFilter *pFilter, int Num );
DH>// Constants
DH>#define NUM_FRAMES_TO_GRAB 5000
DH>//
DH>// Implementation of CSampleGrabberCB object
DH>//
DH>// Note: this object is a SEMI-COM object, and can only be created statically.
DH>class CSampleGrabberCB : public ISampleGrabberCB
DH>{
DH>public:
DH> // These will get set by the main thread below. We need to
DH> // know this in order to write out the bmp
DH> long Width;
DH> long Height;
DH> // Fake out any COM ref counting
DH> //
DH> STDMETHODIMP_(ULONG) AddRef() { return 2; }
DH> STDMETHODIMP_(ULONG) Release() { return 1; }
DH> // Fake out any COM QI'ing
DH> //
DH> STDMETHODIMP QueryInterface(REFIID riid, void ** ppv)
DH> {
DH> CheckPointer(ppv,E_POINTER);
DH> if( riid == IID_ISampleGrabberCB || riid == IID_IUnknown )
DH> {
DH> *ppv = (void *) static_cast<ISampleGrabberCB*> ( this );
DH> return NOERROR;
DH> }
DH> return E_NOINTERFACE;
DH> }
DH> // We don't implement this one
DH> //
DH> STDMETHODIMP SampleCB( double SampleTime, IMediaSample * pSample )
DH> {
DH> return 0;
DH> }
DH> // The sample grabber is calling us back on its deliver thread.
DH> // This is NOT the main app thread!
DH> //
DH> STDMETHODIMP BufferCB( double SampleTime, BYTE * pBuffer, long BufferSize )
DH> {
DH> //
DH> // Convert the buffer into a bitmap
DH> //
DH> TCHAR szFilename[MAX_PATH];
DH> wsprintf(szFilename, TEXT("Bitmap%5.5ld.bmp\0"), long( SampleTime * 1000 ) );
............................................................................................
DH> return 0;
DH> }
DH>};
DH>//
DH>// Main program code
DH>//
DH>int _tmain(int argc, TCHAR* argv[])
DH>{
DH> if( argc != 2 || !argv || !argv[1] )
DH> {
DH> _tprintf( TEXT("GrabBitmaps: You must specify a media filename!\r\n") );
DH> _tprintf( TEXT("Usage: GrabBitmaps Filename\r\n"));
DH> return 0;
DH> }
DH> CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
...................................................
DH> // Find a limited number of frames
DH> //
DH> for( int i = 0 ; i < NUM_FRAMES_TO_GRAB ; i++ )
DH> {
DH> // set position
DH> REFERENCE_TIME Start = i * UNITS;
DH> hr = pSeeking->SetPositions( &Start, AM_SEEKING_AbsolutePositioning,
DH> NULL, AM_SEEKING_NoPositioning );
DH> // activate the threads
DH> CComQIPtr< IMediaControl, &IID_IMediaControl > pControl( pGraph );
DH> hr = pControl->Run( );
DH> // wait for the graph to settle
DH> CComQIPtr< IMediaEvent, &IID_IMediaEvent > pEvent( pGraph );
DH> long EvCode = 0;
DH> hr = pEvent->WaitForCompletion( INFINITE, &EvCode );
DH> // callback wrote the sample
DH> }
DH> _tprintf(TEXT("Sample grabbing complete.\r\n"));
DH> return 0;
DH>}
...............................................................
DH>
Столкнулся с такой проблемой при использовании данного примера:
в цикле перебора кадров после вызова
hr = pControl->Run( );
выполнение останавливается на строке
hr = pEvent->WaitForCompletion( INFINITE, &EvCode );
При этом функция
STDMETHODIMP BufferCB( double SampleTime, BYTE * pBuffer, long BufferSize )
в классе CSampleGrabberCB не вызывается.
Т. е. видимо метод pControl->Run( ) не запускает рендеринг очередного кадра и поэтому функция pEvent->WaitForCompletion бесконечно ждёт возникновения события. Как этого избежать?
Здравствуйте, DEMON HOOD, Вы писали:
DH>Здравствуйте, magician_g, Вы писали:
_>>Как из avi сделать последовательность bmp.
DH>
DH>//------------------------------------------------------------------------------
DH>// File: GrabBitmaps.cpp
DH>//
DH>// Desc: DirectShow sample code - GrabBitmaps sample
DH>// This console app will open a long AVI file in the parent directory,
DH>// create a filter graph with a sample grabber filter,
DH>// read frames out of it every second for a few seconds,
DH>// and write the frames to BMP files in the current directory.
DH>//
DH>// Copyright (c) Microsoft Corporation. All rights reserved.
DH>//------------------------------------------------------------------------------
...................................................................................
DH>
Почему этот пример не выполняется под пошаговым отладчиком и на строчке
hr = pGraph->Render( pGrabOutPin );
выводит сообщение об невозможности выполнения в этом режиме.
При этом в режиме "Start Without Debugging" всё выполняется прекрасно.
Здравствуйте, SergDegun, Вы писали:
SD>в цикле перебора кадров после вызова SD>hr = pControl->Run( ); SD>выполнение останавливается на строке SD>hr = pEvent->WaitForCompletion( INFINITE, &EvCode );
А что Run возвращает?
SD>При этом функция SD>STDMETHODIMP BufferCB( double SampleTime, BYTE * pBuffer, long BufferSize ) SD>в классе CSampleGrabberCB не вызывается.
Возможно, дело в покадровом режиме — не всегда есть возможность позиционировать по кадру, а именно на эту возможность расчитан пример. Я бы убрал SetOneShot и вместо цикла по кадрам просто один раз запускал бы Run, чтобы все кадры по очереди пришли в граббер. Номер кадра тогда придется считать самому.
Здравствуйте, D. Mon, Вы писали:
SD>>При этом функция SD>>STDMETHODIMP BufferCB( double SampleTime, BYTE * pBuffer, long BufferSize ) SD>>в классе CSampleGrabberCB не вызывается.
DM>Возможно, дело в покадровом режиме — не всегда есть возможность позиционировать по кадру, а именно на эту возможность расчитан пример. Я бы убрал SetOneShot и вместо цикла по кадрам просто один раз запускал бы Run, чтобы все кадры по очереди пришли в граббер. Номер кадра тогда придется считать самому.
DM>И еще — в примере source filter задан жестко, но не всегда стоит использовать именно его. См. функцию IGraphBuilder::AddSourceFilter.
В примере строку
hr = pEvent->WaitForCompletion( INFINITE, &EvCode );
заменил на
do {
hr = pEvent->WaitForCompletion( INFINITE, &EvCode );
} while(FAILED(hr));
В общем-то в основной массе зависания пропали. Но всё таки зависания остались в одном случае: когда во время работы программы залочивается компьютер, то после разлокирования обнаруживается, что программа зависла.
Здравствуйте, SergDegun, Вы писали:
SD>Почему этот пример не выполняется под пошаговым отладчиком и на строчке SD> hr = pGraph->Render( pGrabOutPin ); SD>выводит сообщение об невозможности выполнения в этом режиме. SD>При этом в режиме "Start Without Debugging" всё выполняется прекрасно.
читал тему не очень внимательно, но может сторонний фильтр пытается влезть, в нем есть анти-дебаг, и именно он вам мешает? Если юзать в коде ConnectDirect этого можно избежать. Но у вас вообще Render...
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: Как из avi сделать последовательность bmp.
От:
Аноним
Дата:
29.05.09 03:14
Оценка:
Здравствуйте, SergDegun, Вы писали:
SD>Здравствуйте, DEMON HOOD, Вы писали:
DH>>Здравствуйте, magician_g, Вы писали:
_>>>Как из avi сделать последовательность bmp.
DH>>
DH>>//------------------------------------------------------------------------------
DH>>// File: GrabBitmaps.cpp
DH>>//
DH>>//
DH>>// Desc: DirectShow sample code - GrabBitmaps sample
DH>>// This console app will open a long AVI file in the parent directory,
DH>>// create a filter graph with a sample grabber filter,
DH>>// read frames out of it every second for a few seconds,
DH>>// and write the frames to BMP files in the current directory.
DH>>//
DH>>// Copyright (c) Microsoft Corporation. All rights reserved.
DH>>//------------------------------------------------------------------------------
SD>...................................................................................
DH>>
SD>Почему этот пример не выполняется под пошаговым отладчиком и на строчке SD> hr = pGraph->Render( pGrabOutPin ); SD>выводит сообщение об невозможности выполнения в этом режиме. SD>При этом в режиме "Start Without Debugging" всё выполняется прекрасно.
А не подскажите где вы взяли файлик GrabBitmaps.cpp? в новом SDK для винды его нету та и в directx sdk тоже. Пожалуста,очень надо.