Как из avi сделать последовательность bmp.
От: magician_g  
Дата: 21.02.04 20:36
Оценка:
Как из avi сделать последовательность bmp.
Re: Как из avi сделать последовательность bmp.
От: DEMON HOOD  
Дата: 21.02.04 23:09
Оценка:
Здравствуйте, magician_g, Вы писали:

_>Как из avi сделать последовательность bmp.


//------------------------------------------------------------------------------
// File: GrabBitmaps.cpp
//
// Desc: DirectShow sample code - GrabBitmaps sample
//       This console app will open a long AVI file in the parent directory,
//       create a filter graph with a sample grabber filter,
//       read frames out of it every second for a few seconds, 
//       and write the frames to BMP files in the current directory.
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//------------------------------------------------------------------------------

#include <windows.h>
#include <streams.h>
#include <stdio.h>
#include <atlbase.h>
#include <qedit.h>

// Function prototypes
int GrabBitmaps(TCHAR * szFile);
HRESULT GetPin(IBaseFilter * pFilter, PIN_DIRECTION dirrequired,  int iNum, IPin **ppPin);
IPin *  GetInPin ( IBaseFilter *pFilter, int Num );
IPin *  GetOutPin( IBaseFilter *pFilter, int Num );

// Constants
#define NUM_FRAMES_TO_GRAB  5


//
// Implementation of CSampleGrabberCB object
//
// Note: this object is a SEMI-COM object, and can only be created statically.

class CSampleGrabberCB : public ISampleGrabberCB 
{

public:

    // These will get set by the main thread below. We need to
    // know this in order to write out the bmp
    long Width;
    long Height;

    // Fake out any COM ref counting
    //
    STDMETHODIMP_(ULONG) AddRef() { return 2; }
    STDMETHODIMP_(ULONG) Release() { return 1; }

    // Fake out any COM QI'ing
    //
    STDMETHODIMP QueryInterface(REFIID riid, void ** ppv)
    {
        CheckPointer(ppv,E_POINTER);
        
        if( riid == IID_ISampleGrabberCB || riid == IID_IUnknown ) 
        {
            *ppv = (void *) static_cast<ISampleGrabberCB*> ( this );
            return NOERROR;
        }    

        return E_NOINTERFACE;
    }


    // We don't implement this one
    //
    STDMETHODIMP SampleCB( double SampleTime, IMediaSample * pSample )
    {
        return 0;
    }


    // The sample grabber is calling us back on its deliver thread.
    // This is NOT the main app thread!
    //
    STDMETHODIMP BufferCB( double SampleTime, BYTE * pBuffer, long BufferSize )
    {
        //
        // Convert the buffer into a bitmap
        //
        TCHAR szFilename[MAX_PATH];
        wsprintf(szFilename, TEXT("Bitmap%5.5ld.bmp\0"), long( SampleTime * 1000 ) );

        // Create a file to hold the bitmap
        HANDLE hf = CreateFile(szFilename, GENERIC_WRITE, FILE_SHARE_READ, 
                               NULL, CREATE_ALWAYS, NULL, NULL );

        if( hf == INVALID_HANDLE_VALUE )
        {
            return 0;
        }

        _tprintf(TEXT("Found a sample at time %ld ms\t[%s]\r\n"), 
                 long( SampleTime * 1000 ), szFilename );

        // Write out the file header
        //
        BITMAPFILEHEADER bfh;
        memset( &bfh, 0, sizeof( bfh ) );
        bfh.bfType = 'MB';
        bfh.bfSize = sizeof( bfh ) + BufferSize + sizeof( BITMAPINFOHEADER );
        bfh.bfOffBits = sizeof( BITMAPINFOHEADER ) + sizeof( BITMAPFILEHEADER );

        DWORD Written = 0;
        WriteFile( hf, &bfh, sizeof( bfh ), &Written, NULL );

        // Write the bitmap format
        //
        BITMAPINFOHEADER bih;
        memset( &bih, 0, sizeof( bih ) );
        bih.biSize = sizeof( bih );
        bih.biWidth = Width;
        bih.biHeight = Height;
        bih.biPlanes = 1;
        bih.biBitCount = 24;

        Written = 0;
        WriteFile( hf, &bih, sizeof( bih ), &Written, NULL );

        // Write the bitmap bits
        //
        Written = 0;
        WriteFile( hf, pBuffer, BufferSize, &Written, NULL );

        CloseHandle( hf );

        return 0;
    }
};


//
// Main program code
//
int _tmain(int argc, TCHAR* argv[])
{
    if( argc != 2 || !argv || !argv[1] )
    {
        _tprintf( TEXT("GrabBitmaps: You must specify a media filename!\r\n") );
        _tprintf( TEXT("Usage: GrabBitmaps Filename\r\n"));
        return 0;
    }

    CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

    // Read the filename from the command line      
    TCHAR szFile[MAX_PATH];
    _tcsncpy(szFile, argv[1], MAX_PATH-1);
    szFile[MAX_PATH-1] = 0;      // Null-terminate
    
    int nSuccess = GrabBitmaps(szFile);

    CoUninitialize();

    return nSuccess;
}


