Commit 3f59dfc9 by wangguotao

1.更新libyuv版本 2.支持输出sdi hd数据

parent e90327f6
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -65,7 +65,7 @@
<ClCompile>
<AdditionalIncludeDirectories>.\ThirdParty\stb_image\;.\ThirdParty\rabbitmq\include;.\ThirdParty\ffmpeg-master-latest-win64-gpl-shared\include;.\ThirdParty\libyuv\include;.\ThirdParty\OpenCV\include;.\ThirdParty\NewTek\include;.\ThirdParty\BlackmagicDesign\include;.\include;%(AdditionalIncludeDirectories);$(Qt_INCLUDEPATH_)</AdditionalIncludeDirectories>
<ShowIncludes>false</ShowIncludes>
<PreprocessorDefinitions>WIN32;_WINSOCKAPI_;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;_WINSOCKAPI_;HAVE_CONFIG_H;LIBYUV_USING_SHARED_LIBRARY;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<OpenMPSupport>true</OpenMPSupport>
</ClCompile>
<Link>
......@@ -131,6 +131,30 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="include\BlackMagicDesign\DeckLinkDeviceDiscovery.h" />
<QtMoc Include="include\Threads\VideoScaleThread.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\basic_types.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\compare.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\compare_row.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\convert.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\convert_argb.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\convert_from.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\convert_from_argb.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\cpu_id.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\loongson_intrinsics.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\macros_msa.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\mjpeg_decoder.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\planar_functions.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\rotate.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\rotate_argb.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\rotate_row.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\row.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\scale.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\scale_argb.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\scale_rgb.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\scale_row.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\scale_uv.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\version.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\video_common.h" />
<QtMoc Include="include\Threads\ConsumerMqThread.h" />
<QtMoc Include="include\Threads\ProcessMaskThread.h" />
<QtMoc Include="include\Threads\ReplayThread.h" />
......@@ -157,27 +181,6 @@
<ClInclude Include="include\Utils\SSEFunction.h" />
<ClInclude Include="include\Utils\yuv4k.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\basic_types.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\compare.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\compare_row.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\convert.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\convert_argb.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\convert_from.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\convert_from_argb.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\cpu_id.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\macros_msa.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\mjpeg_decoder.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\planar_functions.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\rotate.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\rotate_argb.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\rotate_row.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\row.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\scale.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\scale_argb.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\scale_row.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\scale_uv.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\version.h" />
<ClInclude Include="ThirdParty\libyuv\include\libyuv\video_common.h" />
<QtMoc Include="include\BlackMagicDesign\DeckLinkInputDevice.h" />
<QtMoc Include="include\BlackMagicDesign\DeckLinkOutputDevice.h" />
<QtMoc Include="include\BlackMagicDesign\DeckLinkOutputPage.h" />
......@@ -241,6 +244,7 @@
<ClCompile Include="src\Threads\DecodeMaskThread.cpp" />
<ClCompile Include="src\Threads\ProcessMaskThread.cpp" />
<ClCompile Include="src\Threads\ReplayThread.cpp" />
<ClCompile Include="src\Threads\VideoScaleThread.cpp" />
<ClCompile Include="src\Threads\ZoomThread.cpp" />
<ClCompile Include="src\TimePlus.cpp" />
<ClCompile Include="src\NDI\NDIOutputThread.cpp" />
......
......@@ -140,6 +140,9 @@
<QtMoc Include="include\BlackMagicDesign\OpenFile.h">
<Filter>Header Files\BlackMagicDesign</Filter>
</QtMoc>
<QtMoc Include="include\Threads\VideoScaleThread.h">
<Filter>Header Files\Threads</Filter>
</QtMoc>
</ItemGroup>
<ItemGroup>
<ClInclude Include="include\stdafx.h">
......@@ -202,6 +205,57 @@
<ClInclude Include="ThirdParty\libyuv\include\libyuv.h">
<Filter>ThirdParty\libuv\include</Filter>
</ClInclude>
<ClInclude Include="include\Utils\AudioConvert.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="include\Utils\Base64.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="include\Utils\VideoScale.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="include\Utils\MaskBuffer.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="include\Utils\Algorithm.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="include\Record\Record.h">
<Filter>Header Files\Record</Filter>
</ClInclude>
<ClInclude Include="include\Record\RecordStore.h">
<Filter>Header Files\Record</Filter>
</ClInclude>
<ClInclude Include="include\Record\RecordThread.h">
<Filter>Header Files\Record</Filter>
</ClInclude>
<ClInclude Include="include\Utils\SafeMap.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="include\Utils\SSEFunction.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="include\Utils\Memory4k.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="include\Utils\yuv4k.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="include\Utils\SampleDeque.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="include\Utils\Settings.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="include\Utils\FastMemcpy_Avx.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="include\Utils\FastMemcpy.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="include\Utils\Computer.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="ThirdParty\libyuv\include\libyuv\video_common.h">
<Filter>ThirdParty\libuv\include\include</Filter>
</ClInclude>
......@@ -214,6 +268,9 @@
<ClInclude Include="ThirdParty\libyuv\include\libyuv\scale_row.h">
<Filter>ThirdParty\libuv\include\include</Filter>
</ClInclude>
<ClInclude Include="ThirdParty\libyuv\include\libyuv\scale_rgb.h">
<Filter>ThirdParty\libuv\include\include</Filter>
</ClInclude>
<ClInclude Include="ThirdParty\libyuv\include\libyuv\scale_argb.h">
<Filter>ThirdParty\libuv\include\include</Filter>
</ClInclude>
......@@ -241,6 +298,9 @@
<ClInclude Include="ThirdParty\libyuv\include\libyuv\macros_msa.h">
<Filter>ThirdParty\libuv\include\include</Filter>
</ClInclude>
<ClInclude Include="ThirdParty\libyuv\include\libyuv\loongson_intrinsics.h">
<Filter>ThirdParty\libuv\include\include</Filter>
</ClInclude>
<ClInclude Include="ThirdParty\libyuv\include\libyuv\cpu_id.h">
<Filter>ThirdParty\libuv\include\include</Filter>
</ClInclude>
......@@ -265,57 +325,6 @@
<ClInclude Include="ThirdParty\libyuv\include\libyuv\basic_types.h">
<Filter>ThirdParty\libuv\include\include</Filter>
</ClInclude>
<ClInclude Include="include\Utils\AudioConvert.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="include\Utils\Base64.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="include\Utils\VideoScale.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="include\Utils\MaskBuffer.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="include\Utils\Algorithm.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="include\Record\Record.h">
<Filter>Header Files\Record</Filter>
</ClInclude>
<ClInclude Include="include\Record\RecordStore.h">
<Filter>Header Files\Record</Filter>
</ClInclude>
<ClInclude Include="include\Record\RecordThread.h">
<Filter>Header Files\Record</Filter>
</ClInclude>
<ClInclude Include="include\Utils\SafeMap.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="include\Utils\SSEFunction.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="include\Utils\Memory4k.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="include\Utils\yuv4k.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="include\Utils\SampleDeque.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="include\Utils\Settings.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="include\Utils\FastMemcpy_Avx.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="include\Utils\FastMemcpy.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="include\Utils\Computer.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<QtRcc Include="Form\MomentaMedia.qrc">
......@@ -454,6 +463,9 @@
<ClCompile Include="src\BlackMagicDesign\OpenFile.cpp">
<Filter>Source Files\BlackMagicDesign</Filter>
</ClCompile>
<ClCompile Include="src\Threads\VideoScaleThread.cpp">
<Filter>Source Files\Threads</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<QtUic Include="Form\TimePlus.ui">
......
......@@ -28,7 +28,10 @@ extern "C" {
#endif
// MemorySanitizer does not support assembly code yet. http://crbug.com/344505
#if defined(__has_feature)
#if __has_feature(memory_sanitizer)
#if __has_feature(memory_sanitizer) && !defined(LIBYUV_DISABLE_NEON)
#define LIBYUV_DISABLE_NEON
#endif
#if __has_feature(memory_sanitizer) && !defined(LIBYUV_DISABLE_X86)
#define LIBYUV_DISABLE_X86
#endif
#endif
......@@ -75,8 +78,16 @@ extern "C" {
// The following are available for Neon:
#if !defined(LIBYUV_DISABLE_NEON) && \
(defined(__ARM_NEON__) || defined(LIBYUV_NEON) || defined(__aarch64__))
#define HAS_SUMSQUAREERROR_NEON
#define HAS_HAMMINGDISTANCE_NEON
#define HAS_SUMSQUAREERROR_NEON
#endif
// The following are available for AArch64 Neon:
#if !defined(LIBYUV_DISABLE_NEON) && defined(__aarch64__)
#define HAS_HASHDJB2_NEON
#define HAS_HAMMINGDISTANCE_NEON_DOTPROD
#define HAS_SUMSQUAREERROR_NEON_DOTPROD
#endif
#if !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa)
......@@ -99,6 +110,9 @@ uint32_t HammingDistance_AVX2(const uint8_t* src_a,
uint32_t HammingDistance_NEON(const uint8_t* src_a,
const uint8_t* src_b,
int count);
uint32_t HammingDistance_NEON_DotProd(const uint8_t* src_a,
const uint8_t* src_b,
int count);
uint32_t HammingDistance_MSA(const uint8_t* src_a,
const uint8_t* src_b,
int count);
......@@ -114,6 +128,9 @@ uint32_t SumSquareError_AVX2(const uint8_t* src_a,
uint32_t SumSquareError_NEON(const uint8_t* src_a,
const uint8_t* src_b,
int count);
uint32_t SumSquareError_NEON_DotProd(const uint8_t* src_a,
const uint8_t* src_b,
int count);
uint32_t SumSquareError_MSA(const uint8_t* src_a,
const uint8_t* src_b,
int count);
......@@ -121,6 +138,7 @@ uint32_t SumSquareError_MSA(const uint8_t* src_a,
uint32_t HashDjb2_C(const uint8_t* src, int count, uint32_t seed);
uint32_t HashDjb2_SSE41(const uint8_t* src, int count, uint32_t seed);
uint32_t HashDjb2_AVX2(const uint8_t* src, int count, uint32_t seed);
uint32_t HashDjb2_NEON(const uint8_t* src, int count, uint32_t seed);
#ifdef __cplusplus
} // extern "C"
......
......@@ -367,6 +367,23 @@ int I212ToI422(const uint16_t* src_y,
int width,
int height);
#define H212ToH420 I212ToI420
LIBYUV_API
int I212ToI420(const uint16_t* src_y,
int src_stride_y,
const uint16_t* src_u,
int src_stride_u,
const uint16_t* src_v,
int src_stride_v,
uint8_t* dst_y,
int dst_stride_y,
uint8_t* dst_u,
int dst_stride_u,
uint8_t* dst_v,
int dst_stride_v,
int width,
int height);
#define H412ToH444 I412ToI444
LIBYUV_API
int I412ToI444(const uint16_t* src_y,
......@@ -384,6 +401,23 @@ int I412ToI444(const uint16_t* src_y,
int width,
int height);
#define H412ToH420 I412ToI420
LIBYUV_API
int I412ToI420(const uint16_t* src_y,
int src_stride_y,
const uint16_t* src_u,
int src_stride_u,
const uint16_t* src_v,
int src_stride_v,
uint8_t* dst_y,
int dst_stride_y,
uint8_t* dst_u,
int dst_stride_u,
uint8_t* dst_v,
int dst_stride_v,
int width,
int height);
#define I412ToI012 I410ToI010
#define H410ToH010 I410ToI010
#define H412ToH012 I410ToI010
......@@ -751,6 +785,21 @@ int ARGBToI420(const uint8_t* src_argb,
int width,
int height);
// Convert ARGB to I420 with Alpha
LIBYUV_API
int ARGBToI420Alpha(const uint8_t* src_argb,
int src_stride_argb,
uint8_t* dst_y,
int dst_stride_y,
uint8_t* dst_u,
int dst_stride_u,
uint8_t* dst_v,
int dst_stride_v,
uint8_t* dst_a,
int dst_stride_a,
int width,
int height);
// BGRA little endian (argb in memory) to I420.
LIBYUV_API
int BGRAToI420(const uint8_t* src_bgra,
......
......@@ -67,6 +67,8 @@ LIBYUV_API extern const struct YuvConstants kYvuV2020Constants; // BT.2020 full
I210ToAR30Matrix(a, b, e, f, c, d, g, h, i##VU, j, k)
#define I410ToAB30Matrix(a, b, c, d, e, f, g, h, i, j, k) \
I410ToAR30Matrix(a, b, e, f, c, d, g, h, i##VU, j, k)
#define I012ToAB30Matrix(a, b, c, d, e, f, g, h, i, j, k) \
I012ToAR30Matrix(a, b, e, f, c, d, g, h, i##VU, j, k)
#define I420AlphaToABGRMatrix(a, b, c, d, e, f, g, h, i, j, k, l, m, n) \
I420AlphaToARGBMatrix(a, b, e, f, c, d, g, h, i, j, k##VU, l, m, n)
#define I422AlphaToABGRMatrix(a, b, c, d, e, f, g, h, i, j, k, l, m, n) \
......@@ -1902,6 +1904,26 @@ int NV21ToRGB24Matrix(const uint8_t* src_y,
int width,
int height);
// Convert YUY2 to ARGB with matrix.
LIBYUV_API
int YUY2ToARGBMatrix(const uint8_t* src_yuy2,
int src_stride_yuy2,
uint8_t* dst_argb,
int dst_stride_argb,
const struct YuvConstants* yuvconstants,
int width,
int height);
// Convert UYVY to ARGB with matrix.
LIBYUV_API
int UYVYToARGBMatrix(const uint8_t* src_uyvy,
int src_stride_uyvy,
uint8_t* dst_argb,
int dst_stride_argb,
const struct YuvConstants* yuvconstants,
int width,
int height);
// Convert Android420 to ARGB with matrix.
LIBYUV_API
int Android420ToARGBMatrix(const uint8_t* src_y,
......
......@@ -21,40 +21,52 @@ extern "C" {
// Internal flag to indicate cpuid requires initialization.
static const int kCpuInitialized = 0x1;
// These flags are only valid on ARM processors.
// These flags are only valid on Arm processors.
static const int kCpuHasARM = 0x2;
static const int kCpuHasNEON = 0x4;
// 0x8 reserved for future ARM flag.
// Leave a gap to avoid setting kCpuHasX86.
static const int kCpuHasNeonDotProd = 0x10;
static const int kCpuHasNeonI8MM = 0x20;
static const int kCpuHasSVE = 0x40;
static const int kCpuHasSVE2 = 0x80;
static const int kCpuHasSME = 0x100;
// These flags are only valid on x86 processors.
static const int kCpuHasX86 = 0x10;
static const int kCpuHasSSE2 = 0x20;
static const int kCpuHasSSSE3 = 0x40;
static const int kCpuHasSSE41 = 0x80;
static const int kCpuHasSSE42 = 0x100; // unused at this time.
static const int kCpuHasAVX = 0x200;
static const int kCpuHasAVX2 = 0x400;
static const int kCpuHasERMS = 0x800;
static const int kCpuHasFMA3 = 0x1000;
static const int kCpuHasF16C = 0x2000;
static const int kCpuHasGFNI = 0x4000;
static const int kCpuHasAVX512BW = 0x8000;
static const int kCpuHasAVX512VL = 0x10000;
static const int kCpuHasAVX512VNNI = 0x20000;
static const int kCpuHasAVX512VBMI = 0x40000;
static const int kCpuHasAVX512VBMI2 = 0x80000;
static const int kCpuHasAVX512VBITALG = 0x100000;
static const int kCpuHasAVX512VPOPCNTDQ = 0x200000;
static const int kCpuHasX86 = 0x8;
static const int kCpuHasSSE2 = 0x10;
static const int kCpuHasSSSE3 = 0x20;
static const int kCpuHasSSE41 = 0x40;
static const int kCpuHasSSE42 = 0x80;
static const int kCpuHasAVX = 0x100;
static const int kCpuHasAVX2 = 0x200;
static const int kCpuHasERMS = 0x400;
static const int kCpuHasFMA3 = 0x800;
static const int kCpuHasF16C = 0x1000;
static const int kCpuHasAVX512BW = 0x2000;
static const int kCpuHasAVX512VL = 0x4000;
static const int kCpuHasAVX512VNNI = 0x8000;
static const int kCpuHasAVX512VBMI = 0x10000;
static const int kCpuHasAVX512VBMI2 = 0x20000;
static const int kCpuHasAVX512VBITALG = 0x40000;
static const int kCpuHasAVX10 = 0x80000;
static const int kCpuHasAVXVNNI = 0x100000;
static const int kCpuHasAVXVNNIINT8 = 0x200000;
static const int kCpuHasAMXINT8 = 0x400000;
// These flags are only valid on MIPS processors.
static const int kCpuHasMIPS = 0x400000;
static const int kCpuHasMSA = 0x800000;
static const int kCpuHasMIPS = 0x800000;
static const int kCpuHasMSA = 0x1000000;
// These flags are only valid on LOONGARCH processors.
static const int kCpuHasLOONGARCH = 0x2000000;
static const int kCpuHasLSX = 0x4000000;
static const int kCpuHasLASX = 0x8000000;
// These flags are only valid on RISCV processors.
static const int kCpuHasRISCV = 0x10000000;
static const int kCpuHasRVV = 0x20000000;
static const int kCpuHasRVVZVFH = 0x40000000;
// Optional init function. TestCpuFlag does an auto-init.
// Returns cpu_info flags.
LIBYUV_API
......@@ -78,6 +90,19 @@ LIBYUV_API
int ArmCpuCaps(const char* cpuinfo_name);
LIBYUV_API
int MipsCpuCaps(const char* cpuinfo_name);
LIBYUV_API
int RiscvCpuCaps(const char* cpuinfo_name);
#ifdef __aarch64__
#if __linux__
// On Linux, parse AArch64 features from getauxval(AT_HWCAP{,2}).
LIBYUV_API
int AArch64CpuCaps(unsigned long hwcap, unsigned long hwcap2);
#else
LIBYUV_API
int AArch64CpuCaps();
#endif
#endif
// For testing, allow CPU flags to be disabled.
// ie MaskCpuFlags(~kCpuHasSSSE3) to disable SSSE3.
......
......@@ -20,9 +20,9 @@
({ \
const uint8_t* psrc_lw_m = (const uint8_t*)(psrc); \
uint32_t val_m; \
asm volatile("lw %[val_m], %[psrc_lw_m] \n" \
: [val_m] "=r"(val_m) \
: [psrc_lw_m] "m"(*psrc_lw_m)); \
asm("lw %[val_m], %[psrc_lw_m] \n" \
: [val_m] "=r"(val_m) \
: [psrc_lw_m] "m"(*psrc_lw_m)); \
val_m; \
})
......@@ -31,9 +31,9 @@
({ \
const uint8_t* psrc_ld_m = (const uint8_t*)(psrc); \
uint64_t val_m = 0; \
asm volatile("ld %[val_m], %[psrc_ld_m] \n" \
: [val_m] "=r"(val_m) \
: [psrc_ld_m] "m"(*psrc_ld_m)); \
asm("ld %[val_m], %[psrc_ld_m] \n" \
: [val_m] "=r"(val_m) \
: [psrc_ld_m] "m"(*psrc_ld_m)); \
val_m; \
})
#else // !(__mips == 64)
......@@ -55,9 +55,9 @@
({ \
uint8_t* pdst_sw_m = (uint8_t*)(pdst); /* NOLINT */ \
uint32_t val_m = (val); \
asm volatile("sw %[val_m], %[pdst_sw_m] \n" \
: [pdst_sw_m] "=m"(*pdst_sw_m) \
: [val_m] "r"(val_m)); \
asm("sw %[val_m], %[pdst_sw_m] \n" \
: [pdst_sw_m] "=m"(*pdst_sw_m) \
: [val_m] "r"(val_m)); \
})
#if (__mips == 64)
......@@ -65,9 +65,9 @@
({ \
uint8_t* pdst_sd_m = (uint8_t*)(pdst); /* NOLINT */ \
uint64_t val_m = (val); \
asm volatile("sd %[val_m], %[pdst_sd_m] \n" \
: [pdst_sd_m] "=m"(*pdst_sd_m) \
: [val_m] "r"(val_m)); \
asm("sd %[val_m], %[pdst_sd_m] \n" \
: [pdst_sd_m] "=m"(*pdst_sd_m) \
: [val_m] "r"(val_m)); \
})
#else // !(__mips == 64)
#define SD(val, pdst) \
......@@ -86,8 +86,7 @@
uint8_t* psrc_lw_m = (uint8_t*)(psrc); \
uint32_t val_lw_m; \
\
__asm__ volatile( \
"lwr %[val_lw_m], 0(%[psrc_lw_m]) \n\t" \
asm("lwr %[val_lw_m], 0(%[psrc_lw_m]) \n\t" \
"lwl %[val_lw_m], 3(%[psrc_lw_m]) \n\t" \
\
: [val_lw_m] "=&r"(val_lw_m) \
......@@ -102,8 +101,7 @@
uint8_t* psrc_ld_m = (uint8_t*)(psrc); \
uint64_t val_ld_m = 0; \
\
__asm__ volatile( \
"ldr %[val_ld_m], 0(%[psrc_ld_m]) \n\t" \
asm("ldr %[val_ld_m], 0(%[psrc_ld_m]) \n\t" \
"ldl %[val_ld_m], 7(%[psrc_ld_m]) \n\t" \
\
: [val_ld_m] "=&r"(val_ld_m) \
......@@ -130,9 +128,9 @@
({ \
uint8_t* pdst_sw_m = (uint8_t*)(pdst); /* NOLINT */ \
uint32_t val_m = (val); \
asm volatile("usw %[val_m], %[pdst_sw_m] \n" \
: [pdst_sw_m] "=m"(*pdst_sw_m) \
: [val_m] "r"(val_m)); \
asm("usw %[val_m], %[pdst_sw_m] \n" \
: [pdst_sw_m] "=m"(*pdst_sw_m) \
: [val_m] "r"(val_m)); \
})
#define SD(val, pdst) \
......
......@@ -30,7 +30,10 @@ extern "C" {
#endif
// MemorySanitizer does not support assembly code yet. http://crbug.com/344505
#if defined(__has_feature)
#if __has_feature(memory_sanitizer)
#if __has_feature(memory_sanitizer) && !defined(LIBYUV_DISABLE_NEON)
#define LIBYUV_DISABLE_NEON
#endif
#if __has_feature(memory_sanitizer) && !defined(LIBYUV_DISABLE_X86)
#define LIBYUV_DISABLE_X86
#endif
#endif
......@@ -827,15 +830,6 @@ int ARGBCopyYToAlpha(const uint8_t* src_y,
int width,
int height);
typedef void (*ARGBBlendRow)(const uint8_t* src_argb0,
const uint8_t* src_argb1,
uint8_t* dst_argb,
int width);
// Get function to Alpha Blend ARGB pixels and store to destination.
LIBYUV_API
ARGBBlendRow GetARGBBlend();
// Alpha Blend ARGB images and store to destination.
// Source is pre-multiplied by alpha using ARGBAttenuate.
// Alpha of destination is set to 255.
......
......@@ -26,9 +26,20 @@ extern "C" {
#if defined(__native_client__)
#define LIBYUV_DISABLE_NEON
#endif
// clang >= 19.0.0 required for SME
#if !defined(LIBYUV_DISABLE_SME) && defined(__clang__) && defined(__aarch64__)
#if __clang_major__ < 19
#define LIBYUV_DISABLE_SME
#endif
#endif
// MemorySanitizer does not support assembly code yet. http://crbug.com/344505
#if defined(__has_feature)
#if __has_feature(memory_sanitizer)
#if __has_feature(memory_sanitizer) && !defined(LIBYUV_DISABLE_NEON)
#define LIBYUV_DISABLE_NEON
#endif
#if __has_feature(memory_sanitizer) && !defined(LIBYUV_DISABLE_X86)
#define LIBYUV_DISABLE_X86
#endif
#endif
......@@ -42,6 +53,8 @@ extern "C" {
// The following are available for GCC 32 or 64 bit:
#if !defined(LIBYUV_DISABLE_X86) && (defined(__i386__) || defined(__x86_64__))
#define HAS_TRANSPOSEWX8_SSSE3
#define HAS_TRANSPOSE4X4_32_SSE2
#define HAS_TRANSPOSE4X4_32_AVX2
#endif
// The following are available for 64 bit GCC:
......@@ -52,8 +65,18 @@ extern "C" {
#if !defined(LIBYUV_DISABLE_NEON) && \
(defined(__ARM_NEON__) || defined(LIBYUV_NEON) || defined(__aarch64__))
#if defined(__aarch64__)
#define HAS_TRANSPOSEWX16_NEON
#else
#define HAS_TRANSPOSEWX8_NEON
#endif
#define HAS_TRANSPOSEUVWX8_NEON
#define HAS_TRANSPOSE4X4_32_NEON
#endif
#if !defined(LIBYUV_DISABLE_SME) && defined(__aarch64__)
#define HAS_TRANSPOSEWXH_SME
#define HAS_TRANSPOSEUVWXH_SME
#endif
#if !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa)
......@@ -88,6 +111,17 @@ void TransposeWx8_NEON(const uint8_t* src,
uint8_t* dst,
int dst_stride,
int width);
void TransposeWx16_NEON(const uint8_t* src,
int src_stride,
uint8_t* dst,
int dst_stride,
int width);
void TransposeWxH_SME(const uint8_t* src,
int src_stride,
uint8_t* dst,
int dst_stride,
int width,
int height);
void TransposeWx8_SSSE3(const uint8_t* src,
int src_stride,
uint8_t* dst,
......@@ -114,6 +148,11 @@ void TransposeWx8_Any_NEON(const uint8_t* src,
uint8_t* dst,
int dst_stride,
int width);
void TransposeWx16_Any_NEON(const uint8_t* src,
int src_stride,
uint8_t* dst,
int dst_stride,
int width);
void TransposeWx8_Any_SSSE3(const uint8_t* src,
int src_stride,
uint8_t* dst,
......@@ -172,6 +211,14 @@ void TransposeUVWx8_NEON(const uint8_t* src,
uint8_t* dst_b,
int dst_stride_b,
int width);
void TransposeUVWxH_SME(const uint8_t* src,
int src_stride,
uint8_t* dst_a,
int dst_stride_a,
uint8_t* dst_b,
int dst_stride_b,
int width,
int height);
void TransposeUVWx16_MSA(const uint8_t* src,
int src_stride,
uint8_t* dst_a,
......@@ -240,19 +287,24 @@ void Transpose4x4_32_NEON(const uint8_t* src,
int dst_stride,
int width);
void Transpose4x4_32_C(const uint8_t* src,
int src_stride,
uint8_t* dst,
int dst_stride,
int width);
void Transpose4x4_32_SSE2(const uint8_t* src,
int src_stride,
uint8_t* dst,
int dst_stride,
int width);
// Transpose 32 bit values (ARGB)
void Transpose8x8_32_NEON(const uint8_t* src,
void Transpose4x4_32_AVX2(const uint8_t* src,
int src_stride,
uint8_t* dst,
int dst_stride,
int width);
void Transpose4x4_32_C(const uint8_t* src,
int src_stride,
uint8_t* dst,
int dst_stride,
int width);
#ifdef __cplusplus
} // extern "C"
} // namespace libyuv
......
......@@ -27,39 +27,40 @@ typedef enum FilterMode {
} FilterModeEnum;
// Scale a YUV plane.
// Returns 0 if successful.
LIBYUV_API
void ScalePlane(const uint8_t* src,
int src_stride,
int src_width,
int src_height,
uint8_t* dst,
int dst_stride,
int dst_width,
int dst_height,
enum FilterMode filtering);
int ScalePlane(const uint8_t* src,
int src_stride,
int src_width,
int src_height,
uint8_t* dst,
int dst_stride,
int dst_width,
int dst_height,
enum FilterMode filtering);
LIBYUV_API
void ScalePlane_16(const uint16_t* src,
int src_stride,
int src_width,
int src_height,
uint16_t* dst,
int dst_stride,
int dst_width,
int dst_height,
enum FilterMode filtering);
int ScalePlane_16(const uint16_t* src,
int src_stride,
int src_width,
int src_height,
uint16_t* dst,
int dst_stride,
int dst_width,
int dst_height,
enum FilterMode filtering);
// Sample is expected to be in the low 12 bits.
LIBYUV_API
void ScalePlane_12(const uint16_t* src,
int src_stride,
int src_width,
int src_height,
uint16_t* dst,
int dst_stride,
int dst_width,
int dst_height,
enum FilterMode filtering);
int ScalePlane_12(const uint16_t* src,
int src_stride,
int src_width,
int src_height,
uint16_t* dst,
int dst_stride,
int dst_width,
int dst_height,
enum FilterMode filtering);
// Scales a YUV 4:2:0 image from the src width and height to the
// dst width and height.
......
......@@ -29,7 +29,10 @@ extern "C" {
#endif
// MemorySanitizer does not support assembly code yet. http://crbug.com/344505
#if defined(__has_feature)
#if __has_feature(memory_sanitizer)
#if __has_feature(memory_sanitizer) && !defined(LIBYUV_DISABLE_NEON)
#define LIBYUV_DISABLE_NEON
#endif
#if __has_feature(memory_sanitizer) && !defined(LIBYUV_DISABLE_X86)
#define LIBYUV_DISABLE_X86
#endif
#endif
......@@ -133,6 +136,8 @@ extern "C" {
#define HAS_SCALEROWDOWN34_NEON
#define HAS_SCALEROWDOWN38_NEON
#define HAS_SCALEROWDOWN4_NEON
#define HAS_SCALEUVROWDOWN2_NEON
#define HAS_SCALEUVROWDOWN2LINEAR_NEON
#define HAS_SCALEUVROWDOWN2BOX_NEON
#define HAS_SCALEUVROWDOWNEVEN_NEON
#define HAS_SCALEROWUP2_LINEAR_NEON
......@@ -173,6 +178,38 @@ extern "C" {
#define HAS_SCALEROWDOWN34_LSX
#endif
#if !defined(LIBYUV_DISABLE_RVV) && defined(__riscv_vector)
#define HAS_SCALEADDROW_RVV
// TODO: Test ScaleARGBRowDownEven_RVV and enable it
// #define HAS_SCALEARGBROWDOWNEVEN_RVV
#if defined(__riscv_zve64x)
#define HAS_SCALEUVROWDOWN4_RVV
#endif
#define HAS_SCALEUVROWDOWNEVEN_RVV
#define HAS_SCALEARGBROWDOWN2_RVV
#define HAS_SCALEARGBROWDOWN2BOX_RVV
#define HAS_SCALEARGBROWDOWN2LINEAR_RVV
#define HAS_SCALEARGBROWDOWNEVENBOX_RVV
#define HAS_SCALEROWDOWN2_RVV
#define HAS_SCALEROWDOWN2BOX_RVV
#define HAS_SCALEROWDOWN2LINEAR_RVV
#define HAS_SCALEROWDOWN34_0_BOX_RVV
#define HAS_SCALEROWDOWN34_1_BOX_RVV
#define HAS_SCALEROWDOWN34_RVV
#define HAS_SCALEROWDOWN38_2_BOX_RVV
#define HAS_SCALEROWDOWN38_3_BOX_RVV
#define HAS_SCALEROWDOWN38_RVV
#define HAS_SCALEROWDOWN4_RVV
#define HAS_SCALEROWDOWN4BOX_RVV
#define HAS_SCALEROWUP2_BILINEAR_RVV
#define HAS_SCALEROWUP2_LINEAR_RVV
#define HAS_SCALEUVROWDOWN2_RVV
#define HAS_SCALEUVROWDOWN2BOX_RVV
#define HAS_SCALEUVROWDOWN2LINEAR_RVV
#define HAS_SCALEUVROWUP2_BILINEAR_RVV
#define HAS_SCALEUVROWUP2_LINEAR_RVV
#endif
// Scale ARGB vertically with bilinear interpolation.
void ScalePlaneVertical(int src_height,
int dst_width,
......@@ -947,6 +984,18 @@ void ScaleARGBRowDown2Box_NEON(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst,
int dst_width);
void ScaleARGBRowDown2_RVV(const uint8_t* src_argb,
ptrdiff_t src_stride,
uint8_t* dst_argb,
int dst_width);
void ScaleARGBRowDown2Linear_RVV(const uint8_t* src_argb,
ptrdiff_t src_stride,
uint8_t* dst_argb,
int dst_width);
void ScaleARGBRowDown2Box_RVV(const uint8_t* src_argb,
ptrdiff_t src_stride,
uint8_t* dst_argb,
int dst_width);
void ScaleARGBRowDown2_MSA(const uint8_t* src_argb,
ptrdiff_t src_stride,
uint8_t* dst_argb,
......@@ -1059,6 +1108,16 @@ void ScaleARGBRowDownEvenBox_LSX(const uint8_t* src_argb,
int src_stepx,
uint8_t* dst_argb,
int dst_width);
void ScaleARGBRowDownEven_RVV(const uint8_t* src_argb,
ptrdiff_t src_stride,
int32_t src_stepx,
uint8_t* dst_argb,
int dst_width);
void ScaleARGBRowDownEvenBox_RVV(const uint8_t* src_argb,
ptrdiff_t src_stride,
int src_stepx,
uint8_t* dst_argb,
int dst_width);
void ScaleARGBRowDownEven_Any_SSE2(const uint8_t* src_ptr,
ptrdiff_t src_stride,
int src_stepx,
......@@ -1141,6 +1200,18 @@ void ScaleUVRowDown2Box_MSA(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_uv,
int dst_width);
void ScaleUVRowDown2_RVV(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_uv,
int dst_width);
void ScaleUVRowDown2Linear_RVV(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_uv,
int dst_width);
void ScaleUVRowDown2Box_RVV(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst,
int dst_width);
void ScaleUVRowDown2_Any_SSSE3(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
......@@ -1201,6 +1272,16 @@ void ScaleUVRowDownEvenBox_NEON(const uint8_t* src_ptr,
int src_stepx,
uint8_t* dst_uv,
int dst_width);
void ScaleUVRowDown4_RVV(const uint8_t* src_ptr,
ptrdiff_t src_stride,
int32_t src_stepx,
uint8_t* dst_uv,
int dst_width);
void ScaleUVRowDownEven_RVV(const uint8_t* src_ptr,
ptrdiff_t src_stride,
int32_t src_stepx,
uint8_t* dst_uv,
int dst_width);
void ScaleUVRowDownEven_MSA(const uint8_t* src_ptr,
ptrdiff_t src_stride,
int32_t src_stepx,
......@@ -1290,6 +1371,14 @@ void ScaleUVRowUp2_Bilinear_Any_NEON(const uint8_t* src_ptr,
uint8_t* dst_ptr,
ptrdiff_t dst_stride,
int dst_width);
void ScaleUVRowUp2_Linear_RVV(const uint8_t* src_ptr,
uint8_t* dst_ptr,
int dst_width);
void ScaleUVRowUp2_Bilinear_RVV(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
ptrdiff_t dst_stride,
int dst_width);
void ScaleUVRowUp2_Linear_16_SSE41(const uint16_t* src_ptr,
uint16_t* dst_ptr,
int dst_width);
......@@ -1742,6 +1831,61 @@ void ScaleRowDown34_1_Box_Any_LSX(const uint8_t* src_ptr,
uint8_t* dst_ptr,
int dst_width);
void ScaleAddRow_RVV(const uint8_t* src_ptr, uint16_t* dst_ptr, int src_width);
void ScaleRowDown2_RVV(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst,
int dst_width);
void ScaleRowDown2Linear_RVV(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst,
int dst_width);
void ScaleRowDown2Box_RVV(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst,
int dst_width);
void ScaleRowDown4_RVV(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width);
void ScaleRowDown4Box_RVV(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width);
void ScaleRowDown34_RVV(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width);
void ScaleRowDown34_0_Box_RVV(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width);
void ScaleRowDown34_1_Box_RVV(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width);
void ScaleRowDown38_RVV(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst,
int dst_width);
void ScaleRowDown38_3_Box_RVV(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width);
void ScaleRowDown38_2_Box_RVV(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width);
void ScaleRowUp2_Linear_RVV(const uint8_t* src_ptr,
uint8_t* dst_ptr,
int dst_width);
void ScaleRowUp2_Bilinear_RVV(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
ptrdiff_t dst_stride,
int dst_width);
#ifdef __cplusplus
} // extern "C"
} // namespace libyuv
......
......@@ -11,6 +11,6 @@
#ifndef INCLUDE_LIBYUV_VERSION_H_
#define INCLUDE_LIBYUV_VERSION_H_
#define LIBYUV_VERSION 1860
#define LIBYUV_VERSION 1892
#endif // INCLUDE_LIBYUV_VERSION_H_
/*
* Copyright 2011 The LibYuv Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef INCLUDE_LIBYUV_H_
#define INCLUDE_LIBYUV_H_
#include "libyuv/basic_types.h"
#include "libyuv/compare.h"
#include "libyuv/convert.h"
#include "libyuv/convert_argb.h"
#include "libyuv/convert_from.h"
#include "libyuv/convert_from_argb.h"
#include "libyuv/cpu_id.h"
#include "libyuv/mjpeg_decoder.h"
#include "libyuv/planar_functions.h"
#include "libyuv/rotate.h"
#include "libyuv/rotate_argb.h"
#include "libyuv/row.h"
#include "libyuv/scale.h"
#include "libyuv/scale_argb.h"
#include "libyuv/scale_row.h"
#include "libyuv/scale_uv.h"
#include "libyuv/version.h"
#include "libyuv/video_common.h"
#endif // INCLUDE_LIBYUV_H_
/*
* Copyright 2011 The LibYuv Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef INCLUDE_LIBYUV_BASIC_TYPES_H_
#define INCLUDE_LIBYUV_BASIC_TYPES_H_
#include <stddef.h> // For size_t and NULL
#if !defined(INT_TYPES_DEFINED) && !defined(GG_LONGLONG)
#define INT_TYPES_DEFINED
#if defined(_MSC_VER) && (_MSC_VER < 1600)
#include <sys/types.h> // for uintptr_t on x86
typedef unsigned __int64 uint64_t;
typedef __int64 int64_t;
typedef unsigned int uint32_t;
typedef int int32_t;
typedef unsigned short uint16_t;
typedef short int16_t;
typedef unsigned char uint8_t;
typedef signed char int8_t;
#else
#include <stdint.h> // for uintptr_t and C99 types
#endif // defined(_MSC_VER) && (_MSC_VER < 1600)
// Types are deprecated. Enable this macro for legacy types.
#ifdef LIBYUV_LEGACY_TYPES
typedef uint64_t uint64;
typedef int64_t int64;
typedef uint32_t uint32;
typedef int32_t int32;
typedef uint16_t uint16;
typedef int16_t int16;
typedef uint8_t uint8;
typedef int8_t int8;
#endif // LIBYUV_LEGACY_TYPES
#endif // INT_TYPES_DEFINED
#if !defined(LIBYUV_API)
#if defined(_WIN32) || defined(__CYGWIN__)
#if defined(LIBYUV_BUILDING_SHARED_LIBRARY)
#define LIBYUV_API __declspec(dllexport)
#elif defined(LIBYUV_USING_SHARED_LIBRARY)
#define LIBYUV_API __declspec(dllimport)
#else
#define LIBYUV_API
#endif // LIBYUV_BUILDING_SHARED_LIBRARY
#elif defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__APPLE__) && \
(defined(LIBYUV_BUILDING_SHARED_LIBRARY) || \
defined(LIBYUV_USING_SHARED_LIBRARY))
#define LIBYUV_API __attribute__((visibility("default")))
#else
#define LIBYUV_API
#endif // __GNUC__
#endif // LIBYUV_API
// TODO(fbarchard): Remove bool macros.
#define LIBYUV_BOOL int
#define LIBYUV_FALSE 0
#define LIBYUV_TRUE 1
#endif // INCLUDE_LIBYUV_BASIC_TYPES_H_
/*
* Copyright 2011 The LibYuv Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef INCLUDE_LIBYUV_COMPARE_H_
#define INCLUDE_LIBYUV_COMPARE_H_
#include "libyuv/basic_types.h"
#ifdef __cplusplus
namespace libyuv {
extern "C" {
#endif
// Compute a hash for specified memory. Seed of 5381 recommended.
LIBYUV_API
uint32_t HashDjb2(const uint8_t* src, uint64_t count, uint32_t seed);
// Hamming Distance
LIBYUV_API
uint64_t ComputeHammingDistance(const uint8_t* src_a,
const uint8_t* src_b,
int count);
// Scan an opaque argb image and return fourcc based on alpha offset.
// Returns FOURCC_ARGB, FOURCC_BGRA, or 0 if unknown.
LIBYUV_API
uint32_t ARGBDetect(const uint8_t* argb,
int stride_argb,
int width,
int height);
// Sum Square Error - used to compute Mean Square Error or PSNR.
LIBYUV_API
uint64_t ComputeSumSquareError(const uint8_t* src_a,
const uint8_t* src_b,
int count);
LIBYUV_API
uint64_t ComputeSumSquareErrorPlane(const uint8_t* src_a,
int stride_a,
const uint8_t* src_b,
int stride_b,
int width,
int height);
static const int kMaxPsnr = 128;
LIBYUV_API
double SumSquareErrorToPsnr(uint64_t sse, uint64_t count);
LIBYUV_API
double CalcFramePsnr(const uint8_t* src_a,
int stride_a,
const uint8_t* src_b,
int stride_b,
int width,
int height);
LIBYUV_API
double I420Psnr(const uint8_t* src_y_a,
int stride_y_a,
const uint8_t* src_u_a,
int stride_u_a,
const uint8_t* src_v_a,
int stride_v_a,
const uint8_t* src_y_b,
int stride_y_b,
const uint8_t* src_u_b,
int stride_u_b,
const uint8_t* src_v_b,
int stride_v_b,
int width,
int height);
LIBYUV_API
double CalcFrameSsim(const uint8_t* src_a,
int stride_a,
const uint8_t* src_b,
int stride_b,
int width,
int height);
LIBYUV_API
double I420Ssim(const uint8_t* src_y_a,
int stride_y_a,
const uint8_t* src_u_a,
int stride_u_a,
const uint8_t* src_v_a,
int stride_v_a,
const uint8_t* src_y_b,
int stride_y_b,
const uint8_t* src_u_b,
int stride_u_b,
const uint8_t* src_v_b,
int stride_v_b,
int width,
int height);
#ifdef __cplusplus
} // extern "C"
} // namespace libyuv
#endif
#endif // INCLUDE_LIBYUV_COMPARE_H_
/*
* Copyright 2013 The LibYuv Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef INCLUDE_LIBYUV_COMPARE_ROW_H_
#define INCLUDE_LIBYUV_COMPARE_ROW_H_
#include "libyuv/basic_types.h"
#ifdef __cplusplus
namespace libyuv {
extern "C" {
#endif
#if defined(__pnacl__) || defined(__CLR_VER) || \
(defined(__native_client__) && defined(__x86_64__)) || \
(defined(__i386__) && !defined(__SSE__) && !defined(__clang__))
#define LIBYUV_DISABLE_X86
#endif
#if defined(__native_client__)
#define LIBYUV_DISABLE_NEON
#endif
// MemorySanitizer does not support assembly code yet. http://crbug.com/344505
#if defined(__has_feature)
#if __has_feature(memory_sanitizer)
#define LIBYUV_DISABLE_X86
#endif
#endif
// Visual C 2012 required for AVX2.
#if defined(_M_IX86) && !defined(__clang__) && defined(_MSC_VER) && \
_MSC_VER >= 1700
#define VISUALC_HAS_AVX2 1
#endif // VisualStudio >= 2012
// clang >= 3.4.0 required for AVX2.
#if defined(__clang__) && (defined(__x86_64__) || defined(__i386__))
#if (__clang_major__ > 3) || (__clang_major__ == 3 && (__clang_minor__ >= 4))
#define CLANG_HAS_AVX2 1
#endif // clang >= 3.4
#endif // __clang__
// The following are available for Visual C and GCC:
#if !defined(LIBYUV_DISABLE_X86) && \
(defined(__x86_64__) || defined(__i386__) || defined(_M_IX86))
#define HAS_HASHDJB2_SSE41
#define HAS_SUMSQUAREERROR_SSE2
#define HAS_HAMMINGDISTANCE_SSE42
#endif
// The following are available for Visual C and clangcl 32 bit:
#if !defined(LIBYUV_DISABLE_X86) && defined(_M_IX86) && defined(_MSC_VER) && \
!defined(__clang__) && \
(defined(VISUALC_HAS_AVX2) || defined(CLANG_HAS_AVX2))
#define HAS_HASHDJB2_AVX2
#define HAS_SUMSQUAREERROR_AVX2
#endif
// The following are available for GCC and clangcl:
#if !defined(LIBYUV_DISABLE_X86) && (defined(__x86_64__) || defined(__i386__))
#define HAS_HAMMINGDISTANCE_SSSE3
#endif
// The following are available for GCC and clangcl:
#if !defined(LIBYUV_DISABLE_X86) && defined(CLANG_HAS_AVX2) && \
(defined(__x86_64__) || defined(__i386__))
#define HAS_HAMMINGDISTANCE_AVX2
#endif
// The following are available for Neon:
#if !defined(LIBYUV_DISABLE_NEON) && \
(defined(__ARM_NEON__) || defined(LIBYUV_NEON) || defined(__aarch64__))
#define HAS_SUMSQUAREERROR_NEON
#define HAS_HAMMINGDISTANCE_NEON
#endif
#if !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa)
#define HAS_HAMMINGDISTANCE_MSA
#define HAS_SUMSQUAREERROR_MSA
#endif
uint32_t HammingDistance_C(const uint8_t* src_a,
const uint8_t* src_b,
int count);
uint32_t HammingDistance_SSE42(const uint8_t* src_a,
const uint8_t* src_b,
int count);
uint32_t HammingDistance_SSSE3(const uint8_t* src_a,
const uint8_t* src_b,
int count);
uint32_t HammingDistance_AVX2(const uint8_t* src_a,
const uint8_t* src_b,
int count);
uint32_t HammingDistance_NEON(const uint8_t* src_a,
const uint8_t* src_b,
int count);
uint32_t HammingDistance_MSA(const uint8_t* src_a,
const uint8_t* src_b,
int count);
uint32_t SumSquareError_C(const uint8_t* src_a,
const uint8_t* src_b,
int count);
uint32_t SumSquareError_SSE2(const uint8_t* src_a,
const uint8_t* src_b,
int count);
uint32_t SumSquareError_AVX2(const uint8_t* src_a,
const uint8_t* src_b,
int count);
uint32_t SumSquareError_NEON(const uint8_t* src_a,
const uint8_t* src_b,
int count);
uint32_t SumSquareError_MSA(const uint8_t* src_a,
const uint8_t* src_b,
int count);
uint32_t HashDjb2_C(const uint8_t* src, int count, uint32_t seed);
uint32_t HashDjb2_SSE41(const uint8_t* src, int count, uint32_t seed);
uint32_t HashDjb2_AVX2(const uint8_t* src, int count, uint32_t seed);
#ifdef __cplusplus
} // extern "C"
} // namespace libyuv
#endif
#endif // INCLUDE_LIBYUV_COMPARE_ROW_H_
/*
* Copyright 2011 The LibYuv Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef INCLUDE_LIBYUV_CONVERT_FROM_H_
#define INCLUDE_LIBYUV_CONVERT_FROM_H_
#include "libyuv/basic_types.h"
#include "libyuv/rotate.h"
#ifdef __cplusplus
namespace libyuv {
extern "C" {
#endif
// See Also convert.h for conversions from formats to I420.
// Convert 8 bit YUV to 10 bit.
#define H420ToH010 I420ToI010
LIBYUV_API
int I420ToI010(const uint8_t* src_y,
int src_stride_y,
const uint8_t* src_u,
int src_stride_u,
const uint8_t* src_v,
int src_stride_v,
uint16_t* dst_y,
int dst_stride_y,
uint16_t* dst_u,
int dst_stride_u,
uint16_t* dst_v,
int dst_stride_v,
int width,
int height);
// Convert 8 bit YUV to 12 bit.
#define H420ToH012 I420ToI012
LIBYUV_API
int I420ToI012(const uint8_t* src_y,
int src_stride_y,
const uint8_t* src_u,
int src_stride_u,
const uint8_t* src_v,
int src_stride_v,
uint16_t* dst_y,
int dst_stride_y,
uint16_t* dst_u,
int dst_stride_u,
uint16_t* dst_v,
int dst_stride_v,
int width,
int height);
LIBYUV_API
int I420ToI422(const uint8_t* src_y,
int src_stride_y,
const uint8_t* src_u,
int src_stride_u,
const uint8_t* src_v,
int src_stride_v,
uint8_t* dst_y,
int dst_stride_y,
uint8_t* dst_u,
int dst_stride_u,
uint8_t* dst_v,
int dst_stride_v,
int width,
int height);
LIBYUV_API
int I420ToI444(const uint8_t* src_y,
int src_stride_y,
const uint8_t* src_u,
int src_stride_u,
const uint8_t* src_v,
int src_stride_v,
uint8_t* dst_y,
int dst_stride_y,
uint8_t* dst_u,
int dst_stride_u,
uint8_t* dst_v,
int dst_stride_v,
int width,
int height);
// Copy to I400. Source can be I420, I422, I444, I400, NV12 or NV21.
LIBYUV_API
int I400Copy(const uint8_t* src_y,
int src_stride_y,
uint8_t* dst_y,
int dst_stride_y,
int width,
int height);
LIBYUV_API
int I420ToNV12(const uint8_t* src_y,
int src_stride_y,
const uint8_t* src_u,
int src_stride_u,
const uint8_t* src_v,
int src_stride_v,
uint8_t* dst_y,
int dst_stride_y,
uint8_t* dst_uv,
int dst_stride_uv,
int width,
int height);
LIBYUV_API
int I420ToNV21(const uint8_t* src_y,
int src_stride_y,
const uint8_t* src_u,
int src_stride_u,
const uint8_t* src_v,
int src_stride_v,
uint8_t* dst_y,
int dst_stride_y,
uint8_t* dst_vu,
int dst_stride_vu,
int width,
int height);
LIBYUV_API
int I420ToYUY2(const uint8_t* src_y,
int src_stride_y,
const uint8_t* src_u,
int src_stride_u,
const uint8_t* src_v,
int src_stride_v,
uint8_t* dst_yuy2,
int dst_stride_yuy2,
int width,
int height);
LIBYUV_API
int I420ToUYVY(const uint8_t* src_y,
int src_stride_y,
const uint8_t* src_u,
int src_stride_u,
const uint8_t* src_v,
int src_stride_v,
uint8_t* dst_uyvy,
int dst_stride_uyvy,
int width,
int height);
// The following are from convert_argb.h
// DEPRECATED: The prototypes will be removed in future. Use convert_argb.h
// Convert I420 to ARGB.
LIBYUV_API
int I420ToARGB(const uint8_t* src_y,
int src_stride_y,
const uint8_t* src_u,
int src_stride_u,
const uint8_t* src_v,
int src_stride_v,
uint8_t* dst_argb,
int dst_stride_argb,
int width,
int height);
// Convert I420 to ABGR.
LIBYUV_API
int I420ToABGR(const uint8_t* src_y,
int src_stride_y,
const uint8_t* src_u,
int src_stride_u,
const uint8_t* src_v,
int src_stride_v,
uint8_t* dst_abgr,
int dst_stride_abgr,
int width,
int height);
// Convert I420 to specified format.
// "dst_sample_stride" is bytes in a row for the destination. Pass 0 if the
// buffer has contiguous rows. Can be negative. A multiple of 16 is optimal.
LIBYUV_API
int ConvertFromI420(const uint8_t* y,
int y_stride,
const uint8_t* u,
int u_stride,
const uint8_t* v,
int v_stride,
uint8_t* dst_sample,
int dst_sample_stride,
int width,
int height,
uint32_t fourcc);
#ifdef __cplusplus
} // extern "C"
} // namespace libyuv
#endif
#endif // INCLUDE_LIBYUV_CONVERT_FROM_H_
/*
* Copyright 2011 The LibYuv Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef INCLUDE_LIBYUV_CPU_ID_H_
#define INCLUDE_LIBYUV_CPU_ID_H_
#include "libyuv/basic_types.h"
#ifdef __cplusplus
namespace libyuv {
extern "C" {
#endif
// Internal flag to indicate cpuid requires initialization.
static const int kCpuInitialized = 0x1;
// These flags are only valid on ARM processors.
static const int kCpuHasARM = 0x2;
static const int kCpuHasNEON = 0x4;
// 0x8 reserved for future ARM flag.
// These flags are only valid on x86 processors.
static const int kCpuHasX86 = 0x10;
static const int kCpuHasSSE2 = 0x20;
static const int kCpuHasSSSE3 = 0x40;
static const int kCpuHasSSE41 = 0x80;
static const int kCpuHasSSE42 = 0x100; // unused at this time.
static const int kCpuHasAVX = 0x200;
static const int kCpuHasAVX2 = 0x400;
static const int kCpuHasERMS = 0x800;
static const int kCpuHasFMA3 = 0x1000;
static const int kCpuHasF16C = 0x2000;
static const int kCpuHasGFNI = 0x4000;
static const int kCpuHasAVX512BW = 0x8000;
static const int kCpuHasAVX512VL = 0x10000;
static const int kCpuHasAVX512VNNI = 0x20000;
static const int kCpuHasAVX512VBMI = 0x40000;
static const int kCpuHasAVX512VBMI2 = 0x80000;
static const int kCpuHasAVX512VBITALG = 0x100000;
static const int kCpuHasAVX512VPOPCNTDQ = 0x200000;
// These flags are only valid on MIPS processors.
static const int kCpuHasMIPS = 0x400000;
static const int kCpuHasMSA = 0x800000;
// These flags are only valid on LOONGARCH processors.
static const int kCpuHasLOONGARCH = 0x2000000;
static const int kCpuHasLSX = 0x4000000;
static const int kCpuHasLASX = 0x8000000;
// Optional init function. TestCpuFlag does an auto-init.
// Returns cpu_info flags.
LIBYUV_API
int InitCpuFlags(void);
// Detect CPU has SSE2 etc.
// Test_flag parameter should be one of kCpuHas constants above.
// Returns non-zero if instruction set is detected
static __inline int TestCpuFlag(int test_flag) {
LIBYUV_API extern int cpu_info_;
#ifdef __ATOMIC_RELAXED
int cpu_info = __atomic_load_n(&cpu_info_, __ATOMIC_RELAXED);
#else
int cpu_info = cpu_info_;
#endif
return (!cpu_info ? InitCpuFlags() : cpu_info) & test_flag;
}
// Internal function for parsing /proc/cpuinfo.
LIBYUV_API
int ArmCpuCaps(const char* cpuinfo_name);
LIBYUV_API
int MipsCpuCaps(const char* cpuinfo_name);
// For testing, allow CPU flags to be disabled.
// ie MaskCpuFlags(~kCpuHasSSSE3) to disable SSSE3.
// MaskCpuFlags(-1) to enable all cpu specific optimizations.
// MaskCpuFlags(1) to disable all cpu specific optimizations.
// MaskCpuFlags(0) to reset state so next call will auto init.
// Returns cpu_info flags.
LIBYUV_API
int MaskCpuFlags(int enable_flags);
// Sets the CPU flags to |cpu_flags|, bypassing the detection code. |cpu_flags|
// should be a valid combination of the kCpuHas constants above and include
// kCpuInitialized. Use this method when running in a sandboxed process where
// the detection code might fail (as it might access /proc/cpuinfo). In such
// cases the cpu_info can be obtained from a non sandboxed process by calling
// InitCpuFlags() and passed to the sandboxed process (via command line
// parameters, IPC...) which can then call this method to initialize the CPU
// flags.
// Notes:
// - when specifying 0 for |cpu_flags|, the auto initialization is enabled
// again.
// - enabling CPU features that are not supported by the CPU will result in
// undefined behavior.
// TODO(fbarchard): consider writing a helper function that translates from
// other library CPU info to libyuv CPU info and add a .md doc that explains
// CPU detection.
static __inline void SetCpuFlags(int cpu_flags) {
LIBYUV_API extern int cpu_info_;
#ifdef __ATOMIC_RELAXED
__atomic_store_n(&cpu_info_, cpu_flags, __ATOMIC_RELAXED);
#else
cpu_info_ = cpu_flags;
#endif
}
// Low level cpuid for X86. Returns zeros on other CPUs.
// eax is the info type that you want.
// ecx is typically the cpu number, and should normally be zero.
LIBYUV_API
void CpuId(int info_eax, int info_ecx, int* cpu_info);
#ifdef __cplusplus
} // extern "C"
} // namespace libyuv
#endif
#endif // INCLUDE_LIBYUV_CPU_ID_H_
/*
* Copyright 2012 The LibYuv Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef INCLUDE_LIBYUV_MJPEG_DECODER_H_
#define INCLUDE_LIBYUV_MJPEG_DECODER_H_
#include "libyuv/basic_types.h"
#ifdef __cplusplus
// NOTE: For a simplified public API use convert.h MJPGToI420().
struct jpeg_common_struct;
struct jpeg_decompress_struct;
struct jpeg_source_mgr;
namespace libyuv {
#ifdef __cplusplus
extern "C" {
#endif
LIBYUV_BOOL ValidateJpeg(const uint8_t* sample, size_t sample_size);
#ifdef __cplusplus
} // extern "C"
#endif
static const uint32_t kUnknownDataSize = 0xFFFFFFFF;
enum JpegSubsamplingType {
kJpegYuv420,
kJpegYuv422,
kJpegYuv444,
kJpegYuv400,
kJpegUnknown
};
struct Buffer {
const uint8_t* data;
int len;
};
struct BufferVector {
Buffer* buffers;
int len;
int pos;
};
struct SetJmpErrorMgr;
// MJPEG ("Motion JPEG") is a pseudo-standard video codec where the frames are
// simply independent JPEG images with a fixed huffman table (which is omitted).
// It is rarely used in video transmission, but is common as a camera capture
// format, especially in Logitech devices. This class implements a decoder for
// MJPEG frames.
//
// See http://tools.ietf.org/html/rfc2435
class LIBYUV_API MJpegDecoder {
public:
typedef void (*CallbackFunction)(void* opaque,
const uint8_t* const* data,
const int* strides,
int rows);
static const int kColorSpaceUnknown;
static const int kColorSpaceGrayscale;
static const int kColorSpaceRgb;
static const int kColorSpaceYCbCr;
static const int kColorSpaceCMYK;
static const int kColorSpaceYCCK;
MJpegDecoder();
~MJpegDecoder();
// Loads a new frame, reads its headers, and determines the uncompressed
// image format.
// Returns LIBYUV_TRUE if image looks valid and format is supported.
// If return value is LIBYUV_TRUE, then the values for all the following
// getters are populated.
// src_len is the size of the compressed mjpeg frame in bytes.
LIBYUV_BOOL LoadFrame(const uint8_t* src, size_t src_len);
// Returns width of the last loaded frame in pixels.
int GetWidth();
// Returns height of the last loaded frame in pixels.
int GetHeight();
// Returns format of the last loaded frame. The return value is one of the
// kColorSpace* constants.
int GetColorSpace();
// Number of color components in the color space.
int GetNumComponents();
// Sample factors of the n-th component.
int GetHorizSampFactor(int component);
int GetVertSampFactor(int component);
int GetHorizSubSampFactor(int component);
int GetVertSubSampFactor(int component);
// Public for testability.
int GetImageScanlinesPerImcuRow();
// Public for testability.
int GetComponentScanlinesPerImcuRow(int component);
// Width of a component in bytes.
int GetComponentWidth(int component);
// Height of a component.
int GetComponentHeight(int component);
// Width of a component in bytes with padding for DCTSIZE. Public for testing.
int GetComponentStride(int component);
// Size of a component in bytes.
int GetComponentSize(int component);
// Call this after LoadFrame() if you decide you don't want to decode it
// after all.
LIBYUV_BOOL UnloadFrame();
// Decodes the entire image into a one-buffer-per-color-component format.
// dst_width must match exactly. dst_height must be <= to image height; if
// less, the image is cropped. "planes" must have size equal to at least
// GetNumComponents() and they must point to non-overlapping buffers of size
// at least GetComponentSize(i). The pointers in planes are incremented
// to point to after the end of the written data.
// TODO(fbarchard): Add dst_x, dst_y to allow specific rect to be decoded.
LIBYUV_BOOL DecodeToBuffers(uint8_t** planes, int dst_width, int dst_height);
// Decodes the entire image and passes the data via repeated calls to a
// callback function. Each call will get the data for a whole number of
// image scanlines.
// TODO(fbarchard): Add dst_x, dst_y to allow specific rect to be decoded.
LIBYUV_BOOL DecodeToCallback(CallbackFunction fn,
void* opaque,
int dst_width,
int dst_height);
// The helper function which recognizes the jpeg sub-sampling type.
static JpegSubsamplingType JpegSubsamplingTypeHelper(
int* subsample_x,
int* subsample_y,
int number_of_components);
private:
void AllocOutputBuffers(int num_outbufs);
void DestroyOutputBuffers();
LIBYUV_BOOL StartDecode();
LIBYUV_BOOL FinishDecode();
void SetScanlinePointers(uint8_t** data);
LIBYUV_BOOL DecodeImcuRow();
int GetComponentScanlinePadding(int component);
// A buffer holding the input data for a frame.
Buffer buf_;
BufferVector buf_vec_;
jpeg_decompress_struct* decompress_struct_;
jpeg_source_mgr* source_mgr_;
SetJmpErrorMgr* error_mgr_;
// LIBYUV_TRUE iff at least one component has scanline padding. (i.e.,
// GetComponentScanlinePadding() != 0.)
LIBYUV_BOOL has_scanline_padding_;
// Temporaries used to point to scanline outputs.
int num_outbufs_; // Outermost size of all arrays below.
uint8_t*** scanlines_;
int* scanlines_sizes_;
// Temporary buffer used for decoding when we can't decode directly to the
// output buffers. Large enough for just one iMCU row.
uint8_t** databuf_;
int* databuf_strides_;
};
} // namespace libyuv
#endif // __cplusplus
#endif // INCLUDE_LIBYUV_MJPEG_DECODER_H_
/*
* Copyright 2011 The LibYuv Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef INCLUDE_LIBYUV_ROTATE_H_
#define INCLUDE_LIBYUV_ROTATE_H_
#include "libyuv/basic_types.h"
#ifdef __cplusplus
namespace libyuv {
extern "C" {
#endif
// Supported rotation.
typedef enum RotationMode {
kRotate0 = 0, // No rotation.
kRotate90 = 90, // Rotate 90 degrees clockwise.
kRotate180 = 180, // Rotate 180 degrees.
kRotate270 = 270, // Rotate 270 degrees clockwise.
// Deprecated.
kRotateNone = 0,
kRotateClockwise = 90,
kRotateCounterClockwise = 270,
} RotationModeEnum;
// Rotate I420 frame.
LIBYUV_API
int I420Rotate(const uint8_t* src_y,
int src_stride_y,
const uint8_t* src_u,
int src_stride_u,
const uint8_t* src_v,
int src_stride_v,
uint8_t* dst_y,
int dst_stride_y,
uint8_t* dst_u,
int dst_stride_u,
uint8_t* dst_v,
int dst_stride_v,
int width,
int height,
enum RotationMode mode);
// Rotate I422 frame.
LIBYUV_API
int I422Rotate(const uint8_t* src_y,
int src_stride_y,
const uint8_t* src_u,
int src_stride_u,
const uint8_t* src_v,
int src_stride_v,
uint8_t* dst_y,
int dst_stride_y,
uint8_t* dst_u,
int dst_stride_u,
uint8_t* dst_v,
int dst_stride_v,
int width,
int height,
enum RotationMode mode);
// Rotate I444 frame.
LIBYUV_API
int I444Rotate(const uint8_t* src_y,
int src_stride_y,
const uint8_t* src_u,
int src_stride_u,
const uint8_t* src_v,
int src_stride_v,
uint8_t* dst_y,
int dst_stride_y,
uint8_t* dst_u,
int dst_stride_u,
uint8_t* dst_v,
int dst_stride_v,
int width,
int height,
enum RotationMode mode);
// Rotate I010 frame.
LIBYUV_API
int I010Rotate(const uint16_t* src_y,
int src_stride_y,
const uint16_t* src_u,
int src_stride_u,
const uint16_t* src_v,
int src_stride_v,
uint16_t* dst_y,
int dst_stride_y,
uint16_t* dst_u,
int dst_stride_u,
uint16_t* dst_v,
int dst_stride_v,
int width,
int height,
enum RotationMode mode);
// Rotate I210 frame.
LIBYUV_API
int I210Rotate(const uint16_t* src_y,
int src_stride_y,
const uint16_t* src_u,
int src_stride_u,
const uint16_t* src_v,
int src_stride_v,
uint16_t* dst_y,
int dst_stride_y,
uint16_t* dst_u,
int dst_stride_u,
uint16_t* dst_v,
int dst_stride_v,
int width,
int height,
enum RotationMode mode);
// Rotate I410 frame.
LIBYUV_API
int I410Rotate(const uint16_t* src_y,
int src_stride_y,
const uint16_t* src_u,
int src_stride_u,
const uint16_t* src_v,
int src_stride_v,
uint16_t* dst_y,
int dst_stride_y,
uint16_t* dst_u,
int dst_stride_u,
uint16_t* dst_v,
int dst_stride_v,
int width,
int height,
enum RotationMode mode);
// Rotate NV12 input and store in I420.
LIBYUV_API
int NV12ToI420Rotate(const uint8_t* src_y,
int src_stride_y,
const uint8_t* src_uv,
int src_stride_uv,
uint8_t* dst_y,
int dst_stride_y,
uint8_t* dst_u,
int dst_stride_u,
uint8_t* dst_v,
int dst_stride_v,
int width,
int height,
enum RotationMode mode);
// Convert Android420 to I420 with rotation.
// "rotation" can be 0, 90, 180 or 270.
LIBYUV_API
int Android420ToI420Rotate(const uint8_t* src_y,
int src_stride_y,
const uint8_t* src_u,
int src_stride_u,
const uint8_t* src_v,
int src_stride_v,
int src_pixel_stride_uv,
uint8_t* dst_y,
int dst_stride_y,
uint8_t* dst_u,
int dst_stride_u,
uint8_t* dst_v,
int dst_stride_v,
int width,
int height,
enum RotationMode rotation);
// Rotate a plane by 0, 90, 180, or 270.
LIBYUV_API
int RotatePlane(const uint8_t* src,
int src_stride,
uint8_t* dst,
int dst_stride,
int width,
int height,
enum RotationMode mode);
// Rotate planes by 90, 180, 270. Deprecated.
LIBYUV_API
void RotatePlane90(const uint8_t* src,
int src_stride,
uint8_t* dst,
int dst_stride,
int width,
int height);
LIBYUV_API
void RotatePlane180(const uint8_t* src,
int src_stride,
uint8_t* dst,
int dst_stride,
int width,
int height);
LIBYUV_API
void RotatePlane270(const uint8_t* src,
int src_stride,
uint8_t* dst,
int dst_stride,
int width,
int height);
// Rotate a plane by 0, 90, 180, or 270.
LIBYUV_API
int RotatePlane_16(const uint16_t* src,
int src_stride,
uint16_t* dst,
int dst_stride,
int width,
int height,
enum RotationMode mode);
// Rotations for when U and V are interleaved.
// These functions take one UV input pointer and
// split the data into two buffers while
// rotating them.
// width and height expected to be half size for NV12.
LIBYUV_API
int SplitRotateUV(const uint8_t* src_uv,
int src_stride_uv,
uint8_t* dst_u,
int dst_stride_u,
uint8_t* dst_v,
int dst_stride_v,
int width,
int height,
enum RotationMode mode);
LIBYUV_API
void SplitRotateUV90(const uint8_t* src,
int src_stride,
uint8_t* dst_a,
int dst_stride_a,
uint8_t* dst_b,
int dst_stride_b,
int width,
int height);
LIBYUV_API
void SplitRotateUV180(const uint8_t* src,
int src_stride,
uint8_t* dst_a,
int dst_stride_a,
uint8_t* dst_b,
int dst_stride_b,
int width,
int height);
LIBYUV_API
void SplitRotateUV270(const uint8_t* src,
int src_stride,
uint8_t* dst_a,
int dst_stride_a,
uint8_t* dst_b,
int dst_stride_b,
int width,
int height);
// The 90 and 270 functions are based on transposes.
// Doing a transpose with reversing the read/write
// order will result in a rotation by +- 90 degrees.
// Deprecated.
LIBYUV_API
void TransposePlane(const uint8_t* src,
int src_stride,
uint8_t* dst,
int dst_stride,
int width,
int height);
LIBYUV_API
void SplitTransposeUV(const uint8_t* src,
int src_stride,
uint8_t* dst_a,
int dst_stride_a,
uint8_t* dst_b,
int dst_stride_b,
int width,
int height);
#ifdef __cplusplus
} // extern "C"
} // namespace libyuv
#endif
#endif // INCLUDE_LIBYUV_ROTATE_H_
/*
* Copyright 2012 The LibYuv Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef INCLUDE_LIBYUV_ROTATE_ARGB_H_
#define INCLUDE_LIBYUV_ROTATE_ARGB_H_
#include "libyuv/basic_types.h"
#include "libyuv/rotate.h" // For RotationMode.
#ifdef __cplusplus
namespace libyuv {
extern "C" {
#endif
// Rotate ARGB frame
LIBYUV_API
int ARGBRotate(const uint8_t* src_argb,
int src_stride_argb,
uint8_t* dst_argb,
int dst_stride_argb,
int src_width,
int src_height,
enum RotationMode mode);
#ifdef __cplusplus
} // extern "C"
} // namespace libyuv
#endif
#endif // INCLUDE_LIBYUV_ROTATE_ARGB_H_
/*
* Copyright 2013 The LibYuv Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef INCLUDE_LIBYUV_ROTATE_ROW_H_
#define INCLUDE_LIBYUV_ROTATE_ROW_H_
#include "libyuv/basic_types.h"
#ifdef __cplusplus
namespace libyuv {
extern "C" {
#endif
#if defined(__pnacl__) || defined(__CLR_VER) || \
(defined(__native_client__) && defined(__x86_64__)) || \
(defined(__i386__) && !defined(__SSE__) && !defined(__clang__))
#define LIBYUV_DISABLE_X86
#endif
#if defined(__native_client__)
#define LIBYUV_DISABLE_NEON
#endif
// MemorySanitizer does not support assembly code yet. http://crbug.com/344505
#if defined(__has_feature)
#if __has_feature(memory_sanitizer)
#define LIBYUV_DISABLE_X86
#endif
#endif
// The following are available for Visual C 32 bit:
#if !defined(LIBYUV_DISABLE_X86) && defined(_M_IX86) && defined(_MSC_VER) && \
!defined(__clang__)
#define HAS_TRANSPOSEWX8_SSSE3
#define HAS_TRANSPOSEUVWX8_SSE2
#endif
// The following are available for GCC 32 or 64 bit:
#if !defined(LIBYUV_DISABLE_X86) && (defined(__i386__) || defined(__x86_64__))
#define HAS_TRANSPOSEWX8_SSSE3
#endif
// The following are available for 64 bit GCC:
#if !defined(LIBYUV_DISABLE_X86) && defined(__x86_64__)
#define HAS_TRANSPOSEWX8_FAST_SSSE3
#define HAS_TRANSPOSEUVWX8_SSE2
#endif
#if !defined(LIBYUV_DISABLE_NEON) && \
(defined(__ARM_NEON__) || defined(LIBYUV_NEON) || defined(__aarch64__))
#define HAS_TRANSPOSEWX8_NEON
#define HAS_TRANSPOSEUVWX8_NEON
#endif
#if !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa)
#define HAS_TRANSPOSEWX16_MSA
#define HAS_TRANSPOSEUVWX16_MSA
#endif
#if !defined(LIBYUV_DISABLE_LSX) && defined(__loongarch_sx)
#define HAS_TRANSPOSEWX16_LSX
#define HAS_TRANSPOSEUVWX16_LSX
#endif
void TransposeWxH_C(const uint8_t* src,
int src_stride,
uint8_t* dst,
int dst_stride,
int width,
int height);
void TransposeWx8_C(const uint8_t* src,
int src_stride,
uint8_t* dst,
int dst_stride,
int width);
void TransposeWx16_C(const uint8_t* src,
int src_stride,
uint8_t* dst,
int dst_stride,
int width);
void TransposeWx8_NEON(const uint8_t* src,
int src_stride,
uint8_t* dst,
int dst_stride,
int width);
void TransposeWx8_SSSE3(const uint8_t* src,
int src_stride,
uint8_t* dst,
int dst_stride,
int width);
void TransposeWx8_Fast_SSSE3(const uint8_t* src,
int src_stride,
uint8_t* dst,
int dst_stride,
int width);
void TransposeWx16_MSA(const uint8_t* src,
int src_stride,
uint8_t* dst,
int dst_stride,
int width);
void TransposeWx16_LSX(const uint8_t* src,
int src_stride,
uint8_t* dst,
int dst_stride,
int width);
void TransposeWx8_Any_NEON(const uint8_t* src,
int src_stride,
uint8_t* dst,
int dst_stride,
int width);
void TransposeWx8_Any_SSSE3(const uint8_t* src,
int src_stride,
uint8_t* dst,
int dst_stride,
int width);
void TransposeWx8_Fast_Any_SSSE3(const uint8_t* src,
int src_stride,
uint8_t* dst,
int dst_stride,
int width);
void TransposeWx16_Any_MSA(const uint8_t* src,
int src_stride,
uint8_t* dst,
int dst_stride,
int width);
void TransposeWx16_Any_LSX(const uint8_t* src,
int src_stride,
uint8_t* dst,
int dst_stride,
int width);
void TransposeUVWxH_C(const uint8_t* src,
int src_stride,
uint8_t* dst_a,
int dst_stride_a,
uint8_t* dst_b,
int dst_stride_b,
int width,
int height);
void TransposeUVWx8_C(const uint8_t* src,
int src_stride,
uint8_t* dst_a,
int dst_stride_a,
uint8_t* dst_b,
int dst_stride_b,
int width);
void TransposeUVWx16_C(const uint8_t* src,
int src_stride,
uint8_t* dst_a,
int dst_stride_a,
uint8_t* dst_b,
int dst_stride_b,
int width);
void TransposeUVWx8_SSE2(const uint8_t* src,
int src_stride,
uint8_t* dst_a,
int dst_stride_a,
uint8_t* dst_b,
int dst_stride_b,
int width);
void TransposeUVWx8_NEON(const uint8_t* src,
int src_stride,
uint8_t* dst_a,
int dst_stride_a,
uint8_t* dst_b,
int dst_stride_b,
int width);
void TransposeUVWx16_MSA(const uint8_t* src,
int src_stride,
uint8_t* dst_a,
int dst_stride_a,
uint8_t* dst_b,
int dst_stride_b,
int width);
void TransposeUVWx16_LSX(const uint8_t* src,
int src_stride,
uint8_t* dst_a,
int dst_stride_a,
uint8_t* dst_b,
int dst_stride_b,
int width);
void TransposeUVWx8_Any_SSE2(const uint8_t* src,
int src_stride,
uint8_t* dst_a,
int dst_stride_a,
uint8_t* dst_b,
int dst_stride_b,
int width);
void TransposeUVWx8_Any_NEON(const uint8_t* src,
int src_stride,
uint8_t* dst_a,
int dst_stride_a,
uint8_t* dst_b,
int dst_stride_b,
int width);
void TransposeUVWx16_Any_MSA(const uint8_t* src,
int src_stride,
uint8_t* dst_a,
int dst_stride_a,
uint8_t* dst_b,
int dst_stride_b,
int width);
void TransposeUVWx16_Any_LSX(const uint8_t* src,
int src_stride,
uint8_t* dst_a,
int dst_stride_a,
uint8_t* dst_b,
int dst_stride_b,
int width);
void TransposeWxH_16_C(const uint16_t* src,
int src_stride,
uint16_t* dst,
int dst_stride,
int width,
int height);
void TransposeWx8_16_C(const uint16_t* src,
int src_stride,
uint16_t* dst,
int dst_stride,
int width);
void TransposeWx1_16_C(const uint16_t* src,
int src_stride,
uint16_t* dst,
int dst_stride,
int width);
// Transpose 32 bit values (ARGB)
void Transpose4x4_32_NEON(const uint8_t* src,
int src_stride,
uint8_t* dst,
int dst_stride,
int width);
void Transpose4x4_32_C(const uint8_t* src,
int src_stride,
uint8_t* dst,
int dst_stride,
int width);
// Transpose 32 bit values (ARGB)
void Transpose8x8_32_NEON(const uint8_t* src,
int src_stride,
uint8_t* dst,
int dst_stride,
int width);
#ifdef __cplusplus
} // extern "C"
} // namespace libyuv
#endif
#endif // INCLUDE_LIBYUV_ROTATE_ROW_H_
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
* Copyright 2012 The LibYuv Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef INCLUDE_LIBYUV_SCALE_ARGB_H_
#define INCLUDE_LIBYUV_SCALE_ARGB_H_
#include "libyuv/basic_types.h"
#include "libyuv/scale.h" // For FilterMode
#ifdef __cplusplus
namespace libyuv {
extern "C" {
#endif
LIBYUV_API
int ARGBScale(const uint8_t* src_argb,
int src_stride_argb,
int src_width,
int src_height,
uint8_t* dst_argb,
int dst_stride_argb,
int dst_width,
int dst_height,
enum FilterMode filtering);
// Clipped scale takes destination rectangle coordinates for clip values.
LIBYUV_API
int ARGBScaleClip(const uint8_t* src_argb,
int src_stride_argb,
int src_width,
int src_height,
uint8_t* dst_argb,
int dst_stride_argb,
int dst_width,
int dst_height,
int clip_x,
int clip_y,
int clip_width,
int clip_height,
enum FilterMode filtering);
// Scale with YUV conversion to ARGB and clipping.
LIBYUV_API
int YUVToARGBScaleClip(const uint8_t* src_y,
int src_stride_y,
const uint8_t* src_u,
int src_stride_u,
const uint8_t* src_v,
int src_stride_v,
uint32_t src_fourcc,
int src_width,
int src_height,
uint8_t* dst_argb,
int dst_stride_argb,
uint32_t dst_fourcc,
int dst_width,
int dst_height,
int clip_x,
int clip_y,
int clip_width,
int clip_height,
enum FilterMode filtering);
#ifdef __cplusplus
} // extern "C"
} // namespace libyuv
#endif
#endif // INCLUDE_LIBYUV_SCALE_ARGB_H_
/*
* Copyright 2022 The LibYuv Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef INCLUDE_LIBYUV_SCALE_RGB_H_
#define INCLUDE_LIBYUV_SCALE_RGB_H_
#include "libyuv/basic_types.h"
#include "libyuv/scale.h" // For FilterMode
#ifdef __cplusplus
namespace libyuv {
extern "C" {
#endif
// RGB can be RAW, RGB24 or YUV24
// RGB scales 24 bit images by converting a row at a time to ARGB
// and using ARGB row functions to scale, then convert to RGB.
// TODO(fbarchard): Allow input/output formats to be specified.
LIBYUV_API
int RGBScale(const uint8_t* src_rgb,
int src_stride_rgb,
int src_width,
int src_height,
uint8_t* dst_rgb,
int dst_stride_rgb,
int dst_width,
int dst_height,
enum FilterMode filtering);
#ifdef __cplusplus
} // extern "C"
} // namespace libyuv
#endif
#endif // INCLUDE_LIBYUV_SCALE_UV_H_
/*
* Copyright 2020 The LibYuv Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef INCLUDE_LIBYUV_SCALE_UV_H_
#define INCLUDE_LIBYUV_SCALE_UV_H_
#include "libyuv/basic_types.h"
#include "libyuv/scale.h" // For FilterMode
#ifdef __cplusplus
namespace libyuv {
extern "C" {
#endif
LIBYUV_API
int UVScale(const uint8_t* src_uv,
int src_stride_uv,
int src_width,
int src_height,
uint8_t* dst_uv,
int dst_stride_uv,
int dst_width,
int dst_height,
enum FilterMode filtering);
// Scale a 16 bit UV image.
// This function is currently incomplete, it can't handle all cases.
LIBYUV_API
int UVScale_16(const uint16_t* src_uv,
int src_stride_uv,
int src_width,
int src_height,
uint16_t* dst_uv,
int dst_stride_uv,
int dst_width,
int dst_height,
enum FilterMode filtering);
#ifdef __cplusplus
} // extern "C"
} // namespace libyuv
#endif
#endif // INCLUDE_LIBYUV_SCALE_UV_H_
/*
* Copyright 2012 The LibYuv Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef INCLUDE_LIBYUV_VERSION_H_
#define INCLUDE_LIBYUV_VERSION_H_
#define LIBYUV_VERSION 1860
#endif // INCLUDE_LIBYUV_VERSION_H_
/*
* Copyright 2011 The LibYuv Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// Common definitions for video, including fourcc and VideoFormat.
#ifndef INCLUDE_LIBYUV_VIDEO_COMMON_H_
#define INCLUDE_LIBYUV_VIDEO_COMMON_H_
#include "libyuv/basic_types.h"
#ifdef __cplusplus
namespace libyuv {
extern "C" {
#endif
//////////////////////////////////////////////////////////////////////////////
// Definition of FourCC codes
//////////////////////////////////////////////////////////////////////////////
// Convert four characters to a FourCC code.
// Needs to be a macro otherwise the OS X compiler complains when the kFormat*
// constants are used in a switch.
#ifdef __cplusplus
#define FOURCC(a, b, c, d) \
((static_cast<uint32_t>(a)) | (static_cast<uint32_t>(b) << 8) | \
(static_cast<uint32_t>(c) << 16) | /* NOLINT */ \
(static_cast<uint32_t>(d) << 24)) /* NOLINT */
#else
#define FOURCC(a, b, c, d) \
(((uint32_t)(a)) | ((uint32_t)(b) << 8) | /* NOLINT */ \
((uint32_t)(c) << 16) | ((uint32_t)(d) << 24)) /* NOLINT */
#endif
// Some pages discussing FourCC codes:
// http://www.fourcc.org/yuv.php
// http://v4l2spec.bytesex.org/spec/book1.htm
// http://developer.apple.com/quicktime/icefloe/dispatch020.html
// http://msdn.microsoft.com/library/windows/desktop/dd206750.aspx#nv12
// http://people.xiph.org/~xiphmont/containers/nut/nut4cc.txt
// FourCC codes grouped according to implementation efficiency.
// Primary formats should convert in 1 efficient step.
// Secondary formats are converted in 2 steps.
// Auxilliary formats call primary converters.
enum FourCC {
// 10 Primary YUV formats: 5 planar, 2 biplanar, 2 packed.
FOURCC_I420 = FOURCC('I', '4', '2', '0'),
FOURCC_I422 = FOURCC('I', '4', '2', '2'),
FOURCC_I444 = FOURCC('I', '4', '4', '4'),
FOURCC_I400 = FOURCC('I', '4', '0', '0'),
FOURCC_NV21 = FOURCC('N', 'V', '2', '1'),
FOURCC_NV12 = FOURCC('N', 'V', '1', '2'),
FOURCC_YUY2 = FOURCC('Y', 'U', 'Y', '2'),
FOURCC_UYVY = FOURCC('U', 'Y', 'V', 'Y'),
FOURCC_I010 = FOURCC('I', '0', '1', '0'), // bt.601 10 bit 420
FOURCC_I210 = FOURCC('I', '2', '1', '0'), // bt.601 10 bit 422
// 1 Secondary YUV format: row biplanar. deprecated.
FOURCC_M420 = FOURCC('M', '4', '2', '0'),
// 13 Primary RGB formats: 4 32 bpp, 2 24 bpp, 3 16 bpp, 1 10 bpc 2 64 bpp
FOURCC_ARGB = FOURCC('A', 'R', 'G', 'B'),
FOURCC_BGRA = FOURCC('B', 'G', 'R', 'A'),
FOURCC_ABGR = FOURCC('A', 'B', 'G', 'R'),
FOURCC_AR30 = FOURCC('A', 'R', '3', '0'), // 10 bit per channel. 2101010.
FOURCC_AB30 = FOURCC('A', 'B', '3', '0'), // ABGR version of 10 bit
FOURCC_AR64 = FOURCC('A', 'R', '6', '4'), // 16 bit per channel.
FOURCC_AB64 = FOURCC('A', 'B', '6', '4'), // ABGR version of 16 bit
FOURCC_24BG = FOURCC('2', '4', 'B', 'G'),
FOURCC_RAW = FOURCC('r', 'a', 'w', ' '),
FOURCC_RGBA = FOURCC('R', 'G', 'B', 'A'),
FOURCC_RGBP = FOURCC('R', 'G', 'B', 'P'), // rgb565 LE.
FOURCC_RGBO = FOURCC('R', 'G', 'B', 'O'), // argb1555 LE.
FOURCC_R444 = FOURCC('R', '4', '4', '4'), // argb4444 LE.
// 1 Primary Compressed YUV format.
FOURCC_MJPG = FOURCC('M', 'J', 'P', 'G'),
// 14 Auxiliary YUV variations: 3 with U and V planes are swapped, 1 Alias.
FOURCC_YV12 = FOURCC('Y', 'V', '1', '2'),
FOURCC_YV16 = FOURCC('Y', 'V', '1', '6'),
FOURCC_YV24 = FOURCC('Y', 'V', '2', '4'),
FOURCC_YU12 = FOURCC('Y', 'U', '1', '2'), // Linux version of I420.
FOURCC_J420 =
FOURCC('J', '4', '2', '0'), // jpeg (bt.601 full), unofficial fourcc
FOURCC_J422 =
FOURCC('J', '4', '2', '2'), // jpeg (bt.601 full), unofficial fourcc
FOURCC_J444 =
FOURCC('J', '4', '4', '4'), // jpeg (bt.601 full), unofficial fourcc
FOURCC_J400 =
FOURCC('J', '4', '0', '0'), // jpeg (bt.601 full), unofficial fourcc
FOURCC_F420 = FOURCC('F', '4', '2', '0'), // bt.709 full, unofficial fourcc
FOURCC_F422 = FOURCC('F', '4', '2', '2'), // bt.709 full, unofficial fourcc
FOURCC_F444 = FOURCC('F', '4', '4', '4'), // bt.709 full, unofficial fourcc
FOURCC_H420 = FOURCC('H', '4', '2', '0'), // bt.709, unofficial fourcc
FOURCC_H422 = FOURCC('H', '4', '2', '2'), // bt.709, unofficial fourcc
FOURCC_H444 = FOURCC('H', '4', '4', '4'), // bt.709, unofficial fourcc
FOURCC_U420 = FOURCC('U', '4', '2', '0'), // bt.2020, unofficial fourcc
FOURCC_U422 = FOURCC('U', '4', '2', '2'), // bt.2020, unofficial fourcc
FOURCC_U444 = FOURCC('U', '4', '4', '4'), // bt.2020, unofficial fourcc
FOURCC_F010 = FOURCC('F', '0', '1', '0'), // bt.709 full range 10 bit 420
FOURCC_H010 = FOURCC('H', '0', '1', '0'), // bt.709 10 bit 420
FOURCC_U010 = FOURCC('U', '0', '1', '0'), // bt.2020 10 bit 420
FOURCC_F210 = FOURCC('F', '2', '1', '0'), // bt.709 full range 10 bit 422
FOURCC_H210 = FOURCC('H', '2', '1', '0'), // bt.709 10 bit 422
FOURCC_U210 = FOURCC('U', '2', '1', '0'), // bt.2020 10 bit 422
FOURCC_P010 = FOURCC('P', '0', '1', '0'),
FOURCC_P210 = FOURCC('P', '2', '1', '0'),
// 14 Auxiliary aliases. CanonicalFourCC() maps these to canonical fourcc.
FOURCC_IYUV = FOURCC('I', 'Y', 'U', 'V'), // Alias for I420.
FOURCC_YU16 = FOURCC('Y', 'U', '1', '6'), // Alias for I422.
FOURCC_YU24 = FOURCC('Y', 'U', '2', '4'), // Alias for I444.
FOURCC_YUYV = FOURCC('Y', 'U', 'Y', 'V'), // Alias for YUY2.
FOURCC_YUVS = FOURCC('y', 'u', 'v', 's'), // Alias for YUY2 on Mac.
FOURCC_HDYC = FOURCC('H', 'D', 'Y', 'C'), // Alias for UYVY.
FOURCC_2VUY = FOURCC('2', 'v', 'u', 'y'), // Alias for UYVY on Mac.
FOURCC_JPEG = FOURCC('J', 'P', 'E', 'G'), // Alias for MJPG.
FOURCC_DMB1 = FOURCC('d', 'm', 'b', '1'), // Alias for MJPG on Mac.
FOURCC_BA81 = FOURCC('B', 'A', '8', '1'), // Alias for BGGR.
FOURCC_RGB3 = FOURCC('R', 'G', 'B', '3'), // Alias for RAW.
FOURCC_BGR3 = FOURCC('B', 'G', 'R', '3'), // Alias for 24BG.
FOURCC_CM32 = FOURCC(0, 0, 0, 32), // Alias for BGRA kCMPixelFormat_32ARGB
FOURCC_CM24 = FOURCC(0, 0, 0, 24), // Alias for RAW kCMPixelFormat_24RGB
FOURCC_L555 = FOURCC('L', '5', '5', '5'), // Alias for RGBO.
FOURCC_L565 = FOURCC('L', '5', '6', '5'), // Alias for RGBP.
FOURCC_5551 = FOURCC('5', '5', '5', '1'), // Alias for RGBO.
// deprecated formats. Not supported, but defined for backward compatibility.
FOURCC_I411 = FOURCC('I', '4', '1', '1'),
FOURCC_Q420 = FOURCC('Q', '4', '2', '0'),
FOURCC_RGGB = FOURCC('R', 'G', 'G', 'B'),
FOURCC_BGGR = FOURCC('B', 'G', 'G', 'R'),
FOURCC_GRBG = FOURCC('G', 'R', 'B', 'G'),
FOURCC_GBRG = FOURCC('G', 'B', 'R', 'G'),
FOURCC_H264 = FOURCC('H', '2', '6', '4'),
// Match any fourcc.
FOURCC_ANY = -1,
};
enum FourCCBpp {
// Canonical fourcc codes used in our code.
FOURCC_BPP_I420 = 12,
FOURCC_BPP_I422 = 16,
FOURCC_BPP_I444 = 24,
FOURCC_BPP_I411 = 12,
FOURCC_BPP_I400 = 8,
FOURCC_BPP_NV21 = 12,
FOURCC_BPP_NV12 = 12,
FOURCC_BPP_YUY2 = 16,
FOURCC_BPP_UYVY = 16,
FOURCC_BPP_M420 = 12, // deprecated
FOURCC_BPP_Q420 = 12,
FOURCC_BPP_ARGB = 32,
FOURCC_BPP_BGRA = 32,
FOURCC_BPP_ABGR = 32,
FOURCC_BPP_RGBA = 32,
FOURCC_BPP_AR30 = 32,
FOURCC_BPP_AB30 = 32,
FOURCC_BPP_AR64 = 64,
FOURCC_BPP_AB64 = 64,
FOURCC_BPP_24BG = 24,
FOURCC_BPP_RAW = 24,
FOURCC_BPP_RGBP = 16,
FOURCC_BPP_RGBO = 16,
FOURCC_BPP_R444 = 16,
FOURCC_BPP_RGGB = 8,
FOURCC_BPP_BGGR = 8,
FOURCC_BPP_GRBG = 8,
FOURCC_BPP_GBRG = 8,
FOURCC_BPP_YV12 = 12,
FOURCC_BPP_YV16 = 16,
FOURCC_BPP_YV24 = 24,
FOURCC_BPP_YU12 = 12,
FOURCC_BPP_J420 = 12,
FOURCC_BPP_J400 = 8,
FOURCC_BPP_H420 = 12,
FOURCC_BPP_H422 = 16,
FOURCC_BPP_I010 = 15,
FOURCC_BPP_I210 = 20,
FOURCC_BPP_H010 = 15,
FOURCC_BPP_H210 = 20,
FOURCC_BPP_P010 = 15,
FOURCC_BPP_P210 = 20,
FOURCC_BPP_MJPG = 0, // 0 means unknown.
FOURCC_BPP_H264 = 0,
FOURCC_BPP_IYUV = 12,
FOURCC_BPP_YU16 = 16,
FOURCC_BPP_YU24 = 24,
FOURCC_BPP_YUYV = 16,
FOURCC_BPP_YUVS = 16,
FOURCC_BPP_HDYC = 16,
FOURCC_BPP_2VUY = 16,
FOURCC_BPP_JPEG = 1,
FOURCC_BPP_DMB1 = 1,
FOURCC_BPP_BA81 = 8,
FOURCC_BPP_RGB3 = 24,
FOURCC_BPP_BGR3 = 24,
FOURCC_BPP_CM32 = 32,
FOURCC_BPP_CM24 = 24,
// Match any fourcc.
FOURCC_BPP_ANY = 0, // 0 means unknown.
};
// Converts fourcc aliases into canonical ones.
LIBYUV_API uint32_t CanonicalFourCC(uint32_t fourcc);
#ifdef __cplusplus
} // extern "C"
} // namespace libyuv
#endif
#endif // INCLUDE_LIBYUV_VIDEO_COMMON_H_
......@@ -62,6 +62,7 @@ public:
void SetSendSdiParams(SendSdiParams params);
void ClearFrontQueue();
void AddPicFrame(std::shared_ptr<VideoFrameWithMask> frame);
void GetInOutVideoParams(BmdVideoParams& input_params,BmdVideoParams& output_params);
public slots:
void AddAudioFrame(std::shared_ptr<AudioPacket> audio_packet);
void AddFrame(std::shared_ptr<Image> image);
......@@ -134,6 +135,8 @@ private:
qint32 queue_max_size;
BMDDisplayMode outputDisplayMode;
BMDDisplayMode getOutputDisplayMode() { return outputDisplayMode; }
int m_fps;
uint64_t m_lastRecvTS;
......@@ -162,4 +165,8 @@ private:
qint64 last_start_tm{0};
SafeMap<qint64, std::shared_ptr<VideoFrameWithMask>> output_video_frame_map;
BmdVideoParams output_params;
BmdVideoParams input_params;
};
......@@ -8,8 +8,11 @@
#include "ZoomThread.h"
#include "Utils/Algorithm.h"
#include "CropThread.h"
#include "VideoScaleThread.h"
class ProcessMaskThread : public QThread, public CropThread::Listener
class ProcessMaskThread : public QThread,
public CropThread::Listener,
public VideoScaleThread::Listener
{
Q_OBJECT
public:
......@@ -22,12 +25,14 @@ public slots:
signals:
void PushFrame(std::shared_ptr<VideoFrameWithMask> image);
void PushFrameToReplay(std::shared_ptr<VideoFrameWithMask> image);
void PushScaleFrameToReplay(std::shared_ptr<VideoFrameWithMask> image);
public:
void ClearQueue();
void SetRecordStore(RecordStore* store) { p_store = store; }
void SetZoomThread(std::shared_ptr<ZoomThread> thread) { zoom_thread = thread; }
void StartRecord(const uint64_t& start_time, const uint64_t& end_time);
CropThread* GetCropThread();
void SetBmdInOutVideoParams(const BmdVideoParams& input, const BmdVideoParams& output);
protected:
enum MaskStatus
......@@ -38,6 +43,7 @@ protected:
};
private:
void OnRecvViedoFrame(std::shared_ptr<VideoFrameWithMask>) override;
void OnRecvScaleViedoFrame(std::shared_ptr<VideoFrameWithMask>) override;
void OnChange() override;
void run() override;
void process();
......@@ -80,6 +86,7 @@ private:
std::shared_ptr<ZoomThread> zoom_thread{nullptr};
std::shared_ptr<CropThread> crop_thread{ nullptr };
std::shared_ptr<VideoScaleThread> scale_thread{ nullptr };
Rect mask_rect{0,0,0,0};
int m_fps{0};
......@@ -100,4 +107,11 @@ private:
CropMessage crop_msg;
qint32 dynamic_out_num {0};
bool dynamic_flag{false};
std::atomic_bool replay_flag_clear { false };
BMDDisplayMode output_display_mode;
BmdVideoParams output_params;
BmdVideoParams input_params;
std::atomic_bool scale_flag{ false };
};
\ No newline at end of file
......@@ -6,8 +6,9 @@
#include <queue>
#include "Utils/SafeMap.h"
#include "CropThread.h"
#include "VideoScaleThread.h"
class ReplayThread : public QThread,public CropThread::Listener
class ReplayThread : public QThread,public CropThread::Listener, public VideoScaleThread::Listener
{
Q_OBJECT
public:
......@@ -16,6 +17,7 @@ public:
public slots:
void addFrame(std::shared_ptr<videoFrameData> frameData);
void addCropFrame(std::shared_ptr<VideoFrameWithMask> frame);
void addScaleFrame(std::shared_ptr<VideoFrameWithMask> frame);
signals:
//void PushFrame(std::shared_ptr<Image> image);
void PushFrame(std::shared_ptr<videoFrameData> frameData);
......@@ -24,10 +26,12 @@ public:
bool CanReplay(const ReplayParams& params);
void recvReplayParams(const ReplayParams& params);
CropThread* GetCropThread();
void SetBmdInOutVideoParams(const BmdVideoParams& input, const BmdVideoParams& output);
protected:
void run() override;
private:
void OnRecvViedoFrame(std::shared_ptr<VideoFrameWithMask> crop_frame) override;
void OnRecvScaleViedoFrame(std::shared_ptr<VideoFrameWithMask> scale_frame) override;
void OnChange() override;
void SendFrameFunc();
......@@ -45,6 +49,7 @@ private:
/*std::queue<std::shared_ptr<videoFrameData>> replayVideoQueue1;
std::queue<std::shared_ptr<videoFrameData>> replayVideoQueue2;*/
uint32_t max_store_size;
uint32_t max_store_scale_size;
uint32_t max_store_crop_size;
uint32_t max_store_back_size;
std::atomic_bool replay_flag{ false };
......@@ -57,7 +62,16 @@ private:
bool send_err_flag {false};
std::shared_ptr<CropThread> crop_thread{ nullptr };
std::shared_ptr<VideoScaleThread> scale_thread{ nullptr };
SafeMap<qint64, std::shared_ptr<VideoFrameWithMask>> storeCropMap;
SafeMap<qint64, std::shared_ptr<VideoFrameWithMask>> storeScaleMap;
SampleQueue<std::shared_ptr<videoFrameData>> needCropQueue;
std::thread send_frame_thread;
BMDDisplayMode output_display_mode;
BmdVideoParams output_params;
BmdVideoParams input_params;
std::atomic_bool scale_flag{ false };
};
\ No newline at end of file
#pragma once
#include <QThread>
#include "Utils/SampleQueue.h"
class VideoScaleThread : public QThread
{
Q_OBJECT
public:
class Listener
{
public:
virtual void OnRecvScaleViedoFrame(std::shared_ptr<VideoFrameWithMask>) = 0;
};
public:
VideoScaleThread(Listener* listener);
~VideoScaleThread();
public:
void addVideoFrame(std::shared_ptr<VideoFrameWithMask> frame);
void addScaleMsg(const ScaleMsg& msg);
protected:
void run() override;
private:
void scale();
private:
SampleQueue<std::shared_ptr<VideoFrameWithMask>> video_queue;
SampleQueue<ScaleMsg> scale_msg_queue;
Listener* p_listener{NULL};
uint8_t* uyvy_to_i422{ NULL };
uint8_t* i422_scale{NULL};
qint32 i422_width{K4WIDTH};
qint32 i422_height{K4HEIGHT};
ScaleMsg scale_msg;
};
\ No newline at end of file
......@@ -30,6 +30,12 @@
#define K4WIDTH 3840
#define K4HEIGHT 2160
#define HDWIDHT 1920
#define HDHEIGHT 1080
#define FRAME50P 50
#define FRAME50I 25
#define FRAME60P 60
enum ReplayStatus
{
......@@ -75,6 +81,14 @@ enum CropDirection
CD_RIGHT_LOW,
};
enum OutputFormat
{
OF_SAME_INPUT = 0,
OF_1080_50I,
OF_1080_50P,
OF_2160_50P
};
long GetRowBytesFromPixelFormat(long width, BMDPixelFormat pixelFormat);
static QString GetCurrDateTimeStr()
......@@ -105,6 +119,73 @@ struct SendSdiParams
qint64 start_time;
};
struct BmdVideoParams
{
qint32 width{0};
qint32 height{0};
qint32 frame{0};
};
//void OutputFmtToOutParams(BMDDisplayMode mode, OutputParams& params)
//{
// switch (mode)
// {
// case bmdModeHD1080p50:
// params.width = HDWIDHT;
// params.height = HDHEIGHT;
// params.frame = FRAME50P;
// break;
// case bmdModeHD1080i50:
// params.width = HDWIDHT;
// params.height = HDHEIGHT;
// params.frame = FRAME50I;
// break;
// case bmdMode4K2160p50:
// params.width = K4WIDTH;
// params.height = K4HEIGHT;
// params.frame = FRAME50P;
// break;
// case bmdMode4K2160p5994:
// case bmdMode4K2160p60:
// params.width = K4WIDTH;
// params.height = K4HEIGHT;
// params.frame = FRAME60P;
// break;
// default:
// break;
// }
//}
static void BmdDisplayModeToBmdVideoParams(BMDDisplayMode mode, BmdVideoParams& params)
{
switch (mode)
{
case bmdModeHD1080p50:
params.width = HDWIDHT;
params.height = HDHEIGHT;
params.frame = FRAME50P;
break;
case bmdModeHD1080i50:
params.width = HDWIDHT;
params.height = HDHEIGHT;
params.frame = FRAME50I;
break;
case bmdMode4K2160p50:
params.width = K4WIDTH;
params.height = K4HEIGHT;
params.frame = FRAME50P;
break;
case bmdMode4K2160p5994:
case bmdMode4K2160p60:
params.width = K4WIDTH;
params.height = K4HEIGHT;
params.frame = FRAME60P;
break;
default:
break;
}
}
struct HDRMetadata {
INT64 EOTF;
......@@ -125,6 +206,12 @@ struct HDRMetadata {
enum class EOTF { SDR = 0, HDR = 1, PQ = 2, HLG = 3 };
struct ScaleMsg
{
int32_t scale_width{0};
int32_t scale_height{0};
};
class CropMessage
{
public:
......
......@@ -70,6 +70,7 @@ public:
static CropMessage CropMsg;
/*static uint8_t* PicData;
static std::atomic_bool PicFlag;*/
};
......
......@@ -16,6 +16,50 @@ protected:
size_t h;
};
public:
static void UYVYToARGB4KWithMatrix(uint8_t* src, const size_t& src_step, uint8_t* dst, const size_t& dst_step, const uint32_t& width, const uint32_t& height,const BMDColorspace& space)
{
uint8_t* src1 = src;
uint8_t* src2 = src1 + src_step;
uint8_t* src3 = src2 + src_step;
uint8_t* src4 = src3 + src_step;
uint8_t* dst1 = dst;
uint8_t* dst2 = dst1 + dst_step;
uint8_t* dst3 = dst2 + dst_step;
uint8_t* dst4 = dst3 + dst_step;
{
switch (space)
{
case bmdColorspaceRec601:
libyuv::UYVYToARGBMatrix(src1, width << 1, dst1, width << 2, &libyuv::kYuvI601Constants, width, height);
libyuv::UYVYToARGBMatrix(src1, width << 1, dst1, width << 2, &libyuv::kYuvI601Constants, width, height);
libyuv::UYVYToARGBMatrix(src1, width << 1, dst1, width << 2, &libyuv::kYuvI601Constants, width, height);
libyuv::UYVYToARGBMatrix(src1, width << 1, dst1, width << 2, &libyuv::kYuvI601Constants, width, height);
break;
case bmdColorspaceRec709:
libyuv::UYVYToARGBMatrix(src1, width << 1, dst1, width << 2, &libyuv::kYuvH709Constants, width, height);
libyuv::UYVYToARGBMatrix(src1, width << 1, dst1, width << 2, &libyuv::kYuvH709Constants, width, height);
libyuv::UYVYToARGBMatrix(src1, width << 1, dst1, width << 2, &libyuv::kYuvH709Constants, width, height);
libyuv::UYVYToARGBMatrix(src1, width << 1, dst1, width << 2, &libyuv::kYuvH709Constants, width, height);
break;
case bmdColorspaceRec2020:
libyuv::UYVYToARGBMatrix(src1, width << 1, dst1, width << 2, &libyuv::kYuv2020Constants, width, height);
libyuv::UYVYToARGBMatrix(src1, width << 1, dst1, width << 2, &libyuv::kYuv2020Constants, width, height);
libyuv::UYVYToARGBMatrix(src1, width << 1, dst1, width << 2, &libyuv::kYuv2020Constants, width, height);
libyuv::UYVYToARGBMatrix(src1, width << 1, dst1, width << 2, &libyuv::kYuv2020Constants, width, height);
break;
default:
break;
}
/*libyuv::UYVYToARGB(src1, width << 1, dst1, width << 2, width, height);
libyuv::UYVYToARGB(src2, width << 1, dst2, width << 2, width, height);
libyuv::UYVYToARGB(src3, width << 1, dst3, width << 2, width, height);
libyuv::UYVYToARGB(src4, width << 1, dst4, width << 2, width, height);*/
}
}
static void UYVYToARGB4K(uint8_t* src,const size_t& src_step,uint8_t* dst,const size_t& dst_step,const uint32_t& width,const uint32_t& height)
{
uint8_t* src1 = src;
......@@ -159,6 +203,104 @@ public:
}
static void I422Scale(uint8_t* src, const size_t& src_w, const size_t& src_h, uint8_t* dst, const size_t& dst_w, const size_t& dst_h, const int32_t& omp, int32_t filter = 2)
{
size_t half_src_w = (src_w >> 1);
size_t half_src_h = (src_h >> 1);
size_t half_dst_w = (dst_w >> 1);
size_t half_dst_h = (dst_h >> 1);
uint32_t src_y_size = src_w * src_h;
uint32_t src_u_size = (src_w * src_h >> 1);
size_t src_mode_h = src_h % 2;
size_t src_mode_w = src_w % 2;
uint8_t* src_y = src;
uint8_t* src_u = src_y + src_y_size;
uint8_t* src_v = src_u + src_u_size;
uint8_t* src_y_1 = src_y;
uint8_t* src_y_2 = src_y + half_src_w;
uint8_t* src_y_3 = src_y + src_w * half_src_h;
uint8_t* src_y_4 = src_y + src_w * half_src_h + half_src_w;
uint8_t* src_u_1 = src_u;
uint8_t* src_u_2 = src_u + (half_src_w >> 1);
uint8_t* src_u_3 = src_u + (src_w * half_src_h >> 1);
uint8_t* src_u_4 = src_u + (src_w * half_src_h >> 1) + (half_src_w >> 1);
uint8_t* src_v_1 = src_v;
uint8_t* src_v_2 = src_v + (half_src_w >> 1);
uint8_t* src_v_3 = src_v + (src_w * half_src_h >> 1);
uint8_t* src_v_4 = src_v + (half_src_w >> 1) + (src_w * half_src_h >> 1);
uint32_t dst_y_size = dst_w * dst_h;
uint32_t dst_u_size = (dst_w * dst_h >> 1);
uint8_t* dst_y = dst;
uint8_t* dst_u = dst_y + dst_y_size;
uint8_t* dst_v = dst_u + dst_u_size;
uint8_t* dst_y_1 = dst_y;
uint8_t* dst_y_2 = dst_y + half_dst_w;
uint8_t* dst_y_3 = dst_y + dst_w * half_dst_h;
uint8_t* dst_y_4 = dst_y + dst_w * half_dst_h + half_dst_w;
uint8_t* dst_u_1 = dst_u;
uint8_t* dst_u_2 = dst_u + (half_dst_w >> 1);
uint8_t* dst_u_3 = dst_u + (dst_w * half_dst_h >> 1);
uint8_t* dst_u_4 = dst_u + (dst_w * half_dst_h >> 1) + (half_dst_w >> 1);
uint8_t* dst_v_1 = dst_v;
uint8_t* dst_v_2 = dst_v + (half_dst_w >> 1);
uint8_t* dst_v_3 = dst_v + (dst_w * half_dst_h >> 1);
uint8_t* dst_v_4 = dst_v + (half_dst_w >> 1) + (dst_w * half_dst_h >> 1);
std::vector<WH> src_wh_vec = { { half_src_w, half_src_h },{half_src_w + src_mode_w,half_src_h},{half_src_w,half_src_h + src_mode_h},{half_src_w + src_mode_w,half_src_h + src_mode_h} };
if (omp)
{
uint8_t* src_data[4][3] = { {src_y_1,src_u_1,src_v_1},{src_y_2,src_u_2,src_v_2},{src_y_3,src_u_3,src_v_3},{src_y_4,src_u_4,src_v_4} };
uint8_t* dst_data[4][3] = { {dst_y_1,dst_u_1,dst_v_1},{dst_y_2,dst_u_2,dst_v_2},{dst_y_3,dst_u_3,dst_v_3},{dst_y_4,dst_u_4,dst_v_4} };
int thread_num = 4;
omp_set_num_threads(thread_num);
#pragma omp parallel
{
#pragma omp for
for (int i = 0; i < thread_num; i++)
{
uint8_t* src_y = src_data[i][0];
uint8_t* src_u = src_data[i][1];
uint8_t* src_v = src_data[i][2];
uint8_t* dst_y = dst_data[i][0];
uint8_t* dst_u = dst_data[i][1];
uint8_t* dst_v = dst_data[i][2];
libyuv::I422Scale(src_y, src_w, src_u, src_w >> 1, src_v, src_w >> 1, src_wh_vec[i].w, src_wh_vec[i].h,
dst_y, dst_w, dst_u, dst_w >> 1, dst_v, dst_w >> 1, half_dst_w, half_dst_h, (libyuv::FilterMode)filter);
}
}
}
else
{
{
libyuv::I422Scale(src_y_1, src_w, src_u_1, src_w >> 1, src_v_1, src_w >> 1, src_wh_vec[0].w, src_wh_vec[0].h,
dst_y_1, dst_w, dst_u_1, dst_w >> 1, dst_v_1, dst_w >> 1, half_dst_w, half_dst_h, (libyuv::FilterMode)filter);
libyuv::I422Scale(src_y_2, src_w, src_u_2, src_w >> 1, src_v_2, src_w >> 1, src_wh_vec[1].w, src_wh_vec[1].h,
dst_y_2, dst_w, dst_u_2, dst_w >> 1, dst_v_2, dst_w >> 1, half_dst_w, half_dst_h, (libyuv::FilterMode)filter);
libyuv::I422Scale(src_y_3, src_w, src_u_3, src_w >> 1, src_v_3, src_w >> 1, src_wh_vec[2].w, src_wh_vec[2].h,
dst_y_3, dst_w, dst_u_3, dst_w >> 1, dst_v_3, dst_w >> 1, half_dst_w, half_dst_h, (libyuv::FilterMode)filter);
libyuv::I422Scale(src_y_4, src_w, src_u_4, src_w >> 1, src_v_4, src_w >> 1, src_wh_vec[3].w, src_wh_vec[3].h,
dst_y_4, dst_w, dst_u_4, dst_w >> 1, dst_v_4, dst_w >> 1, half_dst_w, half_dst_h, (libyuv::FilterMode)filter);
}
}
}
static void I422Scale4K(uint8_t* src, const size_t& src_w, const size_t& src_h, uint8_t* dst, const size_t& dst_w, const size_t& dst_h, const int32_t& omp, int32_t filter = 2)
{
size_t half_src_w = (src_w >> 1);
......
......@@ -217,11 +217,12 @@ HRESULT DeckLinkInputDevice::VideoInputFormatChanged(BMDVideoInputFormatChangedE
else
// Invalid color depth for YUV
return E_INVALIDARG;
pixelFormat = bmdFormat8BitYUV;
}
else
// Unexpected detected video input format flags
return E_INVALIDARG;
// Restart streams if either display mode or colorspace has changed
if (notificationEvents & (bmdVideoInputDisplayModeChanged | bmdVideoInputColorspaceChanged))
{
......@@ -230,7 +231,7 @@ HRESULT DeckLinkInputDevice::VideoInputFormatChanged(BMDVideoInputFormatChangedE
// Set the video input mode
//pixelFormat = bmdFormat8BitYUV;
result = DeckLinkInput->EnableVideoInput(displayMode, pixelFormat, bmdVideoInputEnableFormatDetection);
result = DeckLinkInput->EnableVideoInput(displayMode, pixelFormat, bmdVideoInputFlagDefault);
if (result == S_OK)
// Start the capture
......@@ -297,7 +298,7 @@ bool DeckLinkInputDevice::StartCapture(BMDDisplayMode displayMode, IDeckLinkScre
DeckLinkInput->SetCallback(this);
// Set the video input mode
if (DeckLinkInput->EnableVideoInput(bmdMode4K2160p50, bmdFormat8BitYUV, bmdVideoInputFlagDefault) != S_OK)
if (DeckLinkInput->EnableVideoInput(displayMode, bmdFormat8BitYUV, videoInputFlags) != S_OK)
return false;
if (DeckLinkInput->EnableAudioInput(bmdAudioSampleRate48kHz, bmdAudioSampleType32bitInteger, Settings::AudioChannel) != S_OK)
......
......@@ -158,7 +158,7 @@ void DeckLinkInputPage::StartCapture()
if (!SelectedDevice)
return;
BMDDisplayMode displayMode = bmdModeUnknown;
BMDDisplayMode displayMode = bmdModeNTSC;
bool applyDetectedInputMode = AutoDetectCheckBox->isChecked();
displayMode = (BMDDisplayMode)VideoFormatCombo->currentData().value<unsigned int>();
......
......@@ -18,7 +18,7 @@
//extern int SdiOutWaitNums;
//extern std::map<qint32, qint32> map_output_delay;
#define OUTPUT_1080 1
//#define OUTPUT_1080 1
#define AUDIOMAXSIZE (OutputDeleyTime + 3) * 50
#define TESTWRITEFILE 0
#define USETHREADS 1
......@@ -148,25 +148,38 @@ HRESULT DeckLinkOutputDevice::ScheduledPlaybackHasStopped()
return S_OK;
}
void DeckLinkOutputDevice::GetInOutVideoParams(BmdVideoParams& input_params, BmdVideoParams& output_params)
{
input_params = this->input_params;
output_params = this->output_params;
}
bool DeckLinkOutputDevice::StartPlayback(BMDDisplayMode displayMode, bool enable3D, BMDPixelFormat pixelFormat, bool requireReferenceLocked, IDeckLinkScreenPreviewCallback* screenPreviewCallback)
{
BMDDisplayMode outputDisplayMode;
//BMDDisplayMode outputDisplayMode;
#if OUTPUT_1080
switch (Settings::OutputPlayMode)
{
case 1:
case OF_SAME_INPUT:
outputDisplayMode = displayMode;
break;
case OF_1080_50I:
outputDisplayMode = bmdModeHD1080i50;
break;
case OF_1080_50P:
outputDisplayMode = bmdModeHD1080p50;
break;
case OF_2160_50P:
outputDisplayMode = bmdMode4K2160p50;
break;
default:
//outputDisplayMode = bmdModeHD1080p25;
outputDisplayMode = displayMode;
break;
}
#else
outputDisplayMode = BMDDisplayMode::bmdModeHD720p50;
#endif
BmdDisplayModeToBmdVideoParams(outputDisplayMode, output_params);
BmdDisplayModeToBmdVideoParams(displayMode, input_params);
// Pass through RP188 timecode and VANC from input frame. VITC timecode is forwarded with VANC
BMDVideoOutputFlags outputFlags = (BMDVideoOutputFlags)(bmdVideoOutputRP188 | bmdVideoOutputVANC);
......@@ -188,10 +201,10 @@ bool DeckLinkOutputDevice::StartPlayback(BMDDisplayMode displayMode, bool enable
return false;
}
if (outputDisplayMode == bmdModeHD1080i50)
/*if (outputDisplayMode == bmdModeHD1080i50)
qDebug() << "output display HD1080i50";
else if (outputDisplayMode == bmdModeHD1080p25)
qDebug() << "output display HD1080p25";
qDebug() << "output display HD1080p25";*/
if (deckLinkOutput->GetDisplayMode(outputDisplayMode, deckLinkDisplayMode.ReleaseAndGetAddressOf()) != S_OK)
{
......
......@@ -309,6 +309,7 @@ void DeckLinkOutputPage::RequestedDeviceGranted(ComPtr<IDeckLink>& device)
//connect(this, &DeckLinkOutputPage::PushMask, ProcessMask.get(), &ProcessMaskThread::addMaskBuffer, Qt::DirectConnection);
connect(ProcessMask.get(), &ProcessMaskThread::PushFrame, SelectedDevice.Get(), &DeckLinkOutputDevice::AddVideoFrameMask, Qt::DirectConnection);
connect(ProcessMask.get(), &ProcessMaskThread::PushFrameToReplay, BindingInputPage->GetReplay(), &ReplayThread::addCropFrame, Qt::DirectConnection);
connect(ProcessMask.get(), &ProcessMaskThread::PushScaleFrameToReplay, BindingInputPage->GetReplay(), &ReplayThread::addScaleFrame, Qt::DirectConnection);
if (Zoom)
{
......@@ -352,11 +353,11 @@ void DeckLinkOutputPage::RequestedDeviceGranted(ComPtr<IDeckLink>& device)
NDIOutput->start();
}
StartOutput();
#if USE_TIMEPLUS
SelectedDevice->StartPlayback(bmdMode4K2160p50, false, bmdFormat8BitYUV, false, PreviewView->GetDelegate());
#elif USE_H2V
SelectedDevice->StartPlayback(bmdModeHD1080p50, false, bmdFormat10BitYUV, false, PreviewView->GetDelegate());
#endif // USE_TIMEPLUS
//#if USE_TIMEPLUS
// SelectedDevice->StartPlayback(bmdMode4K2160p50, false, bmdFormat8BitYUV, false, PreviewView->GetDelegate());
//#elif USE_H2V
// SelectedDevice->StartPlayback(bmdModeHD1080p50, false, bmdFormat10BitYUV, false, PreviewView->GetDelegate());
//#endif // USE_TIMEPLUS
......@@ -488,10 +489,16 @@ void DeckLinkOutputPage::FormatChanged(BMDDisplayMode displayMode)
if (firstFmtChanged) firstFmtChanged = false;
DisplayMode = displayMode;
//BMDPixelFormat pixelFormat = bmdFormat10BitYUV;
PixelFormat = bmdFormat10BitYUV;
PixelFormat = bmdFormat8BitYUV;
SelectedDevice->StartPlayback(DisplayMode, false, PixelFormat, false, PreviewView->GetDelegate());
BmdVideoParams input_params, output_params;
SelectedDevice->GetInOutVideoParams(input_params, output_params);
if (ProcessMask) ProcessMask->SetBmdInOutVideoParams(input_params,output_params);
if (BindingInputPage->GetReplay()) BindingInputPage->GetReplay()->SetBmdInOutVideoParams(input_params, output_params);
int indexToSelect = DeviceListCombo->findData(QVariant::fromValue((void*)SelectedDevice->GetDeckLinkInstance().Get()));
bool active = SelectedDevice->isPlaybackActive();
QToolBox* toolBox = findParent<QToolBox>(this);
......
......@@ -24,16 +24,17 @@ void COpenFile::doOpenFile()
qDebug() << "read pic fail........." << "\n";
return;
}
if (bk_mat.cols != K4WIDTH || bk_mat.rows != K4HEIGHT) return;
//if (bk_mat.cols != K4WIDTH || bk_mat.rows != K4HEIGHT) return;
qint32 w = bk_mat.cols, h = bk_mat.rows;
//cv::cvtColor(bk_mat, bk_mat, cv::COLOR_RGB2RGBA);
emit tellFilePath(path);
qint32 size = K4WIDTH * K4HEIGHT << 1;
uint8_t* data = new uint8_t[K4WIDTH * K4HEIGHT << 1];
qint32 size = w * h << 1;
uint8_t* data = new uint8_t[w * h << 1];
cv::cvtColor(bk_mat, bk_mat, cv::COLOR_BGR2BGRA);
Yuv4k::ARGBToUYVY4K(bk_mat.data, K4WIDTH * K4HEIGHT, data, K4WIDTH * K4HEIGHT >> 1, K4WIDTH >> 1, K4HEIGHT >> 1);
std::shared_ptr<VideoFrameWithMask> frame = std::make_shared<VideoFrameWithMask>(K4WIDTH,K4HEIGHT, data,bmdFormat8BitYUV, BS_IDEL, kDefaultHLGBT2020HDRMetadata);
Yuv4k::ARGBToUYVY4K(bk_mat.data, w * h, data, w * h >> 1, w >> 1, h >> 1);
std::shared_ptr<VideoFrameWithMask> frame = std::make_shared<VideoFrameWithMask>(w,h, data,bmdFormat8BitYUV, BS_IDEL, kDefaultHLGBT2020HDRMetadata);
emit SendPicData(frame);
}
}
\ No newline at end of file
......@@ -219,6 +219,16 @@ void NDIOutputThread::run()
//if (!frame_mask ||(frame_mask->mask_flag && !frame_mask->data_)) continue;
VideoMaskQueue.Pop(frame_mask);
if (!frame_mask || (!frame_mask->data_ && !frame_mask->pImage && !frame_mask->pImage->data)) continue;
if (frame_mask->flag_ == BS_START)
{
if (send_one_frame_flag)
{
send_one_frame_flag = false;
send_count = 0;
end_blend_frame_ = nullptr;
}
}
if (Settings::NdiOneFrameDuration > 0 && frame_mask->flag_ == BS_END)
{
......@@ -252,6 +262,9 @@ void NDIOutputThread::run()
if (frame_mask->data_) Frame.p_data = frame_mask->data_;
else Frame.p_data = frame_mask->pImage->uyvy_data;
}
Frame.xres = frame_mask->width_;
Frame.yres = frame_mask->height_;
Frame.line_stride_in_bytes = Frame.xres * 2;
Frame.timestamp = frame_mask->timestamp_;
Frame.timecode = frame_mask->timestamp_ * 1000;
NDIlib_send_send_video_v2(Instance, &Frame);
......
......@@ -5,11 +5,18 @@
#include "Utils/Memory4k.h"
#include <omp.h>
#include "Utils/Settings.h"
#include "libyuv/convert_argb.h"
#include "libyuv/row.h"
#pragma intrinsic(memcpy)
//extern int RecordFlag;
//extern int OpenOMP;
//extern "C"
//{
// extern const struct libyuv::YuvConstants libyuv::kYuv2020Constants;
//}
static int64_t GetCurrTimeMS()
{
......@@ -155,7 +162,8 @@ void CaptureThread::run()
if (!Settings::OpenOMP)
{
size_t yuv_size = width_ * height_ << 1;
Yuv4k::UYVYToARGB4K(videoFrame->uyvy_data, yuv_size, videoFrame->data, once_size, width_, height_);
//Yuv4k::UYVYToARGB4K(videoFrame->uyvy_data, yuv_size, videoFrame->data, once_size, width_, height_);
Yuv4k::UYVYToARGB4KWithMatrix(videoFrame->uyvy_data, yuv_size, videoFrame->data, once_size, width_, height_,videoFrame->meta_.colorspace);
}
else
{
......@@ -175,7 +183,24 @@ void CaptureThread::run()
auto dst = videoFrame->data + i * once_size;
auto src = videoFrame->uyvy_data + i * yuv_size;
libyuv::UYVYToARGB(src, width_ << 1, dst, width_ << 2, width_, height_);
switch (videoFrame->meta_.colorspace)
{
case bmdColorspaceRec601:
libyuv::UYVYToARGBMatrix(src, width_ << 1, dst, width_ << 2, &libyuv::kYuvI601Constants, width_, height_);
break;
case bmdColorspaceRec709:
libyuv::UYVYToARGBMatrix(src, width_ << 1, dst, width_ << 2, &libyuv::kYuvI601Constants, width_, height_);
break;
case bmdColorspaceRec2020:
libyuv::UYVYToARGBMatrix(src, width_ << 1, dst, width_ << 2, &libyuv::kYuv2020Constants, width_, height_);
break;
default:
libyuv::UYVYToARGB(src, width_ << 1, dst, width_ << 2, width_, height_);
break;
}
//libyuv::UYVYToARGBMatrix(src, width_ << 1, dst, width_ << 2, &libyuv::kYuvI601Constants, width_, height_);
//libyuv::UYVYToARGB(src, width_ << 1, dst, width_ << 2, width_, height_);
//qDebug() << "get omp thread id:" << omp_get_thread_num() << "\n";
//memcpy(dst, src, once_size);
}
......
......@@ -103,10 +103,10 @@ void CropThread::CropScale()
{
}
else if (p_frame->fmt_ == bmdFormat8BitYUV && (p_frame->data_ || (p_frame->pImage && p_frame->pImage->data)))
else if (p_frame->fmt_ == bmdFormat8BitYUV && (p_frame->data_ /*|| (p_frame->pImage && p_frame->pImage->data)*/))
{
uyvy_data = (p_frame->data_ ? p_frame->data_ : p_frame->pImage->data);
//uyvy_data = (p_frame->data_ ? p_frame->data_ : p_frame->pImage->data);
uyvy_data = p_frame->data_;
Yuv4k::UYVYCopy(uyvy_data, crop_msg.crop_x, crop_msg.crop_y, p_frame->width_, p_frame->height_, uyvy_crop_data, crop_msg.crop_w, crop_msg.crop_h);
Yuv4k::UYVYToI422(uyvy_crop_data, i422_crop_data, crop_msg.crop_w, crop_msg.crop_h);
Yuv4k::I422Scale4K(i422_crop_data, crop_msg.crop_w, crop_msg.crop_h, i422_4k_data, p_frame->width_, p_frame->height_, Settings::ZoomUseOmp);
......
......@@ -135,9 +135,27 @@ CropThread* ProcessMaskThread::GetCropThread()
return crop_thread.get();
}
void ProcessMaskThread::SetBmdInOutVideoParams(const BmdVideoParams& input, const BmdVideoParams& output)
{
input_params = input;
output_params = output;
if (input_params.width != output_params.width || input_params.height != output_params.height) {
scale_flag = true;
if (!scale_thread)
{
scale_thread = std::make_shared<VideoScaleThread>(this);
ScaleMsg msg{output.width,output.height};
scale_thread->addScaleMsg(msg);
scale_thread->start();
}
}
else scale_flag = false;
}
void ProcessMaskThread::ClearQueue()
{
if(taskImageQueue.Size()) taskImageQueue.Reset();
if (!replay_flag_clear) replay_flag_clear = true;
}
void ProcessMaskThread::run()
......@@ -242,6 +260,18 @@ void ProcessMaskThread::OnRecvViedoFrame(std::shared_ptr<VideoFrameWithMask> fra
}
}
void ProcessMaskThread::OnRecvScaleViedoFrame(std::shared_ptr<VideoFrameWithMask> frame)
{
if (frame)
{
emit PushFrame(frame);
if (!frame->replay_flag && frame->flag_ == BS_IDEL)
{
emit PushScaleFrameToReplay(frame);
}
}
}
void ProcessMaskThread::CropScaleWithUYVY()
{
//while (true)
......@@ -339,6 +369,21 @@ void ProcessMaskThread::workMaskWithUYVY(const std::shared_ptr<videoFrameData>&
uint8_t* alpha = NULL;
bool err = false;
if (replay_flag_clear)
{
if (dynamic_flag)
{
dynamic_flag = false;
dynamic_out_num = 0;
}
status = BS_IDEL;
memset(tmp_alpha, 0, width * height);
last_masked = nullptr;
if(masked_map.size()) masked_map.clear();
memset(bk_argb, 0, width * height << 2);
replay_flag_clear = false;
}
if (mask_flag && mask_buffer)
{
x = mask_buffer->upper_left_point.x;
......@@ -403,6 +448,7 @@ void ProcessMaskThread::workMaskWithUYVY(const std::shared_ptr<videoFrameData>&
if (dynamic_flag)
{
dynamic_flag = false;
dynamic_out_num = 0;
status = BS_IDEL;
memset(tmp_alpha, 0, width * height);
last_masked = nullptr;
......@@ -491,7 +537,9 @@ void ProcessMaskThread::workMaskWithUYVY(const std::shared_ptr<videoFrameData>&
libyuv::ARGBAttenuate(crop_buffer_argb, crop_width << 2, crop_buffer_argb, crop_width << 2, crop_width, crop_height);
libyuv::ARGBBlend(crop_buffer_argb, crop_width << 2, bk_argb + offset, width << 2, bk_argb + offset, width << 2, crop_width, crop_height);
Rect cross_rect;
//outputAlpha2(buffer, last_masked, cross_rect);
outputAlphaRect(buffer, last_rect, cross_rect);
......@@ -590,6 +638,7 @@ void ProcessMaskThread::workMaskWithUYVY(const std::shared_ptr<videoFrameData>&
libyuv::ARGBCopy(src_bgra + offset_b, width << 2, tmp_bgra, width << 2, mask_rect.width, mask_rect.height);
libyuv::ARGBBlend(bk_argb + offset_b, width << 2, tmp_bgra, width << 2, tmp_bgra, width << 2, mask_rect.width, mask_rect.height);
qint32 x_ = ((mask_rect.x + 1) >> 1 << 1);
qint32 width_ = (x_ == mask_rect.x ? (mask_rect.width >> 1 << 1) : ((mask_rect.width - 1) >> 1 << 1));
qint32 height_ = (mask_rect.height);
......@@ -627,6 +676,10 @@ void ProcessMaskThread::workMaskWithUYVY(const std::shared_ptr<videoFrameData>&
video_frame->replay_flag = replay_flag;
//std::shared_ptr<VideoFrameWithMask> video_frame = std::make_shared<VideoFrameWithMask>(pImage, status, start_time);
if (Settings::CropFlag && /*(crop_msg.crop_x >= 0 || crop_msg.crop_y >= 0) &&*/ crop_thread) crop_thread->addVideoFrame(video_frame);
else if (scale_flag && scale_thread) {
//if (!scale_thread) scale_thread = std::make_shared<VideoScaleThread>(this);
scale_thread->addVideoFrame(video_frame);
}
else
{
emit PushFrame(video_frame);
......@@ -676,7 +729,7 @@ void ProcessMaskThread::workMaskWithUYVY(const std::shared_ptr<videoFrameData>&
else
{
//emit PushFrame(video_frame);
if (Settings::CropFlag && /*(crop_msg.crop_x >=0 || crop_msg.crop_y >= 0) &&*/ crop_thread)
if ((Settings::CropFlag && crop_thread) /*|| (scale_flag && scale_thread)*/)
{
//auto t2 = TimeMilliSecond();
/*size_t dst_argb_size = width * height << 2;
......@@ -713,9 +766,15 @@ void ProcessMaskThread::workMaskWithUYVY(const std::shared_ptr<videoFrameData>&
std::shared_ptr<VideoFrameWithMask> video_frame_i = std::make_shared<VideoFrameWithMask>(width, height, timestamp, pImage->sequenceNum, dst_uyvy, bmdFormat8BitYUV, pImage->flag_, pImage->meta_);
//std::shared_ptr<VideoFrameWithMask> video_frame = std::make_shared<VideoFrameWithMask>(pImage, status);
if(crop_thread) crop_thread->addVideoFrame(video_frame_i);
if (crop_thread) crop_thread->addVideoFrame(video_frame_i);
//if (scale_thread) scale_thread->addVideoFrame(video_frame_i);
//qDebug() << "memcpy duration:" << TimeMilliSecond() - t2 << "\n";
}
else if (scale_flag && scale_thread) {
std::shared_ptr<VideoFrameWithMask> video_frame = std::make_shared<VideoFrameWithMask>(pImage, pImage->flag_);
scale_thread->addVideoFrame(video_frame);
}
else
{
std::shared_ptr<VideoFrameWithMask> video_frame = std::make_shared<VideoFrameWithMask>(pImage, pImage->flag_);
......
......@@ -11,6 +11,7 @@ ReplayThread::ReplayThread()
max_store_size = Settings::ReplayStoreTime * Settings::FrameRate / 1000;
max_store_back_size = Settings::ReplayBackStoreTime * Settings::FrameRate / 1000;
max_store_crop_size = Settings::ReplayCropStoreTime * Settings::FrameRate / 1000;
max_store_scale_size = max_store_crop_size;
interval = 1000 / Settings::FrameRate;
}
......@@ -33,6 +34,19 @@ void ReplayThread::addCropFrame(std::shared_ptr<VideoFrameWithMask> frame)
}
void ReplayThread::addScaleFrame(std::shared_ptr<VideoFrameWithMask> frame)
{
if (frame && (frame->data_ || frame->pImage))
{
if (replay_params.status == RS_IDEL || replay_params.status == RS_END)
storeScaleMap.Insert(frame->timestamp_, frame);
if (storeScaleMap.Size() > max_store_scale_size)
{
storeScaleMap.Pop();
}
}
}
void ReplayThread::addFrame(std::shared_ptr<videoFrameData> frameData)
{
if(frameData && frameData->data)
......@@ -128,6 +142,23 @@ CropThread* ReplayThread::GetCropThread()
return crop_thread.get();
}
void ReplayThread::SetBmdInOutVideoParams(const BmdVideoParams& input, const BmdVideoParams& output)
{
input_params = input;
output_params = output;
if (input_params.width != output_params.width || input_params.height != output_params.height) {
scale_flag = true;
if (!scale_thread)
{
scale_thread = std::make_shared<VideoScaleThread>(this);
ScaleMsg msg{ output.width,output.height };
scale_thread->addScaleMsg(msg);
scale_thread->start();
}
}
else scale_flag = false;
}
void ReplayThread::OnRecvViedoFrame(std::shared_ptr<VideoFrameWithMask> crop_frame)
{
if (crop_frame)
......@@ -137,6 +168,15 @@ void ReplayThread::OnRecvViedoFrame(std::shared_ptr<VideoFrameWithMask> crop_fra
}
}
void ReplayThread::OnRecvScaleViedoFrame(std::shared_ptr<VideoFrameWithMask> scale_frame)
{
if(scale_frame)
{
storeCropMap.EnsureInsert(scale_frame->timestamp_, scale_frame);
replayVideoSdiVec.push_back(scale_frame);
}
}
void ReplayThread::OnChange()
{
......@@ -239,6 +279,7 @@ void ReplayThread::run()
}
qint64 rp_begin = in_tm - dy_in_count;
if (dy_out_count <= 0) dy_out_count = 1;
qint64 rp_end = out_tm + dy_out_count;
auto begin_tm = storeVideoMap.begin()->first;
......@@ -296,6 +337,7 @@ void ReplayThread::run()
for (auto itor = itor_begin;; itor++)
{
if (itor == in_itor)
//if (itor == ndi_itor)
{
break;
}
......@@ -318,6 +360,19 @@ void ReplayThread::run()
needCropQueue.Push(frame);
}
}
else if (scale_flag)
{
std::shared_ptr<VideoFrameWithMask> scale_frame = nullptr;
if(storeScaleMap.Find(itor->first, scale_frame))
{
replayVideoSdiVec.push_back(scale_frame);
}
else
{
std::shared_ptr<VideoFrameWithMask> video_frame = std::make_shared<VideoFrameWithMask>(frame, frame->flag_);
scale_thread->addVideoFrame(video_frame);
}
}
else
{
std::shared_ptr<VideoFrameWithMask> video_frame = std::make_shared<VideoFrameWithMask>(frame, frame->flag_);
......
#include "Threads/VideoScaleThread.h"
#include "Utils/yuv4k.h"
#include "Utils/Settings.h"
VideoScaleThread::VideoScaleThread(Listener* listener) :p_listener(listener)
{
if(!uyvy_to_i422) uyvy_to_i422 = new uint8_t[i422_width * i422_height << 1];
}
VideoScaleThread::~VideoScaleThread()
{
if (uyvy_to_i422) delete uyvy_to_i422;
if (i422_scale) delete i422_scale;
}
void VideoScaleThread::addVideoFrame(std::shared_ptr<VideoFrameWithMask> frame)
{
if(frame) video_queue.Push(frame);
}
void VideoScaleThread::addScaleMsg(const ScaleMsg& msg)
{
scale_msg_queue.Push(msg);
}
void VideoScaleThread::run()
{
scale();
}
void VideoScaleThread::scale()
{
while (true)
{
std::shared_ptr<VideoFrameWithMask> p_frame = nullptr;
if (video_queue.WaitFor(p_frame))
{
if (scale_msg_queue.Size())
{
ScaleMsg tmp_msg;
scale_msg_queue.PopLast(tmp_msg);
/*if (!crop_msg.equal(tmp_msg) && p_listener)
{
p_listener->OnChange();
}*/
if (tmp_msg.scale_width && tmp_msg.scale_height)
{
if (tmp_msg.scale_width != scale_msg.scale_width || tmp_msg.scale_height != scale_msg.scale_height)
{
if (i422_scale) delete i422_scale;
i422_scale = new uint8_t[tmp_msg.scale_width * tmp_msg.scale_height << 1];
}
scale_msg = tmp_msg;
}
}
if (p_frame)
{
uint8_t* uyvy_data = NULL;
if (p_frame->fmt_ == bmdFormat8BitBGRA && p_frame->data_)
{
}
else if (p_frame->fmt_ == bmdFormat8BitYUV && (p_frame->data_ || (p_frame->pImage && p_frame->pImage->uyvy_data)))
{
uyvy_data = (p_frame->data_ ? p_frame->data_ : p_frame->pImage->uyvy_data);
//uyvy_data = p_frame->data_;
auto src_w = p_frame->width_;
auto src_h = p_frame->height_;
if (src_w * src_h > i422_width * i422_height)
{
delete uyvy_to_i422;
uyvy_to_i422 = new uint8_t[src_w * src_h << 1];
i422_width = src_w;
i422_height = src_h;
}
Yuv4k::UYVYToI422(uyvy_data, uyvy_to_i422, src_w, src_h);
Yuv4k::I422Scale(uyvy_to_i422, src_w, src_h, i422_scale, scale_msg.scale_width, scale_msg.scale_height, Settings::ZoomUseOmp);
uint8_t* scale_uyvy = new uint8_t[scale_msg.scale_width * scale_msg.scale_height << 1];
Yuv4k::I422ToUYVY(i422_scale, scale_uyvy, scale_msg.scale_width, scale_msg.scale_height, 0);
p_frame->width_ = scale_msg.scale_width;
p_frame->height_ = scale_msg.scale_height;
p_frame->size_ = scale_msg.scale_width * scale_msg.scale_height << 1;
if (p_frame->data_) delete p_frame->data_;
p_frame->data_ = scale_uyvy;
}
if (p_listener) p_listener->OnRecvScaleViedoFrame(p_frame);
}
}
}
}
\ No newline at end of file
......@@ -161,6 +161,8 @@ MomentaMedia::MomentaMedia(QWidget *parent)
OutputModeCombo->addItem(QString::fromWCharArray(L"跟随输入格式"));
OutputModeCombo->addItem("1080 50I");
OutputModeCombo->addItem("1080 50P");
OutputModeCombo->addItem("2160 50P");
OutputModeCombo->setCurrentIndex(mode);
connect(OutputModeCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &MomentaMedia::OutputModeChanged);
......
No preview for this file type
No preview for this file type
No preview for this file type
......@@ -29,7 +29,7 @@ CROP_X=3200
CROP_Y=1800
CROP_DIRECTION=4
USE_PIC_FLAG=1
OUTPUT_PLAY_MODE=0
OUTPUT_PLAY_MODE=2
AUDIO_CHANNEL=2
ASPEC_DEN=9
ASPEC_NUM=16
......
No preview for this file type
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment