Воспроизведение видео и закрытие графа.
На страницу 1, 2  След.
 
Начать новую тему   Ответить на тему    Список форумов DirectShow форум -> Общий
Предыдущая тема :: Следующая тема  
Автор Сообщение
AndrеySol
Активный


Зарегистрирован: 27.02.2007
Сообщения: 57

СообщениеДобавлено: Пт Апр 20, 2007 8:42 am    Заголовок сообщения: Воспроизведение видео и закрытие графа. Ответить с цитатой

Собираю граф через RenderFile для видео-файла, запускаю, появляется окно видео, все идет ОК.
Если вызвать
Код:
pMediaControl->Stop();
pGraphBuilder->Release();

воспроизведение останавливается, Release() возвращает ошибку "Неверная функция" и окно видео остается видимым. Если сразу сделать повторно Release() то все происходит как положено - окно видео уничтожается и возвращаемое значение "Операция завершена успешно".
Но самое непонятное - несколько дней назад все было прекрасно, окно видео уничтожалось после первого вызова Release(). Никаких изменений в код своей проги за эти дни не вносил.
Что за беда ? В чем дело ?
На всякий случай: WinXP Pro SP2.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
AndrеySol
Активный


Зарегистрирован: 27.02.2007
Сообщения: 57

СообщениеДобавлено: Сб Апр 21, 2007 3:27 pm    Заголовок сообщения: Ответить с цитатой

Нашел в чем дело - виноват оказался фильтр переделанный по рекомендациям из статьи "Руководство по созданию Transform-фильтра", который позволяет регистрировать графы в ROT. После отмены регистрации этого фильтра все стало ОК.
Интересно в чем причина такого поведения ?

Модератору: как-нить можно этот момент обсудить с автором статьи ?
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
WondeRu
Главвред :)


Зарегистрирован: 30.10.2006
Сообщения: 188
Откуда: Самара

СообщениеДобавлено: Вс Апр 22, 2007 2:30 pm    Заголовок сообщения: Ответить с цитатой

AndrеySol писал(а):
Модератору: как-нить можно этот момент обсудить с автором статьи ?

Сообщил ему Very Happy
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Отправить e-mail Посетить сайт автора
Vlafy
Новенький


Зарегистрирован: 22.04.2007
Сообщения: 7
Откуда: Сосновый Бор

СообщениеДобавлено: Вс Апр 22, 2007 3:10 pm    Заголовок сообщения: Ответить с цитатой

AndrеySol писал(а):
Нашел в чем дело - виноват оказался фильтр переделанный по рекомендациям из статьи "Руководство по созданию Transform-фильтра", который позволяет регистрировать графы в ROT. После отмены регистрации этого фильтра все стало ОК.
Интересно в чем причина такого поведения ?

Модератору: как-нить можно этот момент обсудить с автором статьи ?

Обсудить можно, почему же нет Smile

Собственно, причина такого поведения в том, что вы не убили все фильтры, входящие в граф.
Вообще, рекомендуется строить граф вручную (т.е. с добавлением всех нужных фильтров по их GUID), а потом перед уничтожением графа убивать все фильтры. Особенно это важно, если граф строится в программе многократно. Если где-то что-то недоубить, то даже при внешне правильной работе может быть большая утечка памяти. Я сам недавно на эти грабли наступил.

Либо если вы хотите строить граф автоматически, то надо опять же перед убиванием графа сделать поиск всех фильтров в нём и убить сначала фильтры. Только при этом надо быть готовым к тому, что в графе могут оказаться ненужные фильтры. Например, кодек-пак K-Lite славится внедрением во все графы некоторых своих фильтров, что зачастую приводит к чёрному экрану и прочим проблемам. И даже если на вашем компьютере всё будет работать, то на другом может и глючить.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Отправить e-mail Посетить сайт автора
Alan
Участник


Зарегистрирован: 11.04.2007
Сообщения: 13

СообщениеДобавлено: Сб Май 05, 2007 12:34 am    Заголовок сообщения: Ответить с цитатой