int GrabBitmaps(TCHAR * szFile )
{
    USES_CONVERSION;
    CComPtr< ISampleGrabber > pGrabber;
    CComPtr< IBaseFilter >    pSource;
    CComPtr< IGraphBuilder >  pGraph;
    CComPtr< IVideoWindow >   pVideoWindow;
    HRESULT hr;

    if (!szFile)
        return -1;

    _tprintf(TEXT("Grabbing bitmaps from %s.\r\n"), szFile);

    // Create the sample grabber
    //
    pGrabber.CoCreateInstance( CLSID_SampleGrabber );
    if( !pGrabber )
    {
        _tprintf( TEXT("Could not create CLSID_SampleGrabber\r\n") );
        return -1;
    }
    CComQIPtr< IBaseFilter, &IID_IBaseFilter > pGrabberBase( pGrabber );

    // Create the file reader
    //
    pSource.CoCreateInstance( CLSID_AsyncReader );
    if( !pSource )
    {
        _tprintf( TEXT("Could not create source filter\r\n") );
        return -1;
    }

    // Create the graph
    //
    pGraph.CoCreateInstance( CLSID_FilterGraph );
    if( !pGraph )
    {
        _tprintf( TEXT("Could not not create the graph\r\n") );
        return -1;
    }

    // Put them in the graph
    //
    hr = pGraph->AddFilter( pSource, L"Source" );
    hr = pGraph->AddFilter( pGrabberBase, L"Grabber" );

    // Load the source
    //
    CComQIPtr< IFileSourceFilter, &IID_IFileSourceFilter > pLoad( pSource );
    hr = pLoad->Load( T2W( szFile ), NULL );
    if( FAILED( hr ) )
    {
        _tprintf( TEXT("Could not load the media file\r\n") );
        return -1;
    }

    // Tell the grabber to grab 24-bit video. Must do this
    // before connecting it
    //
    CMediaType GrabType;
    GrabType.SetType( &MEDIATYPE_Video );
    GrabType.SetSubtype( &MEDIASUBTYPE_RGB24 );
    hr = pGrabber->SetMediaType( &GrabType );

    // Get the output pin and the input pin
    //
    CComPtr< IPin > pSourcePin;
    CComPtr< IPin > pGrabPin;

    pSourcePin = GetOutPin( pSource, 0 );
    pGrabPin   = GetInPin( pGrabberBase, 0 );

    // ... and connect them
    //
    hr = pGraph->Connect( pSourcePin, pGrabPin );
    if( FAILED( hr ) )
    {
        _tprintf( TEXT("Could not connect source filter to grabber\r\n") );
        return -1;
    }

    // This semi-COM object will receive sample callbacks for us
    //
    CSampleGrabberCB CB;

    // Ask for the connection media type so we know its size
    //
    AM_MEDIA_TYPE mt;
    hr = pGrabber->GetConnectedMediaType( &mt );

    VIDEOINFOHEADER * vih = (VIDEOINFOHEADER*) mt.pbFormat;
    CB.Width  = vih->bmiHeader.biWidth;
    CB.Height = vih->bmiHeader.biHeight;
    FreeMediaType( mt );

    // Render the grabber output pin (to a video renderer)
    //
    CComPtr <IPin> pGrabOutPin = GetOutPin( pGrabberBase, 0 );
    hr = pGraph->Render( pGrabOutPin );
    if( FAILED( hr ) )
    {
        _tprintf( TEXT("Could not render grabber output pin\r\n") );
        return -1;
    }

    // Don't buffer the samples as they pass through
    //
    hr = pGrabber->SetBufferSamples( FALSE );

    // Only grab one at a time, stop stream after
    // grabbing one sample
    //
    hr = pGrabber->SetOneShot( TRUE );

    // Set the callback, so we can grab the one sample
    //
    hr = pGrabber->SetCallback( &CB, 1 );

    // Get the seeking interface, so we can seek to a location
    //
    CComQIPtr< IMediaSeeking, &IID_IMediaSeeking > pSeeking( pGraph );

    // Query the graph for the IVideoWindow interface and use it to
    // disable AutoShow.  This will prevent the ActiveMovie window from
    // being displayed while we grab bitmaps from the running movie.
    CComQIPtr< IVideoWindow, &IID_IVideoWindow > pWindow = pGraph;
    if (pWindow)
    {
        hr = pWindow->put_AutoShow(OAFALSE);
    }

    // Find a limited number of frames
    //
    for( int i = 0 ; i < NUM_FRAMES_TO_GRAB ; i++ )
    {
        // set position
        REFERENCE_TIME Start = i * UNITS;
        hr = pSeeking->SetPositions( &Start, AM_SEEKING_AbsolutePositioning, 
                                     NULL, AM_SEEKING_NoPositioning );

        // activate the threads
        CComQIPtr< IMediaControl, &IID_IMediaControl > pControl( pGraph );
        hr = pControl->Run( );

        // wait for the graph to settle
        CComQIPtr< IMediaEvent, &IID_IMediaEvent > pEvent( pGraph );
        long EvCode = 0;

        hr = pEvent->WaitForCompletion( INFINITE, &EvCode );
        
        // callback wrote the sample
    }

    _tprintf(TEXT("Sample grabbing complete.\r\n"));
    return 0;
}


HRESULT GetPin( IBaseFilter * pFilter, PIN_DIRECTION dirrequired, int iNum, IPin **ppPin)
{
    CComPtr< IEnumPins > pEnum;
    *ppPin = NULL;

    HRESULT hr = pFilter->EnumPins(&pEnum);
    if(FAILED(hr)) 
        return hr;

    ULONG ulFound;
    IPin *pPin;
    hr = E_FAIL;

    while(S_OK == pEnum->Next(1, &pPin, &ulFound))
    {
        PIN_DIRECTION pindir = (PIN_DIRECTION)3;

        pPin->QueryDirection(&pindir);
        if(pindir == dirrequired)
        {
            if(iNum == 0)
            {
                *ppPin = pPin;  // Return the pin's interface
                hr = S_OK;      // Found requested pin, so clear error
                break;
            }
            iNum--;
        } 

        pPin->Release();
    } 

    return hr;
}


IPin * GetInPin( IBaseFilter * pFilter, int nPin )
{
    CComPtr<IPin> pComPin=0;
    GetPin(pFilter, PINDIR_INPUT, nPin, &pComPin);
    return pComPin;
}


IPin * GetOutPin( IBaseFilter * pFilter, int nPin )
{
    CComPtr<IPin> pComPin=0;
    GetPin(pFilter, PINDIR_OUTPUT, nPin, &pComPin);
    return pComPin;
}
... << RSDN@Home 1.1.2 beta 1 >>
Re[2]: Как из avi сделать последовательность bmp.
От: SergDegun Россия  
Дата: 20.11.06 07:07
Оценка:
Здравствуйте, 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>


