Кто занимался написанием программ видеозахвата?

Тема в разделе "MS Visual C++", создана пользователем skysun, 3 окт 2007.

  1. skysun

    skysun Гость

    Уважаемые, помогите!
    2 дня удараюсь головой... как сделать, что бы моя прога позволяла осуществлять
    следующие функции - захват в AVI-файл, компрессия, грабинг кадра - параллельно.

    Без проблем получается несжатое видео и возможность граббинга кадра или сжатое видео, но без
    граббинга файла.

    В какой последовательности и к каким Pin-ам цеплять фильтры?

    (Вот такая вот байда!)
     
  2. European

    Регистрация:
    4 сен 2006
    Сообщения:
    2.580
    Симпатии:
    0
    Извини за офтоп, я не специалист в данной области...
    Как-то раньше 62316e давал вот такую ссылку: http://www.jmcgowan.com/avitech.html
    Может она тебе чем-то поможет
     
  3. skysun

    skysun Гость

    Спасибо большое, European. Но это к делу неотносится.

    Хотя вопрос снят. Дело, как, я и думал оказалось в последовательности, в которой я подключал фильтры.
    :(

    Если кому интересно могу поделится опытом.
     
  4. tyko

    tyko New Member

    Регистрация:
    2 ноя 2007
    Сообщения:
    4
    Симпатии:
    0
    если предложение еще в силе, очень был бы рад пообщатся...
    Уже вторую неделю бьюсь над написанием приложения, работающим с видео: захват с вебкамеры, скриншоты эрана, компресинг, сохранение и воспроизведение видео;
    много вопросов, непоняток...
     
  5. skysun

    skysun Гость

    Для: tyko
    Давай пообщаемся. Я не против. Помогу чем смогу!
     
  6. tyko

    tyko New Member

    Регистрация:
    2 ноя 2007
    Сообщения:
    4
    Симпатии:
    0
    чтобы по мелочам не доставать тебя, может подкинешь для начала какие то полезные ссылки по данной теме.
    Я в данной теме новичок, так что будет все интересно.
    (пишу я на маке в XCode, и все пока читаю из хелпы, на хорошие ресурсы пока не натыкался).
    проэкт только в начальном этапе, так что если "споемся", думаю будем друг-другу полезны :)
     
  7. skysun

    skysun Гость

    ссылки:
    1)MSDN-разделы DirectX,DirectDraw-очень подробные статьи(особенно если с английским проблем нет)
    2)http://www.codeproject.com/ - буржуйский портал(сплошные китайцы и индусы), много исходников по теме.

    Мне этой инф-ы оказалось достаточно. Будут вопросы пиши!
     
  8. tyko

    tyko New Member

    Регистрация:
    2 ноя 2007
    Сообщения:
    4
    Симпатии:
    0
    разобрался как захватывать видео и сохранять в муви, а как сохранить в mpeg-4(avi)?
     
  9. skysun

    skysun Гость

    1)запрашиваешь список всех видео компрессоров
    Код (Text):
    BOOL CCapture::GetCompressorsList(CStringList& CompressorsList)
    {
    //************************************************************
    HRESULT hr;
    ICreateDevEnum *pSysDevEnum = NULL;
    IEnumMoniker *pEnum = NULL;
    IMoniker *pMoniker = NULL;

    hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
    CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
    (void**)&pSysDevEnum);
    if (FAILED(hr))
    {
    return FALSE;
    }  

    hr = pSysDevEnum->CreateClassEnumerator(
    CLSID_VideoCompressorCategory, &pEnum, 0);
    if (hr == S_OK) // S_FALSE means nothing in this category.
    {
    while (S_OK == pEnum->Next(1, &pMoniker, NULL))
    {
    IPropertyBag *pPropBag = NULL;
    pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
    (void **)&pPropBag);
    VARIANT varName;
    VariantInit(&varName);
    hr = pPropBag->Read(L"FriendlyName", &varName, 0);
    if (SUCCEEDED(hr))
    {
    USES_CONVERSION;
    CComBSTR bstrName(varName.bstrVal);
    CompressorsList.AddTail(OLE2A(bstrName));
    bstrName.Empty();          
    }  
    VariantClear(&varName);
    pPropBag->Release();
    pMoniker->Release();
    }
    }
    pSysDevEnum->Release();
    pEnum->Release();

    //************************************************************

    return TRUE;
    }

    2)аттачишся к нужном тебе. Примерно так CComPtr<IBaseFilter> pVC прикрепляется к компрессору с заданным именем:
    Код (Text):
    BOOL CCapture::FindVideoCompressor(CString CompressorName)
    {
    HRESULT hr = E_FAIL;
    CComPtr<IBaseFilter> pFilter;
    CComPtr<ICreateDevEnum> pSysDevEnum;
    CComPtr<IEnumMoniker> pEnumCat = NULL;

    // Create the System Device Enumerator.
    hr=pSysDevEnum.CoCreateInstance(CLSID_SystemDeviceEnum);
    if(FAILED(hr))
    return FALSE;

    // Obtain a class enumerator for the video compressor category.
    hr=pSysDevEnum->CreateClassEnumerator(CLSID_VideoCompressorCategory, &pEnumCat, 0);
    if(FAILED(hr)||(hr==S_FALSE)||(hr==E_OUTOFMEMORY)||(hr==E_POINTER))
    return FALSE;

    // Enumerate the monikers.
    CComPtr<IMoniker> pMoniker;
    ULONG cFetched=0;

    while(pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK)
    {
    /////////////////////////////////////////////////////
    CComPtr<IPropertyBag> pProp;
    hr=pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pProp);
    if(SUCCEEDED(hr))
    {
    VARIANT varName;
    VariantInit(&varName); // Try to match the friendly name.
    hr = pProp->Read(L"FriendlyName", &varName, 0);
    if (SUCCEEDED(hr))
    {
    CComBSTR bstrDevName(varName.bstrVal);
    USES_CONVERSION;
    if(bstrDevName == T2OLE(CompressorName))
    {
    hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pFilter);
    if (SUCCEEDED(hr))
    {
    pVC = pFilter;
    pVC.p->AddRef(); // Add ref on the way out.
    return TRUE;
    }
    else
    return FALSE;
    break;
    }
    }
    VariantClear(&varName);
    }
    pMoniker = NULL; // Release for the next loop.
    cFetched=0;
    /////////////////////////////////////////////////////
    }
    return FALSE;
    }

    3)затем SetOutputFileName и RenderStream. Пример

    Код (Text):
    CComPtr<IBaseFilter> pVFW;// Create the video file-writing(VFW) portion.
    CComPtr<IBaseFilter> pVC;//Video compressor filter
    CComPtr<IBaseFilter> pSrc;//фильтр прикрепленный к устройству
    CComQIPtr<IMediaControl> pControl;




    hr = pBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi, L"C:\\Example.avi", &pVFW, NULL);

    // Render the capture pin on the video capture filter
    hr = pBuilder->RenderStream(
    &PIN_CATEGORY_CAPTURE, // Pin category
    &MEDIATYPE_Video,     // Media type
    pSrc,                 // Capture filter
    pVC,     // Compression filter (optional)
    pVFW                    // Multiplexer or renderer filter  
    );
    pControl->Run()
    Кажись все.
     
  10. skysun

    skysun Гость

    Кстати забыл! Дело в том, что компрессия "на лету" требует от ПК огромных ресурсов и чем выше качество и уровень компрессии тем сильнее все тормозит и качество конечного ролика оставляет желать лучшего. Может быть имеет смысл уже после захвата видео во временный файл его сжимать. Тогда это делается чуть по другому. Видел статью в MSDN, как точно сказать не могу, но если память меня не подводит разница только в том, что pSrc(в моем примере) должен быть прикреплен к файлу а не к устройству-захвата. Даже спец. метод для этого описывался.

    Удачи!
     
  11. tyko

    tyko New Member

    Регистрация:
    2 ноя 2007
    Сообщения:
    4
    Симпатии:
    0
    спасибо, разобрался!
    сейчас отался кодек flv
     
Загрузка...

Поделиться этой страницей