Титр собственного изготовления

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

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

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

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

Если судить по описанию, то регион не стартовал. Посмотрите, пожалуйста, код ошибки, который возвращает функция SetActive.
kasa
Сообщения: 90
Зарегистрирован: 04 сен 2008 01:50
Откуда: Красноярск

Сообщение kasa »

Даниленко Сергей писал(а):Если судить по описанию, то регион не стартовал. Посмотрите, пожалуйста, код ошибки, который возвращает функция SetActive.
А нет ошибки. SetActive относится к блоку уинициализации, а она проходит успешно. Каждый вызов метода интерфейса из SDK проверяется таким вот образом:

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

		// Activate and run region
		THROW_FAILED(_region->SetActive(TRUE, TRUE, 0),
			_T("Не удалось активировать регион!"));
где THROW_FAILED есть

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

inline void ThrowFailed(TCHAR const* Message, HRESULT Result) {
	if (FAILED(Result)) throw std::runtime_error((CHAR const*)GetErrorMessage(Message, Result));
}

#define THROW_FAILED(hr, msg) ThrowFailed(msg, hr)
Стандартный макрос FAILED не считает ошибкой S_OK и S_FALSE, т.ч. весь код исполняется без критических ошибок. За исключением того, что после заполнения буфера FIFO (я выделяю буфер размером 18 полных экранов), на 19й запрос GetShotBuff возвращается S_FALSE.
Игорь Таранцев
Сообщения: 493
Зарегистрирован: 04 янв 2004 12:45
Откуда: СофтЛаб-НСК

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

Может быть код SetActive никогда не вызывается?
А вообще-то, не могли бы вы прислать письмом куски вашего кода, в которых вы обращаетесь к региону? Было бы проще понять, чем сейчас гадать, что не так.
kasa
Сообщения: 90
Зарегистрирован: 04 сен 2008 01:50
Откуда: Красноярск

Сообщение kasa »

Игорь Таранцев писал(а): А вообще-то, не могли бы вы прислать письмом куски вашего кода, в которых вы обращаетесь к региону? Было бы проще понять, чем сейчас гадать, что не так.
Код, конечно, не секретный, показать не проблема, но, как я уже говорил, абсолютно этот же код нормально работает на соседнем компьютере, который отличается только версией Forward. Вот я и предположил, что либо дело в версии, либо мы какую-то важную настройку забыли настроить :)

А код вот такой. Это инициализация:

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