А не подскажите как создать исполняемый модуль на основе этого примера. Пробовал создавать проект как консольное приложение в трех средах разработки: Microsoft Visual Studio 6.0; Microsoft Visual Studio 2003; Microsoft Visual Studio 2005. Ни в одной среде выполнения создать окончательный модуль не получилось. Наилучший вариант даёт Microsoft Visual Studio 2003, но и он при линковке выдаёт порядка 20 ошибок о нехватке ряда функций и переменных. В системе установлен Microsoft Platform SDK версии for Windows Server 2003 R2 (может нужен более ранний). Сам я только начал разбираться с DirectShow, поэтому, видимо, что то не так делаю. Как нужно правильно создать проект, чтобы сформировать исполняемый файл?
Re[3]: Как из avi сделать последовательность bmp.
От: GDever  
Дата: 20.11.06 09:54
Оценка:
DH>>Здравствуйте, magician_g, Вы писали:
_>>>Как из avi сделать последовательность bmp.
SD>Как нужно правильно создать проект, чтобы сформировать исполняемый файл?

Без приведённых ошибок что-либо конкретное сказать сложно, однако есть мнение что не подключены либы от DirectShow — надо DirectX SDK качать.
Хотя как вариант работы с AVI можно попробовать это (там хоть и на VB но можно легко переделать на C++).
Re[4]: Как из avi сделать последовательность bmp.
От: SergDegun Россия  
Дата: 27.02.08 08:28
Оценка:
Здравствуйте, GDever, Вы писали:

DH>>>Здравствуйте, magician_g, Вы писали:

_>>>>Как из avi сделать последовательность bmp.
SD>>Как нужно правильно создать проект, чтобы сформировать исполняемый файл?

GD>Без приведённых ошибок что-либо конкретное сказать сложно, однако есть мнение что не подключены либы от DirectShow — надо DirectX SDK качать.

GD>Хотя как вариант работы с AVI можно попробовать это (там хоть и на VB но можно легко переделать на C++).

В файле wxdebug.h при определении класса

class CDispBasic
{
public:
    CDispBasic() { m_pString = m_String; };
    ~CDispBasic();
protected:
    PTCHAR m_pString;  // normally points to m_String... unless too much data
    TCHAR m_String[50];
};


на строку
    PTCHAR m_pString;  // normally points to m_String... unless too much data


выдаёт следующие ошибки:

c:\program files\microsoft platform sdk\samples\multimedia\directshow\baseclasses\wxdebug.h(329) : error C2146: syntax error : missing ';' before identifier 'm_pString'
c:\program files\microsoft platform sdk\samples\multimedia\directshow\baseclasses\wxdebug.h(329) : error C4430: missing type specifier — int assumed. Note: C++ does not support default-int
c:\program files\microsoft platform sdk\samples\multimedia\directshow\baseclasses\wxdebug.h(329) : error C4430: missing type specifier — int assumed. Note: C++ does not support default-int

а на строку
    CDispBasic() { m_pString = m_String; };


такую:

c:\program files\microsoft platform sdk\samples\multimedia\directshow\baseclasses\wxdebug.h(326) : error C2065: 'm_pString' : undeclared identifier

Похоже на то, что не определено PTCHAR. Пробовал определять явным образом
#define PTCHAR *TCHAR
но не проходит. Как обойти?
Re[5]: Как из avi сделать последовательность bmp.
От: SergDegun Россия  
Дата: 27.02.08 10:24
Оценка:
Здравствуйте, SergDegun, Вы писали:

SD>Здравствуйте, GDever, Вы писали:


DH>>>>Здравствуйте, magician_g, Вы писали:

_>>>>>Как из avi сделать последовательность bmp.
SD>>>Как нужно правильно создать проект, чтобы сформировать исполняемый файл?

GD>>Без приведённых ошибок что-либо конкретное сказать сложно, однако есть мнение что не подключены либы от DirectShow — надо DirectX SDK качать.

GD>>Хотя как вариант работы с AVI можно попробовать это (там хоть и на VB но можно легко переделать на C++).

SD>В файле wxdebug.h при определении класса



Те ошибки в wxdebug.h я обошёл, отключив Precompiled Header. Но осталась ошибка в файле ctlutil.h при определении класса

class COARefTime : public CRefTime {
public:

    COARefTime() {
    };

    COARefTime(CRefTime t)
        : CRefTime(t)
    {
    };

    COARefTime(REFERENCE_TIME t)
        : CRefTime(t)
    {
    };

    COARefTime(double d) {
        m_time = (LONGLONG) (d * 10000000);
    };

    operator double() {
        return double(m_time) / 10000000;
    };

    operator REFERENCE_TIME() {
        return m_time;
    };

    COARefTime& operator=(const double& rd)  {
        m_time = (LONGLONG) (rd * 10000000);
        return *this;
    }

    COARefTime& operator=(const REFERENCE_TIME& rt)  {
        m_time = rt;
        return *this;
    }

    inline BOOL operator==(const COARefTime& rt)
    {
        return m_time == rt.m_time;
    };

    inline BOOL operator!=(const COARefTime& rt)
    {
        return m_time != rt.m_time;
    };

    inline BOOL operator < (const COARefTime& rt)
    {
        return m_time < rt.m_time;
    };

    inline BOOL operator > (const COARefTime& rt)
    {
        return m_time > rt.m_time;
    };

    inline BOOL operator >= (const COARefTime& rt)
    {
        return m_time >= rt.m_time;
    };

    inline BOOL operator <= (const COARefTime& rt)
    {
        return m_time <= rt.m_time;
    };

    inline COARefTime operator+(const COARefTime& rt)
    {
        return COARefTime(m_time + rt.m_time);
    };

    inline COARefTime operator-(const COARefTime& rt)
    {
        return COARefTime(m_time - rt.m_time);
    };

    inline COARefTime operator*(LONG l)
    {
        return COARefTime(m_time * l);
    };

    inline COARefTime operator/(LONG l)
    {
        return COARefTime(m_time / l);
    };

private:
    //  Prevent bugs from constructing from LONG (which gets
    //  converted to double and then multiplied by 10000000
    COARefTime(LONG);
    operator=(LONG);
};


на последней строке

    operator=(LONG);


выдаёт ошибку
c:\program files\microsoft platform sdk\samples\multimedia\directshow\baseclasses\ctlutil.h(278) : error C4430: missing type specifier — int assumed. Note: C++ does not support default-int
Re[6]: Как из avi сделать последовательность bmp.
От: SergDegun Россия  
Дата: 27.02.08 12:00
Оценка:
Здравствуйте, SergDegun, Вы писали:

