Commit 345d99bc by wangguotao

优化贴图流程 统一出yuv格式数据

parent 9eb8ec43
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -82,6 +82,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<WholeProgramOptimization>true</WholeProgramOptimization>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>.\ThirdParty\rabbitmq\lib;.\ThirdParty\ffmpeg-master-latest-win64-gpl-shared\lib;.\ThirdParty\libyuv\lib;.\ThirdParty\OpenCV\x64\vc15\lib;.\ThirdParty\NewTek\lib\x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
......@@ -112,7 +113,7 @@
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<DebugInformationFormat>None</DebugInformationFormat>
<Optimization>MaxSpeed</Optimization>
<Optimization>Full</Optimization>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<UsePrecompiledHeader>Use</UsePrecompiledHeader>
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
......@@ -142,6 +143,8 @@
<ClInclude Include="include\Utils\Algorithm.h" />
<ClInclude Include="include\Utils\AudioConvert.h" />
<ClInclude Include="include\Utils\Base64.h" />
<ClInclude Include="include\Utils\FastMemcpy.h" />
<ClInclude Include="include\Utils\FastMemcpy_Avx.h" />
<ClInclude Include="include\Utils\MaskBuffer.h" />
<ClInclude Include="include\Utils\Memory4k.h" />
<ClInclude Include="include\Utils\SafeMap.h" />
......
......@@ -298,6 +298,12 @@
<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>
</ItemGroup>
<ItemGroup>
<QtRcc Include="Form\MomentaMedia.qrc">
......
......@@ -38,7 +38,8 @@ private:
void process();
void workMask(const std::shared_ptr<videoFrameData>& frame_data, std::shared_ptr<MaskBuffer> buffer,const bool& mask_flag);
void workMaskSec(const std::shared_ptr<videoFrameData>& frame_data, std::shared_ptr<MaskBuffer> buffer, const bool& mask_flag);
void workMaskModify(const std::shared_ptr<videoFrameData>& frame_data, std::shared_ptr<MaskBuffer> buffer, const bool& mask_flag);
void workMaskModify(const std::shared_ptr<videoFrameData>& pImage, std::shared_ptr<MaskBuffer> mask_buffer, const bool& mask_flag);
void workMaskWithUYVY(const std::shared_ptr<videoFrameData>& pImage, std::shared_ptr<MaskBuffer> mask_buffer, const bool& mask_flag);
void blend(uint8_t* src_argb,int& src_stride_width, uint8_t* dst_argb,int& dst_stride_width,int &width,int &height);
void saveTga(const uint64_t& start_time, const uint64_t& end_time, const std::string& path);
void outputAlpha(std::shared_ptr<MaskedBuffer> current, std::shared_ptr<MaskedBuffer> last);
......@@ -59,6 +60,7 @@ private:
uint8_t* tmp_bgra{NULL};
uint8_t* tmp_alpha{NULL};
uint8_t* tmp_uyvy{NULL};
uint8_t* bk_argb{NULL};
uint8_t* bk_argb_attenuate{NULL};
uint8_t* alpha_{NULL};
......
......@@ -38,4 +38,5 @@ private:
ReplayParams last_replay_params;
uint32_t replay_position{ 0 };
qint64 current_seq{0};
bool send_err_flag {false};
};
\ No newline at end of file
......@@ -145,7 +145,11 @@ typedef struct videoFrameData
data = new uint8_t[capacity];
uyvy_data = new uint8_t[uyvy_size];
//memcpy(uyvy_data, src, uyvy_size);
//auto t1 = TimeMilliSecond();
Memory::MemoryCopy4k((uint8_t*)src,uyvy_data, uyvy_size >> 2);
//memcpy_fast(uyvy_data, src, uyvy_size);
//memcpy(uyvy_data, src, uyvy_size);
//qDebug() << "MemoryCopy4k duration:" << TimeMilliSecond() - t1 << "\n";
}
}
......@@ -249,6 +253,24 @@ typedef struct VideoFrameWithMask
else if (fmt_ == bmdFormat8BitYUV) size_ = width_ * height_ << 1;
}
VideoFrameWithMask(std::shared_ptr<videoFrameData> image, BlendStatus& status, const qint64& start_tm)
{
start_tm_ = start_tm;
flag_ = status;
pImage = image;
mask_flag = false;
fmt_ = pImage->fmt;
width_ = pImage->width;
height_ = pImage->height;
timestamp_ = (pImage->replaySeq ? pImage->replaySeq : pImage->timestamp);
sequenceNum_ = pImage->sequenceNum;
meta_ = image->meta_;
zoom_last = image->zoom_last;
if (fmt_ == bmdFormat8BitBGRA) size_ = width_ * height_ << 2;
else if (fmt_ == bmdFormat8BitYUV) size_ = width_ * height_ << 1;
}
/*VideoFrameWithMask(videoFrameData* image, BlendStatus& status)
{
flag_ = status;
......
//=====================================================================
//
// FastMemcpy.c - skywind3000@163.com, 2015
//
// feature:
// 50% speed up in avg. vs standard memcpy (tested in vc2012/gcc5.1)
//
//=====================================================================
#ifndef __FAST_MEMCPY_H__
#define __FAST_MEMCPY_H__
......
//=====================================================================
//
// FastMemcpy.c - skywind3000@163.com, 2015
//
// feature:
// 50% speed up in avg. vs standard memcpy (tested in vc2012/gcc5.1)
//
//=====================================================================
#ifndef __FAST_MEMCPY_H__
#define __FAST_MEMCPY_H__
......@@ -442,14 +434,22 @@ static void* memcpy_fast(void *destination, const void *source, size_t size)
c7 = _mm256_load_si256(((const __m256i*)src) + 7);
_mm_prefetch((const char*)(src + 512), _MM_HINT_NTA);
src += 256;
_mm256_stream_si256((((__m256i*)dst) + 0), c0);
/*_mm256_stream_si256((((__m256i*)dst) + 0), c0);
_mm256_stream_si256((((__m256i*)dst) + 1), c1);
_mm256_stream_si256((((__m256i*)dst) + 2), c2);
_mm256_stream_si256((((__m256i*)dst) + 3), c3);
_mm256_stream_si256((((__m256i*)dst) + 4), c4);
_mm256_stream_si256((((__m256i*)dst) + 5), c5);
_mm256_stream_si256((((__m256i*)dst) + 6), c6);
_mm256_stream_si256((((__m256i*)dst) + 7), c7);
_mm256_stream_si256((((__m256i*)dst) + 7), c7);*/
_mm256_storeu_si256((((__m256i*)dst) + 0), c0);
_mm256_storeu_si256((((__m256i*)dst) + 1), c1);
_mm256_storeu_si256((((__m256i*)dst) + 2), c2);
_mm256_storeu_si256((((__m256i*)dst) + 3), c3);
_mm256_storeu_si256((((__m256i*)dst) + 4), c4);
_mm256_storeu_si256((((__m256i*)dst) + 5), c5);
_mm256_storeu_si256((((__m256i*)dst) + 6), c6);
_mm256_storeu_si256((((__m256i*)dst) + 7), c7);
dst += 256;
}
}
......@@ -465,14 +465,22 @@ static void* memcpy_fast(void *destination, const void *source, size_t size)
c7 = _mm256_loadu_si256(((const __m256i*)src) + 7);
_mm_prefetch((const char*)(src + 512), _MM_HINT_NTA);
src += 256;
_mm256_stream_si256((((__m256i*)dst) + 0), c0);
/*_mm256_stream_si256((((__m256i*)dst) + 0), c0);
_mm256_stream_si256((((__m256i*)dst) + 1), c1);
_mm256_stream_si256((((__m256i*)dst) + 2), c2);
_mm256_stream_si256((((__m256i*)dst) + 3), c3);
_mm256_stream_si256((((__m256i*)dst) + 4), c4);
_mm256_stream_si256((((__m256i*)dst) + 5), c5);
_mm256_stream_si256((((__m256i*)dst) + 6), c6);
_mm256_stream_si256((((__m256i*)dst) + 7), c7);
_mm256_stream_si256((((__m256i*)dst) + 7), c7);*/
_mm256_storeu_si256((((__m256i*)dst) + 0), c0);
_mm256_storeu_si256((((__m256i*)dst) + 1), c1);
_mm256_storeu_si256((((__m256i*)dst) + 2), c2);
_mm256_storeu_si256((((__m256i*)dst) + 3), c3);
_mm256_storeu_si256((((__m256i*)dst) + 4), c4);
_mm256_storeu_si256((((__m256i*)dst) + 5), c5);
_mm256_storeu_si256((((__m256i*)dst) + 6), c6);
_mm256_storeu_si256((((__m256i*)dst) + 7), c7);
dst += 256;
}
}
......
#pragma once
#include <iostream>
#include "FastMemcpy_Avx.h"
class Memory
{
......@@ -22,6 +23,12 @@ public:
memcpy(dst2, src2, step);
memcpy(dst3, src3, step);
memcpy(dst4, src4, step);
/*memcpy_fast(dst1, src1, step);
memcpy_fast(dst2, src2, step);
memcpy_fast(dst3, src3, step);
memcpy_fast(dst4, src4, step);*/
}
}
};
\ No newline at end of file
......@@ -1062,7 +1062,7 @@ bool DeckLinkOutputDevice::getReferenceSignalMode(BMDDisplayMode* mode)
qDebug() << "frame order is error! error num:" << outputFrame->timestamp_ << ",last num:" << last_tm << "\n";
}
last_tm = outputFrame->timestamp_;*/
qDebug() << GetCurrDateTimeStr() << ":current frame tm:" << outputFrame->timestamp_ << "\n";
//qDebug() << GetCurrDateTimeStr() << ":current frame tm:" << outputFrame->timestamp_ << "\n";
if (outputFrame->flag_ == BS_START)
{
send_sdi_start_time = outputFrame->start_tm_;
......@@ -1572,6 +1572,7 @@ void DeckLinkOutputDevice::AddZoomFrame(std::shared_ptr<VideoFrameWithMask> fram
void DeckLinkOutputDevice::AddVideoFrameMask(std::shared_ptr<VideoFrameWithMask> frame)
{
//auto t1 = TimeMilliSecond();
if (outputMaskVideoFrameQueue.Size() > (50 * 3 + Settings::SecondSdiOutWaitNums) || output_video_frame_map.Size() > (50 * 3 + Settings::SecondSdiOutWaitNums))
{
if(outputMaskVideoFrameQueue.Size()) outputMaskVideoFrameQueue.Reset();
......@@ -1591,8 +1592,45 @@ void DeckLinkOutputDevice::AddVideoFrameMask(std::shared_ptr<VideoFrameWithMask>
{
if (Settings::SecondSdiOutWaitNums)
{
outputMaskVideoFrameQueue.Push(frame);
outputMaskVideoFrameDeque.PushBack(frame);
if (frame->flag_ == BS_IDEL)
{
outputMaskVideoFrameQueue.Push(frame);
outputMaskVideoFrameDeque.PushBack(frame);
}
else
{
auto itor = masked_map.find(frame->start_tm_);
if (frame->flag_ == BS_START)
{
if (itor != masked_map.end()) return;
else
{
auto tmp_map = new std::map<qint64, std::shared_ptr<VideoFrameWithMask>>();
int size = outputMaskVideoFrameDeque.Size();
int nums = (size > Settings::SecondSdiOutWaitNums ? Settings::SecondSdiOutWaitNums : size);
std::vector<std::shared_ptr<VideoFrameWithMask>> tmp_vec;
outputMaskVideoFrameDeque.Put(nums, tmp_vec);
for (auto data : tmp_vec)
{
if (data)
{
data->start_tm_ = frame->timestamp_;
tmp_map->insert({ data->timestamp_,data });
}
}
masked_map.insert({ frame->timestamp_,tmp_map });
tmp_map->insert({ frame->timestamp_, frame});
}
}
else
{
if (itor == masked_map.end()) return;
itor->second->insert({ frame->timestamp_, frame });
}
}
}
else
{
......
......@@ -110,7 +110,7 @@ DeckLinkOutputPage::DeckLinkOutputPage() : SelectedDevice(nullptr), Process(null
Zoom->start();
if (Zoom)
{
connect(this, &DeckLinkOutputPage::PushAttribute, Zoom.get(), &ZoomThread::addSportAttr);
connect(this, &DeckLinkOutputPage::PushAttribute, Zoom.get(), &ZoomThread::addSportAttr, Qt::DirectConnection);
}
}
}
......@@ -306,7 +306,7 @@ void DeckLinkOutputPage::RequestedDeviceGranted(ComPtr<IDeckLink>& device)
connect(BindingInputPage->GetReplay(), &ReplayThread::PushFrame, ProcessMask.get(), &ProcessMaskThread::AddFrame, Qt::DirectConnection);
connect(ProcessMask.get(), &ProcessMaskThread::PushFrame, NDIOutput.get(), &NDIOutputThread::AddVideoFrameWithMask, Qt::DirectConnection);
//if (MqThread) connect(MqThread.get(), &ConsumerMqThread::PushMask, ProcessMask.get(), &ProcessMaskThread::addMaskBuffer);
connect(this, &DeckLinkOutputPage::PushMask, ProcessMask.get(), &ProcessMaskThread::addMaskBuffer);
connect(this, &DeckLinkOutputPage::PushMask, ProcessMask.get(), &ProcessMaskThread::addMaskBuffer, Qt::DirectConnection);
connect(ProcessMask.get(), &ProcessMaskThread::PushFrame, SelectedDevice.Get(), &DeckLinkOutputDevice::AddVideoFrameMask, Qt::DirectConnection);
if (Zoom)
{
......
......@@ -14,6 +14,7 @@
//extern int OneFrameDuration;
#define SENDBGRA 1
#define MAXSIZE 30
#define OUT_UYVY 1
NDIOutputThread::NDIOutputThread(const QString& Name, int w, int h, qint32 deleyTime) : NDISenderName(Name), deleyTime_(deleyTime), width(w), height(h), isSending(false), Instance(nullptr), cropFlag(false),
m_lastTS(TimeMilliSecond()),
......@@ -126,7 +127,7 @@ bool NDIOutputThread::Init()
Frame.yres = height;
/*Frame.xres = 3840;
Frame.yres = 2160;*/
if(timePlusFlag) Frame.FourCC = NDIlib_FourCC_type_BGRA;
if(timePlusFlag) Frame.FourCC = NDIlib_FourCC_type_UYVY;
#if SENDBGRA
else Frame.FourCC = NDIlib_FourCC_type_BGRA;
#else
......@@ -134,7 +135,7 @@ bool NDIOutputThread::Init()
#endif // SENDBGRA
if (timePlusFlag) Frame.line_stride_in_bytes = Frame.xres * 4;
if (timePlusFlag) Frame.line_stride_in_bytes = Frame.xres * 2 ;
#if SENDBGRA
else Frame.line_stride_in_bytes = Frame.xres * 4;
#else
......@@ -261,10 +262,10 @@ void NDIOutputThread::run()
else
{
if (frame_mask->data_) Frame.p_data = frame_mask->data_;
else Frame.p_data = frame_mask->pImage->data;
else Frame.p_data = frame_mask->pImage->uyvy_data;
}
Frame.timestamp = frame_mask->timestamp_;
Frame.timecode = frame_mask->timestamp_ * 10000;
Frame.timecode = frame_mask->timestamp_ * 1000;
NDIlib_send_send_video_v2(Instance, &Frame);
}
......
......@@ -73,8 +73,9 @@ void CaptureThread::AddFrame(ComPtr<IDeckLinkVideoInputFrame> videoFrame, const
{
//videoFrame->GetTimecode();
auto t1 = TimeMilliSecond();
std::shared_ptr<videoFrameData> video_data = std::make_shared<videoFrameData>(videoFrame, sequenceNum, sequenceNum,meta);
//qDebug() << "create videoFrameData duration:" << TimeMilliSecond() - t1 << "\n";
/*std::shared_ptr<videoFrameData> videoFrame1 = std::make_shared<videoFrameData>(videoFrame, timestamp, timestamp);
if (NDIOutput) NDIOutput->AddFrame(videoFrame1);*/
......
......@@ -26,12 +26,15 @@
#define NDI_ALPHA 1
#define THREADNUM 4
#define USE_SECOND 1
#define USE_UYVY_FUNC 1
ProcessMaskThread::ProcessMaskThread()
{
tmp_bgra = new uint8_t[K4WIDTH * K4HEIGHT<< 2];
tmp_alpha = new uint8_t[K4WIDTH * K4HEIGHT];
tmp_uyvy = new uint8_t[K4WIDTH * K4HEIGHT << 1];
memset(tmp_uyvy,0, K4WIDTH * K4HEIGHT << 1);
memset(tmp_bgra, 0, K4WIDTH * K4HEIGHT << 2);
memset(tmp_alpha,0, K4WIDTH * K4HEIGHT);
......@@ -66,6 +69,7 @@ ProcessMaskThread:: ~ProcessMaskThread()
if (bk_argb) delete bk_argb;
if (bk_argb_attenuate) delete bk_argb_attenuate;
if (crop_data) delete crop_data;
if (tmp_uyvy) delete tmp_uyvy;
}
void ProcessMaskThread::addMaskBuffer(std::shared_ptr<MaskBuffer> buffer)
......@@ -139,10 +143,10 @@ void ProcessMaskThread::process()
if (itor != mask_map.end())
{
//qDebug() << "into work mask, frame timestamp:" << timestamp << "\n";
#if USE_SECOND
workMaskModify(image, itor->second, true);
#if USE_UYVY_FUNC
workMaskWithUYVY(image, itor->second, true);
#else
workMask(image, itor->second, true);
workMaskModify(image, itor->second, true);
#endif // USE_SECOND
......@@ -151,10 +155,10 @@ void ProcessMaskThread::process()
else
{
//qDebug() << "no need work mask, frame timestamp:" << timestamp << "\n";
#if USE_SECOND
workMaskModify(image, NULL, false);
#if USE_UYVY_FUNC
workMaskWithUYVY(image, NULL, false);
#else
workMask(image, NULL, false);
workMaskModify(image, itor->second, true);
#endif // USE_SECOND
......@@ -225,6 +229,352 @@ void ProcessMaskThread::CropScale()
}
}
void ProcessMaskThread::workMaskWithUYVY(const std::shared_ptr<videoFrameData>& pImage, std::shared_ptr<MaskBuffer> mask_buffer, const bool& mask_flag)
{
auto startTime = TimeMilliSecond();
if (!m_lastRecvTS) m_lastRecvTS = TimeMilliSecond();
uint32_t x = 0, y = 0, offset = 0;
qint64 timecode = 0;
//bgra src data
if (!pImage) return;
auto src_bgra = pImage->data;
auto src_uyvy = pImage->uyvy_data;
if (!src_bgra) return;
uint32_t width = pImage->width;
uint32_t height = pImage->height;
qint64 timestamp = (pImage->replaySeq ? pImage->replaySeq : pImage->timestamp);
uint32_t crop_width = 0;
uint32_t crop_height = 0;
uint8_t* alpha = NULL;
bool err = false;
if (mask_flag && mask_buffer)
{
x = mask_buffer->upper_left_point.x;
y = mask_buffer->upper_left_point.y;
timecode = mask_buffer->timecode;
//crop i422
crop_width = mask_buffer->width;
crop_height = mask_buffer->height;
alpha = (uint8_t*)mask_buffer->mask_data.c_str();
int size = mask_buffer->mask_data.length();
if (size != crop_width * crop_height)
{
err = true;
qDebug() << "alpha data is error!!!!" << "\n";
}
/*else
{
if(masked_map.size() == 0) mask_status = MS_START;
}*/
}
#if USE_I422
size_t crop_size = crop_width * crop_height << 1;
uint8_t* crop_buffer_i422 = new uint8_t[crop_size];
uint8_t* crop_buffer_y = crop_buffer_i422;
uint8_t* crop_buffer_u = crop_buffer_y + (crop_width * crop_height);
uint8_t* crop_buffer_v = crop_buffer_u + (crop_width * crop_height >> 1);
//to yuv i422
size_t size = width * height << 1;
uint8_t* buffer_i422 = new uint8_t[size];
uint8_t* buffer_y = buffer_i422;
uint8_t* buffer_u = buffer_y + (width * height);
uint8_t* buffer_v = buffer_u + (width * height >> 1);
libyuv::UYVYToI422((uint8_t*)src_uyvy, width << 1, buffer_i422, width, buffer_u, width >> 1, buffer_v, width >> 1, width, height);
uint8_t* src_y = buffer_y + x + y * width;
uint8_t* src_u = buffer_u + (x >> 1) + (y * width >> 1);
uint8_t* src_v = buffer_v + (x >> 1) + (y * width >> 1);
libyuv::I422Copy(src_y, width, src_u, width >> 1, src_v, width >> 1, crop_buffer_y, crop_width, crop_buffer_u, crop_width >> 1,
crop_buffer_v, crop_width >> 1, crop_width, crop_height);
//i422 alpha ->rgba
uint8_t* rgba = new uint8_t[crop_size << 1];
libyuv::I422AlphaToARGB(crop_buffer_y, crop_width, crop_buffer_u, crop_width >> 1, crop_buffer_v, crop_width >> 1, alpha, crop_width, rgba, crop_width << 2, crop_width, crop_height, 0);
#elif USE_BGRA
//memcpy(src_argb,src_bgra, src_argb_size);
//qDebug() << "src data copy duration:" << TimeMilliSecond() - t11 << "\n";
//uyvy-->bgra
//libyuv::UYVYToARGB(src_uyvy, width << 1, src_argb,width << 2, width, height);
if (mask_flag && mask_buffer)
{
if (!err)
{
auto t1 = TimeMilliSecond();
size_t crop_size = crop_width * crop_height << 2;
uint8_t* crop_buffer_argb = new uint8_t[crop_size];
//copy
int offset = (y * width << 2) + (x << 2);
libyuv::ARGBCopy(src_bgra + offset, width << 2, crop_buffer_argb, crop_width << 2, crop_width, crop_height);
//
libyuv::ARGBCopyYToAlpha(alpha, crop_width, crop_buffer_argb, crop_width << 2, crop_width, crop_height);
std::shared_ptr<MaskedBuffer> buffer = nullptr;
#if NDI_ALPHA
uint8_t* tmp = new uint8_t[crop_width * crop_height];
memcpy(tmp, alpha, crop_width * crop_height);
buffer = std::make_shared<MaskedBuffer>(x, y, crop_buffer_argb, crop_width, crop_height, width, height, timecode, mask_buffer->signal, tmp);
#else
buffer = std::make_shared<MaskedBuffer>(x, y, crop_buffer_argb, crop_width, crop_height, width, height, timecode, mask_buffer->signal);
#endif
masked_map.insert({ timecode,buffer });
{
std::lock_guard<std::mutex> lock(mutex);
store_masked_map.insert({ timecode,buffer });
}
if (bk_argb)
{
int32_t x_min = K4WIDTH, x_max = 0, y_min = K4HEIGHT, y_max = 0;
int32_t x_min_s = K4WIDTH, x_max_s = 0, y_min_s = K4HEIGHT, y_max_s = 0;
uint32_t map_size = 0;
for (auto& value : masked_map)
{
auto& mask = value.second;
auto x1 = mask->m_x;
auto y1 = mask->m_y;
auto x2 = x1 + mask->m_width;
auto y2 = y1 + mask->m_height;
map_size++;
if (1 == masked_map.size())
{
x_min = x1;
x_max = x2;
y_min = y1;
y_max = y2;
x_min_s = x1;
x_max_s = x2;
y_min_s = y1;
y_max_s = y2;
}
else
{
x_min = MIN(x_min, x1);
y_min = MIN(y_min, y1);
x_max = MAX(x_max, x2);
y_max = MAX(y_max, y2);
if (map_size < masked_map.size())
{
x_min_s = MIN(x_min_s, x1);
y_min_s = MIN(y_min_s, y1);
x_max_s = MAX(x_max_s, x2);
y_max_s = MAX(y_max_s, y2);
}
}
}
mask_rect = { x_min,y_min,x_max - x_min,y_max - y_min };
Rect last_rect = { x_min_s,y_min_s,x_max_s - x_min_s,y_max_s - y_min_s };
auto t1 = TimeMilliSecond();
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);
libyuv::ARGBCopyYToAlpha(tmp_alpha, width, bk_argb, width << 2, width, height);
last_masked = buffer;
}
}
else {
std::shared_ptr<MaskedBuffer> buffer = std::make_shared<MaskedBuffer>(timecode, mask_buffer->signal);
masked_map.insert({ timecode,buffer });
}
}
#endif
auto t2 = TimeMilliSecond();
bool clear_flag = false;
if (status == BS_END) status = BS_IDEL;
if (last_masked && last_masked->m_timecode < timestamp && (timestamp - last_masked->m_timecode) >= Settings::TimeoutFrames && status != BS_IDEL)
{
memset(tmp_alpha, 0, width * height);
last_masked = nullptr;
masked_map.clear();
memset(bk_argb, 0, width * height << 2);
status = BS_IDEL;
}
auto map_size = masked_map.size();
if (map_size)
{
auto t11 = TimeMilliSecond();
size_t dst_uyvu_size = width * height << 1;
uint8_t* dst_uyvy = new uint8_t[dst_uyvu_size];
size_t once_size = (width * height >> 1);
size_t num = dst_uyvu_size / once_size;
omp_set_num_threads(num);
#pragma omp parallel
{
#pragma omp for nowait
for (int i = 0; i < num; i++)
{
auto dst = dst_uyvy + i * once_size;
auto src = src_uyvy + i * once_size;
memcpy(dst, src, once_size);
//SSE::MemcpySSE(dst, src, once_size);
}
}
//qDebug() << "memcpy 4k duration:" << TimeMilliSecond() - t11 << "\n";
int32_t end_flag = -11;
if (mask_buffer) end_flag = mask_buffer->signal;
if (map_size == 1 && status == BS_IDEL)
{
status = BS_START;
start_time = timestamp;
QString msg = "{\"signal\":\"MaskMsg\",\"data\":{\"status\":" + QString::number(status) + ",\"timestamp\":" + QString::number(timestamp) + "}}";
UdpSend::GetInstance().SendUdpMsg(msg, Settings::UIIpAddr, QString::number(Settings::UIUdpPort));
//qDebug() << "start copy crop pic.......\n";
}
else if (end_flag == 1 && status == BS_ING)
{
status = BS_END;
clear_flag = true;
if (status == BS_END)
{
//send msg to ui with udp-protocol
QString msg = "{\"signal\":\"MaskMsg\",\"data\":{\"status\":" + QString::number(status) + ",\"timestamp\":" + QString::number(timestamp) + "}}";
UdpSend::GetInstance().SendUdpMsg(msg, Settings::UIIpAddr, QString::number(Settings::UIUdpPort));
}
}
else status = BS_ING;
//libyuv::ARGBBlend(bk_argb_attenuate, width << 2, src_argb , width << 2, src_argb, width << 2, width, height);
uint32_t offset_b = (mask_rect.y * width << 2) + (mask_rect.x << 2);
//libyuv::ARGBBlend(bk_argb + offset_b, width << 2, dst_argb + offset_b, width << 2, dst_argb + offset_b, width << 2, mask_rect.width, mask_rect.height);
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);
libyuv::ARGBToUYVY(tmp_bgra, width << 2, tmp_uyvy, width << 1, mask_rect.width, mask_rect.height);
offset_b = (mask_rect.y * width << 1) + (mask_rect.x << 1);
libyuv::CopyPlane(tmp_uyvy, width << 1, dst_uyvy + offset_b, width << 1, mask_rect.width, mask_rect.height);
std::shared_ptr<VideoFrameWithMask> video_frame = std::make_shared<VideoFrameWithMask>(width, height, timestamp, pImage->sequenceNum, dst_uyvy, bmdFormat8BitYUV, status, pImage->meta_, start_time);
//std::shared_ptr<VideoFrameWithMask> video_frame = std::make_shared<VideoFrameWithMask>(pImage, status, start_time);
if (Settings::CropFlag && (crop_msg.crop_x || crop_msg.crop_y)) crop_queue.Push(video_frame);
else
{
emit PushFrame(video_frame);
memset(tmp_bgra, 0, width* height << 2);
memset(tmp_uyvy, 0, width* height << 1);
}
//qDebug()<<"tm:"<< video_frame->timestamp_ <<"," << GetCurrDateTimeStr() << ",process mask frame duration:" << TimeMilliSecond() - t11 << "\n";
if (clear_flag) {
/*if (RecordFlag && record_count < 1)
{
auto start_time = masked_map.begin()->first;
auto end_time = timestamp;
AVPixelFormat fmt = AV_PIX_FMT_UYVY422;
StartRecord_(pImage->width, pImage->height, fmt, start_time, end_time);
}*/
{
std::lock_guard<std::mutex> lock(mutex);
while (store_masked_map.size() > STOREMASKEDSIZE)
{
store_masked_map.erase(store_masked_map.begin()->first);
}
}
if (zoom_thread)
{
zoom_thread->setVideoFrame(video_frame);
}
/*if (tga_masked_map.size() <= 0 && once_save)
{
tga_masked_map = masked_map;
std::thread t(&ProcessMaskThread::saveTga, this);
t.detach();
}*/
memset(tmp_alpha, 0, width * height);
last_masked = nullptr;
masked_map.clear();
memset(bk_argb, 0, width * height << 2);
}
}
else
{
//emit PushFrame(video_frame);
if (Settings::CropFlag && (crop_msg.crop_x || crop_msg.crop_y))
{
//auto t2 = TimeMilliSecond();
size_t dst_argb_size = width * height << 2;
uint8_t* dst_argb = new uint8_t[dst_argb_size];
size_t once_size = width * height;
size_t num = dst_argb_size / once_size;
omp_set_num_threads(num);
#pragma omp parallel
{
#pragma omp for nowait
for (int i = 0; i < num; i++)
{
auto dst = dst_argb + i * once_size;
auto src = src_bgra + i * once_size;
memcpy(dst, src, once_size);
}
}
std::shared_ptr<VideoFrameWithMask> video_frame_i = std::make_shared<VideoFrameWithMask>(width, height, timestamp, pImage->sequenceNum, dst_argb, status, pImage->meta_);
crop_queue.Push(video_frame_i);
//qDebug() << "memcpy duration:" << TimeMilliSecond() - t2 << "\n";
}
else
{
std::shared_ptr<VideoFrameWithMask> video_frame = std::make_shared<VideoFrameWithMask>(pImage, status);
emit PushFrame(video_frame);
}
//qDebug() << "process mask frame:" << video_frame->timestamp_ << ",cur_time:" << GetCurrDateTimeStr() << "\n";
}
//qDebug() << "process mask duration:" << TimeMilliSecond() - t2 << "\n";
/*uint64_t currTime, deltaTime;
int qsize;
m_fps++;
qsize = taskImageQueue.Size();
currTime = TimeMilliSecond();
deltaTime = currTime - m_lastRecvTS;
if (deltaTime >= 1000)
{
qDebug() << GetCurrDateTimeStr() << " mask pic fps " << m_fps << ", qsize " << qsize << "\n";
m_fps = 0;
m_lastRecvTS = currTime;
}*/
}
void ProcessMaskThread::workMaskModify(const std::shared_ptr<videoFrameData>& pImage, std::shared_ptr<MaskBuffer> mask_buffer, const bool& mask_flag)
{
auto startTime = TimeMilliSecond();
......
......@@ -30,6 +30,7 @@ void ReplayThread::addFrame(std::shared_ptr<videoFrameData> frameData)
storeVideoMap.erase(storeVideoMap.begin()->first);
}
if ((replay_params.status == RS_START || replay_params.status == RS_RE_START)) {
if (send_err_flag) send_err_flag = false;
cv.notify_all();
}
......@@ -111,13 +112,17 @@ void ReplayThread::run()
if (itor_end == storeVideoMap.end() || itor_begin == storeVideoMap.end() || tm_end <= tm_begin)
{
qint32 errNo = (itor_end == storeVideoMap.end() ? 2 : (itor_begin == storeVideoMap.end() ? 1 : 3));
if (!send_err_flag)
{
send_err_flag = true;
qint32 errNo = (itor_end == storeVideoMap.end() ? 2 : (itor_begin == storeVideoMap.end() ? 1 : 3));
QString msg = "{\"signal\":\"ReplayResp\",\"data\":{\"inTime\":" + QString::number(replay_params.start_time) +",\"outTime\":" + QString::number(replay_params.end_time) +
",\"status\":0,\"errNo\":" + QString::number(errNo) +"}}";
UdpSend::GetInstance().SendUdpMsg(msg, Settings::UIIpAddr, QString::number(Settings::UIUdpPort));
qDebug() << "replay fail,errno:"<<errNo << "\n";
QString msg = "{\"signal\":\"ReplayResp\",\"data\":{\"inTime\":" + QString::number(replay_params.start_time) + ",\"outTime\":" + QString::number(replay_params.end_time) +
",\"status\":0,\"errNo\":" + QString::number(errNo) + "}}";
UdpSend::GetInstance().SendUdpMsg(msg, Settings::UIIpAddr, QString::number(Settings::UIUdpPort));
qDebug() << "replay fail,errno:" << errNo << "\n";
}
continue;
}
bool first = true;
......
No preview for this file type
No preview for this file type
......@@ -3,15 +3,15 @@ objct name changed "deviceOutputPage4"
available device "DeckLink 8K Pro (1)"
available device "DeckLink 8K Pro (2)"
available device "DeckLink 8K Pro (3)"
"2024-05-27 15:23:37.946" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
available device "DeckLink 8K Pro (4)"
"2024-05-17 19:02:03.216" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
"2024-05-17 19:02:03.236" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
"2024-05-17 19:02:03.256" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
"2024-05-17 19:02:03.276" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
"2024-05-17 19:02:03.296" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
"2024-05-17 19:02:03.316" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
"2024-05-17 19:02:03.336" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
"2024-05-17 19:02:03.394" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
"2024-05-17 19:02:04.438" decklink input fps 51
"2024-05-17 19:02:05.439" decklink input fps 50
"2024-05-17 19:02:06.439" decklink input fps 50
"2024-05-27 15:23:37.966" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
"2024-05-27 15:23:38.009" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
"2024-05-27 15:23:38.029" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
"2024-05-27 15:23:38.049" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
"2024-05-27 15:23:38.069" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
"2024-05-27 15:23:38.089" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
"2024-05-27 15:23:38.109" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
"2024-05-27 15:23:38.129" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
"2024-05-27 15:23:38.187" index: 0 DeckLinkInputDevice get video frame No input source 80000000 ------------
"2024-05-27 15:23:39.211" decklink input fps 50
......@@ -42,10 +42,10 @@ SDIONEFRAMEDURATION=50
RECORDFLAG=1
OPENOMP=1
TIMEOUTFRAMES=250
SECONDDELEYSDINUMS=100
SECONDDELEYSDINUMS=0
REPLAY_START_FORWARD=50
REPLAY_END_DELEY=50
RTSDIOUTPUTWAITNUMS=5
RTSDIOUTPUTWAITNUMS=0
CROPRECORD=0
CROP_X=400
CROP_Y=1800
......
......@@ -24,7 +24,7 @@ BLACK_BOTTOM_HEIGHT_2=20
BLACK_BOTTOM_HEIGHT_3=20
BLACK_BOTTOM_HEIGHT_4=30
ZOOM_DRAW=0
ZOOM_FLAG=0
ZOOM_FLAG=1
ZOOM_SCALE=1.5
ZOOM_SCALE_N=1
ZOOM_SCALE_D=2
......@@ -48,7 +48,7 @@ REPLAY_END_DELEY=50
RTSDIOUTPUTWAITNUMS=5
CROPRECORD=0
CROP_X=400
CROP_Y=1800
CROP_DIRECTION=3
CROP_Y=400
CROP_DIRECTION=1
UI_UDP_PORT=8100
UI_IP_ADDR=127.0.0.1
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