221 lines
5.6 KiB
C++
221 lines
5.6 KiB
C++
#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()
|
|
{
|
|
|
|
}
|