SD>Здравствуйте, SergDegun, Вы писали:


SD>>Здравствуйте, GDever, Вы писали:


DH>>>>>Здравствуйте, magician_g, Вы писали:

_>>>>>>Как из avi сделать последовательность bmp.
SD>>>>Как нужно правильно создать проект, чтобы сформировать исполняемый файл?

GD>>>Без приведённых ошибок что-либо конкретное сказать сложно, однако есть мнение что не подключены либы от DirectShow — надо DirectX SDK качать.

GD>>>Хотя как вариант работы с AVI можно попробовать это (там хоть и на VB но можно легко переделать на C++).

SD>>В файле wxdebug.h при определении класса



SD>Те ошибки в wxdebug.h я обошёл, отключив Precompiled Header. Но осталась ошибка в файле ctlutil.h при определении класса


Предыдущая ошибка в ctlutil.h исправляется заменой предыдущей строки
    operator=(LONG);

на строку
    int operator=(LONG);


После этого компиляция проходит нормально, но при линковке возникают следующие ошибки:
GrabBitmaps.obj : error LNK2019: unresolved external symbol "void __stdcall FreeMediaType(struct _AMMediaType &)" (?FreeMediaType@@YGXAAU_AMMediaType@@@Z) referenced in function "int __cdecl GrabBitmaps(char *)" (?GrabBitmaps@@YAHPAD@Z)
GrabBitmaps.obj : error LNK2019: unresolved external symbol "public: __thiscall CMediaType::~CMediaType(void)" (??1CMediaType@@QAE@XZ) referenced in function "int __cdecl GrabBitmaps(char *)" (?GrabBitmaps@@YAHPAD@Z)
GrabBitmaps.obj : error LNK2019: unresolved external symbol "public: void __thiscall CMediaType::SetType(struct _GUID const *)" (?SetType@CMediaType@@QAEXPBU_GUID@@@Z) referenced in function "int __cdecl GrabBitmaps(char *)" (?GrabBitmaps@@YAHPAD@Z)
GrabBitmaps.obj : error LNK2019: unresolved external symbol "public: void __thiscall CMediaType::SetSubtype(struct _GUID const *)" (?SetSubtype@CMediaType@@QAEXPBU_GUID@@@Z) referenced in function "int __cdecl GrabBitmaps(char *)" (?GrabBitmaps@@YAHPAD@Z)
GrabBitmaps.obj : error LNK2019: unresolved external symbol "public: __thiscall CMediaType::CMediaType(void)" (??0CMediaType@@QAE@XZ) referenced in function "int __cdecl GrabBitmaps(char *)" (?GrabBitmaps@@YAHPAD@Z)
GrabBitmaps.obj : error LNK2001: unresolved external symbol _MEDIASUBTYPE_RGB24
GrabBitmaps.obj : error LNK2001: unresolved external symbol _MEDIATYPE_Video
GrabBitmaps.obj : error LNK2001: unresolved external symbol _CLSID_FilterGraph
GrabBitmaps.obj : error LNK2001: unresolved external symbol _CLSID_AsyncReader
GrabBitmaps.obj : error LNK2001: unresolved external symbol _CLSID_SampleGrabber
GrabBitmaps.obj : error LNK2001: unresolved external symbol _IID_ISampleGrabberCB
GrabBitmaps.obj : error LNK2001: unresolved external symbol _IID_IBaseFilter
GrabBitmaps.obj : error LNK2001: unresolved external symbol _IID_IFileSourceFilter
GrabBitmaps.obj : error LNK2001: unresolved external symbol _IID_IMediaSeeking
GrabBitmaps.obj : error LNK2001: unresolved external symbol _IID_IVideoWindow
GrabBitmaps.obj : error LNK2001: unresolved external symbol _IID_IMediaControl
GrabBitmaps.obj : error LNK2001: unresolved external symbol _IID_IMediaEvent
D:\Projects\GrabBitmaps\Debug\GrabBitmaps.exe : fatal error LNK1120: 17 unresolved externals

После подключения в проект любой их двух библиотек (они одинаковые) из Microsoft Platform SDK Windows® Server 2003 SP1
C:\Program Files\Microsoft Platform SDK\Lib\amstrmid.lib
C:\Program Files\Microsoft Platform SDK\Lib\strmiids.lib

остаются 5 ошибок, связанные с отсутствием необходимых функций:
GrabBitmaps.obj : error LNK2019: unresolved external symbol "void __stdcall FreeMediaType(struct _AMMediaType &)" (?FreeMediaType@@YGXAAU_AMMediaType@@@Z) referenced in function "int __cdecl GrabBitmaps(char *)" (?GrabBitmaps@@YAHPAD@Z)
GrabBitmaps.obj : error LNK2019: unresolved external symbol "public: __thiscall CMediaType::~CMediaType(void)" (??1CMediaType@@QAE@XZ) referenced in function "int __cdecl GrabBitmaps(char *)" (?GrabBitmaps@@YAHPAD@Z)
GrabBitmaps.obj : error LNK2019: unresolved external symbol "public: void __thiscall CMediaType::SetSubtype(struct _GUID const *)" (?SetSubtype@CMediaType@@QAEXPBU_GUID@@@Z) referenced in function "int __cdecl GrabBitmaps(char *)" (?GrabBitmaps@@YAHPAD@Z)
GrabBitmaps.obj : error LNK2019: unresolved external symbol "public: void __thiscall CMediaType::SetType(struct _GUID const *)" (?SetType@CMediaType@@QAEXPBU_GUID@@@Z) referenced in function "int __cdecl GrabBitmaps(char *)" (?GrabBitmaps@@YAHPAD@Z)
GrabBitmaps.obj : error LNK2019: unresolved external symbol "public: __thiscall CMediaType::CMediaType(void)" (??0CMediaType@@QAE@XZ) referenced in function "int __cdecl GrabBitmaps(char *)" (?GrabBitmaps@@YAHPAD@Z)
D:\Projects\GrabBitmaps\Debug\GrabBitmaps.exe : fatal error LNK1120: 5 unresolved externals