STDMETHODIMP CForward::Init()
{
	HRESULT hr = S_OK;
	try {
		//////////////////////////////////////////////////////////////////////////
		CKeyEnumerator<ITVCPlugin2> ke&#40;HKEY_LOCAL_MACHINE, _T&#40;"Software\\*\\RenderObjects"&#41;&#41;;
		ke.DoEnum&#40;_objects&#41;;

		THROW_FAILED&#40;_titler.CoCreateInstance&#40;CLSID_SLTitleTarget&#41;, 
			_T&#40;"Не удалось создать экземпляр TitleTarget!"&#41;&#41;;

		THROW_FAILED&#40;_titler.QueryInterface&#40;&_surface&#41;, 
			_T&#40;"Не удалось получить интерфейс ISLTitleSurface!"&#41;&#41;;

		THROW_FAILED&#40;_titler->ConnectLocalHost&#40;CLSID_SLTMTitleServerTargetMgr, 0&#41;,
			_T&#40;"Не удалось подключить титровальщик к устройству отображения!"&#41;&#41;;

		THROW_FAILED&#40;_titler->GetTargetParams&#40;&_params&#41;, 
			_T&#40;"Не удалось получить параметры карты!"&#41;&#41;;

		// create COM-object for application alive checking
		CComPtr<IUnknown> holder;
		THROW_FAILED&#40;holder.CoCreateInstance&#40;CLSID_SLResourceHolder&#41;,
			_T&#40;"Не удалось создать экземпляр SLResourceHolder!"&#41;&#41;;

		int fifoSize = WIDTH * HEIGHT * 4 * gSett&#91;fd300&#58;&#58;OPTI_MAIN_FIFO_SIZE&#93;;
		CComPtr<IUnknown> unk;
		THROW_FAILED&#40;_surface->CreateTitleRectRegion&#40;holder, fifoSize, fifoSize, &unk&#41;,
			_T&#40;"Не удалось создать регион!"&#41;&#41;;

		THROW_FAILED&#40;unk.QueryInterface&#40;&_region&#41;,
			_T&#40;"Не удалось получить интерфейс ISLTitleRegion!"&#41;&#41;;

		CRegionInfo regionInfo = &#123;0&#125;;
		regionInfo.x0 = XPOS;
		regionInfo.y0 = YPOS;
		regionInfo.x1 = XPOS + WIDTH;
		regionInfo.y1 = YPOS + HEIGHT;
		regionInfo.z = gSett&#91;fd300&#58;&#58;OPTI_MAIN_ZORDER&#93;;
		regionInfo.alfa = 255;
		regionInfo.ShowLastHalfShot = FALSE;
		regionInfo.CurrShot = _currShot = 0;

		CSLTitleRegionPlacementFlds flagsSet = &#40;CSLTitleRegionPlacementFlds&#41;&#40;SLTRG_XYPosition | SLTRG_ZOrder | 
			SLTRG_Alfa | SLTRG_ShowLastHalfShot | SLTRG_CurrShot&#41;;
		CSLTitleRegionPlacementFlds flagsGet = &#40;CSLTitleRegionPlacementFlds&#41;0;

		THROW_FAILED&#40;_region->SetParameters&#40;flagsSet, &flagsGet, &regionInfo&#41;,
			_T&#40;"Не удалось установить параметры региона!"&#41;&#41;;

		&#123;
			CString str;
			str.Format&#40;_T&#40;"Создан регион с FIFO буфером %d байт для %d кадров"&#41;, 
				fifoSize, &#40;int&#41;gSett&#91;fd300&#58;&#58;OPTI_MAIN_FIFO_SIZE&#93;&#41;;
			_log.WriteLine&#40;str&#41;;
		&#125;

		// Activate and run region
		THROW_FAILED&#40;_region->SetActive&#40;TRUE, TRUE, 0&#41;,
			_T&#40;"Не удалось активировать регион!"&#41;&#41;;
	&#125;
	catch&#40;std&#58;&#58;runtime_error& re&#41; &#123;
		_log.WriteLine&#40;re.what&#40;&#41;&#41;;
		return E_FAIL;
	&#125;
	_log.WriteLine&#40;_T&#40;"Инициализация прошла успешно."&#41;&#41;;
	return S_OK;
&#125;
Это основной цикл отрисовки:

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

DWORD CForward&#58;&#58;Run&#40;&#41;
&#123;
	_log.WriteLine&#40;_T&#40;"CForward&#58;&#58;Run"&#41;&#41;;
	HRESULT hr = S_OK;
	DWORD sizeRequired = WIDTH * HEIGHT * 4;
	int waitTime = gSett&#91;fd300&#58;&#58;OPTI_MAIN_FIFO_WAIT&#93;;
	BYTE* buff = 0;
	DWORD size = 0;
	int color = 100;
	CString str;

	while&#40;&#58;&#58;WaitForSingleObject&#40;_stopEvent, 1&#41; == WAIT_TIMEOUT&#41; &#123;
		try &#123;
			// ждем максимум один фрейм для получения буфера
			hr = _region->GetShotBuff&#40;sizeRequired, sizeRequired, &buff, &size, 0&#41;;

			if &#40;hr == S_OK&#41; &#123;
				memset&#40;buff, 0x00, sizeRequired&#41;; // очищаем весь экран

				if &#40;_surfWork != 0&#41; delete _surfWork;
				_surfWork = new VSurface&#40;WIDTH, HEIGHT, WIDTH, &#40;DWORD*&#41;buff, VSurface&#58;&#58;BOTH_FIELD&#41;;

				try &#123;
					std&#58;&#58;vector<CComPtr<ITVCPlugin2>>&#58;&#58;const_iterator p = _objects.begin&#40;&#41;;
					while&#40;p != _objects.end&#40;&#41;&#41; &#123;
						&#40;*p&#41;->RenderRegion&#40;this, true&#41;;
						p++;
					&#125;
				&#125;
				catch&#40;...&#41; &#123;
					throw std&#58;&#58;runtime_error&#40;"Неизвестное исключение в цикле отрисовки объектов!"&#41;;
				&#125;

				// confirm valid image data
				CTitleShotInfo shotInfo;
				shotInfo.DataType = TitleShotDataType_RGBA;
				shotInfo.ShotNumber = _currShot++;
				shotInfo.dx = WIDTH;
				shotInfo.dy = HEIGHT;
				THROW_FAILED&#40;_region->ConfirmShotSize&#40;0, sizeRequired, &shotInfo&#41;,
					_T&#40;"Буфер не прошел валидацию!"&#41;&#41;;
			&#125;
			else if &#40;hr == S_FALSE&#41; &#123;
				// no free memory at this time
				_log.WriteLine&#40;_T&#40;"Нет свободной памяти в буфере FIFO"&#41;&#41;;
				Sleep&#40;waitTime&#41;;
			&#125;
			else &#123;
				THROW_FAILED&#40;hr, _T&#40;"Ошибка при получении свободного буфера кадра!"&#41;&#41;;
			&#125;

		&#125;
		catch&#40;std&#58;&#58;runtime_error& re&#41; &#123;
			_log.WriteLine&#40;re.what&#40;&#41;&#41;;
		&#125;
	&#125;

	return 0;
&#125;
Игорь Таранцев
Сообщения: 493
Зарегистрирован: 04 янв 2004 12:45
Откуда: СофтЛаб-НСК

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

Вам еще нужно проверять значение flagsGet после вызова метода _region->SetParameters. Оно должно быть равно flagsSet. Возможно, что слой с указанным Z-order уже занят и установить такой-же Z-order не удалось. Но все остальные параметры корректно установились, поэтому ошибки не будет. В этом случае параметр flagsGet не будет иметь битика SLTRG_ZOrder. А регион с нулевым значением Z-order считается служебным и не отображается.
Игорь Таранцев
Сообщения: 493
Зарегистрирован: 04 янв 2004 12:45
Откуда: СофтЛаб-НСК

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

Есть одно отличие между старым и новым софтом - выравнивание размеров (границ) до 16 пикселов по горизонтали. Проверьте, что у вас значения XPOS и WIDTH кратны 16.
Кстати, проверка на совпадение flagsSet и flagsGet тоже выявит эту проблему - битик SLTRG_XYPosition не установится в возвращаемом параметре flagsGet.
kasa
Сообщения: 90
Зарегистрирован: 04 сен 2008 01:50
Откуда: Красноярск

Сообщение kasa »

Игорь Таранцев писал(а):Есть одно отличие между старым и новым софтом - выравнивание размеров (границ) до 16 пикселов по горизонтали. Проверьте, что у вас значения XPOS и WIDTH кратны 16.
Кстати, проверка на совпадение flagsSet и flagsGet тоже выявит эту проблему - битик SLTRG_XYPosition не установится в возвращаемом параметре flagsGet.
Спасибо за помощь, но проблема "разрешилась" с легкой руки нашего технического директора. Он взял и переустановил софт Forward. Теперь мы, скорее всего, никогда не узнаем в чем был глюк...а жаль.

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

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

А какой софт в результате установили то?
Ответить