HxNvr/HxIVA/HxDevice.cpp

221 lines
5.6 KiB
C++
Raw Normal View History

2024-01-30 18:59:29 +08:00
#include "HxDevice.h"
HxDevice::HxDevice(int millisecond)
: HxThread{ millisecond }
{
frame_id = 0;
type = -1;
rtspurl = "";
bgr_frame_buffer.u32Width = 1280;
bgr_frame_buffer.u32Height = 720;
bgr_frame_buffer.pu8VirAddr = (unsigned char*)calloc(bgr_frame_buffer.u32Width * bgr_frame_buffer.u32Height * 3, sizeof(unsigned char));
detect_frame_buffer.u32Width = 1280;
detect_frame_buffer.u32Height = 720;
detect_frame_buffer.pu8VirAddr = (unsigned char*)calloc(detect_frame_buffer.u32Width * detect_frame_buffer.u32Height * 3, sizeof(unsigned char));
}
void HxDevice::set(int type, QString rtspurl)
{
this->type = type;
this->rtspurl = rtspurl;
}
void HxDevice::startup()
{
/* 通道被启用的情况下开始线程 */
if (!rtspurl.isEmpty())
{
HxTask::run(this, &HxDevice::frame_read_process, 5000, "_frame_read_process");
this->start();
}
}
void HxDevice::frame_read_process(void)
{
int error = 0;
AVDictionary* avdic = nullptr;
/* 减少卡顿或者花屏现象,相当于增加或扩大了缓冲区,给予编码和发送足够的时间 */
av_dict_set(&avdic, "buffer_size", "1024000", 0);
/* 减少采集缓存 */
// av_dict_set(&avdic, "preset", "fast", 0);
// av_dict_set(&avdic, "tune", "zerolatency", 0);
// /* 减少音频采集sampels数量 */
// av_dict_set(&avdic, "audio_buffer_size","30", 0);
// av_dict_set(&avdic, "stimeout", "500000", 0); // xs9922会报错
// av_dict_set(&avdic, "max_delay", "500000", 0);
// av_dict_set(&avdic, "rtsp_transport", "+udp+tcp", 0);
av_dict_set(&avdic, "rtsp_transport", "tcp", 0);
avformat_network_init();
ifmt_ctx = avformat_alloc_context();
error = avformat_open_input(&ifmt_ctx, rtspurl.toUtf8().data(), nullptr, &avdic);
av_dict_free(&avdic);
if (error != 0)
{
avformat_free_context(ifmt_ctx);
HxTrace::debug_write_line("videolivestream", QString("address=%1, avformat_open_input failed, errorcode=%2").arg(rtspurl).arg(error));
return;
}
if (avformat_find_stream_info(ifmt_ctx, nullptr) < 0)
{
avformat_close_input(&ifmt_ctx);
avformat_free_context(ifmt_ctx);
HxTrace::debug_write_line("videolivestream", QString("address=%1, avformat_find_stream_info failed").arg(rtspurl));
return;
}
av_dump_format(ifmt_ctx, 0, rtspurl.toUtf8().data(), 0);
video_stream_index = -1;
for (uint i = 0; i < ifmt_ctx->nb_streams; i++)
{
if (ifmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
{
video_stream_index = static_cast<int>(i);
break;
}
}
if (video_stream_index == -1)
{
avformat_close_input(&ifmt_ctx);
avformat_free_context(ifmt_ctx);
HxTrace::debug_write_line("videolivestream", QString("address=%1, not found video stream").arg(rtspurl));
return;
}
while (true)
{
AVPacket packet;
if (av_read_frame(ifmt_ctx, &packet) < 0)
{
break;
}
if (packet.stream_index == video_stream_index)
{
mutex.lock();
frames.append(HxVideoFrame(QDateTime::currentDateTime(), &packet));
mutex.unlock();
}
av_packet_unref(&packet);
msleep(10);
}
if (ifmt_ctx != nullptr)
{
avformat_close_input(&ifmt_ctx);
avformat_free_context(ifmt_ctx);
ifmt_ctx = nullptr;
}
}
int HxDevice::mv_convert_images(VideoFrameDataInfo *src_buffer, VideoFrameDataInfo *dst_buffer)
{
Q_UNUSED(src_buffer);
Q_UNUSED(dst_buffer);
#if USE_ALGORITHM
rga_buffer_t src;
rga_buffer_t dst;
src = wrapbuffer_virtualaddr(src_buffer->pu8VirAddr, src_buffer->u32Width, src_buffer->u32Height, RK_FORMAT_BGR_888);
dst = wrapbuffer_virtualaddr(dst_buffer->pu8VirAddr, dst_buffer->u32Width, dst_buffer->u32Height, RK_FORMAT_YCbCr_420_SP);
if (src.width == 0 || dst.width == 0)
{
return -1;
}
src.format = RK_FORMAT_BGR_888;
dst.format = RK_FORMAT_YCbCr_422_SP;
IM_STATUS STATUS;
STATUS = imcvtcolor(src, dst, src.format, dst.format);
if (STATUS != IM_STATUS_SUCCESS)
{
qDebug("imcvtcolor error\n");
return -1;
}
dst_buffer->u64PTS = src_buffer->u64PTS;
dst_buffer->nFrameId = src_buffer->nFrameId;
#endif
return 0;
}
void HxDevice::action()
{
cv::Mat mat;
if (frames.isEmpty())
return;
mutex.lock();
auto frame = frames.dequeue();
mutex.unlock();
if (!decoder.status)
{
// #ifdef USE_ALGORITHM
// decoder.initialization();
// #else
decoder.initialization(ifmt_ctx);
// #endif
if (!decoder.status)
goto frame_free;
}
/* 获取YUV数据 */
decoder._decode(frame.packet, &mat);
if (mat.data != nullptr)
{
if (car_info.fVelocity >= 10)
{
bgr_frame_buffer.nFrameId = frame_id; // 帧号
bgr_frame_buffer.u64PTS = QDateTime::currentMSecsSinceEpoch(); // 时间戳(毫秒)
// bgr_frame_buffer.pu8VirAddr = mat.data;
memcpy(bgr_frame_buffer.pu8VirAddr, mat.data, 1280 * 720 * 3);
mv_convert_images(&bgr_frame_buffer, &detect_frame_buffer); // bgr->nv16
#if USE_ALGORITHM
MvObjectEventDetect(this->type, &detect_frame_buffer, &car_info);
HxTrace::debug_write_line("device", QString("send frame_id=%1").arg(frame_id + 1));
#endif
frame_id++;
}
}
frame_free:
frame.free();
}
void HxDevice::continue_with()
{
}