Но ни в Microsoft Visual Studio 2005 SP1, ни в Microsoft Platform SDK Microsoft Platform SDK Windows® Server 2003 SP1, ни в Microsoft DirectX 9.0 SDK (Summer 2004) нет LIB-файлов, в которых были бы указанные функции. Где их взять или как это обойти?
Re[7]: Как из avi сделать последовательность bmp.
От: Stuw  
Дата: 27.02.08 12:07
Оценка:
Здравствуйте, SergDegun

...
SD>остаются 5 ошибок, связанные с отсутствием необходимых функций:
SD>GrabBitmaps.obj : error LNK2019: unresolved external symbol "void __stdcall FreeMediaType(struct _AMMediaType &)" (?FreeMediaType@@YGXAAU_AMMediaType@@@Z) referenced in function "int __cdecl GrabBitmaps(char *)" (?GrabBitmaps@@YAHPAD@Z)
SD>GrabBitmaps.obj : error LNK2019: unresolved external symbol "public: __thiscall CMediaType::~CMediaType(void)" (??1CMediaType@@QAE@XZ) referenced in function "int __cdecl GrabBitmaps(char *)" (?GrabBitmaps@@YAHPAD@Z)
SD>GrabBitmaps.obj : error LNK2019: unresolved external symbol "public: void __thiscall CMediaType::SetSubtype(struct _GUID const *)" (?SetSubtype@CMediaType@@QAEXPBU_GUID@@@Z) referenced in function "int __cdecl GrabBitmaps(char *)" (?GrabBitmaps@@YAHPAD@Z)
SD>GrabBitmaps.obj : error LNK2019: unresolved external symbol "public: void __thiscall CMediaType::SetType(struct _GUID const *)" (?SetType@CMediaType@@QAEXPBU_GUID@@@Z) referenced in function "int __cdecl GrabBitmaps(char *)" (?GrabBitmaps@@YAHPAD@Z)
SD>GrabBitmaps.obj : error LNK2019: unresolved external symbol "public: __thiscall CMediaType::CMediaType(void)" (??0CMediaType@@QAE@XZ) referenced in function "int __cdecl GrabBitmaps(char *)" (?GrabBitmaps@@YAHPAD@Z)
SD>D:\Projects\GrabBitmaps\Debug\GrabBitmaps.exe : fatal error LNK1120: 5 unresolved externals

SD>Но ни в Microsoft Visual Studio 2005 SP1, ни в Microsoft Platform SDK Microsoft Platform SDK Windows® Server 2003 SP1, ни в Microsoft DirectX 9.0 SDK (Summer 2004) нет LIB-файлов, в которых были бы указанные функции. Где их взять или как это обойти?



т.е. у тебя нигде нет Strmbase.lib (из Microsoft DirectShow 9.0)
Re[8]: Как из avi сделать последовательность bmp.
От: SergDegun Россия  
Дата: 27.02.08 14:04
Оценка:
Здравствуйте, Stuw, Вы писали:

S>Здравствуйте, SergDegun


SD>>Но ни в Microsoft Visual Studio 2005 SP1, ни в Microsoft Platform SDK Microsoft Platform SDK Windows® Server 2003 SP1, ни в Microsoft DirectX 9.0 SDK (Summer 2004) нет LIB-файлов, в которых были бы указанные функции. Где их взять или как это обойти?



S>т.е. у тебя нигде нет Strmbase.lib (из Microsoft DirectShow 9.0)


Нет. Видимо потому, что у меня не установлен Microsoft DirectShow 9.0
Re[9]: Как из avi сделать последовательность bmp.
От: squid  
Дата: 28.02.08 07:34
Оценка:
Здравствуйте, SergDegun, Вы писали:

SD>Здравствуйте, Stuw, Вы писали:


S>>Здравствуйте, SergDegun


SD>>>Но ни в Microsoft Visual Studio 2005 SP1, ни в Microsoft Platform SDK Microsoft Platform SDK Windows® Server 2003 SP1, ни в Microsoft DirectX 9.0 SDK (Summer 2004) нет LIB-файлов, в которых были бы указанные функции. Где их взять или как это обойти?



S>>т.е. у тебя нигде нет Strmbase.lib (из Microsoft DirectShow 9.0)


SD>Нет. Видимо потому, что у меня не установлен Microsoft DirectShow 9.0


нужен Windows SDK / Platform SDK + DirectX SDK. и все.

помоему ваши исправления вовсе не нужны, у меня было подобное, решилось
правильным порядком "include" директорий.

чтобы появились всякие .obj'ы нужно сбилдить baseclasses для DirectShow
(который находиться в Platform SDK / Windows SDK).

вообще в доках описано что и как настраивать.

P.S.
сорри если прочел ваши предыдущие посты невнимательно
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[10]: Как из avi сделать последовательность bmp.
От: SergDegun Россия  
Дата: 28.02.08 10:49
Оценка:
Здравствуйте, squid, Вы писали:

S>Здравствуйте, SergDegun, Вы писали:


SD>>Здравствуйте, Stuw, Вы писали:


S>>>Здравствуйте, SergDegun


SD>>>>Но ни в Microsoft Visual Studio 2005 SP1, ни в Microsoft Platform SDK Microsoft Platform SDK Windows® Server 2003 SP1, ни в Microsoft DirectX 9.0 SDK (Summer 2004) нет LIB-файлов, в которых были бы указанные функции. Где их взять или как это обойти?



S>>>т.е. у тебя нигде нет Strmbase.lib (из Microsoft DirectShow 9.0)


SD>>Нет. Видимо потому, что у меня не установлен Microsoft DirectShow 9.0


S>нужен Windows SDK / Platform SDK + DirectX SDK. и все.


S>помоему ваши исправления вовсе не нужны, у меня было подобное, решилось

S>правильным порядком "include" директорий.

S>чтобы появились всякие .obj'ы нужно сбилдить baseclasses для DirectShow

S>(который находиться в Platform SDK / Windows SDK).