У меня похожая проблема, собираю простой граф
Video Capture Source -> YUV9 Converter -> Video Renderer.
Потом граф останавливаю, удаляю и собираю заново. А ActiveMovie Window остается на экране (окно черное, отрисовка прекращается).
Сначала подумал (точнее здесь прочитал, Smile ) про "лишние" фильтры, посмотрел в GraphEdit'e все в порядке, ничего лишнего.
Пробовал убивать каждый фильтр вручную, пробовал вот так:
Код:
pFilterChain->StopChain(pVideoCaptureFilter, pRenderFilter);
pFilterChain->RemoveChain(pVideoCaptureFilter, pRenderFilter);
ничего не помогает.
Что еще, кроме не удаленных из графа фильтров, может приводить к такой ошибке?
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Vlafy
Новенький


Зарегистрирован: 22.04.2007
Сообщения: 7
Откуда: Сосновый Бор

СообщениеДобавлено: Сб Май 05, 2007 12:46 pm    Заголовок сообщения: Ответить с цитатой

Если остаётся окно просмотра, то это однозначно говорит о том, что остаётся неубитым Video Renderer. Можете попробовать в графэдите это проверить.
Что-то вы неправильно делаете всё-таки.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Отправить e-mail Посетить сайт автора
Alan
Участник


Зарегистрирован: 11.04.2007
Сообщения: 13

СообщениеДобавлено: Пт Май 11, 2007 11:48 pm    Заголовок сообщения: Ответить с цитатой

Проверил и перепроверил все! Video Renderer в GraphEdit'e исчезает, а ActiveMovie Window остается на экране! (Пробовал вариант без регистрации графа в ROT - ничего не меняется)

Удаляю фильтр так:
Код:
hr = pGraphBuilder->RemoveFilter(pRenderFilter);
hr = pRenderFilter->Release();


Вообще, я не совсем понимаю, как один фильтр может повлиять на возможность удаления другого?
Если метод Release срабатывает со второго раза, значит где-то остается "неучтенный" указатель на этот фильтр?
Насколько я понял, фильтры при соединении обмениваются указателями на соединяемые пины, но при разорванном соединении (если можно об этом судить по отсутствию связей в GraphEdit) фильтры никак друг с другом не связаны...
Если не сложно, объясните как правильно удалять фильтры из графа?
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Vlafy
Новенький


Зарегистрирован: 22.04.2007
Сообщения: 7
Откуда: Сосновый Бор

СообщениеДобавлено: Вс Май 20, 2007 11:50 pm    Заголовок сообщения: Ответить с цитатой

Да в общем-то всё правильно, так и надо удалять фильтры. Но если один фильтр получал какой-то интерфейс от другого фильтра и не освобождал его, тогда в памяти будет болтаться экземпляр фильтра, пока другие его не освободят.
Чтобы найти такую ошибку, надо видеть всю программу целиком. Я тоже долго возился с удалением фильтров из графа и в результате всё-таки победил эту проблему.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Отправить e-mail Посетить сайт автора
Alan
Участник


Зарегистрирован: 11.04.2007
Сообщения: 13

СообщениеДобавлено: Пн Май 21, 2007 4:43 pm    Заголовок сообщения: Ответить с цитатой

Вот так выглядит моя программа:
Код:
 IGraphBuilder *pGraphBuilder;
 IBaseFilter *pVideoCaptureFilter;
 IBaseFilter *pconverterFilter;
 IBaseFilter *pRenderFilter;
 IMediaControl *pMediaControl;


Функции GetFilter, GetPin и ConnectFilters я, практически без изменений, позаимствовал из DS SDK и на РСДН
Код:
HRESULT GetFilter(CComBSTR& bstrFilterName, IBaseFilter **pFilter, REFCLSID clsidDeviceClass)
{
    HRESULT hr;

    CComQIPtr<ICreateDevEnum, &IID_ICreateDevEnum> spSysDevEnum;
    hr = spSysDevEnum.CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC);
    if (SUCCEEDED(hr)){
        CComPtr<IEnumMoniker> pEnum;

        hr = spSysDevEnum->CreateClassEnumerator(clsidDeviceClass, &pEnum, 0);
        if (hr == S_OK){
            CComPtr<IMoniker> pMoniker;
            ULONG cFetched;
           
            while (SUCCEEDED(pEnum->Next(1, &pMoniker, &cFetched)))
         {
                if (!pMoniker){
                    hr = E_FAIL;
                    break;
                }
                CComQIPtr<IPropertyBag> pPropBag;
               
                hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag);
               
            if SUCCEEDED(hr){
                    CComVariant varCurFilterName;

                    varCurFilterName.vt = VT_BSTR;                   
                    pPropBag->Read(L"FriendlyName", &varCurFilterName, 0);

                    if (bstrFilterName == varCurFilterName.bstrVal){
                       pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, (void**) pFilter);
                       return S_OK;
                    }
            }
                pMoniker = NULL;
         }
      }
   }
    return E_FAIL;
}

