|
Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » Разное - [решено] *DirectShow* | не работает пример из SDK |
|
Разное - [решено] *DirectShow* | не работает пример из SDK
|
Ветеран Сообщения: 1180 |
Профиль | Отправить PM | Цитировать
Здравствуйте мною глубокоуважаемые обитатели форума, да восхвалится имя ваше (во веки веков). У меня почему-то пример из MSDN перечисления устройств DirectShow захвата видео работает не так, как там описано:
// есть шаблон com_object<typename Interface>, который выполняет IUnknown::Release(), // функции stop_error и log_error, которые сообщают результат HRESULT, // stop* выдаёт исключение в случае ошибки, log* возвращает булевскую удачу-неудачу. IEnumMoniker *dev_enum_val = 0; // получаем перечислитель устройств // com_object<Interface>::com_object<Interface>(Interface** intf, HRESULT hr) проверяет stop_error(hr) и инициализирует // указатель на интерфейс значением *intf com_object<IEnumMoniker> dev_enum(&dev_enum_val, // com_object<Interface>::com_object<Interface>(const GUID&) использует CoCreateInstance для создания объекта com_object<ICreateDevEnum>(CLSID_SystemDeviceEnum)->CreateClassEnumerator( CLSID_VideoInputDeviceCategory, &dev_enum_val, 0)); // перебираем устройства внутри категории IMoniker* dev_item_val=0; while(!log_error(dev_enum->Next(1, &dev_item_val, 0)) { com_object<IMoniker> dev_item(&dev_item_val, 0); // я проверял, dev_item->GetDisplayName(0, 0, &name) даёт правильный результат, // но дальше всё не по сценарию: // получаем набор свойств устройства IPropertyBag* prop_bag = 0; if(log_error(dev_item->BindToStorage(0, 0, IID_IPropertyBag, (void **)&prop_bag_val))) { com_object<IPropertyBag> prop_bag(&prop_bag_val, 0); // меня устраивает любое из свойств variant<wstring> friendly_name; if ( log_error(prop_bag->Read(L"Description", friendly_name.arg(), 0)) || // ошибка: неверный доступ к памяти log_error(prop_bag->Read(L"FriendlyName", friendly_name.arg(), 0)) || // ошибка: неверный доступ к памяти log_error(prop_bag->Read(L"Name", friendly_name.arg(), 0))) // ошибка: неверный доступ к памяти { // здесь, судя по примеру из MSDN, должно отображаться человеческое имя устройства // но до сюда не доходит :( MessageBoxW(Handle, friendly_name.value().c_str(), L"Enum", MB_OK); } } } // шаблон com_object void stop_error(HRESULT hr); bool log_error(HRESULT hr); template<typename Interface> class com_object { public: static const GUID& id(); ~com_object() {_ptr->Release();} com_object(const GUID& type_id, IUnknown* parent=0); com_object(Interface** outer_interface, HRESULT hr); com_object(com_object const& other) throw() : _ptr(other._ptr) {_ptr->AddRef();} template<typename Interface2> com_object(com_object<Interface2> const&); Interface* operator->() throw() {return _ptr;} Interface* get() const throw() {return _ptr;} private: Interface* _ptr; }; template<typename Interface> com_object<Interface>::com_object(const GUID& type_id, IUnknown* parent) : _ptr() { stop_error(CoCreateInstance(type_id, parent, CLSCTX_INPROC_SERVER, id(), reinterpret_cast<void**>(&_ptr))); } template<typename Interface> com_object<Interface>::com_object(Interface** outer_interface, HRESULT hr) : _ptr(*outer_interface) { stop_error(hr); if (!*outer_interface) throw runtime_error("got null interface"); } template<typename Interface> template<typename Interface2> com_object<Interface>::com_object(com_object<Interface2> const& other) : _ptr() { stop_error(other.get()->QueryInterface(id(), reinterpret_cast<void**>(_ptr))); } // шаблон variant template<typename DataT> class variant { public: static const VARTYPE type_id(); ~variant() {VariantClear(&_arg);} variant() {VariantInit(&_arg);} variant(const variant& v2) {VariantCopy(&_arg, &v2._arg);} template<typename Data2> variant(const variant<Data2>& v2) {VariantChangeType(&_arg, &v2._arg, 0, type_id());} void reset() {VariantClear(&_arg);} bool is_clear() const {return _arg.vt == VT_EMPTY;} bool is_null() const {return _arg.vt == VT_NULL;} bool is_error() const {return _arg.vt == VT_ERROR;} DataT value() const; // для вызовов API VARIANT* arg() {return &_arg;} private: VARIANT _arg; const VARIANT& _assert_value() const { // проверка что именно нужного типа (а не VT_EMPTY например) if (_arg.vt!=type_id()) throw logic_error("variant::_assert_value of different type"); return _arg; } }; template<> const VARTYPE variant<unsigned>::type_id(){return VT_UI4;} template<> unsigned variant<unsigned>::value() const {return _assert_value().lVal;} template<> const VARTYPE variant<int>::type_id() {return VT_I4;} template<> int variant<int>::value() const {return _assert_value().ulVal;} template<> const VARTYPE variant<float>::type_id() {return VT_R4;} template<> float variant<float>::value() const {return _assert_value().fltVal;} template<> const VARTYPE variant<double>::type_id() {return VT_R8;} template<> double variant<double>::value() const {return _assert_value().dblVal;} template<> const VARTYPE variant<wstring>::type_id() {return VT_BSTR;} template<> wstring variant<wstring>::value() const {return wstring(_assert_value().bstrVal);} bool log_error(HRESULT hr) { if (hr) { hr &= 0xffff; char *ddstr; if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, 0, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*) &ddstr, 0, 0)) { MessageBoxA(0, ddstr, 0, MB_OK|MB_ICONERROR); LocalFree(ddstr); } else { ostringstream ss; ss << "Undefined error 0x" << hex << hr; MessageBoxA(0, ss.str().c_str(), 0, MB_OK|MB_ICONERROR); } }; return hr==0; } void stop_error(HRESULT hr) { if (!log_error(hr)) { throw runtime_error("check_error"); }; } #include <control.h> #include <strmif.h> #include <uuids.h> template<> GUID const& com_object<ICreateDevEnum>::id() {return IID_ICreateDevEnum;} template<> GUID const& com_object<IPropertyBag>::id() {return IID_IPropertyBag;} template<> GUID const& com_object<IBaseFilter>::id() {return IID_IBaseFilter;} template<> GUID const& com_object<ICaptureGraphBuilder2>::id() {return IID_ICaptureGraphBuilder2;} template<> GUID const& com_object<IGraphBuilder>::id() {return IID_IGraphBuilder;} template<> GUID const& com_object<IVideoWindow>::id() {return IID_IVideoWindow;} template<> GUID const& com_object<IMediaControl>::id() {return IID_IMediaControl;} |
|
Отправлено: 08:33, 01-10-2009 |
Ветеран Сообщения: 5624
|
Профиль | Отправить PM | Цитировать Цитата pva:
|
|
------- Отправлено: 08:38, 01-10-2009 | #2 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
Ветеран Сообщения: 1180
|
Профиль | Отправить PM | Цитировать Цитата Delirium:
Проблема решена очень просто: ти ли я недоглядел, то ли они лоханулись, если сделать всё по аналогии с описанием группы интерфейсов IEnumXXXX, то получается так: // дописал wostream& operator<<(wostream&, const GUID&); // дописал log_message(const wstring&); которая добавляет строчку в ListView unsigned long cnt_fetched = 0; IMoniker* dev_item_val[1]; // здесь изменение // беру только по одному объекту за раз (хотя можно и по 100 взять), // только чтобы соблюсти правила безопасных исключений C++ while (log_error(filter_mons->Next(1, dev_item_val, &cnt_fetched)) && cnt_fetched) { com_object<IMoniker> dev_item(&dev_item_val[0], 0); { GUID dev_guid; wchar_t* str_name; stop_error(dev_item->GetClassID(&dev_guid)); stop_error(dev_item->GetDisplayName(0, 0, &str_name)); wostringstream ss; ss << dev_guid << str_name; __alloc->Free(str_name); log_message(ss.str()); } IPropertyBag* prop_bag_val; com_object<IPropertyBag> prop_bag(&prop_bag_val, dev_item->BindToStorage(0, 0, IID_IPropertyBag, (void**)&prop_bag_val)); variant<wstring> var_str; if (log_error(prop_bag->Read(L"FriendlyName", var_str.arg(), 0))) { log_message(var_str.value()); } } Появились новые вопросы, некоторые помещу в другое темы; Тов. модератор, если сочтёшь нужным, собери обратно в одну тему Вопрос: имя фильтра DirectShow содержит 2 классида: категория и устройство. Как их можно попрость COM узнать, что соответствует этим классидам? Через IPropertyBag? как узнать, какие вообще свойства есть в IPropertyBag (у меня не получилось создать IPropertyBag2, который это умеет)? |
|
Отправлено: 12:52, 01-10-2009 | #3 |
Ветеран Сообщения: 1180
|
Профиль | Отправить PM | Цитировать пример заработал, был косяк в месте IEnumMoniker, нашёл способ получить описание фильтров: http://forum.oszone.net/thread-151991.html
чтобы получить список категорий: http://msdn.microsoft.com/en-us/libr...55(VS.85).aspx вот что меня удивляет - это как с этим косяком у других работает, кто исходники в инете выкладывает.. у меня ни один не заработал |
Отправлено: 12:47, 03-10-2009 | #4 |
Участник сейчас на форуме | Участник вне форума | Автор темы | Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
Выпущен Windows 7 beta SDK | OSZone News | Новости и события Microsoft | 5 | 17-01-2009 10:26 | |
Субтитры в DirectShow | tri777ki | Видео и аудио: обработка и кодирование | 5 | 25-10-2007 19:46 | |
Посоветуйте идеальный баланс CPU - GPU. Using DirectX SDK, MathCad & 3DMax. | SeriousDEN | Выбор отдельных компонентов компьютера и конфигурации в целом | 23 | 18-09-2006 13:11 | |
[решено] Пример схемы сети со спутниковым Интернетом. Работать будет? | Ded_Ts | Сетевые технологии | 3 | 10-07-2006 23:19 | |
*Решено* | Помогите скомпилить пример на С | xgg | Программирование и базы данных | 3 | 23-03-2005 21:07 |
|