Commit c027963f5bf730c6ca10c85b5af7e84cc09d4c9d

Authored by Hu Chunming
1 parent 150d457d

ffmpeg6.1.1版本的接收rtp

src/decoder/dvpp/DvppDecoder.cpp
... ... @@ -174,7 +174,7 @@ AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){
174 174 }
175 175  
176 176 // 查找视频流信息
177   - AVCodec *decoder = nullptr;
  177 + const AVCodec *decoder = nullptr;
178 178 video_index = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0);
179 179 if (video_index < 0) {
180 180 LOG_ERROR("[{}]- Cannot find a video stream in the input file!", m_dec_name);
... ... @@ -480,10 +480,6 @@ DeviceMemory* DvppDecoder::snapshot(){
480 480 return snapshot_mem;
481 481 }
482 482  
483   -int DvppDecoder::getCachedQueueLength(){
484   - return 0;
485   -}
486   -
487 483 void DvppDecoder::release_ffmpeg() {
488 484 m_dec_keyframe = false;
489 485 if(h264bsfc){
... ...
src/decoder/dvpp/DvppDecoder.h
... ... @@ -56,8 +56,6 @@ public:
56 56 void setPostDecArg(const void* postDecArg);
57 57 void setFinishedDecArg(const void* finishedDecArg);
58 58  
59   - int getCachedQueueLength();
60   -
61 59 void doRecode(RecoderInfo& recoderInfo);
62 60  
63 61 void set_mq_callback(mq_callback_t cb);
... ...
src/decoder/dvpp/DvppDecoderApi.cpp
... ... @@ -100,13 +100,6 @@ float DvppDecoderApi::fps(){
100 100 return 0.0;
101 101 }
102 102  
103   -int DvppDecoderApi::getCachedQueueLength(){
104   - if(m_pDecoder != nullptr){
105   - return m_pDecoder->getCachedQueueLength();
106   - }
107   - return 0;
108   -}
109   -
110 103 void DvppDecoderApi::setName(string nm){
111 104 if(m_pDecoder != nullptr){
112 105 return m_pDecoder->setName(nm);
... ...
src/decoder/dvpp/DvppDecoderApi.h
... ... @@ -28,8 +28,6 @@ public:
28 28  
29 29 bool isSurport(FFDecConfig& cfg);
30 30  
31   - int getCachedQueueLength();
32   -
33 31 float fps();
34 32  
35 33 DeviceMemory* snapshot();
... ...
src/decoder/dvpp/DvppRtpDecoder.cpp 0 → 100644
  1 +#include "DvppRtpDecoder.h"
  2 +
  3 +#include "DvppSourceManager.h"
  4 +#include "../gb28181/rtp2/Rtp.h"
  5 +
  6 +
  7 +#define CHECK_AND_RETURN(ret, message) \
  8 + if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message); return ret;}
  9 +#define CHECK_NOT_RETURN(ret, message) \
  10 + if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message);}
  11 +#define CHECK_AND_RETURN_NOVALUE(ret, message) \
  12 + if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message); return;}
  13 +#define CHECK_AND_BREAK(ret, message) \
  14 + if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message); break;}
  15 +
  16 +
  17 +
  18 +
  19 +struct Vdec_CallBack_UserData {
  20 + uint64_t frameId;
  21 + uint64_t frame_nb;
  22 + long startTime;
  23 + long sendTime;
  24 + DvppRtpDecoder* self;
  25 +
  26 + Vdec_CallBack_UserData() {
  27 + frameId = 0;
  28 + frame_nb = 0;
  29 + }
  30 +};
  31 +
  32 +
  33 +static long get_cur_time_ms() {
  34 + chrono::time_point<chrono::system_clock, chrono::milliseconds> tpMicro
  35 + = chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now());
  36 + return tpMicro.time_since_epoch().count();
  37 +}
  38 +
  39 +static void *ReportThd(void *arg)
  40 +{
  41 + DvppRtpDecoder *self = (DvppRtpDecoder *)arg;
  42 + if(nullptr != self){
  43 + self->doProcessReport();
  44 + }
  45 + return (void *)0;
  46 +}
  47 +
  48 +static void VdecCallback(acldvppStreamDesc *input, acldvppPicDesc *output, void *pUserData)
  49 +{
  50 + Vdec_CallBack_UserData *userData = (Vdec_CallBack_UserData *) pUserData;
  51 + if(nullptr != userData){
  52 + DvppRtpDecoder* self = userData->self;
  53 + if(self != nullptr){
  54 + self->doVdppVdecCallBack(input, output, userData);
  55 + }
  56 + delete userData;
  57 + userData = nullptr;
  58 + }
  59 +}
  60 +
  61 +static int avio_read_packet(void* opaque, uint8_t* buf, int buffsize){
  62 + DvppRtpDecoder* rtpDecoder = (DvppRtpDecoder*)opaque;
  63 + if(rtpDecoder) {
  64 + return rtpDecoder->ReadBuffer(buf, buffsize);
  65 + }
  66 +
  67 + LOG_ERROR("rtpDecoder is null");
  68 +
  69 + return 0;
  70 +}
  71 +
  72 +DvppRtpDecoder::DvppRtpDecoder(){
  73 + m_read_thread = nullptr;
  74 +
  75 + fmt_ctx = nullptr;
  76 + m_bRunning = false;
  77 +
  78 + mVideoIndex = -1;
  79 + pix_fmt = AV_PIX_FMT_NONE;
  80 + m_dec_name = "";
  81 +
  82 + m_bPause = false;
  83 +
  84 + m_bFinished = false;
  85 + m_dec_keyframe = false;
  86 + m_fps = 0.0;
  87 +}
  88 +
  89 +DvppRtpDecoder::~DvppRtpDecoder() {
  90 + Close();
  91 +
  92 + LOG_DEBUG("[{}]- ~DvppRtpDecoder() in_count:{} out_count:{}", m_dec_name, m_in_count, m_out_count);
  93 +}
  94 +
  95 +bool DvppRtpDecoder::Init(FFDecConfig cfg) {
  96 +
  97 + m_dec_name = cfg.dec_name;
  98 + m_frameSkip = cfg.skip_frame;
  99 +
  100 + m_cfg = cfg;
  101 +
  102 + m_bResize = m_cfg.resize;
  103 +
  104 + decode_finished_cbk = cfg.decode_finished_cbk;
  105 +
  106 + bool bRet = init_dvpp(cfg);
  107 + if(!bRet){
  108 + return false;
  109 + }
  110 +
  111 + m_bFinished = false;
  112 +
  113 + return true;
  114 +}
  115 +
  116 +void DvppRtpDecoder::calcOutResolution(int width, int height) {
  117 + if(m_bResize) {
  118 + float srcRatio = width / (float)height;
  119 + float stdRatio = 1920.0 / 1080.0f ;
  120 + int outWidth = 1920;
  121 + int outHeight = 1080;
  122 + if (srcRatio > stdRatio) {
  123 + outHeight = static_cast<int>(outWidth * (float)height / width) ;
  124 + if (outHeight % 2 == 1) {
  125 + outHeight += 1;
  126 + }
  127 + } else if (srcRatio < stdRatio) {
  128 + outWidth = static_cast<int>(outHeight * (float)width / height) ;
  129 + if (outWidth % 2 == 1) {
  130 + outWidth += 1;
  131 + }
  132 + }
  133 +
  134 + out_frame_width = outWidth;
  135 + out_frame_height = outHeight;
  136 + } else {
  137 + out_frame_width = width;
  138 + out_frame_height = height;
  139 + }
  140 +}
  141 +
  142 +int DvppRtpDecoder::getVdecType(int videoType, int profile)
  143 +{
  144 + int streamFormat = H264_MAIN_LEVEL;
  145 +
  146 + // VDEC only support H265 main level,264 baseline level,main level,high level
  147 + if (videoType == AV_CODEC_ID_HEVC) {
  148 + streamFormat = H265_MAIN_LEVEL;
  149 + } else if (videoType == AV_CODEC_ID_H264) {
  150 + switch (profile) {
  151 + case FF_PROFILE_H264_BASELINE:
  152 + streamFormat = H264_BASELINE_LEVEL;
  153 + break;
  154 + case FF_PROFILE_H264_MAIN:
  155 + streamFormat = H264_MAIN_LEVEL;
  156 + break;
  157 + case FF_PROFILE_H264_HIGH:
  158 + case FF_PROFILE_H264_HIGH_10:
  159 + case FF_PROFILE_H264_HIGH_10_INTRA:
  160 + case FF_PROFILE_H264_MULTIVIEW_HIGH:
  161 + case FF_PROFILE_H264_HIGH_422:
  162 + case FF_PROFILE_H264_HIGH_422_INTRA:
  163 + case FF_PROFILE_H264_STEREO_HIGH:
  164 + case FF_PROFILE_H264_HIGH_444:
  165 + case FF_PROFILE_H264_HIGH_444_PREDICTIVE:
  166 + case FF_PROFILE_H264_HIGH_444_INTRA:
  167 + streamFormat = H264_HIGH_LEVEL;
  168 + break;
  169 + default:
  170 + LOG_INFO("Not support h264 profile {}, use as mp", profile);
  171 + streamFormat = H264_MAIN_LEVEL;
  172 + break;
  173 + }
  174 + } else {
  175 + streamFormat = -1;
  176 + LOG_ERROR("Not support stream, type {}, profile {}", videoType, profile);
  177 + }
  178 +
  179 + return streamFormat;
  180 +}
  181 +
  182 + bool DvppRtpDecoder::init_dvpp(FFDecConfig cfg) {
  183 +
  184 + LOG_INFO("[{}]- Init device start...", m_dec_name);
  185 +
  186 + m_dvpp_deviceId = atoi(cfg.gpuid.c_str());
  187 +
  188 + post_decoded_cbk = cfg.post_decoded_cbk;
  189 +
  190 + do{
  191 + aclError ret = aclrtSetDevice(m_dvpp_deviceId);
  192 + if(ret != ACL_ERROR_NONE){
  193 + LOG_ERROR("[{}]-aclrtSetDevice failed !", m_dec_name);
  194 + break;
  195 + }
  196 +
  197 + ret = aclrtCreateContext(&m_context, m_dvpp_deviceId);
  198 + if (ret != ACL_ERROR_NONE) {
  199 + LOG_ERROR("[{}]-aclrtCreateContext failed !", m_dec_name);
  200 + break;
  201 + }
  202 +
  203 + // DvppSourceManager 创建时包含 aclInit,析构时包含 aclFinalize
  204 + DvppSourceManager* pSrcMgr = DvppSourceManager::getInstance();
  205 + m_dvpp_channel = pSrcMgr->getChannel(m_dvpp_deviceId);
  206 + if(m_dvpp_channel < 0){
  207 + LOG_ERROR("[{}]-该设备channel已经用完了!", m_dec_name);
  208 + break;
  209 + }
  210 +
  211 + m_vpcUtils.init(m_dvpp_deviceId);
  212 +
  213 + LOG_INFO("[{}]- init vdpp success! device:{} channel:{}", m_dec_name, m_dvpp_deviceId, m_dvpp_channel);
  214 + return true;
  215 + }while(0);
  216 +
  217 + release_dvpp();
  218 +
  219 + return false;
  220 +}
  221 +
  222 +bool DvppRtpDecoder::isSurport(FFDecConfig& cfg){
  223 + return true;
  224 +}
  225 +
  226 +bool DvppRtpDecoder::start(){
  227 +
  228 + if(!probe()) {
  229 + return false;
  230 + }
  231 +
  232 + m_bRunning = true;
  233 +
  234 + m_read_thread = new std::thread([](void* arg)
  235 + {
  236 + DvppRtpDecoder* a=(DvppRtpDecoder*)arg;
  237 + a->read_thread();
  238 + return (void*)0;
  239 + }, this);
  240 +
  241 + return true;
  242 +}
  243 +
  244 +void DvppRtpDecoder::Close(){
  245 + m_bRunning=false;
  246 +
  247 + if(m_read_thread != nullptr){
  248 + m_read_thread->join();
  249 + delete m_read_thread;
  250 + m_read_thread = nullptr;
  251 + }
  252 +
  253 + m_recoderManager.close();
  254 +
  255 + release_ffmpeg();
  256 + release_dvpp();
  257 +}
  258 +
  259 +void DvppRtpDecoder::setPostDecArg(const void* postDecArg){
  260 + m_postDecArg = postDecArg;
  261 +}
  262 +
  263 +void DvppRtpDecoder::setFinishedDecArg(const void* finishedDecArg){
  264 + m_finishedDecArg = finishedDecArg;
  265 +}
  266 +
  267 +void DvppRtpDecoder::pause(){
  268 + m_bPause = true;
  269 +}
  270 +
  271 +void DvppRtpDecoder::resume(){
  272 + m_bPause = false;
  273 +}
  274 +
  275 +void DvppRtpDecoder::setDecKeyframe(bool bKeyframe){
  276 + m_dec_keyframe = bKeyframe;
  277 +}
  278 +
  279 +bool DvppRtpDecoder::isRunning(){
  280 + return m_bRunning;
  281 +}
  282 +
  283 +bool DvppRtpDecoder::isFinished(){
  284 + return m_bFinished;
  285 +}
  286 +
  287 +bool DvppRtpDecoder::isPausing(){
  288 + return m_bPause;
  289 +}
  290 +
  291 +bool DvppRtpDecoder::getResolution(int &width, int &height){
  292 + width = frame_width;
  293 + height = frame_height;
  294 + return true;
  295 +}
  296 +
  297 +bool DvppRtpDecoder::getOutResolution( int &width, int &height ) {
  298 + width = out_frame_width;
  299 + height = out_frame_height;
  300 + return true;
  301 +}
  302 +
  303 +float DvppRtpDecoder::fps(){
  304 + return m_fps;
  305 +}
  306 +
  307 +static int snap_count = 0;
  308 +
  309 +DeviceMemory* DvppRtpDecoder::snapshot(){
  310 +
  311 + int ret = aclrtSetCurrentContext(m_context);
  312 + if(ret != ACL_ERROR_NONE){
  313 + LOG_ERROR("[{}]- aclrtSetCurrentContext failed", m_dec_name);
  314 + return nullptr;
  315 + }
  316 +
  317 + // 注意有锁
  318 + DeviceMemory* snapshot_mem = nullptr;
  319 + int loop_times = 0;
  320 + while(m_bRunning) {
  321 + m_decoded_data_queue_mtx.lock();
  322 + if(m_decoded_data_queue.size() <= 0) {
  323 + m_decoded_data_queue_mtx.unlock();
  324 + loop_times++;
  325 + if(loop_times > 100) {
  326 + // 1s都没截取到图,退出
  327 + break;
  328 + }
  329 + std::this_thread::sleep_for(std::chrono::milliseconds(10));
  330 + continue;
  331 + }
  332 +
  333 + DvppDataMemory* mem = m_decoded_data_queue.front();
  334 + snapshot_mem = new DvppDataMemory(mem);
  335 + m_decoded_data_queue_mtx.unlock();
  336 +
  337 + // snap_count++;
  338 + // LOG_INFO("[{}]- snap_count:{} ", m_dec_name, snap_count);
  339 + break;
  340 + }
  341 +
  342 + return snapshot_mem;
  343 +}
  344 +
  345 +void DvppRtpDecoder::release_ffmpeg() {
  346 + m_dec_keyframe = false;
  347 + if(h264bsfc){
  348 + av_bsf_free(&h264bsfc);
  349 + h264bsfc = nullptr;
  350 + }
  351 + if(avctx){
  352 + avcodec_free_context(&avctx);
  353 + avctx = nullptr;
  354 + }
  355 + if (fmt_ctx){
  356 + avformat_close_input(&fmt_ctx);
  357 + fmt_ctx = nullptr;
  358 + }
  359 +
  360 + LOG_DEBUG("[{}]- release_ffmpeg", m_dec_name);
  361 +}
  362 +
  363 +void DvppRtpDecoder::CacheBuffer(uint8_t* recvBuf, int recvBufSize) {
  364 + if ((m_bufferSize + recvBufSize - RTP_HEADER_SIZE) < MAX_RTP_BUFFER_SIZE) {
  365 + memcpy(m_buffer + m_bufferSize, recvBuf + RTP_HEADER_SIZE, recvBufSize - RTP_HEADER_SIZE);
  366 + m_bufferSize += recvBufSize - RTP_HEADER_SIZE;
  367 + } else {
  368 + LOG_WARN("recvBufSize = {} over MAX_RTP_BUFFER_SIZE ", recvBufSize);
  369 + }
  370 +}
  371 +
  372 +int DvppRtpDecoder::ReadBuffer(uint8_t* buf, int buffsize) {
  373 + int ret = 0;
  374 + if (m_bufferSize >= buffsize) {
  375 + memcpy(buf, m_buffer, buffsize);
  376 + m_bufferSize = m_bufferSize - buffsize;
  377 + memmove(m_buffer, m_buffer + buffsize, m_bufferSize);
  378 + ret = buffsize;
  379 +
  380 + LOG_DEBUG("avio_read_packet={}", buffsize);
  381 + }
  382 +
  383 + return ret;
  384 +}
  385 +
  386 +bool DvppRtpDecoder::probe() {
  387 + // todo: 此处可能有泄露
  388 + unsigned char* avioBuff = (unsigned char*)av_malloc(7680 * 4320);
  389 + ioCtx = avio_alloc_context(avioBuff, sizeof(avioBuff), 0, this, avio_read_packet, NULL, NULL);
  390 + //探测流(获取码流格式)
  391 + const AVInputFormat* inputFmt;
  392 + int ret = av_probe_input_buffer2(ioCtx, &inputFmt, "", NULL, 0, 0);
  393 + if (ret < 0){
  394 + LOG_ERROR("av_probe_input_buffer2 error: {}", ret);
  395 + return false;
  396 + }
  397 +
  398 + do{
  399 + fmt_ctx = avformat_alloc_context();
  400 + fmt_ctx->pb = ioCtx;
  401 +
  402 +
  403 + AVDictionary* net_options{nullptr};//网络连接参数
  404 +
  405 + //配置流参数
  406 + //av_dict_set(&net_options, "fflags", "nobuffer", 0); //不缓存直接解码
  407 +
  408 + //打开流
  409 + ret = avformat_open_input(&fmt_ctx, "", inputFmt, &net_options);
  410 + if (ret != 0)
  411 + {
  412 + LOG_ERROR("avformat_open_input error: {}", ret);
  413 + break;
  414 + }
  415 + //获取流信息
  416 + if (avformat_find_stream_info(fmt_ctx, NULL) < 0)//?
  417 + {
  418 + LOG_ERROR("avformat_find_stream_info error");
  419 + break;
  420 + }
  421 + //获取视频流
  422 + mVideoIndex = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
  423 + if (mVideoIndex < 0)
  424 + {
  425 + LOG_ERROR("av_find_best_stream error");
  426 + break;
  427 + }
  428 + //获取解码信息
  429 + AVStream* stream = fmt_ctx->streams[mVideoIndex];
  430 + AVCodecParameters *codecpar = stream->codecpar;
  431 + const AVCodec* videoCodec = avcodec_find_decoder(codecpar->codec_id);
  432 + if (!videoCodec){
  433 + LOG_ERROR("avcodec_find_decoder error");
  434 + break;
  435 + }
  436 + avctx = avcodec_alloc_context3(videoCodec);
  437 +
  438 + //codecpar为解码器上下文赋值
  439 + if (avcodec_parameters_to_context(avctx, codecpar) != 0)
  440 + {
  441 + LOG_ERROR("avcodec_parameters_to_context error");
  442 + break;
  443 + }
  444 +
  445 + int enType = getVdecType(codecpar->codec_id, codecpar->profile);
  446 + if(-1 == enType) {
  447 + break;
  448 + }
  449 + m_enType = static_cast<acldvppStreamFormat>(enType);
  450 +
  451 + const AVBitStreamFilter * filter = nullptr;
  452 + if(codecpar->codec_id == AV_CODEC_ID_H264){
  453 + filter = av_bsf_get_by_name("h264_mp4toannexb");
  454 + }else if(codecpar->codec_id == AV_CODEC_ID_HEVC){
  455 + filter = av_bsf_get_by_name("hevc_mp4toannexb");
  456 + }else {
  457 + LOG_ERROR("[{}]- codec_id is not supported!", m_dec_name);
  458 + break;
  459 + }
  460 +
  461 + ret = av_bsf_alloc(filter, &h264bsfc);
  462 + if (ret < 0){
  463 + break;
  464 + }
  465 +
  466 + avcodec_parameters_copy(h264bsfc->par_in, codecpar);
  467 + av_bsf_init(h264bsfc);
  468 +
  469 + frame_width = codecpar->width;
  470 + frame_height = codecpar->height;
  471 + pix_fmt = (AVPixelFormat)codecpar->format;
  472 +
  473 + calcOutResolution(frame_width, frame_height);
  474 +
  475 + if (stream->avg_frame_rate.den) {
  476 + m_fps = av_q2d(stream ->avg_frame_rate);
  477 + } else {
  478 + m_fps = 0.0;
  479 + }
  480 +
  481 + m_vdec_out_size = frame_width * frame_height * 3 / 2;
  482 +
  483 + if (avctx->gop_size > 0) {
  484 + m_cache_gop = avctx->gop_size + 1;
  485 + } else {
  486 + m_cache_gop = 20;
  487 + }
  488 +
  489 + #ifdef USE_VILLAGE
  490 + bool bRet = m_recoderManager.init(frame_width, frame_height, m_fps, avctx->bit_rate);
  491 + if (!bRet){
  492 + LOG_ERROR("[{}]- m_recoderManager 初始化失败!", m_dec_name);
  493 + }
  494 + #endif
  495 +
  496 + LOG_INFO("[{}]- init ffmpeg success! src:({}, {}) out:({}, {}) fps:{} ", m_dec_name, frame_width, frame_height, out_frame_width, out_frame_height, m_fps);
  497 +
  498 + return true;
  499 + } while(0);
  500 +
  501 + release_ffmpeg();
  502 +
  503 + return false;
  504 +}
  505 +
  506 +void DvppRtpDecoder::read_thread() {
  507 +
  508 + int ret = -1;
  509 +
  510 + m_bExitReportThd = false;
  511 + pthread_t report_thread;
  512 + ret = pthread_create(&report_thread, nullptr, ReportThd, (void *)this);
  513 + if(ret != 0){
  514 + LOG_ERROR("[{}]- pthread_create failed", m_dec_name);
  515 + return;
  516 + }
  517 +
  518 + aclrtContext ctx = nullptr;
  519 + aclvdecChannelDesc *vdecChannelDesc = nullptr;
  520 +
  521 + do {
  522 + CHECK_AND_BREAK(aclrtSetDevice(m_dvpp_deviceId), "aclrtSetDevice failed");
  523 + int ret = aclrtSetCurrentContext(m_context);
  524 + if(ret != ACL_ERROR_NONE){
  525 + LOG_ERROR("[{}]- aclrtSetCurrentContext failed", m_dec_name);
  526 + break;
  527 + }
  528 +
  529 + vdecChannelDesc = aclvdecCreateChannelDesc();
  530 + if (vdecChannelDesc == nullptr) {
  531 + LOG_ERROR("[{}]- aclvdecCreateChannelDesc failed", m_dec_name);
  532 + break;
  533 + }
  534 +
  535 + // 创建 channel dec结构体
  536 + // 通道ID在dvpp层面为0~31
  537 + CHECK_AND_BREAK(aclvdecSetChannelDescChannelId(vdecChannelDesc, m_dvpp_channel), "aclvdecSetChannelDescChannelId failed");
  538 + CHECK_AND_BREAK(aclvdecSetChannelDescThreadId(vdecChannelDesc, report_thread), "aclvdecSetChannelDescThreadId failed");
  539 + CHECK_AND_BREAK(aclvdecSetChannelDescCallback(vdecChannelDesc, VdecCallback), "aclvdecSetChannelDescCallback failed");
  540 + CHECK_AND_BREAK(aclvdecSetChannelDescEnType(vdecChannelDesc, m_enType), "aclvdecSetChannelDescEnType failed");
  541 + CHECK_AND_BREAK(aclvdecSetChannelDescOutPicFormat(vdecChannelDesc, PIXEL_FORMAT_YUV_SEMIPLANAR_420), "aclvdecSetChannelDescOutPicFormat failed");
  542 + CHECK_AND_BREAK(aclvdecCreateChannel(vdecChannelDesc), "aclvdecCreateChannel failed");
  543 +
  544 + unsigned long long frame_nb = 0;
  545 + while (m_bRunning){
  546 +
  547 + AVPacket* pkt = av_packet_alloc();
  548 + av_init_packet( pkt );
  549 + int result = av_read_frame(fmt_ctx, pkt);
  550 + if (result == AVERROR_EOF || result < 0){
  551 + av_packet_free(&pkt);
  552 + pkt = nullptr;
  553 + LOG_WARN("[{}]- Failed to read frame!", m_dec_name);
  554 + break;
  555 + }
  556 +
  557 + if (m_DvppCacheCounter.load() > m_cache_gop){
  558 + // 解码器解码不过来。实时流在此处的处理会导致花屏,这是由于解码器性能问题导致,无法避免
  559 + // 实时流在这里处理是为了避免长时间不读取数据导致数据中断
  560 + std::this_thread::sleep_for(std::chrono::milliseconds(10));
  561 + continue;
  562 + }
  563 +
  564 + if (m_dec_keyframe && !(pkt->flags & AV_PKT_FLAG_KEY)) {
  565 + av_packet_free(&pkt);
  566 + pkt = nullptr;
  567 + continue;
  568 + }
  569 +
  570 + if (mVideoIndex == pkt->stream_index){
  571 +
  572 + ret = av_bsf_send_packet(h264bsfc, pkt);
  573 + if(ret < 0) {
  574 + LOG_ERROR("[{}]- av_bsf_send_packet error!", m_dec_name);
  575 + av_packet_free(&pkt);
  576 + pkt = nullptr;
  577 + continue;
  578 + }
  579 +
  580 + frame_nb++;
  581 + int nSended = -1;
  582 + while ((ret = av_bsf_receive_packet(h264bsfc, pkt)) == 0) {
  583 + if(!m_bRunning){
  584 + break;
  585 + }
  586 + nSended = sendPkt(vdecChannelDesc, pkt, frame_nb);
  587 + }
  588 +
  589 + if(nSended < 0) {
  590 + // 执行出错,强行结束整个任务
  591 + m_bRunning=false;
  592 + break;
  593 + }
  594 +
  595 + #ifdef USE_VILLAGE
  596 + m_recoderManager.cache_pkt(pkt, frame_nb, m_dec_name);
  597 + #endif
  598 + } else {
  599 + av_packet_free(&pkt);
  600 + pkt = nullptr;
  601 + }
  602 + }
  603 +
  604 + if (vdecChannelDesc) {
  605 + sendVdecEos(vdecChannelDesc);
  606 + }
  607 +
  608 + while(m_bRunning && m_decoded_data_queue.size() > 0) {
  609 + std::this_thread::sleep_for(std::chrono::milliseconds(5));
  610 + }
  611 +
  612 + } while (0);
  613 +
  614 + if (vdecChannelDesc) {
  615 + CHECK_NOT_RETURN(aclvdecDestroyChannel(vdecChannelDesc), "aclvdecDestroyChannel failed");
  616 + CHECK_NOT_RETURN(aclvdecDestroyChannelDesc(vdecChannelDesc), "aclvdecDestroyChannelDesc failed");
  617 + vdecChannelDesc = nullptr;
  618 + }
  619 +
  620 + m_bRunning=false;
  621 +
  622 + m_bExitReportThd = true;
  623 + CHECK_NOT_RETURN(pthread_join(report_thread, nullptr), "report_thread join failed");
  624 +
  625 + m_bFinished = true;
  626 +
  627 + LOG_INFO("[{}]- read thread exit.", m_dec_name);
  628 +
  629 + if(decode_finished_cbk) {
  630 + decode_finished_cbk(m_finishedDecArg);
  631 + }
  632 +}
  633 +
  634 +int DvppRtpDecoder::sendPkt(aclvdecChannelDesc *vdecChannelDesc, AVPacket* pkt, unsigned long long frame_nb){
  635 +
  636 + void *vdecInputbuf = nullptr;
  637 + void *vdecOutputBuf = nullptr;
  638 + acldvppStreamDesc *input_stream_desc = nullptr;
  639 + acldvppPicDesc *output_pic_desc = nullptr;
  640 + do{
  641 + int ret = acldvppMalloc((void **)&vdecInputbuf, pkt->size);
  642 + if(ACL_ERROR_NONE != ret){
  643 + LOG_ERROR("[{}]- acldvppMalloc failed!, ret:{}", m_dec_name, ret);
  644 + break;
  645 + }
  646 +
  647 + ret = aclrtMemcpy(vdecInputbuf, pkt->size, pkt->data, pkt->size, ACL_MEMCPY_HOST_TO_DEVICE);
  648 + if(ACL_ERROR_NONE != ret){
  649 + LOG_ERROR("[{}]- aclrtMemcpy failed", m_dec_name);
  650 + break;
  651 + }
  652 +
  653 + ret = acldvppMalloc((void **)&vdecOutputBuf, m_vdec_out_size);
  654 + if(ret != ACL_ERROR_NONE){
  655 + LOG_ERROR("[{}]- acldvppMalloc failed", m_dec_name);
  656 + break;
  657 + }
  658 +
  659 + input_stream_desc = acldvppCreateStreamDesc();
  660 + if (input_stream_desc == nullptr) {
  661 + LOG_ERROR("[{}]- acldvppCreateStreamDesc failed", m_dec_name);
  662 + break;
  663 + }
  664 + output_pic_desc = acldvppCreatePicDesc();
  665 + if (output_pic_desc == nullptr) {
  666 + LOG_ERROR("[{}]- acldvppCreatePicDesc failed", m_dec_name);
  667 + break;
  668 + }
  669 + CHECK_AND_BREAK(acldvppSetStreamDescData(input_stream_desc, vdecInputbuf), "acldvppSetStreamDescData failed");
  670 + CHECK_AND_BREAK(acldvppSetStreamDescSize(input_stream_desc, pkt->size), "acldvppSetStreamDescSize failed");
  671 + CHECK_AND_BREAK(acldvppSetPicDescData(output_pic_desc, vdecOutputBuf), "acldvppSetPicDescData failed");
  672 + CHECK_AND_BREAK(acldvppSetPicDescSize(output_pic_desc, m_vdec_out_size), "acldvppSetPicDescSize failed");
  673 +
  674 + Vdec_CallBack_UserData *user_data = NULL;
  675 + user_data = new Vdec_CallBack_UserData;
  676 + user_data->frameId = frame_nb;
  677 + user_data->frame_nb = frame_nb;
  678 + // user_data->startTime = startTime;
  679 + user_data->sendTime = UtilTools::get_cur_time_ms();
  680 + user_data->self = this;
  681 +
  682 + m_in_count++;
  683 +
  684 + // 内部缓存计数加1
  685 + m_DvppCacheCounter++;
  686 + ret = aclvdecSendFrame(vdecChannelDesc, input_stream_desc, output_pic_desc, nullptr, reinterpret_cast<void *>(user_data));
  687 + if(ret != ACL_ERROR_NONE){
  688 + LOG_ERROR("[{}]- aclvdecSendFrame failed", m_dec_name);
  689 + delete user_data;
  690 + user_data = nullptr;
  691 + return -2;
  692 + }
  693 +
  694 + return 0;
  695 + }while (0);
  696 +
  697 + if (vdecInputbuf){
  698 + acldvppFree(vdecInputbuf);
  699 + vdecInputbuf = nullptr;
  700 + }
  701 +
  702 + // 报错情形
  703 + if(input_stream_desc){
  704 + CHECK_NOT_RETURN(acldvppDestroyStreamDesc(input_stream_desc), "acldvppDestroyStreamDesc failed");
  705 + }
  706 +
  707 + if (vdecOutputBuf){
  708 + acldvppFree(vdecOutputBuf);
  709 + vdecOutputBuf = nullptr;
  710 + }
  711 +
  712 + if(output_pic_desc){
  713 + CHECK_NOT_RETURN(acldvppDestroyPicDesc(output_pic_desc), "acldvppDestroyPicDesc failed");
  714 + }
  715 +
  716 + return -1;
  717 +}
  718 +
  719 +void DvppRtpDecoder::doProcessReport(){
  720 +
  721 + aclError ret = aclrtSetDevice(m_dvpp_deviceId);
  722 + if(ret != ACL_ERROR_NONE){
  723 + // cout << "aclrtSetDevice failed" << endl;
  724 + LOG_ERROR("aclrtSetDevice failed !");
  725 + return ;
  726 + }
  727 +
  728 + aclrtContext ctx;
  729 + ret = aclrtCreateContext(&ctx, m_dvpp_deviceId);
  730 + if (ret != ACL_ERROR_NONE) {
  731 + // cout << "aclrtCreateContext failed " << endl;
  732 + LOG_ERROR("aclrtCreateContext failed !");
  733 + return ;
  734 + }
  735 +
  736 + while (!m_bExitReportThd) {
  737 + aclrtProcessReport(1000);
  738 + }
  739 +
  740 + ret = aclrtDestroyContext(ctx);
  741 + if(ret != ACL_ERROR_NONE){
  742 + LOG_ERROR("aclrtDestroyContext failed !");
  743 + }
  744 + LOG_INFO("doProcessReport exit.");
  745 +}
  746 +
  747 +void DvppRtpDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output, void *pUserData){
  748 +
  749 + // 内部缓存计数减1
  750 + m_DvppCacheCounter--;
  751 +
  752 + if(nullptr == pUserData){
  753 + return;
  754 + }
  755 +
  756 + Vdec_CallBack_UserData *userData = (Vdec_CallBack_UserData *) pUserData;
  757 + uint64_t frame_nb = userData->frame_nb;
  758 +
  759 + m_out_count++;
  760 +
  761 + CHECK_AND_RETURN_NOVALUE(aclrtSetCurrentContext(m_context), "aclrtSetCurrentContext failed");
  762 +
  763 + void *inputDataDev = acldvppGetStreamDescData(input);
  764 + acldvppFree(inputDataDev);
  765 + inputDataDev = nullptr;
  766 +
  767 + void *outputDataDev = acldvppGetPicDescData(output);
  768 + uint32_t outputSize = acldvppGetPicDescSize(output);
  769 + uint32_t width = acldvppGetPicDescWidth(output);
  770 + uint32_t width_stride = acldvppGetPicDescWidthStride(output);
  771 + uint32_t height = acldvppGetPicDescHeight(output);
  772 + uint32_t height_stride = acldvppGetPicDescHeightStride(output);
  773 +
  774 + do{
  775 + int ret = acldvppGetPicDescRetCode(output);
  776 + if(ret != ACL_ERROR_NONE){
  777 + LOG_ERROR("[{}]- decode result error, retCode:{} ", m_dec_name, ret);
  778 + acldvppFree(outputDataDev);
  779 + outputDataDev = nullptr;
  780 + break;
  781 + }
  782 +
  783 + bool bCached = false;
  784 + if(width > 0 && height > 0 && outputSize > 0){
  785 +
  786 + // cout << m_dec_name << " 解码时间间隔: " << get_cur_time_ms() - last_ts << endl;
  787 + // last_ts = get_cur_time_ms();
  788 +
  789 + // 换成解码后数据, 这里这样做的是为了保证解码一直持续进行,避免后续操作阻碍文件读取和解码从而导致花屏
  790 + DvppDataMemory* mem = nullptr;
  791 + if (m_bResize && (width > 1920 || height > 1080)) {
  792 +
  793 + mem = m_vpcUtils.resize(output, out_frame_width, out_frame_height);
  794 + if (mem) {
  795 + acldvppFree(outputDataDev);
  796 + outputDataDev = nullptr;
  797 +
  798 + mem->setDeviceId(to_string(m_dvpp_deviceId));
  799 + mem->setId(m_dec_name);
  800 + mem->setFrameNb(frame_nb);
  801 + }
  802 + } else {
  803 + mem = new DvppDataMemory(width, width_stride, height, height_stride, outputSize, m_dec_name, to_string(m_dvpp_deviceId), false, frame_nb, (unsigned char *)outputDataDev);
  804 + }
  805 +
  806 + if(mem){
  807 + m_decoded_data_queue_mtx.lock();
  808 + m_decoded_data_queue.push(mem);
  809 + m_decoded_data_queue_mtx.unlock();
  810 + bCached = true;
  811 + }
  812 + }
  813 +
  814 + if(!bCached) {
  815 + LOG_WARN("[{}]- decode result warning, width:{} width_stride:{} height:{} height_stride:{} size:{}", m_dec_name, width, width_stride, height, height_stride, outputSize);
  816 + acldvppFree(outputDataDev);
  817 + outputDataDev = nullptr;
  818 + }
  819 + }while(0);
  820 +
  821 + CHECK_AND_RETURN_NOVALUE(acldvppDestroyStreamDesc(input), "acldvppDestroyStreamDesc failed");
  822 + CHECK_AND_RETURN_NOVALUE(acldvppDestroyPicDesc(output), "acldvppDestroyPicDesc failed");
  823 +}
  824 +
  825 +bool DvppRtpDecoder::sendVdecEos(aclvdecChannelDesc *vdecChannelDesc) {
  826 + // create stream desc
  827 + acldvppStreamDesc *streamInputDesc = acldvppCreateStreamDesc();
  828 + if (streamInputDesc == nullptr) {
  829 + LOG_ERROR("[{}]- fail to create input stream desc", m_dec_name);
  830 + return false;
  831 + }
  832 + aclError ret = acldvppSetStreamDescEos(streamInputDesc, 1);
  833 + if (ret != ACL_SUCCESS) {
  834 + LOG_ERROR("[{}]- fail to set eos for stream desc, errorCode = {}", m_dec_name, static_cast<int32_t>(ret));
  835 + (void)acldvppDestroyStreamDesc(streamInputDesc);
  836 + return false;
  837 + }
  838 +
  839 + // send vdec eos frame. when all vdec callback are completed, aclvdecSendFrame can be returned.
  840 + LOG_INFO("[{}]- send eos", m_dec_name);
  841 + ret = aclvdecSendFrame(vdecChannelDesc, streamInputDesc, nullptr, nullptr, nullptr);
  842 + (void)acldvppDestroyStreamDesc(streamInputDesc);
  843 + if (ret != ACL_SUCCESS) {
  844 + LOG_ERROR("[{}]- fail to send eos frame, ret={}", m_dec_name, ret);
  845 + return false;
  846 + }
  847 +
  848 + return true;
  849 +}
  850 +
  851 +DvppDataMemory* DvppRtpDecoder::GetFrame() {
  852 + DvppDataMemory* mem = nullptr;
  853 + m_decoded_data_queue_mtx.lock();
  854 + if (m_decoded_data_queue.size() > 0) {
  855 + mem = m_decoded_data_queue.front();
  856 + m_decoded_data_queue.pop();
  857 + }
  858 + m_decoded_data_queue_mtx.unlock();
  859 +
  860 + return mem;
  861 +}
  862 +
  863 +void DvppRtpDecoder::release_dvpp(){
  864 + if(m_context){
  865 + aclError ret = aclrtDestroyContext(m_context);
  866 + if(ret != ACL_ERROR_NONE){
  867 + LOG_ERROR("[{}]- aclrtDestroyContext failed !", m_dec_name);
  868 + }
  869 + m_context = nullptr;
  870 + }
  871 +
  872 + if(m_dvpp_channel >= 0){
  873 + DvppSourceManager* pSrcMgr = DvppSourceManager::getInstance();
  874 + pSrcMgr->releaseChannel(m_dvpp_deviceId, m_dvpp_channel);
  875 + m_dvpp_channel = -1;
  876 + }
  877 +}
  878 +
  879 +void DvppRtpDecoder::doRecode(RecoderInfo& recoderInfo) {
  880 + m_recoderManager.create_recode_task(recoderInfo);
  881 +}
  882 +
  883 +void DvppRtpDecoder::set_mq_callback(mq_callback_t cb) {
  884 + m_recoderManager.set_mq_callback(cb);
  885 +}