HRESULT GetPin(PIN_INFO* pPinInfo, CComPtr<IPin>& pPin)
{
    HRESULT hr;

    if (pPinInfo->pFilter){
        CComPtr<IEnumPins> pEnumPins;
        ULONG cFetched;

        hr = pPinInfo->pFilter->EnumPins(&pEnumPins);
       
        while(pEnumPins->Next(1, &pPin, &cFetched) == S_OK)
        {
            PIN_INFO piPinInfo;           
            hr = pPin->QueryPinInfo(&piPinInfo);
            if (SUCCEEDED(hr)){
                if (piPinInfo.dir == pPinInfo->dir && piPinInfo.achName[0] != L'~'){
                    CComPtr<IPin> pConnectedPin;
                    hr = pPin->ConnectedTo(&pConnectedPin);

                    if (hr == VFW_E_NOT_CONNECTED || !pConnectedPin){
                        hr = S_OK;
                        break;
                    }
                }
            }
            pPin = NULL;
        }
    }
    else {
        hr = E_INVALIDARG;
    }
    return hr;
}

HRESULT ConnectFilters(IBaseFilter* pSourceFilter, IBaseFilter* pReceiveFilter, IGraphBuilder* pGraphBuilder)
{
    HRESULT hr;
    CComPtr<IPin> pOutputPin;
    CComPtr<IPin> pInputPin;
    PIN_INFO piPinInfo = {pSourceFilter, PINDIR_OUTPUT, {0}};
   
    hr = GetPin(&piPinInfo, pOutputPin);
    if (SUCCEEDED(hr)){       
        piPinInfo.pFilter = pReceiveFilter;
        piPinInfo.dir = PINDIR_INPUT;
       
        hr = GetPin(&piPinInfo, pInputPin);       
        hr = pGraphBuilder->Connect(pOutputPin, pInputPin);
    }
    return hr;
}


Построение графа:
Код:
HRESULT BuildCaptureGraph()
{
CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC,
                 IID_IGraphBuilder, (void**)&pGraphBuilder);

GetFilter(CComBSTR("Ewclid® VideoSynth Source"), &pVideoCaptureFilter,
                     CLSID_VideoInputDeviceCategory);
GetFilter(CComBSTR("Ewclid® YVU9 converter"), &pconverterFilter,
                     CLSID_LegacyAmFilterCategory);
GetFilter(CComBSTR("Video Renderer"), &pRenderFilter,
                     CLSID_LegacyAmFilterCategory);

pGraphBuilder->AddFilter(pVideoCaptureFilter, L"Ewclid® VideoSynth Source");
pGraphBuilder->AddFilter(pconverterFilter, L"Ewclid® YVU9 converter");
pGraphBuilder->AddFilter(pRenderFilter, L"Video Renderer");
   
ConnectFilters(pVideoCaptureFilter, pconverterFilter, pGraphBuilder);
ConnectFilters(pconverterFilter, pRenderFilter, pGraphBuilder);
   
pGraphBuilder->QueryInterface(&pMediaControl);   
pMediaControl->Run();

hr = AddToRot(pGraphBuilder, &dwRegister);

return S_OK;
}


и удаление графа:
Код:
void ReleaseGraph()
{   
pMediaControl->Stop();

hr = pGraphBuilder->RemoveFilter(pRenderFilter);
hr = pGraphBuilder->RemoveFilter(pconverterFilter);
hr = pGraphBuilder->RemoveFilter(pVideoCaptureFilter);//до этого момента hr = S_OK

hr = pRenderFilter->Release();//здесь счетчик ссылок равен 1
hr = pconverterFilter->Release(); //здесь счетчик ссылок равен 3
hr = pVideoCaptureFilter->Release();//здесь счетчик ссылок равен 1

hr = pMediaControl->Release();//S_FALSE
hr = pGraphBuilder->Release();//S_OK
}

После этого ActiveMovie window становится черным и убирается только после следующего pRenderFilter->Release(); Я так чувствую, самое правильное мне сейчас за книжки по отладке и по COM взяться Evil or Very Mad
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
AndrеySol
Активный


