Проблема с титровальным сервером в собственной программе

Здесь обсуждаются любые продукты компании СофтЛаб-НСК для телевизионного вещания (Форвард Т, Форвард ТС, Форвард Голкипер, Форвард Рефери, Форвард Офис, Форвард Инжест)

Модераторы: ElenVR, Людмила, PR

Ответить
kasa
Сообщения: 90
Зарегистрирован: 04 сен 2008 01:50
Откуда: Красноярск

Проблема с титровальным сервером в собственной программе

Сообщение kasa »

Здравствуйте!

Имеем два ПО собственного изготовления, которые используют титровальный сервер. Если обе программы запустить на одном сервере, а через некоторое время одну из них закрыть, то вторая тоже перестает работать.

Если после сбоя закрыть вторую программу и отркыть снова, то она работает нормально.

Я подозреваю, что проблема в освобождении объекта CLSID_SLTitleTarget, который освобождается через Release в обоих программах при их закрытии. Подскажите, пожалуйста, это баг или фича? В описании SDK ничего не нашел по этому поводу...

И как мне решить эту проблему? Что будет, если я просто оставлю ссылку на этот объект? Не будет ли утечки ссылок? Логика подсказывает, что этот класс реализован в виде синглетона и ничего страшного от "зависшей" ссылки не произойдет, но хотелось бы официального подтверждения.

Спасибо.
Даниленко Сергей
Сообщения: 7093
Зарегистрирован: 26 фев 2004 09:53
Откуда: Techsupport SoftLab-NSK

Сообщение Даниленко Сергей »

Разработчики, которые отвечают за данное направление, сейчас в отпуске. Появятся ближе к середине следующей недели.
Пока хотелось бы получить какие-нибудь подробности.
А именно:
1)Какая версия нашего ПО используется? Как посмотреть: http://www.softlab-nsk.com/rus/forward/qna.html#a2_14
2)Было бы здорово если бы вы прислали фрагменты кода где создается объект и где он уничтожается. Присылайте на адрес техподдержки:
forward@softlab.tv
forward@sl.iae.nsk.su
forward@softlab-nsk.com

В письме укажите, пожалуйста, ссылку на этот топик.
kasa
Сообщения: 90
Зарегистрирован: 04 сен 2008 01:50
Откуда: Красноярск

Сообщение kasa »

1) 5.0.15

2) В моем классе содержится стандартный ATL враппер

CComPtr<ISLTitleTarget> _titler;

инициализируется он так:

_titler.CoCreateInstance(CLSID_SLTitleTarget)

Release вызывается в деструкторе CComPtr, который, в свою очередь, вызывается при закрытии программы.
Игорь Таранцев
Сообщения: 493
Зарегистрирован: 04 янв 2004 12:45
Откуда: СофтЛаб-НСК

Сообщение Игорь Таранцев »

Во-первых, про проблему - это не фича. Клиенты титровального ядра работают независимо, поэтому закрытие одной программы никак не сказывается на работе второй программы. Скорее всего это косвенные связи работы программ. В первую очередь проверьте, что после закрытия первой программы продолжает нормально работать цикл выкладывания картинок (кадров) в фифо во второй программе. Например, поставьте отладочную печать и убедитесь, что картинки с тем же темпом выкладываются в фифо.

Во-вторых, не могли бы Вы сделать две простенькие программы, которые бы повторяли ошибку и прислать эти программы с исходниками мне? Это бы очень ускорило решение проблемы.
Если нет, то прийдется задавать разные вопросы, чтобы понять что именно не работает:

1) К какому титровальному объекту Вы подключаетесь в программах. Дайте CLSID этого объекта, например,

Код: Выделить всё

extern "C" const GUID CLSID_SLDirectShowTitleEngine = &#123;0x73DA552F,0x4946,0x4670,&#123;0x84,0x84,0x95,0x8F,0x97,0xA2,0x23,0xF2&#125;&#125;;
2) Вы работете с именованованным или с обычным титровальным регионом?