0 886 \ No newline at end of file
... ...
src/decoder/dvpp/DvppRtpDecoder.h 0 → 100644
  1 +#ifndef __DVPP_RTP_DECODER_H__
  2 +#define __DVPP_RTP_DECODER_H__
  3 +
  4 +#include <stdint.h>
  5 +#include <atomic>
  6 +#include <thread>
  7 +#include <queue>
  8 +#include <mutex>
  9 +#include <chrono>
  10 +#include<string>
  11 +
  12 +#include "depend_headers.h"
  13 +#include "dvpp_headers.h"
  14 +#include "DvppDataMemory.hpp"
  15 +
  16 +#include "FFRecoderTaskManager.h"
  17 +
  18 +#include "VpcUtils.h"
  19 +
  20 +using namespace std;
  21 +
  22 +#define MAX_RTP_BUFFER_SIZE 4194304 // 4M = 4 * 1024 * 1024 = 4194304 字节
  23 +
  24 +class DvppRtpDecoder
  25 +{
  26 +public:
  27 + DvppRtpDecoder();
  28 + ~DvppRtpDecoder();
  29 +
  30 +public:
  31 + std::atomic<char> m_buffer[MAX_RTP_BUFFER_SIZE];
  32 + std::atomic_int m_bufferSize {0};
  33 +
  34 +public:
  35 + bool Init(FFDecConfig cfg);
  36 + void Close();
  37 + bool start();
  38 + void pause();
  39 + void resume();
  40 +
  41 + void setDecKeyframe(bool bKeyframe);
  42 +
  43 + bool isRunning();
  44 + bool isFinished();
  45 + bool isPausing();
  46 + bool getResolution( int &width, int &height );
  47 + bool getOutResolution( int &width, int &height );
  48 +
  49 + bool isSurport(FFDecConfig& cfg);
  50 +
  51 + float fps();
  52 +
  53 + void setName(string nm){
  54 + m_dec_name = nm;
  55 + }
  56 +
  57 + string getName(){
  58 + return m_dec_name;
  59 + }
  60 +
  61 + DeviceMemory* snapshot();
  62 +
  63 + void setPostDecArg(const void* postDecArg);
  64 + void setFinishedDecArg(const void* finishedDecArg);
  65 +
  66 + DvppDataMemory* GetFrame();
  67 +
  68 + void doRecode(RecoderInfo& recoderInfo);
  69 +
  70 + void set_mq_callback(mq_callback_t cb);
  71 +
  72 + void CacheBuffer(uint8_t* buf, int buf_size);
  73 +
  74 + int ReadBuffer(uint8_t* buf, int buffsize);
  75 +
  76 +public:
  77 + void doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output, void *pUserData);
  78 + void doProcessReport();
  79 +
  80 +private:
  81 + bool init_dvpp(FFDecConfig cfg);
  82 + void release_ffmpeg();
  83 + void read_thread();
  84 + bool probe();//阻塞式探测国标流并获取解码参数
  85 +
  86 + int sendPkt(aclvdecChannelDesc *vdecChannelDesc, AVPacket* pkt, unsigned long long frame_nb);
  87 + bool sendVdecEos(aclvdecChannelDesc *vdecChannelDesc);
  88 + void release_dvpp();
  89 +
  90 + int getVdecType(int videoType, int profile);
  91 +
  92 + void calcOutResolution(int w, int h);
  93 +
  94 +private:
  95 + FFDecConfig m_cfg;
  96 + string m_dec_name;
  97 +
  98 + const void * m_finishedDecArg {nullptr};
  99 + DECODE_FINISHED_CALLBACK decode_finished_cbk {nullptr};
  100 +
  101 + bool m_bFinished{false};
  102 + bool m_bRunning{false};
  103 + bool m_bPause{false};
  104 +
  105 + bool m_bExitReportThd{false};
  106 +
  107 + // 读取数据
  108 + AVFormatContext *fmt_ctx{nullptr};
  109 + AVIOContext * ioCtx{nullptr};
  110 + int mVideoIndex {-1};
  111 + AVPixelFormat pix_fmt;
  112 + AVCodecContext *avctx{nullptr};
  113 + AVBSFContext * h264bsfc{nullptr};
  114 +
  115 + int frame_width{0};
  116 + int frame_height{0};
  117 + int out_frame_width{0};
  118 + int out_frame_height{0};
  119 + float m_fps{0.0};
  120 +
  121 + std::thread* m_read_thread{nullptr};
  122 +
  123 + bool m_dec_keyframe {false};
  124 + bool m_bResize {false};
  125 +
  126 + // 解码
  127 + int m_dvpp_deviceId {-1};
  128 + int m_dvpp_channel {-1};
  129 + aclrtContext m_context{nullptr};
  130 + acldvppStreamFormat m_enType;
  131 +
  132 + const void * m_postDecArg {nullptr};
  133 + POST_DECODE_CALLBACK post_decoded_cbk {nullptr};
  134 +
  135 + int m_vdec_out_size {-1};
  136 +
  137 + FFRecoderTaskManager m_recoderManager;
  138 +
  139 + queue<DvppDataMemory*> m_decoded_data_queue;
  140 + mutex m_decoded_data_queue_mtx;
  141 +
  142 + long long last_ts {0};
  143 +
  144 + long long m_last_read_ts {0};
  145 +
  146 + uint64_t m_in_count {0};
  147 + uint64_t m_out_count {0};
  148 +
  149 + int m_frameSkip {1};
  150 +
  151 + std::atomic<int> m_DvppCacheCounter{0};
  152 + int m_cache_gop{0};
  153 +
  154 + VpcUtils m_vpcUtils;
  155 +
  156 +};
  157 +#endif //__DVPP_RTP_DECODER_H__