Зарегистрирован: 27.02.2007
Сообщения: 57

СообщениеДобавлено: Пт Май 25, 2007 1:02 am    Заголовок сообщения: Ответить с цитатой

Не очень понятна тема с ручным удалением каждого фильтра - у меня прога воспроизводит список видео-клипов 15-20 штук, при этом для каждого строится граф а затем убивается обычным pGraphBuilder->Release() - проблем нет.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Alan
Участник


Зарегистрирован: 11.04.2007
Сообщения: 13

СообщениеДобавлено: Сб Май 26, 2007 12:45 am    Заголовок сообщения: Ответить с цитатой

А у меня есть. Если просто сделать pGraphBuilder->Release(), фильтры остаются в памяти, со всеми вытекающими в виде черного ActiveMovie Window и т.д. Наверное что-то не так в процедуре получения фильтра или связывания фильтров между собой, потому как результат не зависит от набора фильтров или получаемых от них интерфейсов.

А можете показать как вы добавляете фильтры в граф и соединяете их?
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
AndrеySol
Активный


Зарегистрирован: 27.02.2007
Сообщения: 57

СообщениеДобавлено: Сб Май 26, 2007 12:37 pm    Заголовок сообщения: Ответить с цитатой

Да в общем все так-же как и в вашем примере.
Только для воспроизведения (рендеринга) использую не ручное а автоматическое построение графа, а ручное - при сборке графа конвертирования. В обоих случаях все нормально.
Кстати попробуйте для теста убрать
hr = AddToRot(pGraphBuilder, &dwRegister);
и посмотреть как будет ?
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Vlafy
Новенький


Зарегистрирован: 22.04.2007
Сообщения: 7
Откуда: Сосновый Бор

СообщениеДобавлено: Вт Июн 26, 2007 8:19 pm    Заголовок сообщения: Ответить с цитатой

Автоматический рендер плох тем, что сильно зависит от фильтров, установленных в системе, у которых высокий мерит. Такие фильтры будут в любом случае грузиться в граф. На этом "основан" нередкий глюк с фильтрами из K-Lite, проявляющийся в чёрном экране вместо картинки. Причём, на одном компе может всё работать, а на другом - нет. Поэтому лучше делать ручную сборку графа.

Alan, у меня сейчас совсем мало времени, напишите на мыло, может быть удастся совместно найти причину ваших проблем.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Отправить e-mail Посетить сайт автора
Vlafy
Новенький


Зарегистрирован: 22.04.2007
Сообщения: 7
Откуда: Сосновый Бор

СообщениеДобавлено: Сб Июл 07, 2007 3:35 pm    Заголовок сообщения: Ответить с цитатой

Я тут столкнулся с аналогичной проблемой - остаётся окно ActiveMovie Window. Стал рыться в своих исходниках других программ, и нашёл такое решение:

Код:

IVideoWindow *pVideoWindow;
...
if (pVideoWindow) {
    pVideoWindow->put_Visible(0);
    pVideoWindow->put_Owner(NULL);
}


Кроме того, полезно перед Release() удалять каждый фильтр из графа с помощью IFilterGraph->RemoveFilter(). И ещё есть полезная ф-ция CoFreeUnusedLibraries(), которая отцепляет неиспользуемые библиотеки.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Отправить e-mail Посетить сайт автора
Alan
Участник


Зарегистрирован: 11.04.2007
Сообщения: 13

СообщениеДобавлено: Пн Июл 09, 2007 7:15 pm    Заголовок сообщения: Ответить с цитатой

Две недели был в отпуске, за это время полностью переписал все функции связанные с созданием и соединением фильтров (без смарт-поинтеров, все делаю вручную). Собственно это и решило проблему, теперь все удаляется/закрывается как и должно.
У меня ошибка была либо в процедуре выделения неподключенного пина, либо в процедуре соединения фильтров.

Я так понимаю, put_Visible(0) просто закрывает ActiveMovie Window, а фильтр при этом все равно повисает в памяти.

В общем большое всем спасибо, когда точно определю в чем была проблема - напишу, может кому пригодится.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Показать сообщения:   
Начать новую тему   Ответить на тему    Список форумов DirectShow форум -> Общий Часовой пояс: GMT + 4
На страницу 1, 2  След.
Страница 1 из 2
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах


Powered by phpBB © 2001, 2005 phpBB Group
Русская поддержка phpBB


Рейтинг@Mail.ru