Video and Vision Processing Suite Intel® FPGA IPユーザーガイド

ID 683329
日付 6/26/2023
Public
ドキュメント目次
1. Video and Vision Processing Suiteについて 2. Video and Vision Processing IPのスタートガイド 3. Video and Vision Processing IPの機能の説明 4. Video and Vision Processing IPインターフェイス 5. Video and Vision Processing IPレジスター 6. Video and Vision Processing IPのソフトウェア・プログラミング・モデル 7. Protocol Converter Intel® FPGA IP 8. 3D LUT Intel® FPGA IP 9. AXI-Stream Broadcaster Intel® FPGA IP 10. Bits per Color Sample Adapter Intel FPGA IP 11. Chroma Key Intel® FPGA IP 12. Chroma Resampler Intel® FPGA IP 13. Clipper Intel® FPGA IP 14. Clocked Video Input Intel® FPGA IP 15. Clocked Video to Full-Raster Converter Intel® FPGA IP 16. Clocked Video Output Intel® FPGA IP 17. Color Space Converter Intel® FPGA IP 18. Deinterlacer Intel® FPGA IP 19. FIR Filter Intel® FPGA IP 20. Frame Cleaner Intel® FPGA IP 21. Full-Raster to Clocked Video Converter Intel® FPGA IP 22. Full-Raster to Streaming Converter Intel® FPGA IP 23. Genlock Controller Intel® FPGA IP 24. Generic Crosspoint Intel® FPGA IP 25. Genlock Signal Router Intel® FPGA IP 26. Guard Bands Intel® FPGA IP 27. Interlacer Intel® FPGA IP 28. Mixer Intel® FPGA IP 29. Parallel Converter Intel® FPGA IPのピクセル 30. Scaler Intel® FPGA IP 31. Stream Cleaner Intel® FPGA IP 32. Switch Intel® FPGA IP 33. Tone Mapping Operator Intel® FPGA IP 34. Test Pattern Generator Intel® FPGA IP 35. Video and Vision Monitor Intel FPGA IP 36. Video Frame Buffer Intel® FPGA IP 37. Video Frame Reader Intel FPGA IP 38. Video Frame Writer Intel FPGA IP 39. Video Streaming FIFO Intel® FPGA IP 40. Video Timing Generator Intel® FPGA IP 41. Warp Intel® FPGA IP 42. デザイン・セキュリティー 43. Video and Vision Processing Suiteユーザーガイドの文書改訂履歴

41.5.2. Warp IPのソフトウェアのコード例

UHD 60 Hzワークフローの例

この例では、15度の回転ワープを生成して適用するためのC++ソースコードのワークフローおよび、基本的なワープ・ソフトウェアの使用法を示しています。この例は3840x2160@60 Hzビデオ用であり、処理を2つのワープエンジンに分割する必要があります。この例のフレームバッファーとワープ係数のベースアドレスは任意です。実際の値は特定のシステムデザインによって異なります。

const uint32_t FRAMEBUF_BASE_ADDR	= 0x80000000;
const uint32_t COEF_BASE_ADDR		= 0xa0000000;
const uint32_t SKIP_RAM_PAGE		= 0;
intel_vvp_warp_base_t base			= INTEL_VVP_WARP_BASE;
intel_vvp_warp_instance_t wrp0;

// Initialize driver instance
intel_vvp_warp_init_instance(&wrp0, base);

// Create warp channel
intel_vvp_warp_channel_t* ch0 = intel_vvp_warp_create_double_channel(&wrp0, 0, 0, 1, 0);

// Fill in warp channel configuration structure
intel_vvp_warp_channel_config_t cfg;
cfg.ram_addr = FRAMEBUF_BASE_ADDR;	// Frame buffers base address
cfg.cs = ERGB_FULL;					// Video colourspace
cfg.width_input = 3840;				// Video dimensions 
cfg.height_input = 2160;
cfg.width_output = 3840;
cfg.height_output = 2160;
cfg.lfr = 0;						// No low frame rate fallback

// Configure warp channel using the parameters above
intel_vvp_warp_configure_channel(ch0, &cfg);

// Obtain required hardware information
WarpHwContextPtr hw = WarpDataHelper::GetHwContext(ch0);

// Instantiate and initialize mesh generator
WarpConfigurator configurator{ hw };
configurator.SetInputResolution(3840, 2160);
configurator.SetOutputResolution(3840, 2160);
configurator.Reset();
configurator.SetRotate(15.0f);

// Generate mesh
WarpMeshPtr mesh = configurator.GenerateMeshFromFixed();
WarpMeshSet mesh_set{ mesh };

// Instantiate data generator
WarpDataGenerator data_generator;

WarpDataContext ctx{ hw,
	3840, 2160,
	3840, 2160
};

// Generate warp data using provided hardware configuration and mesh
WarpDataPtr user_data = data_generator.GenerateData(ctx, mesh_set);

// Allocate and fill in intel_vvp_warp_data_t object required by the warp driver
WarpDataHelper::WarpDriverDataPtr driver_data =
WarpDataHelper::GenerateDriverData(ctx, user_data, COEF_BASE_ADDR, SKIP_RAM_PAGE);

// Transfer generated warp data to the calculated destination for each engine
for(uint32_t i = 0; i < driver_data->num_engines; ++i)
{
	const WarpEngineData* ue = user_data->GetEngineData(i);
	intel_vvp_warp_engine_data_t* de = &(driver_data->engine_data[i]);
	memcpy((void*)(de->mesh_addr), ue->GetMeshData(), de->mesh_size);
	memcpy((void*)(de->filter_addr),ue->GetFilterData(), de->filter_size);
	memcpy((void*)(de->fetch_addr), ue->GetFetchData(), de->fetch_size);
}

