add 3rd party folders back
This commit is contained in:
363
3rd/omt-examples/.gitignore
vendored
Normal file
363
3rd/omt-examples/.gitignore
vendored
Normal file
@@ -0,0 +1,363 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Mono auto generated files
|
||||
mono_crash.*
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
[Ww][Ii][Nn]32/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Oo]ut/
|
||||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUnit
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
nunit-*.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# ASP.NET Scaffolding
|
||||
ScaffoldingReadMe.txt
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_h.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Coverlet is a free, cross platform Code Coverage Tool
|
||||
coverage*.json
|
||||
coverage*.xml
|
||||
coverage*.info
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# NuGet Symbol Packages
|
||||
*.snupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
*.appxbundle
|
||||
*.appxupload
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!?*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
*- [Bb]ackup.rdl
|
||||
*- [Bb]ackup ([0-9]).rdl
|
||||
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# CodeRush personal settings
|
||||
.cr/personal
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
||||
|
||||
# Local History for Visual Studio
|
||||
.localhistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
|
||||
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||
MigrationBackup/
|
||||
|
||||
# Ionide (cross platform F# VS Code tools) working folder
|
||||
.ionide/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
102
3rd/omt-examples/C#/omtgraphicsexample/Program.cs
Normal file
102
3rd/omt-examples/C#/omtgraphicsexample/Program.cs
Normal file
@@ -0,0 +1,102 @@
|
||||
using libomtnet;
|
||||
using SkiaSharp;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
/*
|
||||
* OMT Graphics Example
|
||||
*
|
||||
* This example generates a horizontal ticker graphic and sends it via an OMT Sender.
|
||||
*
|
||||
* This demonstrates the alpha channel functionality built into Open Media Transport.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace omtgraphicsexample
|
||||
{
|
||||
internal class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
Console.WriteLine("OMT Graphics Example");
|
||||
|
||||
//Create the graphics format we will be sending, in this example this is a standard 1080p video.
|
||||
SKImageInfo imageInfo = new SKImageInfo(1920, 1080, SKColorType.Bgra8888, SKAlphaType.Unpremul);
|
||||
|
||||
//This is the surface we will be drawing to to create out frame
|
||||
SKSurface image = SKSurface.Create(imageInfo);
|
||||
|
||||
//Canvas contains all the drawing functions we will be utilising
|
||||
SKCanvas canvas = image.Canvas;
|
||||
|
||||
//Define a rectangle for our ticker
|
||||
SKRect rect = new SKRect(0, 960, 1920, 1080);
|
||||
SKRoundRect roundRect = new SKRoundRect(rect, 8);
|
||||
|
||||
//Create a simple gradient background for our ticker
|
||||
SKShader gradient = SKShader.CreateLinearGradient(new SKPoint(rect.Left, rect.Top), new SKPoint(rect.Right, rect.Bottom), new[] {
|
||||
new SKColor(0, 19, 69, 192), // semi-transparent deep blue
|
||||
new SKColor(0, 89, 254, 192) // semi-transparent light blue
|
||||
}, null, SKShaderTileMode.Clamp);
|
||||
SKPaint gradientPaint = new SKPaint() { Shader = gradient };
|
||||
|
||||
//Create the text formatting to use
|
||||
SKFont textFont = new SKFont(SKTypeface.FromFamilyName("Sans Serif", SKFontStyle.Bold), 48);
|
||||
SKPaint textPaint = new SKPaint() { IsAntialias = true, Color = SKColors.White };
|
||||
|
||||
//Position text in the middle of the gradient rectangle
|
||||
SKFontMetrics fontMetrics = new SKFontMetrics();
|
||||
textFont.GetFontMetrics(out fontMetrics);
|
||||
SKPoint textPosition =new SKPoint(rect.Right, rect.Top + ((rect.Height - (fontMetrics.Ascent + fontMetrics.Descent)) / 2f));
|
||||
|
||||
//This is the text we will be sending along with an estimate of its width to know when to repeat.
|
||||
string tickerText = "This is an example of text rendering in SkiaSharp that is sent over Open Media Transport!";
|
||||
float tickerTextWidth = textFont.MeasureText(tickerText);
|
||||
|
||||
//Create our sender
|
||||
using (OMTSend send = new OMTSend("Graphics", OMTQuality.Default))
|
||||
{
|
||||
|
||||
//Create the media frame that contains the final graphic ready for sending
|
||||
OMTMediaFrame frame = new OMTMediaFrame();
|
||||
frame.Type = OMTFrameType.Video;
|
||||
frame.Codec = (int)OMTCodec.BGRA;
|
||||
frame.Width = imageInfo.Width;
|
||||
frame.Height = imageInfo.Height;
|
||||
frame.FrameRate = 59.94F;
|
||||
frame.Flags = OMTVideoFlags.Alpha; //Set premultiplied here also if necessary
|
||||
frame.AspectRatio = (float)imageInfo.Width / (float)imageInfo.Height;
|
||||
frame.ColorSpace = OMTColorSpace.BT709;
|
||||
frame.Stride = imageInfo.Width * 4;
|
||||
frame.DataLength = frame.Stride * frame.Height;
|
||||
frame.Data = Marshal.AllocHGlobal(frame.DataLength);
|
||||
frame.Timestamp = -1; //Important, informs OMT to automatically pace our frames to the frame rate.
|
||||
|
||||
Console.WriteLine("Sending graphics on: \"" + send.Address + "\"");
|
||||
Console.WriteLine("");
|
||||
|
||||
while (true)
|
||||
{
|
||||
canvas.Clear(); //Clear our canvas so it is fully transparent
|
||||
canvas.DrawRoundRect(roundRect, gradientPaint);
|
||||
canvas.DrawText(tickerText, textPosition, textFont, textPaint);
|
||||
|
||||
if (image.ReadPixels(imageInfo, frame.Data, frame.Stride, 0, 0))
|
||||
{
|
||||
send.Send(frame);
|
||||
Console.Write(".");
|
||||
} else
|
||||
{
|
||||
Console.WriteLine("Failed to read pixels from SkiaSharp Surface, exiting....");
|
||||
break;
|
||||
}
|
||||
|
||||
//Update text position to scroll along the screen
|
||||
textPosition.X -= 4;
|
||||
if (textPosition.X < -tickerTextWidth) { textPosition.X = rect.Width; }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
3rd/omt-examples/C#/omtgraphicsexample/libomtnet.dll
Normal file
BIN
3rd/omt-examples/C#/omtgraphicsexample/libomtnet.dll
Normal file
Binary file not shown.
BIN
3rd/omt-examples/C#/omtgraphicsexample/libvmx.dll
Normal file
BIN
3rd/omt-examples/C#/omtgraphicsexample/libvmx.dll
Normal file
Binary file not shown.
@@ -0,0 +1,31 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<PublishAot>true</PublishAot>
|
||||
<InvariantGlobalization>true</InvariantGlobalization>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SkiaSharp" Version="3.119.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="libomtnet">
|
||||
<HintPath>libomtnet.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="libomtnet.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="libvmx.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,25 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.11.35431.28
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "omtgraphicsexample", "omtgraphicsexample.csproj", "{0E671018-770B-4F53-9199-30807405A368}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{0E671018-770B-4F53-9199-30807405A368}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0E671018-770B-4F53-9199-30807405A368}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0E671018-770B-4F53-9199-30807405A368}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0E671018-770B-4F53-9199-30807405A368}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {232A60FB-F452-4930-B746-90D05F7646A6}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
186
3rd/omt-examples/C++/omtrecvtest/omtrecvtest.cpp
Normal file
186
3rd/omt-examples/C++/omtrecvtest/omtrecvtest.cpp
Normal file
@@ -0,0 +1,186 @@
|
||||
#include <iostream>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include "libomt.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define strcasecmp _stricmp
|
||||
#endif
|
||||
|
||||
// We will use this to dump info about the incoming OMT
|
||||
static int dumpOMTMediaFrameInfo(OMTMediaFrame * video);
|
||||
|
||||
|
||||
int main(int argc, const char * argv[])
|
||||
{
|
||||
omt_send_t * sndloop;
|
||||
int nativeReceiveMode = 0;
|
||||
int sixteenBitReceiveMode = 0;
|
||||
|
||||
// optionally setup logging
|
||||
string filename = "omtrecvtest.log";
|
||||
omt_setloggingfilename(filename.c_str());
|
||||
|
||||
// this example can just take a Stream name, plus it can optionally also have either nativevmx or 16bit as a second parameter
|
||||
// to request compressed VMX data instead of uncompressed video, or to request specifically 16-bit uncompressed video
|
||||
if (argc<2)
|
||||
{
|
||||
printf("Usage : omtrecvtest \"HOST (OMTSOURCE)\" [nativevmx|16bit]");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// this example receives OMT then sends it back out again through another stream.
|
||||
// Create a loop out stream
|
||||
sndloop = omt_send_create("OMLoopBack", OMTQuality_Default);
|
||||
|
||||
// the instance of an OMT receiver.
|
||||
omt_receive_t* recv;
|
||||
|
||||
// check for parameters
|
||||
if (argc>2)
|
||||
{
|
||||
if (!strcasecmp((char *)argv[2],"nativevmx"))
|
||||
{
|
||||
nativeReceiveMode = 1;
|
||||
}
|
||||
if (!strcasecmp((char *)argv[2],"16bit"))
|
||||
{
|
||||
sixteenBitReceiveMode = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// setup an OMT Receiver. We specify the types of data we are interested in and then the format, and an optional flag.
|
||||
if (nativeReceiveMode)
|
||||
{
|
||||
// force receive of compressed data only
|
||||
recv = omt_receive_create((const char *)argv[1], (OMTFrameType)(OMTFrameType_Video | OMTFrameType_Audio | OMTFrameType_Metadata), (OMTPreferredVideoFormat)OMTPreferredVideoFormat_UYVYorUYVAorP216orPA16, (OMTReceiveFlags)OMTReceiveFlags_CompressedOnly);
|
||||
}
|
||||
else
|
||||
{
|
||||
// optionally force 16bit receive
|
||||
if (sixteenBitReceiveMode)
|
||||
{
|
||||
recv = omt_receive_create((const char *)argv[1], (OMTFrameType)(OMTFrameType_Video | OMTFrameType_Audio | OMTFrameType_Metadata), (OMTPreferredVideoFormat)OMTPreferredVideoFormat_P216, (OMTReceiveFlags)OMTReceiveFlags_None);
|
||||
}
|
||||
else
|
||||
{
|
||||
recv = omt_receive_create((const char *)argv[1], (OMTFrameType)(OMTFrameType_Video | OMTFrameType_Audio | OMTFrameType_Metadata), (OMTPreferredVideoFormat)OMTPreferredVideoFormat_UYVYorUYVAorP216orPA16, (OMTReceiveFlags)OMTReceiveFlags_None);
|
||||
}
|
||||
}
|
||||
|
||||
while(1)
|
||||
{
|
||||
OMTMediaFrame frame = {}; // loop out frame
|
||||
OMTMediaFrame * theOMTFrame;
|
||||
OMTFrameType t = OMTFrameType_None;
|
||||
|
||||
// capture a frame of video, audio or metadata from the OMT Source
|
||||
theOMTFrame = omt_receive(recv, (OMTFrameType)(OMTFrameType_Video | OMTFrameType_Audio | OMTFrameType_Metadata), 40);
|
||||
if (theOMTFrame)
|
||||
{
|
||||
t = theOMTFrame->Type;
|
||||
|
||||
// dump what we got to the console
|
||||
dumpOMTMediaFrameInfo(theOMTFrame);
|
||||
|
||||
|
||||
// we are going to loop the OMT stream back out, so let's make a copy of the Frame
|
||||
memcpy(&frame,theOMTFrame,sizeof(OMTMediaFrame));
|
||||
switch (t)
|
||||
{
|
||||
case OMTFrameType_Video:
|
||||
{
|
||||
// send it back out.. If its native VMX we need to move the ComressedData into Data and CompressedLength into DataLength
|
||||
if (nativeReceiveMode && theOMTFrame->Codec == OMTCodec_VMX1)
|
||||
{
|
||||
frame.Data = theOMTFrame->CompressedData;
|
||||
frame.DataLength = theOMTFrame->CompressedLength;
|
||||
frame.CompressedData = NULL;
|
||||
frame.CompressedLength = 0;
|
||||
}
|
||||
omt_send(sndloop, &frame);
|
||||
}
|
||||
break;
|
||||
|
||||
case OMTFrameType_Audio: case OMTFrameType_Metadata:
|
||||
{
|
||||
omt_send(sndloop, &frame);
|
||||
}
|
||||
break;
|
||||
|
||||
case OMTFrameType_None: default:
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
omt_receive_destroy(recv);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define FourCharCodeToString(code) (code) & 0xFF, ((code) >> 8) & 0xFF, ((code) >> 16) & 0xFF, ((code) >> 24) & 0xFF
|
||||
|
||||
static int dumpOMTMediaFrameInfo(OMTMediaFrame * video)
|
||||
{
|
||||
printf("----------------------------------------------\n");
|
||||
if (video)
|
||||
{
|
||||
if (video->Type == OMTFrameType_Video)
|
||||
{
|
||||
printf("VIDEO FRAME:\n");
|
||||
printf("Timestamp=%llu\n", (unsigned long long)(video->Timestamp));
|
||||
printf("Codec=%c%c%c%c\n", FourCharCodeToString(video->Codec));
|
||||
printf("Width=%d\n", video->Width);
|
||||
printf("Height=%d\n", video->Height);
|
||||
printf("Stride=%d\n", video->Stride);
|
||||
printf("Flags=%d\n", video->Flags);
|
||||
printf("FrameRateN=%d\n", video->FrameRateN);
|
||||
printf("FrameRateD=%d\n", video->FrameRateD);
|
||||
printf("AspectRatio=%.2f\n", video->AspectRatio);
|
||||
printf("ColorSpace=%d\n", video->ColorSpace);
|
||||
printf("Data=%llu\n", (unsigned long long)video->Data);
|
||||
printf("DataLength=%d\n", video->DataLength);
|
||||
printf("CompressedData=%llu\n", (unsigned long long)video->CompressedData);
|
||||
printf("CompressedLength=%llu\n", (unsigned long long)video->CompressedLength);
|
||||
printf("FrameMetadata=%llu\n", (unsigned long long)video->FrameMetadata);
|
||||
printf("FrameMetadataLength=%llu\n", (unsigned long long)video->FrameMetadataLength);
|
||||
}
|
||||
|
||||
if (video->Type == OMTFrameType_Audio)
|
||||
{
|
||||
printf("AUDIO FRAME:\n");
|
||||
printf("Timestamp=%llu\n", (unsigned long long)video->Timestamp);
|
||||
printf("Codec=%c%c%c%c\n", FourCharCodeToString(video->Codec));
|
||||
printf("Flags=%d\n", video->Flags);
|
||||
printf("SampleRate=%d\n", video->SampleRate);
|
||||
printf("Channels=%d\n", video->Channels);
|
||||
printf("SamplesPerChannel=%d\n", video->SamplesPerChannel);
|
||||
printf("Data=%llu\n", (unsigned long long)video->Data);
|
||||
printf("DataLength=%d\n", video->DataLength);
|
||||
printf("FrameMetadata=%llu\n", (unsigned long long)video->FrameMetadata);
|
||||
printf("FrameMetadataLength=%llu\n", (unsigned long long)video->FrameMetadataLength);
|
||||
}
|
||||
|
||||
if (video->Type == OMTFrameType_Metadata)
|
||||
{
|
||||
printf("METADATA FRAME:\n");
|
||||
printf("Timestamp=%llu\n", (unsigned long long)video->Timestamp);
|
||||
printf("Flags=%d\n", video->Flags);
|
||||
printf("Data=%llu\n", (unsigned long long)video->Data);
|
||||
printf("DataLength=%d\n", video->DataLength);
|
||||
printf("FrameMetadata=%llu\n", (unsigned long long)video->FrameMetadata);
|
||||
printf("FrameMetadataLength=%llu\n", (unsigned long long)video->FrameMetadataLength);
|
||||
}
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
239
3rd/omt-examples/C++/omtsendtest/omtsendtest.cpp
Normal file
239
3rd/omt-examples/C++/omtsendtest/omtsendtest.cpp
Normal file
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2025 Open Media Transport Contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/* omtsendtest.cpp demonstrates the process of creating a named OMT output,
|
||||
and emitting an 8-bit image repeatedly, with the frame rate controlled by OMT
|
||||
it also demonstrates how to setup a log destination, attach vendor information
|
||||
to the stream, retrieve OMT statistics on the output stream and also monitor tally */
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <fstream>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// The header for the C/C++ wrapper of OMT
|
||||
#include "libomt.h"
|
||||
// link this exe with libomt, and make sure libomt and libvpx are accessible to the exe, either in the same folder, or linked explicitly via rpath or otherwise.
|
||||
// libomt will dynamically open libvpx at runtime
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include <random>
|
||||
|
||||
// Generate a random number between a and b
|
||||
// used to generate audio noise.
|
||||
float rand_FloatRange(float a, float b)
|
||||
{
|
||||
return ((b - a) * ((float)rand() / (float)RAND_MAX)) + a;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << "OMTSendTest\n";
|
||||
|
||||
string filename = "omtsendtest.log";
|
||||
omt_setloggingfilename(filename.c_str());
|
||||
std::cout << "omt_setloggingfilename.success\n";
|
||||
|
||||
// this is the name of the generated OMT Stream in the form HOSTNAME (Test)
|
||||
string name = "Test";
|
||||
|
||||
// Create the OMT output stream using the default (medium) quality.
|
||||
omt_send_t * snd = omt_send_create(name.c_str(), OMTQuality_Default);
|
||||
if (snd)
|
||||
{
|
||||
std::cout << "omt_send_create.success\n";
|
||||
|
||||
// Optionally attach some vendor specific information to the stream.
|
||||
OMTSenderInfo info = {};
|
||||
string ProductName = "SendTest";
|
||||
string Manufacturer = "OMT";
|
||||
string Version = "1.0";
|
||||
ProductName.copy(&info.ProductName[0], OMT_MAX_STRING_LENGTH, 0);
|
||||
Manufacturer.copy(&info.Manufacturer[0], OMT_MAX_STRING_LENGTH, 0);
|
||||
Version.copy(&info.Version[0], OMT_MAX_STRING_LENGTH, 0);
|
||||
omt_send_setsenderinformation(snd, &info);
|
||||
|
||||
std::cout << "omt_send_setsenderinformation.success\n";
|
||||
|
||||
// Prepare the OMTMediaFrame Video Frame structure. Be sure to zero any unused fields
|
||||
// here the frame = {} will zero-initialise the structure in C++
|
||||
OMTMediaFrame video_frame = {};
|
||||
|
||||
// OMTMediaFrames can be Video, Audio or Metadata
|
||||
video_frame.Type = OMTFrameType_Video;
|
||||
video_frame.Width = 1920;
|
||||
video_frame.Height = 1080;
|
||||
|
||||
// Select the format of data you are passing to OMT
|
||||
// This is typically UYVY or BGRA for 8bit or P216 for 10-bit (16 bit data).
|
||||
video_frame.Codec = OMTCodec_UYVY;
|
||||
|
||||
// Setting Timestamp to -1 will force OMT to auto increment this from zero
|
||||
// -1 also enables output clocking so OMT will hold the output on each send
|
||||
// to enforce the correct frame rate if your code is able to send faster.
|
||||
video_frame.Timestamp = -1;
|
||||
|
||||
// OMT uses BT709 for HD and UHD. Use BT601 for SD streams
|
||||
video_frame.ColorSpace = OMTColorSpace_BT709;
|
||||
|
||||
// if the Video Frame was interleaved (interlaced), pass OMTVideoFlags_Interlaced
|
||||
// OMT uses a single frame of data for Progressive and Interlaced sources.
|
||||
video_frame.Flags = OMTVideoFlags_None;
|
||||
|
||||
// line stride in bytes, typically width*2 for UYVY and also P216 formats.
|
||||
// Can be a custom value in case you are padding lines for byte alignment efficiency,
|
||||
video_frame.Stride = video_frame.Width * 2;
|
||||
|
||||
// Total size of the data
|
||||
video_frame.DataLength = video_frame.Stride * video_frame.Height;
|
||||
|
||||
// A pointer to the UYVY data which will be passed to OMT
|
||||
video_frame.Data = malloc(video_frame.DataLength);
|
||||
|
||||
|
||||
|
||||
// The target frame rate expressed as numerator and denominator. In this case 60 fps
|
||||
video_frame.FrameRateN = 60000;
|
||||
video_frame.FrameRateD = 1000;
|
||||
|
||||
// we are passing uncompressed, rather than pre-compressed VMX codec data, so set these to zero
|
||||
// video_frame.CompressedData = NULL;
|
||||
// video_frame.CompressedLength = 0;
|
||||
|
||||
// its possible to attach frame specific XML metadata to each frame, otherwise zero these.
|
||||
video_frame.FrameMetadata = NULL;
|
||||
video_frame.FrameMetadataLength = 0;
|
||||
|
||||
|
||||
// load sample UYVY data from the california-1080-uyvy.yuv file
|
||||
// make sure its in the same folder with the built executable
|
||||
void * uyvy = malloc(video_frame.DataLength);
|
||||
std::ifstream file("california-1080-uyvy.yuv", std::ios::binary | std::ios::in | std::ios::ate);
|
||||
if (file.is_open())
|
||||
{
|
||||
std::streamsize size = file.tellg();
|
||||
file.seekg(0, std::ios::beg);
|
||||
file.read((char*)uyvy, size);
|
||||
file.close();
|
||||
}
|
||||
|
||||
// create some audio a stereo buffer exactly 1 frame long
|
||||
float * audioBuffer = (float *)malloc(800 * sizeof(float) * 2 );
|
||||
// fill the buffer with noise
|
||||
srand((unsigned int)time(NULL));
|
||||
for (int z=0;z<1600;z++)
|
||||
{
|
||||
audioBuffer[z] = rand_FloatRange(-1.0,+1.0);
|
||||
}
|
||||
|
||||
// prepare an OMTMediaFrame for the audio
|
||||
OMTMediaFrame audio_frame = {};
|
||||
memset(&audio_frame,0,sizeof(OMTMediaFrame));
|
||||
audio_frame.Type = OMTFrameType_Audio;
|
||||
audio_frame.Timestamp = -1;
|
||||
audio_frame.Codec = OMTCodec_FPA1; // floating point planar data format
|
||||
audio_frame.SampleRate = 48000;
|
||||
audio_frame.Channels = 2;
|
||||
audio_frame.SamplesPerChannel = 800; // we are sending exactly 1 frame of audio per 60fps video frame
|
||||
audio_frame.Data = (void *)audioBuffer;
|
||||
audio_frame.DataLength = (800 * sizeof(float) * 2);
|
||||
audio_frame.FrameMetadata = NULL;
|
||||
audio_frame.FrameMetadataLength = 0;
|
||||
|
||||
// used to create a dynamically changing image
|
||||
void* twoLines = malloc(video_frame.Stride * 2);
|
||||
memset(twoLines, 255, video_frame.Stride * 2);
|
||||
int linePos = 0;
|
||||
|
||||
|
||||
// structs ready to receive streaming statistics and tally
|
||||
OMTTally tally = {};
|
||||
OMTStatistics stats = {};
|
||||
|
||||
int frameCount = 0;
|
||||
int bytes = 0;
|
||||
for (int i = 0; i < 10000; i++)
|
||||
{
|
||||
|
||||
//used to create a dynamically changing image by overwriting 2 lines moving down the image
|
||||
memcpy(video_frame.Data, uyvy, video_frame.DataLength);
|
||||
memcpy((char*)video_frame.Data + linePos, twoLines, video_frame.Stride * 2);
|
||||
linePos += video_frame.Stride * 2;
|
||||
if (linePos >= video_frame.DataLength)
|
||||
{
|
||||
linePos = 0;
|
||||
}
|
||||
|
||||
// Send out the prepared OMT Video Frame.
|
||||
bytes += omt_send(snd, &video_frame);
|
||||
|
||||
// gather and output statistics once per second
|
||||
frameCount += 1;
|
||||
if (frameCount >= 60)
|
||||
{
|
||||
std::cout << "omt_send.ok: " << bytes << "\n";
|
||||
omt_send_gettally(snd, 0, &tally);
|
||||
std::cout << "omt_send.tally: " << tally.preview << " " << tally.program << "\n";
|
||||
|
||||
OMTMediaFrame* frame = omt_send_receive(snd, 0);
|
||||
if (frame) {
|
||||
char* sz = (char*)frame->Data;
|
||||
std::cout << "omt_send.meta: " << sz << "\n";
|
||||
}
|
||||
|
||||
int connections = omt_send_connections(snd);
|
||||
std::cout << "omt_send.connections: " << connections << "\n";
|
||||
|
||||
omt_send_getvideostatistics(snd, &stats);
|
||||
std::cout << "omt_send_getvideostatistics: Bytes: " << stats.BytesSent << " Frames: " << stats.Frames << "\n";
|
||||
|
||||
frameCount = 0;
|
||||
bytes = 0;
|
||||
}
|
||||
|
||||
// Send out the prepared OMT Audio Frame.
|
||||
omt_send(snd, &audio_frame);
|
||||
// make some different noise for next frame
|
||||
for (int z=0;z<1600;z++)
|
||||
{
|
||||
audioBuffer[z] = rand_FloatRange(-1.0,+1.0);
|
||||
}
|
||||
}
|
||||
|
||||
// close and clean up the OMT output
|
||||
omt_send_destroy(snd);
|
||||
std::cout << "omt_send_destroy.success\n";
|
||||
}
|
||||
else {
|
||||
std::cout << "omt_send_create.failed\n";
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
21
3rd/omt-examples/LICENSE
Normal file
21
3rd/omt-examples/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Open Media Transport Contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
38
3rd/omt-examples/README.md
Normal file
38
3rd/omt-examples/README.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# Open Media Transport (OMT) Code Examples
|
||||
|
||||
This repository contains some basic C++ and C# code examples for common use cases.
|
||||
|
||||
## C#
|
||||
|
||||
```
|
||||
omtgraphicsexample
|
||||
```
|
||||
|
||||
This example generates a horizontal ticker graphic with alpha channel and sends it via an OMT Sender.
|
||||
|
||||
## C++
|
||||
|
||||
```
|
||||
omtrecvtest
|
||||
omtsendtest
|
||||
```
|
||||
|
||||
These are cross platform examples that use libomt and libvmx to send and receive video frames over a network.
|
||||
|
||||
### Windows Compile Notes
|
||||
|
||||
These examples can be compiled in Visual C++ using a command line similar to the follwing (from the VS x64 Command Prompt)
|
||||
|
||||
```
|
||||
cl omtrecvtest.cpp
|
||||
```
|
||||
|
||||
### Linux Compilation Notes
|
||||
|
||||
These can be compiled from the command line using Clang on Linux with a command similar to the following:
|
||||
|
||||
```
|
||||
clang++ -O3 -std=c++17 -o omtrecvtest omtrecvtest.cpp -L./ -lomt -Wl,-rpath,'$ORIGIN'
|
||||
```
|
||||
|
||||
Note the above command adds the app directory as a search path for the library libomt.so which should be placed in the same directory alongside libvmx.so
|
||||
Reference in New Issue
Block a user