0 158 \ No newline at end of file
... ...
src/decoder/dvpp/DvppStreamDecoder.cpp
... ... @@ -668,6 +668,16 @@ void DvppStreamDecoder::Close() {
668 668 decode_finished_cbk(m_finishedDecArg);
669 669 decode_finished_cbk = nullptr;
670 670 }
  671 +
  672 + DvppDataMemory* mem = nullptr;
  673 + m_decoded_data_queue_mtx.lock();
  674 + while (m_decoded_data_queue.size() > 0) {
  675 + mem = m_decoded_data_queue.front();
  676 + delete mem;
  677 + mem = nullptr;
  678 + m_decoded_data_queue.pop();
  679 + }
  680 + m_decoded_data_queue_mtx.unlock();
671 681 }
672 682  
673 683 void DvppStreamDecoder::doRecode(RecoderInfo& recoderInfo) {
... ...
src/decoder/dvpp/FFRecoder.cpp
... ... @@ -134,10 +134,17 @@ bool FFRecoder::init(AVStream* stream, AVCodecContext* avctx, const char* outfil
134 134 return false;
135 135 }
136 136  
137   - avcodec_copy_context(codec_ctx_, avctx);
138   - codec_ctx_->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
139 137 m_inStream = stream;
140 138  
  139 + int ret = avcodec_parameters_to_context(codec_ctx_, m_inStream->codecpar);
  140 + if (ret < 0) {
  141 + printf("Failed to copy in_stream codecpar to codec context\n");
  142 + return false;
  143 + }
  144 +
  145 + // avcodec_copy_context(codec_ctx_, avctx);
  146 + codec_ctx_->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
  147 +
141 148 // [2] 创建输出上下文
142 149 avformat_alloc_output_context2(&fmt_ctx_, nullptr, nullptr, outfile_name);
143 150  
... ... @@ -154,8 +161,8 @@ bool FFRecoder::init(AVStream* stream, AVCodecContext* avctx, const char* outfil
154 161  
155 162 codec_ctx_->time_base = out_stream_->time_base;
156 163  
157   - av_opt_set(out_stream_->codec->priv_data, "preset", "ultrafast", 0);
158   - av_opt_set(out_stream_->codec->priv_data, "tune", "zerolatency", 0);
  164 + av_opt_set(out_stream_->priv_data, "preset", "ultrafast", 0);
  165 + av_opt_set(out_stream_->priv_data, "tune", "zerolatency", 0);
159 166  
160 167 // av_dump_format(fmt_ctx_, out_stream_->id, outfile_name, 1);
161 168  
... ... @@ -175,8 +182,7 @@ bool FFRecoder::init(AVStream* stream, AVCodecContext* avctx, const char* outfil
175 182 void FFRecoder::release() {
176 183 av_write_trailer(fmt_ctx_);
177 184  
178   - avcodec_close(fmt_ctx_->streams[0]->codec);
179   - av_freep(&fmt_ctx_->streams[0]->codec);
  185 + avcodec_parameters_free(&fmt_ctx_->streams[0]->codecpar);
180 186 av_freep(&fmt_ctx_->streams[0]);
181 187  
182 188 avio_close(fmt_ctx_->pb);
... ...
src/decoder/dvpp/depend_headers.h
... ... @@ -27,9 +27,10 @@ extern &quot;C&quot; {
27 27 #include "libavutil/samplefmt.h"
28 28 #include "libavformat/avformat.h"
29 29 #include "libavcodec/avcodec.h"
30   - #include <libavutil/opt.h>
31   - #include <libavutil/timestamp.h>
32   - #include <libswscale/swscale.h>
  30 + #include "libavcodec/bsf.h"
  31 + #include "libavutil/opt.h"
  32 + #include "libavutil/timestamp.h"
  33 + #include "libswscale/swscale.h"
33 34 }
34 35  
35 36  
... ...
src/decoder/gb28181/DvppGB28181Decoder.cpp renamed to src/decoder/gb28181/DvppGB28181Decoder.cpp0
... ... @@ -373,10 +373,6 @@ bool DvppGB28181Decoder::isSurport(FFDecConfig&amp; cfg){
373 373 return true;
374 374 }
375 375  
376   -int DvppGB28181Decoder::getCachedQueueLength(){
377   - return m_rtpPtr->GetPsFrameListSize();
378   -}
379   -
380 376 DeviceMemory* DvppGB28181Decoder::snapshot() {
381 377  
382 378 DeviceMemory* snapshot_mem = nullptr;
... ...
src/decoder/gb28181/DvppGB28181Decoder.h
... ... @@ -42,8 +42,6 @@ public:
42 42  
43 43 bool isSurport(FFDecConfig& cfg);
44 44  
45   - int getCachedQueueLength();
46   -
47 45 float fps();
48 46  
49 47 DECODER_TYPE getDecoderType(){ return DECODER_TYPE_DVPP_GB28181; }
... ...
src/decoder/gb28181/DvppGB28181Decoder2.cpp 0 → 100644
  1 +//#include "LOG_manager.h"
  2 +#include <iostream>
  3 +#include "DvppGB28181Decoder2.h"
  4 +#include "common_header.h"
  5 +
  6 +
  7 +#define ECLOSED 0
  8 +#define ECLOSING 1
  9 +#define ERUNNING 2
  10 +#define EPAUSE 3
  11 +#define EINITED 4
  12 +
  13 +static void RTP_Stream_CallBack(void* userdata, uint8_t* buf, int buf_size, uint64_t pts)
  14 +{
  15 + DvppGB28181Decoder2* decoder = (DvppGB28181Decoder2*)userdata;
  16 + decoder->stream_callback(buf, buf_size, pts);
  17 +}
  18 +
  19 +static void RTP_Stream_End_CallBack(void* userdata)
  20 +{
  21 + DvppGB28181Decoder2* decoder = (DvppGB28181Decoder2*)userdata;
  22 + decoder->stream_end_callback();
  23 +}
  24 +
  25 +DvppGB28181Decoder2::DvppGB28181Decoder2() {
  26 + m_frameSkip = 1;
  27 + m_dec_keyframe = false;
  28 + m_post_decode_thread = 0;
  29 +}
  30 +
  31 +DvppGB28181Decoder2::~DvppGB28181Decoder2()
  32 +{
  33 + close();
  34 +
  35 + m_dec_keyframe = false;
  36 +
  37 + LOG_INFO("destroy OK--{}", m_dec_name);
  38 +}
  39 +
  40 +void DvppGB28181Decoder2::close(){
  41 +
  42 + if (m_status == ECLOSED) return;
  43 +
  44 + m_status = ECLOSING;
  45 +
  46 + LOG_DEBUG("real decode thread exit success 1--{}", m_dec_name);
  47 +
  48 + if(nullptr != m_rtpPtr){
  49 + if (m_rtpPtr->IsOpened()) {
  50 + m_rtpPtr->Close();
  51 + LOG_DEBUG("real decode thread exit success 2--{}", m_dec_name);
  52 + }
  53 +
  54 + delete m_rtpPtr;
  55 + m_rtpPtr = nullptr;
  56 + }
  57 +
  58 + if (m_post_decode_thread != 0) {
  59 + pthread_join(m_post_decode_thread,0);
  60 + m_post_decode_thread = 0;
  61 + }
  62 +
  63 + rtpDecoder.Close();
  64 +
  65 + m_status = ECLOSED;
  66 +
  67 + LOG_INFO("解码器关闭成功 --{}", m_dec_name);
  68 +}
  69 +
  70 +bool DvppGB28181Decoder2::init(FFDecConfig& cfg){
  71 +
  72 + m_rtpPtr = new RTPReceiver2();
  73 + if(nullptr == m_rtpPtr){
  74 + return false;
  75 + }
  76 +
  77 + m_dec_name = cfg.dec_name;
  78 + m_frameSkip = cfg.skip_frame;
  79 + if (m_frameSkip < 1) m_frameSkip = 1;
  80 +
  81 + m_gpuid = atoi(cfg.gpuid.c_str());
  82 +
  83 + m_rtpPtr->SetOutputCallback(RTP_Stream_CallBack, this);
  84 + m_rtpPtr->SetVodEndCallback(RTP_Stream_End_CallBack, this);
  85 +
  86 + post_decoded_cbk = cfg.post_decoded_cbk;
  87 + decode_finished_cbk = cfg.decode_finished_cbk;
  88 +
  89 + if (!rtpDecoder.Init(cfg)) {
  90 + return false;
  91 + }
  92 +
  93 + m_cfg = cfg;
  94 +
  95 + LOG_INFO("init - {} ", m_dec_name);
  96 +
  97 + m_status = EINITED;
  98 +
  99 + return true;
  100 +}
  101 +
  102 +bool DvppGB28181Decoder2::start() {
  103 +
  104 + m_status = ERUNNING;
  105 +
  106 + bool bRet = m_rtpPtr->Open(m_cfg.uri, !m_cfg.force_tcp);
  107 + if(bRet && rtpDecoder.start()) {
  108 + pthread_create(&m_post_decode_thread,0,
  109 + [](void* arg)
  110 + {
  111 + DvppGB28181Decoder2* a=(DvppGB28181Decoder2*)arg;
  112 + a->display_thread();
  113 + return (void*)0;
  114 + }
  115 + ,this);
  116 +
  117 + return true;
  118 + }
  119 +
  120 + close();
  121 +
  122 + LOG_ERROR("[{}] - rtp receiver open failed !", m_dec_name);
  123 +
  124 + return false;
  125 +}
  126 +
  127 +void DvppGB28181Decoder2::setDecKeyframe(bool bKeyframe){
  128 + m_dec_keyframe = bKeyframe;
  129 +}
  130 +
  131 +void DvppGB28181Decoder2::stream_callback(uint8_t* buf, int buf_size, uint64_t pts) {
  132 + if (m_status == EPAUSE) return;
  133 +
  134 + // 若设置为关键帧解码,非关键帧数据直接返回
  135 + // if(m_dec_keyframe && !isKey) return;
  136 +
  137 + rtpDecoder.CacheBuffer(buf, buf_size);
  138 +}
  139 +
  140 +void DvppGB28181Decoder2::display_thread(){
  141 +
  142 + int index = 0;
  143 + while (isRunning())
  144 + {
  145 + auto mem = rtpDecoder.GetFrame();
  146 + if(mem) {
  147 + if ((m_frameSkip == 1 || index % m_frameSkip == 0) && post_decoded_cbk){
  148 + post_decoded_cbk(m_postDecArg, mem);
  149 + } else {
  150 + delete mem;
  151 + mem = nullptr;
  152 + }
  153 +
  154 + index++;
  155 + if(index >= 100000){
  156 + index = 0;
  157 + }
  158 + }
  159 +
  160 + std::this_thread::sleep_for(std::chrono::milliseconds(10));
  161 + }
  162 +
  163 + LOG_INFO("[{}] - display thread exited.", m_dec_name);
  164 +}
  165 +
  166 +void DvppGB28181Decoder2::stream_end_callback()
  167 +{
  168 + LOG_INFO("[{}] - stream end.", m_dec_name);
  169 +
  170 + m_status = ECLOSING;
  171 +
  172 + decode_finished_cbk(m_finishedDecArg);
  173 +
  174 + return;
  175 +}
  176 +
  177 +void DvppGB28181Decoder2::setPostDecArg(const void* postDecArg){
  178 + m_postDecArg = postDecArg;
  179 +}
  180 +
  181 +void DvppGB28181Decoder2::setFinishedDecArg(const void* finishedDecArg){
  182 + m_finishedDecArg = finishedDecArg;
  183 +}
  184 +
  185 +void DvppGB28181Decoder2::pause() {
  186 + m_status = EPAUSE;
  187 + LOG_INFO("[{}] - pause", m_dec_name);
  188 +}
  189 +
  190 +void DvppGB28181Decoder2::resume() {
  191 + m_status = ERUNNING;
  192 + LOG_INFO("[{}] - resume", m_dec_name);
  193 +}
  194 +
  195 +bool DvppGB28181Decoder2::isRunning(){
  196 + if (m_status == ECLOSED || m_status == ECLOSING){
  197 + return false;
  198 + }
  199 + return true;
  200 +}
  201 +
  202 +bool DvppGB28181Decoder2::isFinished(){
  203 + if (m_status == ECLOSED || m_status == ECLOSING){
  204 + return true;
  205 + }
  206 + return false;
  207 +}
  208 +
  209 +bool DvppGB28181Decoder2::isPausing(){
  210 + if (m_status == EPAUSE){
  211 + return true;
  212 + }
  213 + return false;
  214 +}
  215 +
  216 +bool DvppGB28181Decoder2::getResolution( int &width, int &height ){
  217 + width = frameW;
  218 + height = frameH;
  219 + return true;
  220 +}
  221 +
  222 +bool DvppGB28181Decoder2::getOutResolution( int &width, int &height ) {
  223 + width = frameW;
  224 + height = frameH;
  225 + return true;
  226 +}
  227 +
  228 +float DvppGB28181Decoder2::fps() {
  229 + return m_fps;
  230 +}
  231 +
  232 +bool DvppGB28181Decoder2::isSurport(FFDecConfig& cfg){
  233 + // 由于是否支持需要在拿到数据后才能断定,无法事先判断,所以这个地方默认返回true
  234 + return true;
  235 +}
  236 +
  237 +DeviceMemory* DvppGB28181Decoder2::snapshot() {
  238 +
  239 + DeviceMemory* snapshot_mem = nullptr;
  240 + int loop_times = 0;
  241 + while (isRunning()) {
  242 + snapshot_mem = rtpDecoder.GetFrame();
  243 + if (snapshot_mem) {
  244 + break;
  245 + }
  246 +
  247 + loop_times++;
  248 + if(loop_times > 100) {
  249 + // 1s都没截取到图,退出
  250 + break;
  251 + }
  252 + std::this_thread::sleep_for(std::chrono::milliseconds(10));
  253 + }
  254 +
  255 + return snapshot_mem;
  256 +}
  257 +
  258 +void DvppGB28181Decoder2::doRecode(RecoderInfo& recoderInfo) {
  259 + return rtpDecoder.doRecode(recoderInfo);
  260 +}
  261 +
  262 +void DvppGB28181Decoder2::set_mq_callback(std::function<bool(const char *msg)> mq_publish) {
  263 + rtpDecoder.set_mq_callback(mq_publish);
  264 +}
0 265 \ No newline at end of file
... ...
src/decoder/gb28181/DvppGB28181Decoder2.h 0 → 100644
  1 +#ifndef _GB28181_DECODER_H_
  2 +#define _GB28181_DECODER_H_
  3 +
  4 +#include <atomic>
  5 +#include <mutex>
  6 +
  7 +#include "./rtp2/RTPReceiver2.h"
  8 +#include "../dvpp/DvppRtpDecoder.h"
  9 +
  10 +#include "common_header.h"
  11 +#include "../interface/AbstractDecoder.h"
  12 +
  13 +using namespace std;
  14 +
  15 +class DvppGB28181Decoder2: public AbstractDecoder
  16 +{
  17 +public:
  18 + DvppGB28181Decoder2();
  19 + ~DvppGB28181Decoder2();
  20 +
  21 + bool init(FFDecConfig& cfg);
  22 + void close();
  23 + bool start();
  24 + void pause();
  25 + void resume();
  26 +
  27 + void setDecKeyframe(bool bKeyframe);
  28 +
  29 + bool isRunning();
  30 + bool isFinished();
  31 + bool isPausing();
  32 + bool getResolution( int &width, int &height );
  33 + bool getOutResolution( int &width, int &height );
  34 +
  35 + bool isSurport(FFDecConfig& cfg);
  36 +
  37 + float fps();
  38 +
  39 + DECODER_TYPE getDecoderType(){ return DECODER_TYPE_DVPP_GB28181; }
  40 +
  41 + DeviceMemory* snapshot();
  42 +
  43 + void setName(string nm){
  44 + m_dec_name = nm;
  45 + }
  46 +
  47 + string getName(){
  48 + return m_dec_name;
  49 + }
  50 +
  51 + void setPostDecArg(const void* postDecArg);
  52 + void setFinishedDecArg(const void* finishedDecArg);
  53 +
  54 + void doRecode(RecoderInfo& recoderInfo);
  55 +
  56 + void set_mq_callback(std::function<bool(const char *msg)> mq_publish);
  57 +
  58 +public:
  59 + void stream_callback(uint8_t* buf, int buf_size, uint64_t pts);
  60 + void stream_end_callback();
  61 + void display_thread();
  62 +
  63 +private:
  64 + string m_dec_name; // 必须为28181编码
  65 + FFDecConfig m_cfg;
  66 +
  67 + RTPReceiver2* m_rtpPtr {nullptr};
  68 +
  69 + uint64_t m_startPts {};
  70 + uint64_t m_lastPts {}; //上一次pts的值
  71 + uint64_t m_curPts {}; //当前的pts值
  72 + uint64_t m_diffPts {};
  73 +
  74 + uint32_t frameW {}, frameH {};
  75 + float m_fps {};
  76 + int m_frameSkip {};
  77 +
  78 + int log_count {};
  79 +
  80 + std::atomic_int m_status {};
  81 +
  82 + pthread_t m_post_decode_thread;
  83 + const void * m_postDecArg;
  84 + POST_DECODE_CALLBACK post_decoded_cbk; // 解码数据回调接口
  85 +
  86 + const void * m_finishedDecArg;
  87 + DECODE_FINISHED_CALLBACK decode_finished_cbk;
  88 +
  89 + queue<AVFrame*> mFrameQueue;
  90 + mutex m_queue_mutex;
  91 + mutex m_snapshot_mutex;
  92 +
  93 + bool m_dec_keyframe;
  94 +
  95 + DvppRtpDecoder rtpDecoder;
  96 +
  97 + int m_gpuid {0};
  98 +};
  99 +
  100 +#endif // _GB28181_DECODER_H_
... ...
src/decoder/gb28181/rtp/FFRtpParser.cpp deleted
1   -//
2   -// Created by bxc on 2023/4/18.
3   -// 作者:北小菜
4   -// 邮箱:bilibili_bxc@126.com
5   -// 西瓜视频主页:https://www.ixigua.com/home/4171970536803763
6   -// 哔哩哔哩主页:https://space.bilibili.com/487906612/
7   -//
8   -
9   -#include "FFRtpParser.h"
10   -#include "Utils.h"
11   -#include <string.h>
12   -
13   -int avio_read_packet(void* opaque, uint8_t* buf, int buffsize){
14   - FFRtpParser* player = (FFRtpParser*)opaque;
15   -
16   - int ret = 0;
17   - if (player->bufferSize >= buffsize)
18   - {
19   - memcpy(buf, player->buffer, buffsize);
20   - player->bufferSize = player->bufferSize - buffsize;
21   - memmove(player->buffer, player->buffer + buffsize, player->bufferSize);
22   - ret = buffsize;
23   -
24   - LOG_INFO("avio_read_packet=%d", buffsize);
25   - }
26   - return ret;
27   -}
28   -
29   -FFRtpParser::FFRtpParser()
30   -{
31   -}
32   -
33   -FFRtpParser::~FFRtpParser()
34   -{
35   - if (mVideoCodecPar) {
36   - avcodec_parameters_free(&mVideoCodecPar);
37   - }
38   - if (mVideoCodecCtx) {
39   - avcodec_close(mVideoCodecCtx);
40   - mVideoCodecCtx = nullptr;
41   - }
42   -
43   - if (mFmtCtx) {
44   - avformat_close_input(&mFmtCtx);
45   - mFmtCtx = nullptr;
46   - }
47   -}
48   -
49   -bool FFRtpParser::probe()
50   -{
51   - mFmtCtx = avformat_alloc_context();
52   -
53   - unsigned char* avioBuff = (unsigned char*)av_malloc(1920 * 1080);
54   - mAvioCtx = avio_alloc_context(avioBuff, sizeof(avioBuff), 0, this, avio_read_packet, NULL, NULL);
55   - //探测流(获取码流格式)
56   - if (av_probe_input_buffer2(mAvioCtx, (const AVInputFormat**)&mInputFmt, "", NULL, 0, 0) < 0){
57   - LOG_ERROR("av_probe_input_buffer2 error");
58   - return false;
59   - }
60   - mFmtCtx->pb = mAvioCtx;
61   -
62   - //配置流参数
63   - //av_dict_set(&options, "fflags", "nobuffer", 0); //不缓存直接解码
64   -
65   - //打开流
66   - if (avformat_open_input(&mFmtCtx, "", mInputFmt, &net_options) != 0)
67   - {
68   - LOG_ERROR("avformat_open_input error");
69   - return false;
70   - }
71   - //获取流信息
72   - if (avformat_find_stream_info(mFmtCtx, NULL) < 0)//?
73   - {
74   - LOG_ERROR("avformat_find_stream_info error");
75   - return false;
76   - }
77   - //获取视频流
78   - mVideoStream = av_find_best_stream(mFmtCtx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
79   - if (mVideoStream < 0)
80   - {
81   - LOG_ERROR("av_find_best_stream error");
82   - return false;
83   - }
84   - //获取解码信息
85   - mVideoCodecPar = mFmtCtx->streams[mVideoStream]->codecpar;
86   - const AVCodec* videoCodec = avcodec_find_decoder(mVideoCodecPar->codec_id);
87   - if (!videoCodec){
88   - LOG_ERROR("avcodec_find_decoder error");
89   - return false;
90   - }
91   - mVideoCodecCtx = avcodec_alloc_context3(videoCodec);
92   -
93   - //codecpar为解码器上下文赋值
94   - if (avcodec_parameters_to_context(mVideoCodecCtx, mVideoCodecPar) != 0)
95   - {
96   - LOG_ERROR("avcodec_parameters_to_context error");
97   - return false;
98   - }
99   -
100   - //设置解码器参数
101   - //av_dict_set(&codec_options, "tune", "zero-latency", 0);//设置零延迟
102   - //av_dict_set(&codec_options, "preset", "ultrafast", 0);//设置最模糊但是最快的解码方式
103   - //av_dict_set(&codec_options, "x265-params", "qp=20", 0);//设置265量化参数
104   - //量化参数:控制了视频帧中每一个宏区块(Macroblock)的压缩量。较大的数值,量化值更高,意味着更多的压缩,更低的质量,较小的数值代表相反的含义。
105   -
106   - //打开解码器
107   - if (avcodec_open2(mVideoCodecCtx, videoCodec, &codec_options) < 0)
108   - {
109   - LOG_ERROR("avcodec_open2 error");
110   - return false;
111   - }
112   - LOG_INFO("mVideoCodecCtx->width=%d,mVideoCodecCtx->height=%d", mVideoCodecCtx->width, mVideoCodecCtx->height);
113   - return true;
114   -}
115   -
116   -void FFRtpParser::play(){
117   - LOG_INFO("start");
118   -
119   - AVPacket pkt;
120   - while (av_read_frame(mFmtCtx, &pkt) >= 0) {
121   - if (pkt.stream_index == mVideoStream){
122   -
123   - }
124   - av_packet_unref(&pkt);
125   - }
126   - LOG_INFO("end");
127   -}
128 0 \ No newline at end of file
src/decoder/gb28181/rtp/FFRtpParser.h deleted
1   -//
2   -// Created by bxc on 2023/4/18.
3   -// 作者:北小菜
4   -// 邮箱:bilibili_bxc@126.com
5   -// 西瓜视频主页:https://www.ixigua.com/home/4171970536803763
6   -// 哔哩哔哩主页:https://space.bilibili.com/487906612/
7   -//
8   -
9   -#ifndef GB28181_RTP_FFRTPPARSER_H
10   -#define GB28181_RTP_FFRTPPARSER_H
11   -
12   -#include <atomic>
13   -
14   -extern "C"
15   -{
16   - #include <libavcodec/avcodec.h>
17   - #include <libavformat/avformat.h>
18   - #include <libswscale/swscale.h>
19   -}
20   -
21   -#define RtpParser_buffer_max_size 4194304 // 4M = 4 * 1024 * 1024 = 4194304 字节
22   -
23   -class FFRtpParser
24   -{
25   -public:
26   - FFRtpParser();
27   - ~FFRtpParser();
28   -public:
29   - bool probe();//阻塞式探测国标流并获取解码参数
30   - void play();//在探测国标流成功以后,解码并渲染国标视频流
31   -public:
32   - std::atomic<char> buffer[RtpParser_buffer_max_size];
33   - std::atomic_int bufferSize {0};
34   -private:
35   - AVFormatContext * mFmtCtx;
36   - AVIOContext * mAvioCtx;
37   - const AVInputFormat* mInputFmt;
38   - int mVideoStream = -1;
39   - AVCodecParameters * mVideoCodecPar;
40   - AVCodecContext * mVideoCodecCtx;
41   -
42   - AVDictionary* net_options;//网络连接参数
43   - AVDictionary* codec_options;//编码参数
44   -
45   -};
46   -#endif //GB28181_RTP_FFRTPPARSER_H
47 0 \ No newline at end of file
src/decoder/gb28181/rtp/RTPReceiver2.cpp deleted
1   -#include "RTPReceiver2.h"
2   -#include "rtppacket.h"
3   -#include <thread>
4   -
5   -#include "../common_header.h"
6   -#include "../websocket/WebsocketClient.h"
7   -
8   -#ifdef __linux__
9   -#include "arpa/inet.h"
10   -#endif
11   -
12   -#include "Rtp.h"
13   -
14   -const int MAX_RTP_BUFFER_SIZE = 1024*1024*10;
15   -
16   -#define Server_cache_max_size 4194304 // 1M = 1 * 1024 * 1024 = 1048576 字节
17   -#define Server_rtp_max_size 1800
18   -
19   -
20   -RTPReceiver2::RTPReceiver2()
21   -{
22   - mRecvCache = (uint8_t*)malloc(Server_cache_max_size);
23   - mRecvRtpBuffer = (uint8_t*)malloc(Server_rtp_max_size);
24   -}
25   -
26   -RTPReceiver2::~RTPReceiver2(){
27   - if (mRecvCache) {
28   - free(mRecvCache);
29   - mRecvCache = nullptr;
30   - }
31   -
32   - if (mRecvRtpBuffer) {
33   - free(mRecvRtpBuffer);
34   - mRecvRtpBuffer = nullptr;
35   - }
36   -}
37   -
38   -int RTPReceiver2::init(const char* ip, uint16_t port, bool isUdp) {
39   - if (!isUdp) {
40   - LOG_INFO("tcp://%s:%d", ip, port);
41   - startTcpServer(ip, port);
42   - }
43   - else {
44   - LOG_INFO("udp://%s:%d", ip, port);
45   - startUdpServer(ip, port);
46   - }
47   -}
48   -
49   -int RTPReceiver2::startUdpServer(const char* ip, uint16_t port) {
50   -
51   - int server_fd, ret;
52   - struct sockaddr_in ser_addr;
53   -
54   - server_fd = socket(AF_INET, SOCK_DGRAM, 0); //AF_INET:IPV4;SOCK_DGRAM:UDP
55   - if(server_fd < 0)
56   - {
57   - printf("create socket fail!\n");
58   - return -1;
59   - }
60   -
61   - memset(&ser_addr, 0, sizeof(ser_addr));
62   - ser_addr.sin_family = AF_INET;
63   - ser_addr.sin_addr.s_addr = htonl(INADDR_ANY); //IP地址,需要进行网络序转换,INADDR_ANY:本地地址
64   - ser_addr.sin_port = htons(port); //端口号,需要网络序转换
65   -
66   - ret = bind(server_fd, (struct sockaddr*)&ser_addr, sizeof(ser_addr));
67   - if(ret < 0)
68   - {
69   - printf("socket bind fail!\n");
70   - return -1;
71   - }
72   -
73   -
74   - char recvBuf[10000];
75   - int recvBufSize;
76   -
77   - socklen_t len;
78   - struct sockaddr_in clent_addr; //clent_addr用于记录发送方的地址信息
79   - while(!m_bRtpExit)
80   - {
81   - memset(recvBuf, 0, sizeof(recvBuf));
82   - len = sizeof(clent_addr);
83   - recvBufSize = recvfrom(server_fd, recvBuf, sizeof(recvBuf), 0, (struct sockaddr*)&clent_addr, &len); //recvfrom是拥塞函数,没有数据就一直拥塞
84   - if(recvBufSize <= 0) {
85   - printf("recieve data fail!\n");
86   - break;
87   - }
88   -
89   - if ((mPlayer->bufferSize + recvBufSize - RTP_HEADER_SIZE) < MAX_RTP_BUFFER_SIZE) {
90   - memcpy(mPlayer->buffer + mPlayer->bufferSize, recvBuf + RTP_HEADER_SIZE, recvBufSize - RTP_HEADER_SIZE);
91   - mPlayer->bufferSize += recvBufSize - RTP_HEADER_SIZE;
92   - } else {
93   - LOG_ERROR("recvBufSize = {} over GB28181Player_buffer_max_size ", recvBufSize);
94   - }
95   - }
96   -
97   - close(server_fd);
98   -
99   - return 0;
100   -}
101   -
102   -int RTPReceiver2::startTcpServer(const char* ip, uint16_t port) {
103   -
104   - int listenfd, connfd;
105   - struct sockaddr_in servaddr;
106   - char buff[4096];
107   - int n;
108   -
109   - if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ){
110   - printf("create socket error: %s(errno: %d)\n",strerror(errno),errno);
111   - return 0;
112   - }
113   -
114   - memset(&servaddr, 0, sizeof(servaddr));
115   - servaddr.sin_family = AF_INET;
116   - servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
117   - servaddr.sin_port = htons(port);
118   -
119   - if( bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1){
120   - printf("bind socket error: %s(errno: %d)\n",strerror(errno),errno);
121   - return 0;
122   - }
123   -
124   - if( listen(listenfd, 10) == -1){
125   - printf("listen socket error: %s(errno: %d)\n",strerror(errno),errno);
126   - return 0;
127   - }
128   -
129   -
130   - char recvBuf[10000];
131   - int recvBufSize = 0;
132   -
133   - while (!m_bRtpExit)
134   - {
135   - LOG_INFO("阻塞监听新连接...");
136   - // 阻塞接收请求 start
137   -
138   - int clientFd = accept(listenfd, (struct sockaddr*)NULL, NULL);
139   - if (clientFd < 0) {
140   - LOG_ERROR("accept connection error");
141   - continue;
142   - }
143   - // 阻塞接收请求 end
144   - LOG_INFO("发现新连接:clientFd=%d", clientFd);
145   -
146   - while (!m_bRtpExit) {
147   - recvBufSize = recv(clientFd, recvBuf, sizeof(recvBuf), 0);
148   - if (recvBufSize <= 0) {
149   - LOG_ERROR("::recv error: clientFd={},recvBufSize={}", clientFd, recvBufSize);
150   - break;
151   - }
152   -
153   - parseTcpData(recvBuf, recvBufSize);
154   - }
155   -
156   - close(clientFd);
157   - LOG_INFO("关闭连接 clientFd={}", clientFd);
158   -
159   - }
160   -
161   - close(listenfd);
162   - return 0;
163   -}
164   -
165   -void RTPReceiver2::parseTcpData(char* recvBuf, int recvBufSize) {
166   -
167   - if ((mRecvCacheSize + recvBufSize) > Server_cache_max_size) {
168   - LOG_ERROR("超过缓冲容量上限,忽略本次读取的数据。mRecvCacheSize=%d,recvBufSize=%d",mRecvCacheSize, recvBufSize);
169   -
170   - }
171   - else {
172   - memcpy(mRecvCache + mRecvCacheSize, recvBuf, recvBufSize);
173   - mRecvCacheSize += recvBufSize;
174   - }
175   - //LOGI("cacheSize=%d,开始进入解析 ... ...", cacheSize);
176   -
177   - while (true) {
178   -
179   - if (mRecvCacheSize > 2) {
180   -
181   - bool success = false;
182   -
183   - if (mRecvCacheSize > 2) {
184   - mRecvRtpBufferSize = ntohs(*(int16_t*)(mRecvCache));
185   - if ((mRecvCacheSize - 2) >= mRecvRtpBufferSize) {
186   - success = true;
187   - }
188   - }
189   -
190   - if (success) {
191   - mRecvCacheSize -= 2;
192   - mRecvCacheSize -= mRecvRtpBufferSize;
193   -
194   - // 提取RTP
195   - memcpy(mRecvRtpBuffer, mRecvCache + 2, mRecvRtpBufferSize);
196   - memmove(mRecvCache, mRecvCache + 2 + mRecvRtpBufferSize, mRecvCacheSize);
197   -
198   - // RTP
199   - RtpHeader rtpHeader;
200   - parseRtpHeader(mRecvRtpBuffer, &rtpHeader);
201   - printf("get a rtp seq=%d,RtpBufferSize=%d,mRecvCacheSize=%d,marker=%d,timestamp=%d\n",
202   - rtpHeader.seq,
203   - mRecvRtpBufferSize,
204   - mRecvCacheSize,rtpHeader.marker, rtpHeader.timestamp);
205   -
206   -
207   - // 将从mRecvCache提取出来的rtp字节流 mRecvRtpBuffer去掉RTP_HEADER_SIZE,存储到播放器缓存中
208   - if ((mPlayer->bufferSize + mRecvRtpBufferSize - RTP_HEADER_SIZE) < MAX_RTP_BUFFER_SIZE) {
209   - memcpy(mPlayer->buffer + mPlayer->bufferSize, mRecvRtpBuffer + RTP_HEADER_SIZE, mRecvRtpBufferSize - RTP_HEADER_SIZE);
210   - mPlayer->bufferSize += mRecvRtpBufferSize - RTP_HEADER_SIZE;
211   - }
212   - else {
213   - LOG_ERROR("recvBufSize = %d over MAX_RTP_BUFFER_SIZE ", recvBufSize);
214   - }
215   -
216   - }
217   - else {
218   - //LOGI("跳出解析:cacheSize=%d,pktSize=%d", cacheSize, pktSize);
219   - break;
220   - }
221   - }
222   - else {
223   - //LOGI("跳出解析:缓冲数据未发现完整数据包");
224   - break;
225   - }
226   - }
227   -}
228   -
229   -int RTPReceiver2::allocRtpPort() {
230   -
231   - WebsocketClient* pServer = WebsocketClient::getInstance();
232   - int MIN_RTP_PORT = pServer->GetMinRtpPort() ;
233   - int MAX_RTP_PORT = pServer->GetMaxRtpPort();
234   -
235   - int s_rtpPort = MIN_RTP_PORT;
236   -
237   - srand((unsigned int)time(NULL));
238   - s_rtpPort = MIN_RTP_PORT + (rand() % MIN_RTP_PORT);
239   -
240   - if (s_rtpPort % 2)
241   - ++s_rtpPort;
242   -
243   - int count = 0;
244   -
245   - while (true)
246   - {
247   - if (s_rtpPort >= MAX_RTP_PORT) {
248   - s_rtpPort = MIN_RTP_PORT;
249   - count ++;
250   - if (count > 1) {
251   - LOG_ERROR("[{}] - 范围内没有可用的port", m_SipChannelId);
252   - }
253   - }
254   -
255   - int i = 0;
256   - for (; i < 2; i++) {
257   - sockaddr_in sRecvAddr;
258   - int s = socket(AF_INET, SOCK_DGRAM, 0);
259   -
260   - sRecvAddr.sin_family = AF_INET;
261   - sRecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
262   - sRecvAddr.sin_port = htons(s_rtpPort + i);
263   -
264   - int nResult = bind(s, (sockaddr *)&sRecvAddr, sizeof(sRecvAddr));
265   - if (nResult != 0) {
266   - break;
267   - }
268   -
269   - nResult = close(s);
270   - if (nResult != 0) {
271   - LOG_ERROR("[{}] - closesocket failed : {}", m_SipChannelId, nResult);
272   - break;
273   - }
274   - }
275   -
276   - if (i == 2)
277   - break;
278   -
279   - s_rtpPort += 2;
280   - }
281   -
282   - return s_rtpPort;
283   -}
284   -
285   -void RTPReceiver2::RequestStreamFailed() {
286   - m_bRtpExit = true;
287   -}
288 0 \ No newline at end of file
src/decoder/gb28181/rtp2/RTPReceiver2.cpp 0 → 100644
  1 +#include "RTPReceiver2.h"
  2 +#include "rtppacket.h"
  3 +#include <thread>
  4 +
  5 +#include "../common_header.h"
  6 +#include "../websocket/WebsocketClient.h"
  7 +
  8 +#ifdef __linux__
  9 +#include "arpa/inet.h"
  10 +#endif
  11 +
  12 +#include "Rtp.h"
  13 +
  14 +const int MAX_RTP_BUFFER_SIZE = 1024*1024*10;
  15 +
  16 +#define Server_cache_max_size 4194304 // 1M = 1 * 1024 * 1024 = 1048576 字节
  17 +#define Server_rtp_max_size 1800
  18 +
  19 +
  20 +RTPReceiver2::RTPReceiver2()
  21 +{
  22 + mRecvCache = (uint8_t*)malloc(Server_cache_max_size);
  23 + mRecvRtpBuffer = (uint8_t*)malloc(Server_rtp_max_size);
  24 +}
  25 +
  26 +RTPReceiver2::~RTPReceiver2(){
  27 + if (mRecvCache) {
  28 + free(mRecvCache);
  29 + mRecvCache = nullptr;
  30 + }
  31 +
  32 + if (mRecvRtpBuffer) {
  33 + free(mRecvRtpBuffer);
  34 + mRecvRtpBuffer = nullptr;
  35 + }
  36 +}
  37 +
  38 +void RTPReceiver2::SetOutputCallback(CallBack_Stream cb, void* param)
  39 +{
  40 + m_buffer_cbk = cb;
  41 + m_bufferParam = param;
  42 +}
  43 +
  44 +void RTPReceiver2::SetVodEndCallback(CallBack_VodFileEnd cb, void* param)
  45 +{
  46 + m_finish_cbk = cb;
  47 + m_finishParam = param;
  48 +}
  49 +
  50 +bool RTPReceiver2::Open(string channel_id, bool isUdp) {
  51 + m_SipChannelId = channel_id;
  52 +
  53 + m_rtp_port = allocRtpPort();
  54 + if (m_rtp_port < 0) {
  55 + return false;
  56 + }
  57 +
  58 + bool bReq = start_server(channel_id, m_rtp_port, isUdp);
  59 + if (!bReq) {
  60 + LOG_INFO("[{}] start_server failed !", m_SipChannelId);
  61 + Close();
  62 + return false;
  63 + }
  64 +
  65 + m_bOpened = true;
  66 +
  67 + LOG_INFO("[{}] started.", m_SipChannelId);
  68 +
  69 + return true;
  70 +}
  71 +
  72 +bool RTPReceiver2::IsOpened(){
  73 + LOG_INFO("[{}] isopen:{} ", m_SipChannelId, m_bOpened);
  74 + return m_bOpened;
  75 +}
  76 +
  77 +void RTPReceiver2::Close(){
  78 + m_bRtpExit = true;
  79 +
  80 + WebsocketClient* pServer = WebsocketClient::getInstance();
  81 + if (pServer){
  82 + pServer->ByeInvite(m_SipChannelId, m_rtp_port);
  83 + }
  84 +
  85 + if(m_server_thread) {
  86 + m_server_thread->join();
  87 + delete m_server_thread;
  88 + m_server_thread = nullptr;
  89 + }
  90 +}
  91 +
  92 +bool RTPReceiver2::start_server(string channel_id, int port, bool isUdp) {
  93 + WebsocketClient* pClient = WebsocketClient::getInstance();
  94 + if (pClient){
  95 +
  96 + if (isUdp) {
  97 + m_server_thread = new std::thread([](void* arg) {
  98 + RTPReceiver2* a=(RTPReceiver2*)arg;
  99 + a->udp_server();
  100 + return (void*)0;
  101 + }, this);
  102 +
  103 + if (pClient->InviteUdp(channel_id, port, this) < 0) {
  104 + return false;
  105 + }
  106 +
  107 + } else {
  108 + m_server_thread = new std::thread([](void* arg) {
  109 + RTPReceiver2* a=(RTPReceiver2*)arg;
  110 + a->tcp_server();
  111 + return (void*)0;
  112 + }, this);
  113 +
  114 + if (pClient->InviteTcp(channel_id, port, this) < 0) {
  115 + return false;
  116 + }
  117 + }
  118 + }
  119 +
  120 + return true;
  121 +}
  122 +
  123 +int RTPReceiver2::udp_server() {
  124 +
  125 + uint16_t port = m_rtp_port;
  126 +
  127 + LOG_INFO("udp {}",port);
  128 +
  129 + int server_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); //AF_INET:IPV4;SOCK_DGRAM:UDP
  130 + if(server_fd < 0)
  131 + {
  132 + printf("create socket fail!\n");
  133 + return -1;
  134 + }
  135 +
  136 + struct sockaddr_in ser_addr;
  137 + memset(&ser_addr, 0, sizeof(ser_addr));
  138 + ser_addr.sin_family = AF_INET;
  139 + ser_addr.sin_addr.s_addr = htonl(INADDR_ANY); //IP地址,需要进行网络序转换,INADDR_ANY:本地地址
  140 + ser_addr.sin_port = htons(port); //端口号,需要网络序转换
  141 +
  142 + int ret = bind(server_fd, (struct sockaddr*)&ser_addr, sizeof(ser_addr));
  143 + if(ret < 0) {
  144 + printf("socket bind fail!\n");
  145 + return -1;
  146 + }
  147 +
  148 + uint8_t recvBuf[10000];
  149 + int recvBufSize;
  150 +
  151 + socklen_t len;
  152 + struct sockaddr_in clent_addr; //clent_addr用于记录发送方的地址信息
  153 + while(!m_bRtpExit)
  154 + {
  155 + memset(recvBuf, 0, sizeof(recvBuf));
  156 + len = sizeof(clent_addr);
  157 + recvBufSize = recvfrom(server_fd, recvBuf, sizeof(recvBuf), 0, (struct sockaddr*)&clent_addr, &len); //recvfrom是拥塞函数,没有数据就一直拥塞
  158 + if(recvBufSize <= 0) {
  159 + LOG_ERROR("recieve data fail!");
  160 + break;
  161 + }
  162 +
  163 + // buffer 抛出
  164 + m_buffer_cbk(m_bufferParam, recvBuf, recvBufSize, 0);
  165 + }
  166 +
  167 + close(server_fd);
  168 +
  169 + m_finish_cbk(m_finishParam);
  170 +
  171 + LOG_INFO("udp server exit.");
  172 +
  173 + return 0;
  174 +}
  175 +
  176 +int RTPReceiver2::tcp_server() {
  177 +
  178 + uint16_t port = m_rtp_port;
  179 +
  180 + LOG_INFO("tcp {}", port);
  181 +
  182 + int listenfd, connfd;
  183 + struct sockaddr_in servaddr;
  184 + char buff[4096];
  185 + int n;
  186 +
  187 + if( (listenfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1 ){
  188 + printf("create socket error: %s(errno: %d)\n",strerror(errno),errno);
  189 + return 0;
  190 + }
  191 +
  192 + memset(&servaddr, 0, sizeof(servaddr));
  193 + servaddr.sin_family = AF_INET;
  194 + servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
  195 + servaddr.sin_port = htons(port);
  196 +
  197 + if( bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1){
  198 + printf("bind socket error: %s(errno: %d)\n",strerror(errno),errno);
  199 + return 0;
  200 + }
  201 +
  202 + if( listen(listenfd, SOMAXCONN) == -1){
  203 + printf("listen socket error: %s(errno: %d)\n",strerror(errno),errno);
  204 + return 0;
  205 + }
  206 +
  207 + char recvBuf[10000];
  208 + int recvBufSize = 0;
  209 +
  210 + while (!m_bRtpExit)
  211 + {
  212 + LOG_INFO("阻塞监听新连接...");
  213 + // 阻塞接收请求 start
  214 + socklen_t len = sizeof(sockaddr);
  215 + sockaddr_in accept_addr;
  216 + int clientFd = accept(listenfd, (struct sockaddr*)&accept_addr, &len);
  217 + if (clientFd < 0) {
  218 + LOG_WARN("accept connection error");
  219 + std::this_thread::sleep_for(std::chrono::milliseconds(5));
  220 + continue;
  221 + }
  222 + // 阻塞接收请求 end
  223 + LOG_INFO("发现新连接:clientFd={}", clientFd);
  224 +
  225 + while (!m_bRtpExit) {
  226 + recvBufSize = recv(clientFd, recvBuf, sizeof(recvBuf), 0);
  227 + if (recvBufSize <= 0) {
  228 + LOG_ERROR("::recv error: clientFd={},recvBufSize={}", clientFd, recvBufSize);
  229 + break;
  230 + }
  231 +
  232 + parseTcpData(recvBuf, recvBufSize);
  233 + }
  234 +
  235 + close(clientFd);
  236 + LOG_WARN("关闭连接 clientFd={}", clientFd);
  237 + }
  238 +
  239 + close(listenfd);
  240 +
  241 + m_finish_cbk(m_finishParam);
  242 +
  243 + LOG_INFO("tcp server exit.");
  244 + return 0;
  245 +}
  246 +
  247 +void RTPReceiver2::parseTcpData(char* recvBuf, int recvBufSize) {
  248 +
  249 + if ((mRecvCacheSize + recvBufSize) > Server_cache_max_size) {
  250 + LOG_ERROR("超过缓冲容量上限,忽略本次读取的数据。mRecvCacheSize=%d,recvBufSize=%d",mRecvCacheSize, recvBufSize);
  251 + } else {
  252 + memcpy(mRecvCache + mRecvCacheSize, recvBuf, recvBufSize);
  253 + mRecvCacheSize += recvBufSize;
  254 + }
  255 + //LOGI("cacheSize=%d,开始进入解析 ... ...", cacheSize);
  256 +
  257 + while (true) {
  258 +
  259 + if (mRecvCacheSize > 2) {
  260 +
  261 + bool success = false;
  262 +
  263 + if (mRecvCacheSize > 2) {
  264 + mRecvRtpBufferSize = ntohs(*(int16_t*)(mRecvCache));
  265 + if ((mRecvCacheSize - 2) >= mRecvRtpBufferSize) {
  266 + success = true;
  267 + }
  268 + }
  269 +
  270 + if (success) {
  271 + mRecvCacheSize -= 2;
  272 + mRecvCacheSize -= mRecvRtpBufferSize;
  273 +
  274 + // 提取RTP
  275 + memcpy(mRecvRtpBuffer, mRecvCache + 2, mRecvRtpBufferSize);
  276 + memmove(mRecvCache, mRecvCache + 2 + mRecvRtpBufferSize, mRecvCacheSize);
  277 +
  278 + struct RtpHeader rtpHeader;
  279 + parseRtpHeader(mRecvRtpBuffer, &rtpHeader);
  280 + printf("get a rtp seq=%d,RtpBufferSize=%d,mRecvCacheSize=%d,marker=%d,timestamp=%d\n",
  281 + rtpHeader.seq,
  282 + mRecvRtpBufferSize,
  283 + mRecvCacheSize,rtpHeader.marker, rtpHeader.timestamp);
  284 +
  285 + // buffer 抛出
  286 + m_buffer_cbk(m_bufferParam, mRecvRtpBuffer, mRecvRtpBufferSize, rtpHeader.timestamp);
  287 +
  288 + } else {
  289 + //LOGI("跳出解析:cacheSize=%d,pktSize=%d", cacheSize, pktSize);
  290 + break;
  291 + }
  292 + } else {
  293 + //LOGI("跳出解析:缓冲数据未发现完整数据包");
  294 + break;
  295 + }
  296 + }
  297 +}
  298 +
  299 +int RTPReceiver2::allocRtpPort() {
  300 +
  301 + WebsocketClient* pServer = WebsocketClient::getInstance();
  302 + int MIN_RTP_PORT = pServer->GetMinRtpPort() ;
  303 + int MAX_RTP_PORT = pServer->GetMaxRtpPort();
  304 +
  305 + int s_rtpPort = MIN_RTP_PORT;
  306 +
  307 + srand((unsigned int)time(NULL));
  308 + s_rtpPort = MIN_RTP_PORT + (rand() % MIN_RTP_PORT);
  309 +
  310 + if (s_rtpPort % 2)
  311 + ++s_rtpPort;
  312 +
  313 + int count = 0;
  314 +
  315 + while (true)
  316 + {
  317 + if (s_rtpPort >= MAX_RTP_PORT) {
  318 + s_rtpPort = MIN_RTP_PORT;
  319 + count ++;
  320 + if (count > 1) {
  321 + LOG_ERROR("[{}] - 范围内没有可用的port", m_SipChannelId);
  322 + }
  323 + }
  324 +
  325 + int i = 0;
  326 + for (; i < 2; i++) {
  327 + sockaddr_in sRecvAddr;
  328 + int s = socket(AF_INET, SOCK_DGRAM, 0);
  329 +
  330 + sRecvAddr.sin_family = AF_INET;
  331 + sRecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
  332 + sRecvAddr.sin_port = htons(s_rtpPort + i);
  333 +
  334 + int nResult = bind(s, (sockaddr *)&sRecvAddr, sizeof(sRecvAddr));
  335 + if (nResult != 0) {
  336 + break;
  337 + }
  338 +
  339 + nResult = close(s);
  340 + if (nResult != 0) {
  341 + LOG_ERROR("[{}] - closesocket failed : {}", m_SipChannelId, nResult);
  342 + break;
  343 + }
  344 + }
  345 +
  346 + if (i == 2)
  347 + break;
  348 +
  349 + s_rtpPort += 2;
  350 + }
  351 +
  352 + return s_rtpPort;
  353 +}
  354 +
  355 +void RTPReceiver2::RequestStreamFailed() {
  356 + m_bRtpExit = true;
  357 +}
0 358 \ No newline at end of file
... ...
src/decoder/gb28181/rtp/RTPReceiver2.h renamed to src/decoder/gb28181/rtp2/RTPReceiver2.h
... ... @@ -7,23 +7,35 @@
7 7  
8 8 using namespace std;
9 9  
  10 +typedef void(*CallBack_Stream)(void* userdata, uint8_t* buf, int buf_size, uint64_t pts);
10 11  
11   -class RTPReceiver2{
  12 +typedef void(*CallBack_VodFileEnd)(void* userdata);
  13 +
  14 +
  15 +class RTPReceiver2 {
12 16  
13 17 public:
14 18 RTPReceiver2();
15 19 virtual ~RTPReceiver2();
16 20  
17   - int init(const char* ip, uint16_t port, bool isUdp);
  21 + bool Open(string channel_id, bool isUdp);
  22 + bool IsOpened();
  23 + void Close();
  24 +
  25 + void SetVodEndCallback(CallBack_VodFileEnd cb, void* param);
  26 +
  27 + void SetOutputCallback(CallBack_Stream cb, void* param);
18 28  
19 29 void RequestStreamFailed();
20 30  
21 31 int allocRtpPort();
22 32  
23   -private:
24   - int startUdpServer(const char* ip, uint16_t port);
25   - int startTcpServer(const char* ip, uint16_t port);
  33 +public:
  34 + int udp_server();
  35 + int tcp_server();
26 36  
  37 +private:
  38 + bool start_server(string channel_id, int port, bool isUdp);
27 39 void parseTcpData(char* recvBuf, int recvBufSize);
28 40  
29 41 public:
... ... @@ -31,9 +43,24 @@ public:
31 43 uint64_t mRecvCacheSize {0};
32 44  
33 45 uint8_t* mRecvRtpBuffer {nullptr}; // 从mRecvCache提取出来的rtp字节流
34   - int16_t mRecvRtpBufferSize {0};// 从mRecvCache提取出来的rtp字节流总长度 (rtpHeader+rtpBody)
  46 + int16_t mRecvRtpBufferSize {0}; // 从mRecvCache提取出来的rtp字节流总长度 (rtpHeader+rtpBody)
35 47  
36 48 bool m_bRtpExit {false};
  49 +
  50 + string m_SipChannelId;
  51 + int m_rtp_port{-1};
  52 +
  53 + std::atomic_bool m_bOpened;
  54 + std::atomic_bool m_bAccepted;
  55 + std::atomic_bool m_bClosing;
  56 +
  57 + std::thread* m_server_thread{nullptr};
  58 +
  59 + void* m_bufferParam;
  60 + CallBack_Stream m_buffer_cbk; // 视频流回调
  61 +
  62 + void* m_finishParam;
  63 + CallBack_VodFileEnd m_finish_cbk; // 录像流结束回调
37 64 };
38 65  
39 66 #endif // _RTP_RECEIVER_H_
40 67 \ No newline at end of file
... ...
src/decoder/gb28181/rtp/Rtp.cpp renamed to src/decoder/gb28181/rtp2/Rtp.cpp
src/decoder/gb28181/rtp/Rtp.h renamed to src/decoder/gb28181/rtp2/Rtp.h
... ... @@ -16,7 +16,6 @@
16 16 #define RTP_PAYLOAD_TYPE_AAC 97
17 17  
18 18 #define RTP_HEADER_SIZE 12
19   -#define RTP_MAX_SIZE 1400
20 19  
21 20 /*
22 21 *
... ...
src/decoder/gb28181/websocket/WebsocketClient.cpp
... ... @@ -191,7 +191,7 @@ int WebsocketClient::GetMaxRtpPort(){
191 191 return mInfo.getMaxRtpPort();
192 192 }
193 193  
194   -int WebsocketClient::InviteUdp(std::string sip_channel_id, int rtp_port, RTPReceiver* r) {
  194 +int WebsocketClient::InviteUdp(std::string sip_channel_id, int rtp_port, RTPReceiver2* r) {
195 195 if (check_connect() < 0) {
196 196 return -1;
197 197 }
... ... @@ -204,7 +204,7 @@ int WebsocketClient::InviteUdp(std::string sip_channel_id, int rtp_port, RTPRece
204 204 return 0;
205 205 }
206 206  
207   -int WebsocketClient::InviteTcp(std::string sip_channel_id, int rtp_port, RTPReceiver* r) {
  207 +int WebsocketClient::InviteTcp(std::string sip_channel_id, int rtp_port, RTPReceiver2* r) {
208 208 if (check_connect() < 0) {
209 209 return -1;
210 210 }
... ... @@ -228,7 +228,7 @@ int WebsocketClient::ByeInvite(std::string sip_channel_id, int rtp_port) {
228 228 return 0;
229 229 }
230 230  
231   -void WebsocketClient::cache_receiver(std::string sip_channel_id, int rtp_port, RTPReceiver* r) {
  231 +void WebsocketClient::cache_receiver(std::string sip_channel_id, int rtp_port, RTPReceiver2* r) {
232 232 std::lock_guard<std::mutex> l(m_receiver_map_mtx);
233 233 string rKey = sip_channel_id + "_" + to_string(rtp_port);
234 234 m_receiver_map[rKey] = r;
... ...
src/decoder/gb28181/websocket/WebsocketClient.h
... ... @@ -6,7 +6,7 @@
6 6  
7 7 #include "Message/CatalogParser.h"
8 8  
9   -#include "../rtp/RTPReceiver.h"
  9 +#include "../rtp2/RTPReceiver2.h"
10 10  
11 11 typedef websocketpp::client<websocketpp::config::asio_client> client;
12 12 typedef websocketpp::config::asio_client::message_type::ptr message_ptr;
... ... @@ -32,8 +32,8 @@ public:
32 32 int GetMinRtpPort();
33 33 int GetMaxRtpPort();
34 34  
35   - int InviteUdp(std::string sip_channel_id, int rtp_port, RTPReceiver* r);
36   - int InviteTcp(std::string sip_channel_id, int rtp_port, RTPReceiver* r);
  35 + int InviteUdp(std::string sip_channel_id, int rtp_port, RTPReceiver2* r);
  36 + int InviteTcp(std::string sip_channel_id, int rtp_port, RTPReceiver2* r);
37 37  
38 38 int ByeInvite(std::string sip_channel_id, int rtp_port);
39 39  
... ... @@ -56,7 +56,7 @@ private:
56 56  
57 57 int msg_parser(websocketpp::connection_hdl hdl, string msg);
58 58  
59   - void cache_receiver(std::string sip_channel_id, int rtp_port, RTPReceiver* r);
  59 + void cache_receiver(std::string sip_channel_id, int rtp_port, RTPReceiver2* r);
60 60  
61 61 void response_invite_failed(std::string rKey);
62 62  
... ... @@ -70,6 +70,6 @@ private:
70 70  
71 71 bool mbClosed{false};
72 72  
73   - std::map<string, RTPReceiver*> m_receiver_map;
  73 + std::map<string, RTPReceiver2*> m_receiver_map;
74 74 std::mutex m_receiver_map_mtx;
75 75 };
76 76 \ No newline at end of file
... ...
src/decoder/interface/AbstractDecoder.h
... ... @@ -27,8 +27,6 @@ public:
27 27 virtual bool getOutResolution( int &width, int &height ) = 0;
28 28  
29 29 virtual bool isSurport(FFDecConfig& cfg) = 0;
30   -
31   - virtual int getCachedQueueLength() = 0;
32 30  
33 31 virtual float fps() = 0;
34 32  
... ...
src/decoder/interface/DecoderManager.cpp
... ... @@ -7,7 +7,7 @@
7 7  
8 8 #ifdef USE_DVPP
9 9 #include "../dvpp/DvppDecoderApi.h"
10   -#include "../gb28181/DvppGB28181Decoder.h"
  10 +#include "../gb28181/DvppGB28181Decoder2.h"
11 11 #endif
12 12  
13 13 #include "logger.hpp"
... ... @@ -61,7 +61,7 @@ AbstractDecoder* DecoderManager::createDecoder(MgrDecConfig config){
61 61 if(DECODER_TYPE_DVPP == config.dec_type){
62 62 dec = new DvppDecoderApi();
63 63 } else if(DECODER_TYPE_DVPP_GB28181 == config.dec_type){
64   - dec = new DvppGB28181Decoder();
  64 + dec = new DvppGB28181Decoder2();
65 65 }
66 66 #endif
67 67  
... ... @@ -470,23 +470,6 @@ vector&lt;string&gt; DecoderManager::getAllDecodeName(){
470 470 return decode_names;
471 471 }
472 472  
473   -int DecoderManager::getCachedQueueLength(const string name){
474   - if (name.empty()){
475   - LOG_ERROR("name 为空!");
476   - return -1;
477   - }
478   -
479   - std::lock_guard<std::mutex> l(m_mutex);
480   -
481   - auto dec = decoderMap.find(name);
482   - if (dec != decoderMap.end()){
483   - return dec->second->getCachedQueueLength();
484   - }
485   -
486   - LOG_ERROR("没有找到name为{}的解码器",name);
487   - return -1;
488   -}
489   -
490 473 void DecoderManager::releaseDeviceMemory(DeviceMemory* info){
491 474 if(nullptr != info){
492 475 delete info;
... ...
src/decoder/interface/DecoderManager.h
... ... @@ -230,15 +230,6 @@ public:
230 230 vector<string> getAllDecodeName();
231 231  
232 232 /**************************************************
233   - * 接口:getCachedQueueLength
234   - * 功能:获取解码缓冲队列当前长度
235   - * 参数:const string name 解码器名称
236   - * 返回:int 解码缓冲队列当前长度
237   - * 备注:
238   - **************************************************/
239   - int getCachedQueueLength(const string name);
240   -
241   - /**************************************************
242 233 * 接口:releaseDeviceMemory
243 234 * 功能:释放视频快照信息
244 235 * 参数:DeviceMemory* info 视频快照信息
... ...
src/decoder/interface/VideoTools.cpp deleted
1   -#include "VideoTools.h"
2   -#include "logger.hpp"
3   -
4   -extern "C" {
5   - #include <libavcodec/avcodec.h>
6   - #include <libavdevice/avdevice.h>
7   - #include <libavformat/avformat.h>
8   - #include <libavfilter/avfilter.h>
9   - #include <libavutil/avutil.h>
10   - #include <libavutil/pixdesc.h>
11   - #include <libswscale/swscale.h>
12   - #include <libavutil/imgutils.h>
13   -}
14   -
15   -namespace VideoTools {
16   -
17   -FFImgInfo* snapshot(const string& uri){
18   - if (uri.empty()){
19   - return nullptr;
20   - }
21   -
22   - AVFormatContext* ifmt_ctx = nullptr;
23   - AVCodecContext* codec_ctx = nullptr;
24   - AVCodec* codec = nullptr;
25   - AVPacket* pkt = nullptr;
26   - AVFrame *frame = nullptr;
27   - AVFrame *pFrameRGB = nullptr;
28   - int video_index = -1;
29   - AVStream* st = nullptr;
30   - SwsContext *img_convert_ctx = nullptr;
31   - uint8_t *buffer = nullptr;
32   - int numBytes = 0;
33   - int index = 0;
34   -
35   - FFImgInfo* imgInfo = nullptr;
36   -
37   - //av_register_all();
38   - avformat_network_init();
39   -
40   - // 参数设置
41   - AVDictionary *options = nullptr;
42   - av_dict_set( &options, "bufsize", "655360", 0 );
43   - av_dict_set( &options, "rtsp_transport", "tcp", 0 );
44   - av_dict_set( &options, "stimeout", "30000000", 0 ); // 单位为 百万分之一秒
45   -
46   - ///打开输入的流
47   - int ret = avformat_open_input(&ifmt_ctx, uri.c_str(), nullptr, &options);
48   - if (ret != 0){
49   - printf("Couldn't open input stream.\n");
50   - goto end_flag ;
51   - }
52   -
53   - //查找流信息
54   - if (avformat_find_stream_info(ifmt_ctx, nullptr) < 0){
55   - printf("Couldn't find stream information.\n");
56   - goto end_flag ;
57   - }
58   -
59   - //找到视频流索引
60   - video_index = av_find_best_stream(ifmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, nullptr, 0);
61   -
62   - st = ifmt_ctx->streams[video_index];
63   -
64   - //找到解码器
65   - codec = avcodec_find_decoder(st->codecpar->codec_id);
66   - if (!codec){
67   - fprintf(stderr, "Codec not found\n");
68   - goto end_flag ;
69   - }
70   -
71   - //申请AVCodecContext
72   - codec_ctx = avcodec_alloc_context3(codec);
73   - if (!codec_ctx){
74   - goto end_flag ;
75   - }
76   -
77   - avcodec_parameters_to_context(codec_ctx, ifmt_ctx->streams[video_index]->codecpar);
78   -
79   - //打开解码器
80   - if ((ret = avcodec_open2(codec_ctx, codec, nullptr) < 0)){
81   - goto end_flag ;
82   - }
83   -
84   - // 计算解码后原始数据所需缓冲区大小,并分配内存空间 Determine required buffer size and allocate buffer
85   - numBytes = av_image_get_buffer_size(AV_PIX_FMT_BGR24, codec_ctx->width, codec_ctx->height, 1);
86   - buffer = (uint8_t *)av_malloc(numBytes * sizeof(uint8_t));
87   -
88   - pFrameRGB = av_frame_alloc();
89   - av_image_fill_arrays(pFrameRGB->data, pFrameRGB->linesize, buffer, AV_PIX_FMT_BGR24, codec_ctx->width, codec_ctx->height, 1);
90   -
91   - img_convert_ctx = sws_getContext(codec_ctx->width, codec_ctx->height,codec_ctx->pix_fmt, codec_ctx->width, codec_ctx->height, AV_PIX_FMT_BGR24,
92   - SWS_BICUBIC, nullptr, nullptr, nullptr);
93   -
94   - pkt = av_packet_alloc();
95   - frame = av_frame_alloc();
96   - while (av_read_frame(ifmt_ctx, pkt) >= 0){
97   - if (pkt->stream_index == video_index){
98   - int ret = avcodec_send_packet(codec_ctx, pkt);
99   - if (ret >= 0){
100   - ret = avcodec_receive_frame(codec_ctx, frame);
101   - if ((ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) || ret < 0){
102   - LOG_ERROR("Failed to receive frame: {}",ret);
103   - continue;
104   - }
105   -
106   - index ++ ;
107   -
108   - if (index >= 5){
109   - // 取解码出来的第三帧,应该可以一定程度优化花屏问题
110   - sws_scale(img_convert_ctx, (const unsigned char* const*)frame->data, frame->linesize, 0, codec_ctx->height, pFrameRGB->data, pFrameRGB->linesize);
111   -
112   - imgInfo = new FFImgInfo();
113   - imgInfo->pData = buffer;
114   - imgInfo->height = codec_ctx->height;
115   - imgInfo->width = codec_ctx->width;
116   -
117   - break;
118   - }
119   - }
120   - }
121   - av_packet_unref(pkt);
122   - }
123   -
124   -end_flag:
125   - if (codec_ctx != nullptr){
126   - avcodec_close(codec_ctx);
127   - avcodec_free_context(&codec_ctx);
128   - }
129   -
130   - if (ifmt_ctx != nullptr){
131   - avformat_close_input(&ifmt_ctx);
132   - }
133   -
134   - if (frame != nullptr){
135   - av_frame_free(&frame);
136   - }
137   -
138   - if (pFrameRGB != nullptr){
139   - av_frame_free(&pFrameRGB);
140   - }
141   -
142   - if (pkt != nullptr){
143   - av_packet_free(&pkt);
144   - }
145   -
146   - return imgInfo;
147   -}
148   -
149   -void releaseFFImgInfo(FFImgInfo* info) {
150   - if(nullptr != info){
151   - if(info->pData != nullptr){
152   - av_free(info->pData);
153   - info->pData = nullptr;
154   - }
155   - delete info;
156   - info = nullptr;
157   - }
158   -}
159   -
160   -} // namespace
161 0 \ No newline at end of file
src/decoder/interface/VideoTools.h deleted
1   -#ifndef __VIDEO_TOOLS_H__
2   -#define __VIDEO_TOOLS_H__
3   -
4   -#include <string>
5   -
6   -using namespace std;
7   -
8   -struct FFImgInfo{
9   - string dec_name;
10   - int width;
11   - int height;
12   - unsigned char * pData;
13   - long timestamp;
14   - long index;
15   -};
16   -
17   -namespace VideoTools {
18   -
19   - FFImgInfo* snapshot(const string& uri);
20   -
21   - void releaseFFImgInfo(FFImgInfo* info);
22   -}
23   -
24   -
25   -#endif // __VIDEO_TOOLS_H__
26 0 \ No newline at end of file