123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447 |
- #include <QCoreApplication>
- #include <QFile>
- extern "C"
- {
- #include <libavcodec/avcodec.h>
- #include <libavutil/opt.h>
- #include <libavutil/imgutils.h>
- #include <libavutil/common.h>
- #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 <iostream>
- #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<char> 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<char> pstr = std::shared_ptr<char>(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<char>(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<char>(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<char>(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<char>(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<char>(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<iv::datapac> 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)<<std::endl;
- }
- }
- gmutexlat.unlock();
- std::cout<<" time: "<<std::chrono::system_clock::now().time_since_epoch().count()/1000000<<" read packet size:"<<i_pkt.size<<std::endl;
- av_packet_unref(&i_pkt);
- }
- }
- int main(int argc, char *argv[])
- {
- QCoreApplication a(argc, argv);
- std::string strxmlpath;
- if(argc == 1)
- {
- strxmlpath = "./driver_h264_rtspclient.xml";
- }
- else
- {
- strxmlpath = argv[1];
- }
- iv::xmlparam::Xmlparam xp(strxmlpath);
- std::string strfrontmsgname = xp.GetParam("frontmsg","h264front");
- std::string strrearmsgname = xp.GetParam("rearmsg","h264rear");
- std::string strleftmsgname = xp.GetParam("leftmsg","h264left");
- std::string strrightmsgname = xp.GetParam("rightmsg","h264right");
- std::string strvin = xp.GetParam("VIN","AAAAAAAAAAAAAAVTD");
- std::string strpass = xp.GetParam("pass","hello");
- int nwidth = xp.GetParam("width",1920);
- int nheigth = xp.GetParam("height",1080);
- std::string strserverip = xp.GetParam("ServerIP","111.33.136.149");
- std::string strserverport = xp.GetParam("ServerPort","9554");
- std::string strfrontrtsp = "rtsp://" + strserverip+":"+strserverport+"/"
- +strvin + "-front-" + strpass;
- std::string strrearrtsp = "rtsp://" + strserverip+":"+strserverport+"/"
- +strvin + "-rear-" + strpass;
- std::string strleftrtsp = "rtsp://" + strserverip+":"+strserverport+"/"
- +strvin + "-left-" + strpass;
- std::string strrightrtsp = "rtsp://" + strserverip+":"+strserverport+"/"
- +strvin + "-right-" + strpass;
- av_register_all(); //初始化FFMPEG 调用了这个才能正常适用编码器和解码器
- //Network
- avformat_network_init();
- #ifndef TESTLATENCY
- rtspclientup * pup = new rtspclientup(strfrontrtsp.data(),nwidth,nheigth);
- gupfront = pup;
- void * pafront = iv::modulecomm::RegisterRecv(strfrontmsgname.data(),Listenfront);
- (void)pafront;
- if(strrearmsgname != "nomessage")
- {
- guprear = new rtspclientup(strrearrtsp.data(),nwidth,nheigth);
- void * parear = iv::modulecomm::RegisterRecv(strrearmsgname.data(),Listenrear);
- (void)parear;
- }
- if(strrearmsgname != "nomessage")
- {
- gupleft = new rtspclientup(strleftrtsp.data(),nwidth,nheigth);
- void * paleft = iv::modulecomm::RegisterRecv(strleftmsgname.data(),Listenleft);
- (void)paleft;
- }
- if(strrearmsgname != "nomessage")
- {
- gupright = new rtspclientup(strrightrtsp.data(),nwidth,nheigth);
- void * paright = iv::modulecomm::RegisterRecv(strrightmsgname.data(),Listenright);
- (void)paright;
- }
- return a.exec();
- #endif
- void * pa = iv::modulecomm::RegisterRecv("h264front",Listenframe);
- (void)pa;
- AVFormatContext *ifmt_ctx = NULL;
- AVPacket pkt;
- const char *in_filename, *out_filename;
- FfmpegOutputer *pusher = NULL;
- int ret;
- int frame_index = 0;
- in_filename = "./imx291.h264";
- out_filename = "rtsp://111.33.136.149:9554/testhello2";
- std::thread * precvthread = new std::thread(threadrecv);
- (void)precvthread;
- if ((ret = avformat_open_input(&ifmt_ctx, in_filename, 0, 0)) < 0) {
- printf("Could not open input file.");
- return -1;
- }
- if ((ret = avformat_find_stream_info(ifmt_ctx, 0)) < 0) {
- printf("Failed to retrieve input stream information");
- return -2 ;
- }
- ifmt_ctx->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."<<std::endl;
- return -1;
- }
- out_stream->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. "<<std::endl;
- continue;
- }
- // continue;
- gmutex.lock();
- pkt.buf = NULL;
- pkt.duration = 0;
- pkt.data = new unsigned char[gndatasize];
- // pkt.buf->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 : "<<gndatasize<<std::endl;
- // std::cout<<" buf size: "<<pkt.buf->size<<std::endl;
- // pkt.buf->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 "<<std::endl;
- // ret = av_read_frame(ifmt_ctx, &pkt);
- gmutexlat.lock();
- gvectorsend.push_back(xpac);
- while(gvectorsend.size()>100)gvectorsend.erase(gvectorsend.begin());
- gmutexlat.unlock();
- std::cout<<" time: "<<std::chrono::system_clock::now().time_since_epoch().count()/1000000<<" pos: "<<pkt.pos<<" size: "<<pkt.size<<" flats: "<<pkt.flags<< std::endl;
- // if (ret < 0) break;
- pkt.duration = 3*1000;
- // std::cout<<" pts: "<<pkt.pts<<" dts: "<<pkt.dts<<std::endl;
- if (pkt.pts == AV_NOPTS_VALUE) {
- pkt.dts = pkt.pts = 1000* (1.0/30)*90*frame_index;
- // pkt.dts = pkt.pts = frame_index * 1;
- // frame_index++;
- }
- // std::cout<<" pts: "<<pkt.pts<<" dts: "<<pkt.dts<<std::endl;
- pusher->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();
- }
|