// Apply warp by passing new warp data set to the driver
intel_vvp_warp_apply_transform(ch0, driver_data.get());

// Release allocated resources
intel_vvp_warp_free_channel(ch0);

ワープメッシュ使用法

WarpMesh オブジェクトを使用して必要なワープを定義します。この例では、3840x2160ビデオの1:1 (ユニティー) ワープの最も簡単なケースを示しています。

intel_vvp_warp::WarpMesh mesh{3840, 2160};

for(uint32_t v = 0; v < mesh.GetVNodes(); ++v)
{
	mesh_node_t* node = mesh.GetRow(v);

	for(uint32_t h = 0; h < mesh.GetHNodes(); ++h)
	{
					  node->_x = (h * mesh.GetStep()) << 4;
		  node->_y = (v * mesh.GetStep()) << 4;
	}
}

メッシュ座標は、サブピクセル精度の小数部として最下位4ビットを使用します。上記の例では、小数部は常に0です。サブピクセルの位置は次のように保存します。

mesh_node_t* node = mesh.GetRow(v);
…
float pos_x = 10.6f;
node->_x = static_cast<int32_t>(roundf(pos_x * 16.0f));

簡単なワープの例

Easy warpをオンにすると、変換メッシュや関連するワープデータを必要とせずに、入力ビデオを0、90、180、または270度に回転したり、ビデオをミラーリングしたりできます。

const uint32_t FRAMEBUF_BASE_ADDR	= 0x80000000;
const uint32_t width			= 1920;
const uint32_t height			= 1080;
intel_vvp_warp_base_t base		= INTEL_VVP_WARP_BASE;
intel_vvp_warp_instance wrp0;

// Initialize driver instance
intel_vvp_warp_init_instance(&wrp0, base);

// Allocate Easy warp channel
intel_vvp_warp_channel_t* ch0 = intel_vvp_warp_create_easy_warp_channel(&wrp0, 0, 0);
assert(ch0 != NULL);
assert(intel_vvp_warp_check_easy_warp_capable(ch0) == 0);

// Configure channel
intel_vvp_warp_channel_config_t cfg;

// Configure in 4K, RGB Full colourspace
cfg.ram_addr = FRAMEBUF_BASE_ADDR;
cfg.cs = ERGB_FULL;
cfg.width_input = width;
cfg.height_input = height;
cfg.width_output = width;
cfg.height_output = height;
cfg.lfr = 0;

intel_vvp_warp_configure_channel(ch0, &cfg);	

// Mirror input video
// Enable video bypass, keep original resolution
intel_vvp_warp_bypass(ch0, 1, 0, width, height);
// Configure Easy warp mirror
intel_vvp_warp_set_easy_warp(ch0, 0x4);

// Rotate input video 90 degrees CCW
// Enable video bypass, flip input width and height
intel_vvp_warp_bypass(ch0, 1, 0, height, width);
// Configure Easy warp rotation
intel_vvp_warp_set_easy_warp(ch0, 0x01);	

// Release warp channel
intel_vvp_warp_free_channel(ch0);
assert(wrp0.num_engines > 0);

ワープ・レイテンシー・パラメーターの生成例

この例では、特定のビデオ変換に対して推奨される最小レイテンシー・パラメーターを生成する方法を示しています。これらのパラメーターは、Lowレイテンシー動作用にビデオ・パイプラインをコンフィグレーションするために必要です。

// Example video and system clock
static constexpr uint32_t EXAMPLE_CLOCK	= 300000000;
// UHD video dimensions
static constexpr uint32_t WIDTH_UHD		= 3840;
static constexpr uint32_t HEIGHT_UHD		= 2160;
static constexpr uint32_t FULL_HEIGHT_UHD	= 2250;
// Output frame rate x100
static constexpr uint32_t OUTPUT_FRAME_RATE	= 6000;

// In this example system and video clock are the same
const uint32_t system_clock = EXAMPLE_CLOCK;
const uint32_t video_clock = EXAMPLE_CLOCK;

// Warp channel
intel_vvp_warp_channel_t* ch0{nullptr};

// Allocate and initialize a warp channel here
//	...
//////////////////////////////////////////////

// Generate a 4K mesh for 5 degree CCW rotation
WarpConfigurator configurator{WarpDataHelper::GetHwContext(ch0)};

configurator.SetInputResolution(WIDTH_UHD, HEIGHT_UHD);
configurator.SetOutputResolution(WIDTH_UHD, HEIGHT_UHD);
configurator.Reset();
configurator.SetRotate(5.0f);

WarpMeshSet mesh_set{configurator.GenerateMeshFromFixed()};

// Parameters required for warp data generation
WarpDataContext ctx{
	WarpDataHelper::GetHwContext(ch0),
	WIDTH_UHD, HEIGHT_UHD,
	WIDTH_UHD, HEIGHT_UHD
};
			
WarpDataGenerator data_generator;

WarpDataPtr user_data = data_generator.GenerateData(ctx, mesh_set);

// Obtain latency params for the configured warp
WarpLatencyParams latency_params = data_generator.GenerateLatencyParams(ctx, user_data, system_clock, video_clock, FULL_HEIGHT_UHD, OUTPUT_FRAME_RATE);

// Upload and apply generated warp data here
// …
// intel_vvp_warp_apply_transform(ch0, …);
// …

// Pass on “output_latency” to the driver
intel_vvp_warp_set_output_latency(ch0, latency_params._output_latency);

// The “total_latency” member represents the recommended minimum offset
// between the input and output frames
// The value is in axi4s_vid_out_0_clock clock cycles
// Use the this parameter to configure the rest of the video pipeline
// as appropriate
//
//	latency_params._total_latency;
//assert(wrp0.num_engines > 0);