From ab3d17cd44625a762fc10f0f1fd8f2c46b980aff Mon Sep 17 00:00:00 2001 From: zhangmeng <775834166@qq.com> Date: 星期二, 26 四月 2022 11:42:19 +0800 Subject: [PATCH] capture use cpu and add arm version --- csrc/wrapper.cpp | 353 +++++++++++++++++++++------------------------------------- 1 files changed, 131 insertions(+), 222 deletions(-) diff --git a/csrc/wrapper.cpp b/csrc/wrapper.cpp index 803ebac..eec65a7 100644 --- a/csrc/wrapper.cpp +++ b/csrc/wrapper.cpp @@ -1,6 +1,7 @@ #include "wrapper.hpp" #include <thread> +#include <atomic> #include <unistd.h> #include <sys/time.h> @@ -45,7 +46,10 @@ ,audio_(false) ,gb_(0) ,cpu_(0) + ,devid_(-1) ,run_dec_(false) + ,run_stream_(true) + ,run_rec_(false) ,thread_(nullptr) ,stop_stream_(false) ,stream_(nullptr) @@ -53,6 +57,8 @@ ,rec_(new rec) ,logit_(false) ,fps_(25) + ,file_finished_(false) + ,min_duration_(0) { makeTheWorld(); } @@ -62,13 +68,19 @@ ,audio_(false) ,gb_(0) ,cpu_(0) + ,devid_(-1) ,run_dec_(false) + ,run_stream_(true) + ,run_rec_(false) ,thread_(nullptr) ,stop_stream_(false) ,stream_(nullptr) ,decoder_(nullptr) ,rec_(new rec) ,logit_(true) + ,fps_(25) + ,file_finished_(false) + ,min_duration_(0) { makeTheWorld(); logif::CreateLogger(logfile, true); @@ -98,19 +110,27 @@ VideoProp prop; prop.url_ = input; prop.rtsp_tcp_ = true; - prop.gpu_acc_ = !cpu_; + prop.gpu_acc_ = false; + prop.gpu_index_ = devid_; - std::unique_ptr<FormatIn> in(new FormatIn(prop.gpuAccl())); - AVDictionary *avdic = prop.optsFormat(); + std::unique_ptr<FormatIn> in(new FormatIn(prop, prop.gpuAccl())); int flag = -1; +#ifdef GB28181 if (gb_){ flag = in->openGb28181(input, NULL); }else{ - flag = in->open(input, &avdic); +#endif + AVDictionary *avdic = prop.optsFormat(); + if(avdic){ + flag = in->open(input, &avdic); + av_dict_free(&avdic); + }else{ + flag = in->open(input, NULL); + } +#ifdef GB28181 } - if(avdic){ - av_dict_free(&avdic); - } +#endif + if(flag == 0){ if(!in->findStreamInfo(NULL)){ logIt("can't find video stream\n"); @@ -150,7 +170,7 @@ stream_ = new stream(in, 3 * in->getFPS()); // stream_->AudioSwitch(audio_); - + decoder_ = new decoder(in); rec_->Load(in); @@ -166,9 +186,9 @@ p.pts = p.dts = AV_NOPTS_VALUE; } int flag = 0; - if (stream_) stream_->SetPacket(pkt); - if (decoder_ && run_dec_) flag = decoder_->SetFrame(pkt); - if (rec_->Loaded()) rec_->SetPacket(pkt); + if (run_stream_ && stream_) stream_->SetPacket(pkt); + if (run_dec_ && decoder_) flag = decoder_->SetFrame(pkt); + if (run_rec_ && rec_->Loaded()) rec_->SetPacket(pkt); return flag; } @@ -181,6 +201,9 @@ void Wrapper::run_stream_thread(){ + int64_t file_rebootime = 0; + int64_t file_frame = 0; + while(!stop_stream_.load()){ auto in = init_reader(input_url_.c_str()); @@ -192,9 +215,12 @@ fps_ = in->getFPS(); - int wTime = 1000000.0 / in->getFPS() ; + if (fps_ < 1 || fps_ > 200){ + fps_ = 25; + } + + int wTime = 1000000.0 / fps_ ; wTime >>= 1; - logIt("WAIT TIME PER FRAME: %d", wTime); init_worker(in.get()); @@ -202,7 +228,13 @@ int64_t v_id = id; int64_t a_id = id; - bool exist = access(input_url_.c_str(), 0) == 0 ? true : false; + bool exist = access(input_url_.c_str(), 0) == 0; + if (exist){ + wTime += wTime/2; + file_rebootime++; + } + + logIt("WAIT TIME PER FRAME: %d", wTime); while(!stop_stream_.load()){ auto data(std::make_shared<CodedData>()); @@ -214,6 +246,7 @@ if (in->notVideoAudio(&data->getAVPacket())){ continue; } + // 闈炲浗鏍囪烦杩囩涓�甯�,娴嬭瘯绗竴甯ф湁闂 if (!gb_ && id < 0){ id++; v_id++; a_id++; @@ -234,20 +267,43 @@ id++; //鏈湴鏂囦欢澶揩sleep涓�涓� - if (exist){ + if (exist && in->isVideoPkt(&data->getAVPacket())){ + // 璁板綍瑙g爜鐨勬枃浠舵湁澶氬皯甯� + file_frame++; usleep(wTime); } } deinit_worker(); + if (exist) { + // 涓夋涓�甯ч兘娌¤В鍑烘潵锛岄��鍑� + if (file_frame == 0 && file_rebootime < 3){ + logIt("libcffmpeg.so-> run %lld time, current frames %lld", file_rebootime, file_frame); + continue; + } + // 鏈�灏忛渶瑕佽В鍑哄灏戝抚 + if (file_frame < min_duration_ * fps_){ + logIt("libcffmpeg.so-> run %lld time, current frames %lld, mind %d, fps: %d", + file_rebootime, file_frame, min_duration_, fps_); + continue; + } + logIt("libcffmpeg.so-> local file %s run %lld time, all frames %lld, mind %d, fps: %d", + input_url_.c_str(), file_rebootime, file_frame, min_duration_, fps_); + file_finished_ = true; + break; + } } } - void Wrapper::SetRecMinCacheTime(const int mind){ - rec_->SetRecMinCacheTime(mind); + void Wrapper::SetRecMinCacheTime(const int mind, const int maxd){ + min_duration_ = mind; } + void Wrapper::OpenRecorder(){ + run_rec_ = true; + } + void Wrapper::BuildRecorder(const char* id, const char *output, const int64_t &fid, const int mindur, const int maxdur, const bool audio){ bool a = audio; if (gb_) a = false; @@ -260,33 +316,43 @@ [=]{rec_->NewRec(rid.c_str(), dir.c_str(), fid, mindur, maxdur, a);}; } } - int Wrapper::FireRecorder(const char* sid,const int64_t &id){ if (rec_->Loaded()){ rec_->FireRecSignal(sid, id); } + return 0; } - void Wrapper::GetInfoRecorder(std::string &recID, int &index, std::string &path){ + int Wrapper::GetInfoRecorder(std::string &recID, int &index, std::string &path){ if (rec_){ rec_->GetRecInfo(recID, index, path); } + return 0; } ////////decoder - void Wrapper::BuildDecoder(){ + void Wrapper::OpenDecoder(){ run_dec_ = true; } - void Wrapper::GetPicDecoder(unsigned char **data, int *w, int *h, int *format, int *length, int64_t *id){ + int Wrapper::GetPicDecoder(unsigned char **data, int *w, int *h, int *format, int *length, int64_t *id){ + if (file_finished_){ + return -1; + } if (decoder_){ decoder_->GetFrame(data, w, h, format, length, id); } + return 0; } - void Wrapper::GetPacket(unsigned char **pktData, int *size, int *key){ + void Wrapper::CloseStream(){ + run_stream_ = false; + } + + int Wrapper::GetPacket(unsigned char **pktData, int *size, int *key){ if (stream_){ stream_->GetPacket(pktData, size, key); } + return 0; } } // end class wrapper @@ -298,69 +364,6 @@ // return val: -1 open error; -2, find stream error; -3, converter create namespace cffmpeg_wrap{ // start test functions - uint8_t* Decode(const char *file, const int gb, int *w, int *h){ - VideoProp prop; - prop.url_ = file; - prop.gpu_acc_ = false; - - std::unique_ptr<FormatIn> in(new FormatIn(prop.gpuAccl())); - int flag = -1; - if (gb){ - flag = in->openGb28181(file, NULL); - }else{ - flag = in->open(file, NULL); - } - - std::unique_ptr<cvbridge> bridge_(nullptr); - - if(flag == 0){ - if(!in->findStreamInfo(NULL)){ - logIt("yolo can't find video stream\n"); - *w = *h = -2; - return NULL; - } - auto flag = in->openCodec(NULL); - if(flag){ - auto dec_ctx = in->getCodecContext(); - - AVPixelFormat pix_fmt = AV_PIX_FMT_BGR24; - bridge_.reset(new cvbridge( - dec_ctx->width, dec_ctx->height, dec_ctx->pix_fmt, - dec_ctx->width, dec_ctx->height, pix_fmt, SWS_BICUBIC)); - - }else{ - logIt("FormatIn openCodec Failed!"); - *w = *h = -3; - return NULL; - } - }else{ - logIt("open %s error", file); - *w = *h = -1; - return NULL; - } - - uint8_t *pic = NULL; - *w = *h = 0; - - int tryTime = 0; - while (tryTime++ < 100){ - - auto data(std::make_shared<CodedData>()); - if (in->readPacket(&data->getAVPacket()) == 0){ - - auto frame(std::make_shared<FrameData>()); - AVFrame *frm = frame->getAVFrame(); - if(in->decode(frm, &data->getAVPacket()) == 0){ - *w = frm->width; - *h = frm->height; - pic = bridge_->convert2Data(frm); - break; - } - } - } - - return pic; - } /////// for encoder typedef struct _PicEncoder{ FormatOut *enc; @@ -369,15 +372,13 @@ int fps; int br; int gi; + int pix_fmt; int flag; - int fmt; cvbridge *bridge; } PicEncoder; void *CreateEncoder(const int w, const int h, const int fps, const int br, - const int scale_flag, const int gi, const int fmt, const char *file){ - - if (fmt < 0) return NULL; + const int pix_fmt, const int scale_flag, const int gi){ PicEncoder *e = (PicEncoder*)malloc(sizeof(PicEncoder)); e->enc = NULL; @@ -386,8 +387,8 @@ e->fps = fps; e->br = br; e->gi = gi; + e->pix_fmt = pix_fmt; e->flag = scale_flag; - e->fmt = fmt; e->bridge = NULL; VideoProp prop_; @@ -397,10 +398,7 @@ prop_.bit_rate_ = br; gi < 0 ? prop_.gpu_acc_ = false : prop_.gpu_acc_ = true; - std::string filename("./88.mp4"); - if (file) filename = file; - - FormatOut *enc = new FormatOut(prop_, filename.c_str()); + FormatOut *enc = new FormatOut(prop_, "./88.mp4"); e->enc = enc; return e; @@ -425,11 +423,11 @@ if (e->bridge == NULL){ e->bridge = new cvbridge( - w, h, e->fmt, + w, h, e->pix_fmt, e->w, e->h, ctx->pix_fmt, e->flag); } - AVFrame *bgr_frame = cvbridge::fillFrame(in, w, h, e->fmt); + AVFrame *bgr_frame = cvbridge::fillFrame(in, w, h, e->pix_fmt); AVFrame *frame = e->bridge->convert2Frame(bgr_frame); av_frame_free(&bgr_frame); @@ -460,138 +458,49 @@ return flag; } -/////////////////////////////////////////////////////////// - typedef struct _conv - { - int srcW; - int srcH; - int srcF; - int dstW; - int dstH; - cvbridge *b; - }Conv; - - void *CreateConvertor(const int srcW, const int srcH, const int srcFormat, - const int dstW, const int dstH, const int dstFormat, const int flag){ - - auto bridge = new cvbridge( - srcW, srcH, srcFormat, - dstW, dstH, dstFormat, flag); - if (!bridge) return NULL; +#ifdef GB28181 + int GetGb28181Pic(const char *rtspUrl, char *retData, int *retDataLen, const int tt){ + int ret = 0; + std::atomic_bool add_camera{false}; - Conv *c = (Conv*)malloc(sizeof(Conv)); - c->b = bridge; - c->dstW = dstW; - c->dstH = dstH; - c->srcW = srcW; - c->srcH = srcH; - c->srcF = srcFormat; + std::thread t([&]{ + auto handle_gb28181 = new GB28181API; + std::string ru(rtspUrl); + if(handle_gb28181->addCamera(ru) == -1){ + delete(handle_gb28181); + logIt("do addCamera Error\n"); + ret = -2; + return; + } + add_camera.store(true); + std::this_thread::sleep_for(std::chrono::seconds(1)); + int retLen = handle_gb28181->capturePic(handle_gb28181, retData, retDataLen, tt); + if(retLen == 0){ + logIt("do capturePic failed:%d"); + ret = -1; + } - return c; - } + handle_gb28181->deleteCamera(); + delete handle_gb28181; + }); - uint8_t *Convert(void *h, uint8_t *src){ - Conv *c = (Conv*)h; + std::this_thread::sleep_for(std::chrono::seconds(1)); - auto b = c->b; + int ttt = tt; + if (ttt < 6) ttt = 6; - AVFrame *tmp_frm = cvbridge::fillFrame(src, c->srcW, c->srcH, c->srcF); - if (!tmp_frm) return NULL; - - unsigned char *picData = b->convert2Data(tmp_frm); - - av_frame_free(&tmp_frm); - - return picData; - } - - void DestoryConvertor(void *h){ - Conv *c = (Conv*)h; - delete c->b; - free(c); - } - -// mjpeg av pix fmt yuv420p - - static int save2PIC(uint8_t *data, const int w, const int h, const char *filename){ - AVPixelFormat src_fmt = AV_PIX_FMT_BGR24; - AVPixelFormat dst_fmt = AV_PIX_FMT_YUV420P; - - cvbridge *bridge = new cvbridge(w, h, src_fmt, w, h, dst_fmt, 16); - - AVFrame *bgr_frame = cvbridge::fillFrame(data, w, h, src_fmt); - AVFrame *frame_jpeg = bridge->convert2Frame(bgr_frame); - av_frame_free(&bgr_frame); - - AVFormatContext *ctx = avformat_alloc_context(); - ctx->oformat = av_guess_format("mjpeg", NULL, NULL); - if( avio_open(&ctx->pb, filename, AVIO_FLAG_READ_WRITE) < 0) { - printf("Couldn't open output file."); - avformat_free_context(ctx); - - delete bridge; - return -1; + int i = -1; + while (true) { + std::this_thread::sleep_for(std::chrono::seconds(1)); + if (add_camera.load()) { + t.join(); + return ret; + } + if (i++ > ttt) break; } - AVStream* pAVStream = avformat_new_stream(ctx, 0); - if( pAVStream == NULL ){ - delete bridge; - return -1; - } - AVCodecContext* pCodecCtx = pAVStream->codec; - pCodecCtx->codec_id = ctx->oformat->video_codec; - pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO; - pCodecCtx->pix_fmt = dst_fmt; - pCodecCtx->width = w; - pCodecCtx->height = h; - pCodecCtx->time_base.num = 1; - pCodecCtx->time_base.den = 25; - AVCodec* pCodec = avcodec_find_encoder(pCodecCtx->codec_id); - if( !pCodec ) { - printf("Codec not found."); - avformat_free_context(ctx); - - delete bridge; - return -1; - } - if( avcodec_open2(pCodecCtx, pCodec, NULL) < 0 ){ - printf("Could not open codec."); - avformat_free_context(ctx); - avio_close(ctx->pb); - delete bridge; - return -1; - } - avformat_write_header(ctx, NULL); - int y_size = pCodecCtx->width * pCodecCtx->height; - AVPacket pkt; - av_new_packet(&pkt, y_size * 3); - int got_picture = 0; - int ret = avcodec_encode_video2(pCodecCtx, &pkt, frame_jpeg, &got_picture); - av_frame_free(&frame_jpeg); - delete bridge; - if( ret < 0 ) { - printf("Encode Error.\n"); - avformat_free_context(ctx); - if( pAVStream ) { - avcodec_close(pAVStream->codec); - } - avio_close(ctx->pb); - - return -1; - } - if( got_picture == 1 ) { - pkt.stream_index = pAVStream->index; - ret = av_write_frame(ctx, &pkt); - avio_flush(ctx->pb); - } - av_free_packet(&pkt); - //Write Trailer - av_write_trailer(ctx); - if( pAVStream ) { - avcodec_close(pAVStream->codec); - } - avio_close(ctx->pb); - avformat_free_context(ctx); - return 0; + t.detach(); + return -1; } +#endif } -- Gitblit v1.8.0