Если сбилдить исходники из baseclasses, то как раз из них можно сделать Strmbase.lib.
Я пытаюсь в Microsoft Visual Studio 2005, но меня получается Release версия размером аж 20 МБайт
Так, что лучше, наверное, взять уже готовую версию Strmbase.lib из Microsoft DirectShow 9.0
Re[8]: Как из avi сделать последовательность bmp.
От: SergDegun Россия  
Дата: 28.02.08 10:50
Оценка:
Здравствуйте, Stuw, Вы писали:

S>Здравствуйте, SergDegun


S>...

SD>>остаются 5 ошибок, связанные с отсутствием необходимых функций:
SD>>Но ни в Microsoft Visual Studio 2005 SP1, ни в Microsoft Platform SDK Microsoft Platform SDK Windows® Server 2003 SP1, ни в Microsoft DirectX 9.0 SDK (Summer 2004) нет LIB-файлов, в которых были бы указанные функции. Где их взять или как это обойти?


S>т.е. у тебя нигде нет Strmbase.lib (из Microsoft DirectShow 9.0)


А не подскажите где можно скачать Microsoft DirectShow 9.0
Re[9]: Как из avi сделать последовательность bmp.
От: Stuw  
Дата: 28.02.08 11:56
Оценка:
Здравствуйте, SergDegun, Вы писали:

SD>Здравствуйте, Stuw, Вы писали:


S>>Здравствуйте, SergDegun


S>>...

SD>>>остаются 5 ошибок, связанные с отсутствием необходимых функций:
SD>>>Но ни в Microsoft Visual Studio 2005 SP1, ни в Microsoft Platform SDK Microsoft Platform SDK Windows® Server 2003 SP1, ни в Microsoft DirectX 9.0 SDK (Summer 2004) нет LIB-файлов, в которых были бы указанные функции. Где их взять или как это обойти?


S>>т.е. у тебя нигде нет Strmbase.lib (из Microsoft DirectShow 9.0)


SD>А не подскажите где можно скачать Microsoft DirectShow 9.0


на сколько мне известно Direct Show, это часть DirectX.
либу обычно собирают самостоятельно. про размер в 20 мегабайт релизной версии ничего сказать не могу. (разве что попробовать собрать той студией под которую делались проекты, если конечно вы не собирали нужной студией).

собраную либу получилось использовать? размер получившегося экзешника нормальный?
Re[11]: Как из avi сделать последовательность bmp.
От: squid  
Дата: 28.02.08 14:32
Оценка:
Здравствуйте, SergDegun, Вы писали:

SD>Если сбилдить исходники из baseclasses, то как раз из них можно сделать Strmbase.lib.

SD>Я пытаюсь в Microsoft Visual Studio 2005, но меня получается Release версия размером аж 20 МБайт
SD>Так, что лучше, наверное, взять уже готовую версию Strmbase.lib из Microsoft DirectShow 9.0

самый простой способ — в Пуск выбрать ярлык (в меню Platform/Windows SDK), запускающий нужную (Release/Debug) консоль, зайти в baseclasses и ввести nmake.
вроде так. ты так делаешь?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[10]: Как из avi сделать последовательность bmp.
От: squid  
Дата: 28.02.08 14:32
Оценка:
Здравствуйте, Stuw, Вы писали:

S>Здравствуйте, SergDegun, Вы писали:


SD>>Здравствуйте, Stuw, Вы писали:


S>>>Здравствуйте, SergDegun


S>>>...

SD>>>>остаются 5 ошибок, связанные с отсутствием необходимых функций:
SD>>>>Но ни в Microsoft Visual Studio 2005 SP1, ни в Microsoft Platform SDK Microsoft Platform SDK Windows® Server 2003 SP1, ни в Microsoft DirectX 9.0 SDK (Summer 2004) нет LIB-файлов, в которых были бы указанные функции. Где их взять или как это обойти?


S>>>т.е. у тебя нигде нет Strmbase.lib (из Microsoft DirectShow 9.0)


SD>>А не подскажите где можно скачать Microsoft DirectShow 9.0


S>на сколько мне известно Direct Show, это часть DirectX.


нет. оно часть Platform/Windows SDK. но DirectX SDK тоже нужен.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[12]: Как из avi сделать последовательность bmp.
От: SergDegun Россия  
Дата: 28.02.08 19:19
Оценка:
Здравствуйте, squid, Вы писали:

S>Здравствуйте, SergDegun, Вы писали:


SD>>Если сбилдить исходники из baseclasses, то как раз из них можно сделать Strmbase.lib.

SD>>Я пытаюсь в Microsoft Visual Studio 2005, но меня получается Release версия размером аж 20 МБайт
SD>>Так, что лучше, наверное, взять уже готовую версию Strmbase.lib из Microsoft DirectShow 9.0

S>самый простой способ — в Пуск выбрать ярлык (в меню Platform/Windows SDK), запускающий нужную (Release/Debug) консоль, зайти в baseclasses и ввести nmake.

S>вроде так. ты так делаешь?

Спасибо. Сделал так и всё получилось А раньше я сам создал проект статической библиотеки, в него собрал необходимы файлы и пытался так скомпилить LIB-файл
Re[13]: Как из avi сделать последовательность bmp.
От: squid  
Дата: 29.02.08 06:50
Оценка:
Здравствуйте, SergDegun, Вы писали:

SD>Здравствуйте, squid, Вы писали:


S>>Здравствуйте, SergDegun, Вы писали:


SD>>>Если сбилдить исходники из baseclasses, то как раз из них можно сделать Strmbase.lib.

SD>>>Я пытаюсь в Microsoft Visual Studio 2005, но меня получается Release версия размером аж 20 МБайт
SD>>>Так, что лучше, наверное, взять уже готовую версию Strmbase.lib из Microsoft DirectShow 9.0

S>>самый простой способ — в Пуск выбрать ярлык (в меню Platform/Windows SDK), запускающий нужную (Release/Debug) консоль, зайти в baseclasses и ввести nmake.

S>>вроде так. ты так делаешь?

SD>Спасибо. Сделал так и всё получилось А раньше я сам создал проект статической библиотеки, в него собрал необходимы файлы и пытался так скомпилить LIB-файл


этот способ описан на первой странице хелпа по DirectShow
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[9]: Как из avi сделать последовательность bmp.
От: 8bit  
Дата: 02.03.08 21:07
Оценка:
Здравствуйте, SergDegun, Вы писали:

