#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(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() { }