#include #include extern "C" { #include #include #include #include #include "libavutil/error.h" #include "libavutil/hwcontext.h" #include "libavformat/avformat.h" #include "libavformat/avio.h" #ifdef USE_QSV //#include "libavutil/hwcontext_qsv.h" //#include "libavutil/hwcontext_vaapi.h" #endif } #include #include "ffmpeg_outputer.h" #include "modulecomm.h" #include "xmlparam.h" #include "rtspclientup.h" rtspclientup * gupfront = NULL; rtspclientup * guprear = NULL; rtspclientup * gupleft = NULL; rtspclientup * gupright = NULL; std::shared_ptr gpstr_data; bool gbUpdate = false; int gndatasize; std::mutex gmutex; void Listenframe(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname) { if(nSize<10)return; std::shared_ptr pstr = std::shared_ptr(new char[nSize]); memcpy(pstr.get(),strdata,nSize); gmutex.lock(); gpstr_data = pstr; gndatasize = nSize; gbUpdate = true; gmutex.unlock(); // qDebug(" %02x %02x %02x %02x %02x %02x",strdata[0],strdata[1],strdata[2],strdata[3],strdata[4],strdata[5]); iv::framedata xframe; xframe.mframe_ptr = std::shared_ptr(new char[nSize]); mempcpy(xframe.mframe_ptr.get(),strdata,nSize); xframe.mndatasize = nSize; if(gupfront != NULL) { gupfront->AddData(xframe); } } void Listenfront(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname) { if(nSize<6)return; iv::framedata xframe; xframe.mframe_ptr = std::shared_ptr(new char[nSize]); mempcpy(xframe.mframe_ptr.get(),strdata,nSize); xframe.mndatasize = nSize; if(gupfront != NULL) { gupfront->AddData(xframe); } } void Listenrear(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname) { if(nSize<6)return; iv::framedata xframe; xframe.mframe_ptr = std::shared_ptr(new char[nSize]); mempcpy(xframe.mframe_ptr.get(),strdata,nSize); xframe.mndatasize = nSize; if(guprear != NULL) { guprear->AddData(xframe); } } void Listenleft(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname) { if(nSize<6)return; iv::framedata xframe; xframe.mframe_ptr = std::shared_ptr(new char[nSize]); mempcpy(xframe.mframe_ptr.get(),strdata,nSize); xframe.mndatasize = nSize; if(gupleft != NULL) { gupleft->AddData(xframe); } } void Listenright(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname) { if(nSize<6)return; iv::framedata xframe; xframe.mframe_ptr = std::shared_ptr(new char[nSize]); mempcpy(xframe.mframe_ptr.get(),strdata,nSize); xframe.mndatasize = nSize; if(gupright != NULL) { gupright->AddData(xframe); } } std::mutex gmutexlat; namespace iv { struct datapac { int64_t sendtime; int nsize; }; } std::vector gvectorsend; void threadrecv() { // return; static AVFormatContext *i_fmt_ctx; int i; static bool bStop = false; std::this_thread::sleep_for(std::chrono::milliseconds(1000)); /* should set to NULL so that avformat_open_input() allocate a new one */ i_fmt_ctx = NULL; //这是我用ONVIF协议得到的摄像头RTSP流媒体地址 char rtspUrl[] = "rtsp://111.33.136.149:9554/testlatency"; AVDictionary *avdic=NULL; char option_key[]="rtsp_transport"; char option_value[]="tcp"; av_dict_set(&avdic,option_key,option_value,0); if (avformat_open_input(&i_fmt_ctx, rtspUrl, NULL, &avdic)!=0) { fprintf(stderr, " = could not open input file\n"); return ; } AVDictionary *opts = NULL; av_dict_set(&opts, "rtsp_transport", "tcp", 0); // av_dict_set(&opts, "muxdelay", "0.1", 0); if (avformat_find_stream_info(i_fmt_ctx,NULL)<0) { fprintf(stderr, " = could not find stream info\n"); return ; } while(!bStop) { //printf("------------------------------------------------------\n"); AVPacket i_pkt; av_init_packet(&i_pkt); i_pkt.size = 0; i_pkt.data = NULL; if (av_read_frame(i_fmt_ctx, &i_pkt) <0 ) break; gmutexlat.lock(); for(i=gvectorsend.size();i>=0;i--) { iv::datapac xpac = gvectorsend[i]; if(xpac.nsize == i_pkt.size) { std::cout<<"Latency: "<<(std::chrono::system_clock::now().time_since_epoch().count()/1000000 - xpac.sendtime)<streams[0]->codecpar->width = 1920; ifmt_ctx->streams[0]->codecpar->height = 1080; AVFormatContext * fmtctx = NULL; out_filename = "rtsp://111.33.136.149:9554/testlatency"; int nrtn = avformat_alloc_output_context2(&fmtctx,NULL,"rtsp","rtsp://111.33.136.149:9554/testlatency"); (void)nrtn; fmtctx->bit_rate = 2000000; fmtctx->fps_probe_size = 30; AVStream *out_stream = avformat_new_stream(fmtctx, NULL); QFile xFile; #ifdef SAVECODEPAR xFile.setFileName("./codepar"); if(xFile.open(QIODevice::ReadWrite)) { xFile.write((char*)ifmt_ctx->streams[0]->codecpar,sizeof(AVCodecParameters)); if(ifmt_ctx->streams[0]->codecpar->extradata_size>0) { xFile.write((char*)ifmt_ctx->streams[0]->codecpar->extradata,ifmt_ctx->streams[0]->codecpar->extradata_size); } xFile.close(); return 0; } #endif xFile.setFileName(":/codepar"); if(xFile.open(QIODevice::ReadOnly)) { xFile.read((char *)out_stream->codecpar,sizeof(AVCodecParameters)); if(out_stream->codecpar->extradata_size>0) { out_stream->codecpar->extradata = new uint8_t[out_stream->codecpar->extradata_size]; xFile.read((char*)out_stream->codecpar->extradata,out_stream->codecpar->extradata_size); } xFile.close(); } else { std::cout<<"can't get codepar from file."<codecpar->bit_rate = 2000000; out_stream->codecpar->width = 1280; out_stream->codecpar->height = 720; if (NULL == pusher) { pusher = new FfmpegOutputer(); // ret = pusher->OpenOutputStream(out_filename, ifmt_ctx); ret = pusher->OpenOutputStream(out_filename, fmtctx); if (ret != 0){ return -3; } } av_dump_format(ifmt_ctx, 0, in_filename, 0); int pos = 0; // av_read_frame(ifmt_ctx, &pkt); // pkt = av_packet_alloc(); while (true) { if(gbUpdate == false) { std::this_thread::sleep_for(std::chrono::milliseconds(1)); // av_usleep(1000); // std::cout<<"sleep. "<data = pkt.data; memcpy(pkt.data, gpstr_data.get(),gndatasize); pkt.size = gndatasize; pkt.stream_index = 0; pkt.side_data = 0; pkt.side_data_elems = 0; // std::cout<<" size : "<size<size = gndatasize; pkt.pos = pos; pkt.pts = AV_NOPTS_VALUE; pkt.dts = AV_NOPTS_VALUE; pos = pos + gndatasize; gbUpdate = false; gmutex.unlock(); pkt.flags = 0; iv::datapac xpac; xpac.nsize = pkt.size; xpac.sendtime = std::chrono::system_clock::now().time_since_epoch().count()/1000000; // std::cout<<"send frame "<100)gvectorsend.erase(gvectorsend.begin()); gmutexlat.unlock(); std::cout<<" time: "<InputPacket(&pkt); delete pkt.data; av_packet_unref(&pkt); frame_index++; // av_usleep(40000); } end: avformat_close_input(&ifmt_ctx); avformat_free_context(ifmt_ctx); delete pusher; return a.exec(); }