SD>А не подскажите где можно скачать Microsoft DirectShow 9.0


Вот тут без всяких танцев вокруг DirectShow
http://www.codeproject.com/KB/audio-video/ExtractAVIFrames.aspx
Re[2]: Как из avi сделать последовательность bmp.
От: SergDegun Россия  
Дата: 06.03.08 14:39
Оценка:
Здравствуйте, 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>


Немного поменял пример от Microsoft, чтобы каждый из кадров AVI-файла выводился в отдельный BMP-файл. Для этого получаю сначала общее кол-во кадров в AVI-файле путем перевода через интерфейс IMediaSeeking графа в режим TIME_FORMAT_FRAME. Затем в цикле позиционирую на каждый кадр по отдельности и запускаю рендеринг для каждого кадра. Но почему то при этом в функцию BufferCB в первый параметр SampleTime поступает не номер кадра, а номер секунды, к которой относится данный кадр. Хотя надо отметить, что общее кол-во вызовов функции BufferCB равно общему кол-ву кадров в AVI-файле. Что нужно сделать, чтобы при вызове функции BufferCB в первый параметр поступал номер кадра?
#include <windows.h>
#include <streams.h>
#include <stdio.h>
#include <atlbase.h>
#include <qedit.h>

// Function prototypes
int GrabBitmaps(TCHAR * szFile);
HRESULT GetPin(IBaseFilter * pFilter, PIN_DIRECTION dirrequired,  int iNum, IPin **ppPin);
IPin *  GetInPin ( IBaseFilter *pFilter, int Num );
IPin *  GetOutPin( IBaseFilter *pFilter, int Num );


//
// Implementation of CSampleGrabberCB object
//
// Note: this object is a SEMI-COM object, and can only be created statically.

class CSampleGrabberCB : public ISampleGrabberCB 
{

public:

    // These will get set by the main thread below. We need to
    // know this in order to write out the bmp
    long Width;
    long Height;

    // Fake out any COM ref counting
    //
    STDMETHODIMP_(ULONG) AddRef() { return 2; }
    STDMETHODIMP_(ULONG) Release() { return 1; }

    // Fake out any COM QI'ing
    //
    STDMETHODIMP QueryInterface(REFIID riid, void ** ppv)
    {
        CheckPointer(ppv,E_POINTER);
        
        if( riid == IID_ISampleGrabberCB || riid == IID_IUnknown ) 
        {
            *ppv = (void *) static_cast<ISampleGrabberCB*> ( this );
            return NOERROR;
        }    

        return E_NOINTERFACE;
    }


    // We don't implement this one
    //
    STDMETHODIMP SampleCB( double SampleTime, IMediaSample * pSample )
    {
        return 0;
    }


    // The sample grabber is calling us back on its deliver thread.
    // This is NOT the main app thread!
    //
    STDMETHODIMP BufferCB( double SampleTime, BYTE * pBuffer, long BufferSize )
    {
        //
        // Convert the buffer into a bitmap
        //
        TCHAR szFilename[MAX_PATH];
        wsprintf(szFilename, TEXT("Bitmap%5.5ld.bmp\0"), long( SampleTime ) );

        // Create a file to hold the bitmap
        HANDLE hf = CreateFile(szFilename, GENERIC_WRITE, FILE_SHARE_READ, 
                               NULL, CREATE_ALWAYS, NULL, NULL );

        if( hf == INVALID_HANDLE_VALUE )
        {
            return 0;
        }

        _tprintf(TEXT("Found a sample number %ld \t[%s]\r\n"), 
                 long( SampleTime ), szFilename );

        // Write out the file header
        //
        BITMAPFILEHEADER bfh;
        memset( &bfh, 0, sizeof( bfh ) );
        bfh.bfType = 'MB';
        bfh.bfSize = sizeof( bfh ) + BufferSize + sizeof( BITMAPINFOHEADER );
        bfh.bfOffBits = sizeof( BITMAPINFOHEADER ) + sizeof( BITMAPFILEHEADER );

        DWORD Written = 0;
        WriteFile( hf, &bfh, sizeof( bfh ), &Written, NULL );

        // Write the bitmap format
        //
        BITMAPINFOHEADER bih;
        memset( &bih, 0, sizeof( bih ) );
        bih.biSize = sizeof( bih );
        bih.biWidth = Width;
        bih.biHeight = Height;
        bih.biPlanes = 1;
        bih.biBitCount = 24;

        Written = 0;
        WriteFile( hf, &bih, sizeof( bih ), &Written, NULL );

        // Write the bitmap bits
        //
        Written = 0;
        WriteFile( hf, pBuffer, BufferSize, &Written, NULL );

        CloseHandle( hf );

        return 0;
    }
};


//
// Main program code
//
int _tmain(int argc, TCHAR* argv[])
{
    if( argc != 2 || !argv || !argv[1] )
    {
        _tprintf( TEXT("GrabBitmaps: You must specify a media filename!\r\n") );
        _tprintf( TEXT("Usage: GrabBitmaps Filename\r\n"));
        return 0;
    }

    CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

    // Read the filename from the command line      
    TCHAR szFile[MAX_PATH];
    _tcsncpy(szFile, argv[1], MAX_PATH-1);
    szFile[MAX_PATH-1] = 0;      // Null-terminate
    
    int nSuccess = GrabBitmaps(szFile);

    CoUninitialize();

    return nSuccess;
}