3) Пользуетесь ли Вы методом KeepAlive() ?

4) Объясните подробнее что именно перестает работать, то есть какая из наших функций начинает возвращать ошибку и какую? А если все возвращают S_OK, то что идет не так, как должно идти? Например: регион показывал статичную картинку (в фифо второй программы был положен кадр с номером, время которого уже прошло) и при закрытии первой программы эта картинка перестала быть видна на экране.
kasa
Сообщения: 90
Зарегистрирован: 04 сен 2008 01:50
Откуда: Красноярск

Сообщение kasa »

Набросал проектик тестовый, так оно надежнее будет :)
Отправил по указанным выше адресам. Надеюсь, rar-архивы к вам проходят без проблем...
Игорь Таранцев
Сообщения: 493
Зарегистрирован: 04 янв 2004 12:45
Откуда: СофтЛаб-НСК

Сообщение Игорь Таранцев »

Ошибка здесь:

Код: Выделить всё

		// create COM-object for application alive checking
		CComPtr<IUnknown> holder;
		THROW_FAILED&#40;holder.CoCreateInstance&#40;CLSID_SLResourceHolder&#41;,
			_T&#40;"Не удалось создать экземпляр SLResourceHolder"&#41;&#41;;
Объект создается "на стеке", поэтому после выхода из функции он автоматически удалится. Соответственно при проверке "жизнеспособности" всех регионов, которые были созданы с его участием титровальное ядро обратится к этому объекту, обнаружит, что его уже нет и закроет эти регионы - программа перестанет работать. Проверка жизнеспособности делается редко (например, при закрытии клиента титровального ядра), поэтому второй экземпляр перестает работать именно при закрытии первого экземпляра программы. Но на самом деле, программа может перестать работать и в других случаях.

Предлагаю сделать объект "holder" переменной класса (как объект "_region"), чтобы он закрывался только при отключении от титровального ядра.
kasa
Сообщения: 90
Зарегистрирован: 04 сен 2008 01:50
Откуда: Красноярск

Сообщение kasa »

К сожалению это не помогло :(
vd
Сообщения: 2311
Зарегистрирован: 05 мар 2003 19:21

Сообщение vd »

Грубо говоря, этот объект нужно создать в начале работы программы (например, в конструкторе главного окна).

Вы это в обеих программах сделали?
kasa
Сообщения: 90
Зарегистрирован: 04 сен 2008 01:50
Откуда: Красноярск

Сообщение kasa »

Я это сделал пока только в тестовом проекте, он один, но запускается дважды.
Экземпляр holder теперь сидит внутри класса, который уничтожается только по выходу из функции main, то есть holder существует всё время жизни программы.
Игорь Таранцев
Сообщения: 493
Зарегистрирован: 04 янв 2004 12:45
Откуда: СофтЛаб-НСК

Сообщение Игорь Таранцев »

Проблема в том, что Вы создаете событие (Event) для остановки рабочего потока с одним и тем же именем во всех экземплярах программ, поэтому когда выходит любой экземпляр программы, он "взводит событие" для всех программ. Все программы обнаруживают, что надо остановиться и перестают работать.
Надо исправить:

Код: Выделить всё

_stopEvent = &#58;&#58;CreateEvent&#40;0, TRUE, FALSE, _T&#40;"Render thread stop event"&#41;&#41;;
на

Код: Выделить всё

_stopEvent = &#58;&#58;CreateEvent&#40;0, TRUE, FALSE, NULL&#41;;
и все заработает как надо.
kasa
Сообщения: 90
Зарегистрирован: 04 сен 2008 01:50
Откуда: Красноярск

Сообщение kasa »

Спасибо огромное за помощь! Проблема решена. Это ж надо было в одном проекте допустить две ошибки, которые приводили к одному "результату". Профессионализм не пропьешь, чо 8)

ЗЫ: за всю свою практику никогда не использовал именованные события, окромя последнего проекта, где используется ваш титровальный сервер. И надо же было код скопипастить в тестовый проект именно оттуда...
Ответить