int GrabBitmaps(TCHAR * szFile )
{
    USES_CONVERSION;
    CComPtr< ISampleGrabber > pGrabber;
    CComPtr< IBaseFilter >    pSource;
    CComPtr< IGraphBuilder >  pGraph;
    LONGLONG iAmountOfFrames;
    HRESULT hr;

    if (!szFile)
        return -1;

    _tprintf(TEXT("Grabbing bitmaps from %s.\r\n"), szFile);

    // Create the sample grabber
    //
    pGrabber.CoCreateInstance( CLSID_SampleGrabber );
    if( !pGrabber )
    {
        _tprintf( TEXT("Could not create CLSID_SampleGrabber\r\n") );
        return -1;
    }
    CComQIPtr< IBaseFilter, &IID_IBaseFilter > pGrabberBase( pGrabber );

    // Create the file reader
    //
    pSource.CoCreateInstance( CLSID_AsyncReader );
    if( !pSource )
    {
        _tprintf( TEXT("Could not create source filter\r\n") );
        return -1;
    }

    // Create the graph
    //
    pGraph.CoCreateInstance( CLSID_FilterGraph );
    if( !pGraph )
    {
        _tprintf( TEXT("Could not not create the graph\r\n") );
        return -1;
    }

    // Put them in the graph
    //
    hr = pGraph->AddFilter( pSource, L"Source" );
    hr = pGraph->AddFilter( pGrabberBase, L"Grabber" );

    // Load the source
    //
    CComQIPtr< IFileSourceFilter, &IID_IFileSourceFilter > pLoad( pSource );
    hr = pLoad->Load( T2W( szFile ), NULL );
    if( FAILED( hr ) )
    {
        _tprintf( TEXT("Could not load the media file\r\n") );
        return -1;
    }

    // Tell the grabber to grab 24-bit video. Must do this
    // before connecting it
    //
    CMediaType GrabType;
    GrabType.SetType( &MEDIATYPE_Video );
    GrabType.SetSubtype( &MEDIASUBTYPE_RGB24 );
    hr = pGrabber->SetMediaType( &GrabType );

    // Get the output pin and the input pin
    //
    CComPtr< IPin > pSourcePin;
    CComPtr< IPin > pGrabPin;

    pSourcePin = GetOutPin( pSource, 0 );
    pGrabPin   = GetInPin( pGrabberBase, 0 );

    // ... and connect them
    //
    hr = pGraph->Connect( pSourcePin, pGrabPin );
    if( FAILED( hr ) )
    {
        _tprintf( TEXT("Could not connect source filter to grabber\r\n") );
        return -1;
    }

    // This semi-COM object will receive sample callbacks for us
    //
    CSampleGrabberCB CB;

    // Ask for the connection media type so we know its size
    //
    AM_MEDIA_TYPE mt;
    hr = pGrabber->GetConnectedMediaType( &mt );

    VIDEOINFOHEADER * vih = (VIDEOINFOHEADER*) mt.pbFormat;
    CB.Width  = vih->bmiHeader.biWidth;
    CB.Height = vih->bmiHeader.biHeight;
    FreeMediaType( mt );

    // Render the grabber output pin (to a video renderer)
    //
    CComPtr <IPin> pGrabOutPin = GetOutPin( pGrabberBase, 0 );
    hr = pGraph->Render( pGrabOutPin );
    if( FAILED( hr ) )
    {
        _tprintf( TEXT("Could not render grabber output pin\r\n") );
        return -1;
    }

    // Don't buffer the samples as they pass through
    //
    hr = pGrabber->SetBufferSamples( FALSE );

    // Only grab one at a time, stop stream after
    // grabbing one sample
    //
    hr = pGrabber->SetOneShot( TRUE );

    // Set the callback, so we can grab the one sample
    //
    hr = pGrabber->SetCallback( &CB, 1 );

    // Get the seeking interface, so we can seek to a location
    //
    CComQIPtr< IMediaSeeking, &IID_IMediaSeeking > pSeeking( pGraph );

    // Query the graph for the IVideoWindow interface and use it to
    // disable AutoShow.  This will prevent the ActiveMovie window from
    // being displayed while we grab bitmaps from the running movie.
    CComQIPtr< IVideoWindow, &IID_IVideoWindow > pWindow = pGraph;
    if (pWindow)
    {
        hr = pWindow->put_AutoShow(OAFALSE);
    }

    // Obtainment amount of frames
    GUID iFormat=TIME_FORMAT_FRAME;
    pSeeking->SetTimeFormat(&iFormat);
    pSeeking->GetDuration(&iAmountOfFrames);

    // Find a limited number of frames
    //
    for( LONGLONG i = 0 ; i < iAmountOfFrames ; i++ )
    {
        // set position
        hr = pSeeking->SetPositions( &i, AM_SEEKING_AbsolutePositioning, 
                                     NULL, AM_SEEKING_NoPositioning );

        // activate the threads
        CComQIPtr< IMediaControl, &IID_IMediaControl > pControl( pGraph );
        hr = pControl->Run( );

        // wait for the graph to settle
        CComQIPtr< IMediaEvent, &IID_IMediaEvent > pEvent( pGraph );
        long EvCode = 0;

        hr = pEvent->WaitForCompletion( INFINITE, &EvCode );
        
        // callback wrote the sample
    }

    _tprintf(TEXT("Sample grabbing complete.\r\n"));
    return 0;
}


HRESULT GetPin( IBaseFilter * pFilter, PIN_DIRECTION dirrequired, int iNum, IPin **ppPin)
{
    CComPtr< IEnumPins > pEnum;
    *ppPin = NULL;

    HRESULT hr = pFilter->EnumPins(&pEnum);
    if(FAILED(hr)) 
        return hr;

    ULONG ulFound;
    IPin *pPin;
    hr = E_FAIL;

    while(S_OK == pEnum->Next(1, &pPin, &ulFound))
    {
        PIN_DIRECTION pindir = (PIN_DIRECTION)3;

        pPin->QueryDirection(&pindir);
        if(pindir == dirrequired)
        {
            if(iNum == 0)
            {
                *ppPin = pPin;  // Return the pin's interface
                hr = S_OK;      // Found requested pin, so clear error
                break;
            }
            iNum--;
        } 

        pPin->Release();
    } 

    return hr;
}


IPin * GetInPin( IBaseFilter * pFilter, int nPin )
{
    CComPtr<IPin> pComPin=0;
    GetPin(pFilter, PINDIR_INPUT, nPin, &pComPin);
    return pComPin;
}


IPin * GetOutPin( IBaseFilter * pFilter, int nPin )
{
    CComPtr<IPin> pComPin=0;
    GetPin(pFilter, PINDIR_OUTPUT, nPin, &pComPin);
    return pComPin;
}
Re[3]: Что никто не знает ответа на данный вопрос?
От: Аноним  
Дата: 20.03.08 11:42
Оценка:
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.