瀏覽代碼

change driver_h264_rtspclient. change RemoteCtrl_h264, test rtsp,latency is good. not complete.

yuchuli 3 年之前
父節點
當前提交
f496bea0b5

+ 2 - 0
src/driver/driver_h264_rtspclient/driver_h264_rtspclient.pro

@@ -51,6 +51,8 @@ RESOURCES += \
 
 #DEFINES += SAVECODEPAR
 
+#DEFINES += TESTLATENCY
+
 HEADERS += \
     rtspclientup.h \
     ffmpeg_outputer.h

+ 14 - 0
src/driver/driver_h264_rtspclient/driver_h264_rtspclient.xml

@@ -0,0 +1,14 @@
+<xml>	
+	<node name="driver_h264_rtspclient">
+		<param name="frontmsg" value="h264front" />
+		<param name="rearmsg" value="h264rear" />
+		<param name="leftmsg" value="h264left" />
+		<param name="rightmsg" value="h264right" />
+		<param name="width" value = "1920" />
+		<param name="height" value="1080" />
+		<param name="VIN" value="AAAAAAAAAAAAAAAAA" />
+		<param name="pass" value="hello" />
+		<param name="ServerIP" value = "111.33.136.149" />
+		<param name="ServerPort" value="9554" />
+	</node>
+</xml>

+ 6 - 0
src/driver/driver_h264_rtspclient/ffmpeg_outputer.h

@@ -198,8 +198,14 @@ public:
 
 
     int InputPacket(AVPacket *pkt) {
+        if(m_list_packets.size()>90)
+        {
+            std::cout<<" ignore packete. buffer full."<<std::endl;
+            return -1;
+        }
         AVPacket *pkt1 = av_packet_alloc();
         av_packet_ref(pkt1, pkt);
+
         m_list_packets.push_back(pkt1);
         return 0;
     }

+ 81 - 230
src/driver/driver_h264_rtspclient/main.cpp

@@ -1,6 +1,6 @@
 #include <QCoreApplication>
 
-
+#include <QFile>
 
 extern "C"
 {
@@ -24,178 +24,9 @@ extern "C"
 
 #include <iostream>
 
-
-
-//AVCodec *pCodec=NULL; //解码器指针
-//AVCodecContext* pCodecCtx=NULL; //ffmpeg 解码类的类成员
-
-//AVFormatContext* pFormatCtx=NULL; //保存视频流的信息
-
-//AVFormatContext * fmtctx = avformat_alloc_context();
-
-//    fmtctx->oformat= av_guess_format("rtsp",NULL,NULL);
-//    snprintf(fmtctx->filename,sizeof(fmtctx->filename),"rtsp://127.0.0.1:9554/te.sdp");
-////    pFormatCtx=avformat_alloc_context();
-//AVDictionary* options=NULL;
-////    av_dict_set(&options,"buffer_size","1024000",0);
-////    av_dict_set(&options,"max_delay","500000",0);
-//av_dict_set(&options,"rtsp_transport","tcp",0);
-////    av_dict_set(&options,"stimeout","2000000",0);//如果没有设置stimeout,那么流地址错误,av_read_frame会阻塞(时间单位是微妙)
-
-//int nrtn =  avformat_init_output(fmtctx,&options);
-
-
-int openOutputFile()
-{
-    av_register_all();  //注册库中所有的文件格式和编码器
-    avformat_network_init();
-
-    avcodec_register_all();
-
-
-    const AVCodec *codec = avcodec_find_encoder(AV_CODEC_ID_H264);
-    AVCodecContext *c= NULL;
-
-    c = avcodec_alloc_context3(codec);
-
-    if(c == NULL)std::cout<<"c NULL ."<<std::endl;
-//    pkt = av_packet_alloc();
-//        if (!pkt)
-//            exit(1);
-        c->bit_rate = 4000000;
-
-        c->width = 1280;
-        c->height = 720;
-
-        c->time_base = (AVRational){1, 30};
-        c->framerate = (AVRational){30, 1};
-
-        c->gop_size = 10;
-        c->max_b_frames = 1;
-        c->pix_fmt =  AV_PIX_FMT_NV12;// AV_PIX_FMT_YUV420P;
-
-
-
-        if (codec->id == AV_CODEC_ID_H264)
-        {
-            av_opt_set(c->priv_data, "profile", "baseline", 0);
-
-
-             av_opt_set(c->priv_data, "preset", "fast", 0);
-           av_opt_set(c->priv_data, "tune", "zerolatency", 0);
-        }
-
-        int retc = avcodec_open2(c, codec, NULL);
-        if (retc < 0) {
-            std::cout<<"Could not open codec: "<<std::endl;
-//             fprintf(stderr, "Could not open codec: %s\n", av_err2str(ret));
-            exit(1);
-        }
-
-    AVFormatContext * fmtctx = NULL;
-    int nrtn = avformat_alloc_output_context2(&fmtctx,NULL,"rtsp","rtsp://127.0.0.1:9554/test2.sdp");
-
-
-
-    fmtctx->bit_rate = 2000000;
-    fmtctx->fps_probe_size = 30;
-
-    int err = 0;
-
-    AVStream *out_stream = avformat_new_stream(fmtctx, codec);
-
-    out_stream->codecpar->bit_rate = 2000000;
-    out_stream->codecpar->width = 1280;
-    out_stream->codecpar->height = 720;
-
-
-        int ret = 0;
-
-
-
-
-            av_dump_format(fmtctx, 0, fmtctx->filename, 1);
-
-//        int nrx = avformat_init_output(fmtctx,NULL);
-
-        ret = avio_open(&fmtctx->pb,fmtctx->filename,AVIO_FLAG_WRITE);
-//		fmtctx->flags |= AVFMT_FLAG_NONBLOCK;
-//		if (!(fmtctx->flags & AVFMT_NOFILE)) {
-////			AVIOInterruptCB ioCb = { &FfmpegMuxer::ioInterruptCallback, this };
-//			ret = avio_open2(&fmtctx->pb, m_outputFilename.c_str(), AVIO_FLAG_WRITE, &ioCb, nullptr);
-//			if (ret < 0) {
-//				err = ERROR_CODE_FFMPEG_OPEN_AVIO_FAILED;
-//				break;
-//			}
-//		}
-
-        std::cout<<"ret: "<<ret<<std::endl;
-        AVDictionary* options = nullptr;
-            av_dict_set(&options, "rtsp_transport", "tcp", 0);
-            av_dict_set(&options, "stimeout", "8000000", 0);
-        ret = avformat_write_header(fmtctx, &options);
-        if (options != nullptr) {
-            av_dict_free(&options);
-        }
-        if (ret < 0) {
-            err = -1;
-        }
-//	} while (0);
-
-    return err;
-}
-
-
-int test2()
-{
-    AVFormatContext *pFormatCtx;
-    AVCodecContext *pCodecCtx;
-    AVCodec *pCodec;
-    AVFrame *pFrame, *pFrameRGB;
-    AVPacket *packet;
-    uint8_t *out_buffer;
-
-    static struct SwsContext *img_convert_ctx;
-
-    int videoStream, i, numBytes;
-    int ret, got_picture;
-
-    avformat_network_init();   ///初始化FFmpeg网络模块,2017.8.5---lizhen
-    av_register_all();         //初始化FFMPEG  调用了这个才能正常适用编码器和解码器
-
-
-    //Allocate an AVFormatContext.
-    pFormatCtx = avformat_alloc_context();
-
-    ///2017.8.5---lizhen
-    AVDictionary *avdic=NULL;
-    char option_key[]="rtsp_transport";
-    char option_value[]="tcp";
-    av_dict_set(&avdic,option_key,option_value,0);
-//    char option_key2[]="max_delay";
-//    char option_value2[]="100";
-//    av_dict_set(&avdic,option_key2,option_value2,0);
-    ///rtsp地址,可根据实际情况修改
-    char url[]="rtsp://111.33.136.149:9554/test2.sdp";
-
-
-    if (avformat_open_input(&pFormatCtx, url, NULL, &avdic) != 0) {
-        printf("can't open the file. \n");
-        return -1;
-    }
-
-    if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
-        printf("Could't find stream infomation.\n");
-        return -2;
-    }
-
-}
-
-
 #include "ffmpeg_outputer.h"
-
-
 #include "modulecomm.h"
+#include "xmlparam.h"
 #include "rtspclientup.h"
 
 rtspclientup * gupfront = NULL;
@@ -300,20 +131,16 @@ void threadrecv()
 {
 //    return;
     static AVFormatContext *i_fmt_ctx;
-    static AVStream *i_video_stream;
-
-    static AVFormatContext *o_fmt_ctx;
-    static AVStream *o_video_stream;
 
+    int i;
     static bool bStop = false;
-    static int frame_nums = 0;
 
     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/testhello2";
+        char rtspUrl[] = "rtsp://111.33.136.149:9554/testlatency";
 
 
         AVDictionary *avdic=NULL;
@@ -341,11 +168,6 @@ void threadrecv()
         }
 
 
-
-        int last_pts = 0;
-           int last_dts = 0;
-
-           int64_t pts, dts;
            while(!bStop)
            {
                //printf("------------------------------------------------------\n");
@@ -356,10 +178,6 @@ void threadrecv()
                if (av_read_frame(i_fmt_ctx, &i_pkt) <0 )
                    break;
 
-
-
-               int sizedata = i_pkt.size;
-               int i;;
                gmutexlat.lock();
                for(i=gvectorsend.size();i>=0;i--)
                {
@@ -376,7 +194,7 @@ void threadrecv()
 
 
 }
-#include <QFile>
+
 
 
 
@@ -384,35 +202,92 @@ 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","AAAAAAAAAAAAAAAAA");
+    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();
 
-    rtspclientup * pup = new rtspclientup("rtsp://111.33.136.149:9554/test",1920,1080);
+#ifndef TESTLATENCY
+
+    rtspclientup * pup = new rtspclientup(strfrontrtsp.data(),nwidth,nheigth);
     gupfront = pup;
-    void * pa = iv::modulecomm::RegisterRecv("h264front",Listenframe);
-    return a.exec();
+    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;
+    }
 
-    AVFormatContext *ifmt_ctx = NULL;
-       AVPacket pkt;
-       const char *in_filename, *out_filename;
-       FfmpegOutputer *pusher = NULL;
-       int ret;
-       int frame_index = 0;
+    if(strrearmsgname != "nomessage")
+    {
+        gupright = new rtspclientup(strrightrtsp.data(),nwidth,nheigth);
+        void * paright = iv::modulecomm::RegisterRecv(strrightmsgname.data(),Listenright);
+        (void)paright;
+    }
 
-       in_filename = "./imx291.h264";
 
-       out_filename = "rtsp://111.33.136.149:9554/testhello2";
-       //out_filename = "rtp://233.233.233.233:6666";
-       //out_filename = "tcp://127.0.0.1:9000";
-       //out_filename = "udp://127.0.0.1:9000";
+    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);
+    std::thread * precvthread = new std::thread(threadrecv);
+    (void)precvthread;
 
 
 
@@ -433,15 +308,13 @@ int main(int argc, char *argv[])
 
 
        AVFormatContext * fmtctx = NULL;
-       int nrtn = avformat_alloc_output_context2(&fmtctx,NULL,"rtsp","rtsp://127.0.0.1:9554/test2.sdp");
-
-
+       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;
 
-       int err = 0;
-
        AVStream *out_stream = avformat_new_stream(fmtctx, NULL);
 
        QFile xFile;
@@ -464,7 +337,6 @@ int main(int argc, char *argv[])
        xFile.setFileName(":/codepar");
        if(xFile.open(QIODevice::ReadOnly))
        {
-           int n = sizeof(AVCodecParameters);
            xFile.read((char *)out_stream->codecpar,sizeof(AVCodecParameters));
            if(out_stream->codecpar->extradata_size>0)
            {
@@ -479,15 +351,10 @@ int main(int argc, char *argv[])
            return -1;
        }
 
-
-
        out_stream->codecpar->bit_rate = 2000000;
        out_stream->codecpar->width = 1280;
        out_stream->codecpar->height = 720;
 
-//       avcodec_parameters_copy(fmtctx->streams[0]->codecpar, ifmt_ctx->streams[0]->codecpar);
-
-//       memcpy(fmtctx->streams[0]->codecpar, ifmt_ctx->streams[0]->codecpar,sizeof(AVCodecParameters));
 
        if (NULL == pusher) {
            pusher = new FfmpegOutputer();
@@ -573,24 +440,8 @@ int main(int argc, char *argv[])
        avformat_free_context(ifmt_ctx);
        delete pusher;
 
-
- //   test2();
-//    openOutputFile();
-//    avcodec_register_all();
-//    avformat_network_init();
-
-//    char* video_dir="rtsp://admin:yltx8888@192.168.37.210:554/h264/ch1/main/av_stream";
-//    char* video_dir="rtmp://58.200.131.2:1935/livetv/cctv6";
-
-
-//    AVFormatContext * fmtctx = avformat_alloc_context();
-//    fmtctx->oformat= av_guess_format("rtsp",NULL,NULL);
-//    snprintf(fmtctx->filename,sizeof(fmtctx->filename),"rtsp://127.0.0.1:9554/te.sdp");
-//    int nrtn = avio_open(&fmtctx->pb,fmtctx->filename,AVIO_FLAG_WRITE);
-//    std::cout<<"hello "<<std::endl;
-////    int nrtn = avformat_open_input(&fmtctx,fmtctx->filename,NULL,NULL);
-//    std::cout<<" nrtn : "<<nrtn<<std::endl;
     return a.exec();
+
 }
 
 

+ 4 - 2
src/tool/RemoteCtrl_h264/RemoteCtrl_h264.pro

@@ -55,7 +55,8 @@ SOURCES += \
     ../../include/msgtype/uploadthreadmsg.pb.cc \
     grpcpc.cpp \
     remotecomm.cpp \
-    ../../driver/driver_h264_dec/ivh264framedecode.cpp
+    ../../driver/driver_h264_dec/ivh264framedecode.cpp \
+    rtspclientdown.cpp
 
 HEADERS += \
     ../../common/common/getinterface/get_interface.h \
@@ -85,7 +86,8 @@ HEADERS += \
     ../../include/msgtype/uploadthreadmsg.pb.h \
     grpcpc.h \
     remotecomm.h \
-    ../../driver/driver_h264_dec/ivh264framedecode.h
+    ../../driver/driver_h264_dec/ivh264framedecode.h \
+    rtspclientdown.h
 
 FORMS += \
     dialogbigpic.ui \

+ 24 - 1
src/tool/RemoteCtrl_h264/grpcpc.cpp

@@ -9,12 +9,14 @@ static grpcpc * ggrpcpc;
 grpcpc::grpcpc(std::string stryamlpath)
 {
 
-
+    (void)stryamlpath;
 
     ggrpcpc = this;
 
     int i;
 
+    if(mbUseRTSP == false)
+    {
     for(i=0;i<NUM_CAM;i++)
     {
         unsigned int j;
@@ -23,6 +25,19 @@ grpcpc::grpcpc(std::string stryamlpath)
             mpThread[i*NUM_THREAD_PERCAM + j] = new std::thread(&grpcpc::threadpicdownload,this,i);
         }
     }
+    }
+    else
+    {
+        mstrrtspserverip = ServiceRCIni.GetServerIP();
+        std::string strfront = "rtsp://"+mstrrtspserverip+":"+mstrrtspserverport+"/"+gstrVIN+"-front-"+mstrrtsppass;
+        mprtspdown[0] = new rtspclientdown(strfront);
+        std::string strrear = "rtsp://"+mstrrtspserverip+":"+mstrrtspserverport+"/"+gstrVIN+"-rear-"+mstrrtsppass;
+        mprtspdown[1] = new rtspclientdown(strrear);
+        std::string strleft = "rtsp://"+mstrrtspserverip+":"+mstrrtspserverport+"/"+gstrVIN+"-left-"+mstrrtsppass;
+        mprtspdown[2] = new rtspclientdown(strleft);
+        std::string strright = "rtsp://"+mstrrtspserverip+":"+mstrrtspserverport+"/"+gstrVIN+"-right-"+mstrrtsppass;
+        mprtspdown[3] = new rtspclientdown(strright);
+    }
 }
 
 
@@ -45,6 +60,10 @@ int grpcpc::Produceh264frame(int ncampos,iv::h264rawframedata & xframe)
 
 int grpcpc::Consumeh264frame(int ncampos,iv::h264rawframedata & xframe)
 {
+    if(mbUseRTSP)
+    {
+        return mprtspdown[ncampos]->Getrtspframe(xframe,0);
+    }
     int nrtn = 0;
     mmutexh264frame[ncampos].lock();
     if(mvectorh264frame[ncampos].size() == 0)nrtn = 0;
@@ -60,6 +79,10 @@ int grpcpc::Consumeh264frame(int ncampos,iv::h264rawframedata & xframe)
 
 int grpcpc::Consumeh264frame(int ncampos,iv::h264rawframedata & xframe,int nwaitms)
 {
+    if(mbUseRTSP)
+    {
+        return mprtspdown[ncampos]->Getrtspframe(xframe,nwaitms);
+    }
     int nrtn = 0;
     mmutexh264frame[ncampos].lock();
     if(mvectorh264frame[ncampos].size() == 0)nrtn = 0;

+ 10 - 5
src/tool/RemoteCtrl_h264/grpcpc.h

@@ -28,6 +28,8 @@
 
 #include "uploadthreadmsg.grpc.pb.h"
 
+#include "rtspclientdown.h"
+
 #ifndef NUM_CAM
 #define NUM_CAM 4
 #endif
@@ -55,11 +57,7 @@ struct msgunit
     int mnkeeptime = 100;
 };
 
-struct h264rawframedata
-{
-    std::shared_ptr<char> mpstr_ptr;
-    int mdatasize;
-};
+
 }
 
 class grpcpc : public QThread
@@ -141,6 +139,13 @@ private:
     std::mutex mmutexquerycv;
     std::condition_variable mcvquery;
 
+private:
+    bool mbUseRTSP = true;  //Use RTSP connect to the server.
+    std::string mstrrtspserverip = "111.33.136.149";
+    std::string mstrrtspserverport = "9554";
+    std::string mstrrtsppass = "hello";
+    rtspclientdown * mprtspdown[NUM_CAM];
+
 
 };
 

+ 2 - 2
src/tool/RemoteCtrl_h264/mainwindow.h

@@ -233,8 +233,8 @@ private:
 private:
     ivh264framedecode * mph264decode[NUM_CAM];
 
-    int mnframewidth = 1280;
-    int mnframeheight = 720;
+    int mnframewidth = 1920;
+    int mnframeheight = 1080;
 
     std::thread * mpthreadframe[NUM_CAM];
     std::thread * mpthreadpic[NUM_CAM];

+ 130 - 0
src/tool/RemoteCtrl_h264/rtspclientdown.cpp

@@ -0,0 +1,130 @@
+#include "rtspclientdown.h"
+
+#include <iostream>
+
+rtspclientdown::rtspclientdown(std::string strrtspserver)
+{
+    mpthread = new std::thread(&rtspclientdown::threadrtspdown,this,strrtspserver);
+}
+
+
+rtspclientdown::~rtspclientdown()
+{
+    mbthreadrun = false;
+    mpthread->join();
+}
+
+void rtspclientdown::threadrtspdown(std::string strrtspserver)
+{
+
+    AVFormatContext *i_fmt_ctx;
+    /* should set to NULL so that avformat_open_input() allocate a new one */
+    i_fmt_ctx = NULL;
+
+    AVDictionary *avdic=NULL;
+    char option_key[]="rtsp_transport";
+    char option_value[]="tcp";
+    av_dict_set(&avdic,option_key,option_value,0);
+
+    bool bConnected = false;
+
+    while(mbthreadrun)
+    {
+        if(bConnected == false)
+        {
+            i_fmt_ctx = NULL;
+            if (avformat_open_input(&i_fmt_ctx, strrtspserver.data(), NULL, &avdic)!=0)
+            {
+                fprintf(stderr, " = could not open input file\n");
+                std::this_thread::sleep_for(std::chrono::milliseconds(1000));
+                continue ;
+            }
+
+
+            if (avformat_find_stream_info(i_fmt_ctx,NULL)<0)
+            {
+                fprintf(stderr, " = could not find stream info\n");
+                std::this_thread::sleep_for(std::chrono::milliseconds(1000));
+                continue ;
+            }
+            bConnected = true;
+        }
+        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 )
+        {
+            bConnected = false;
+            std::cout<<"connect fail. retry."<<std::endl;
+            continue;
+        }
+
+        iv::h264rawframedata xframe;
+        xframe.mdatasize = i_pkt.size;
+        xframe.mpstr_ptr = std::shared_ptr<char>(new char[xframe.mdatasize]);
+        memcpy(xframe.mpstr_ptr.get(),i_pkt.data,xframe.mdatasize);
+        mmutexframe.lock();
+        while(mvectorframe.size()>900)
+        {
+            std::cout<<" rtspclientdown::threadrtspdown. erase frame."<<std::endl;
+            mvectorframe.erase(mvectorframe.begin());
+        }
+        mvectorframe.push_back(xframe);
+        mmutexframe.unlock();
+
+        mcv.notify_all();
+
+
+         av_packet_unref(&i_pkt);
+    }
+}
+
+int rtspclientdown::Getrtspframe(iv::h264rawframedata &xframe, int nwaitms)
+{
+    int nrtn = 0;
+    if(mvectorframe.size()>0)
+    {
+        mmutexframe.lock();
+        if(mvectorframe.size()>0)
+        {
+            xframe = mvectorframe[0];
+            mvectorframe.erase(mvectorframe.begin());
+            nrtn = 1;
+        }
+        else
+        {
+            nrtn = 0;
+        }
+        mmutexframe.unlock();
+        return nrtn;
+    }
+
+    if(nwaitms == 0)return nrtn;
+
+    std::unique_lock<std::mutex> lk(mmutexcv);
+    if(mcv.wait_for(lk, std::chrono::milliseconds(nwaitms)) == std::cv_status::timeout)
+    {
+        lk.unlock();
+    }
+    else
+    {
+        lk.unlock();
+    }
+
+    mmutexframe.lock();
+    if(mvectorframe.size()>0)
+    {
+        xframe = mvectorframe[0];
+        mvectorframe.erase(mvectorframe.begin());
+        nrtn = 1;
+    }
+    else
+    {
+        nrtn = 0;
+    }
+    mmutexframe.unlock();
+    return nrtn;
+
+
+}

+ 51 - 0
src/tool/RemoteCtrl_h264/rtspclientdown.h

@@ -0,0 +1,51 @@
+#ifndef RTSPCLIENTDOWN_H
+#define RTSPCLIENTDOWN_H
+
+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"
+}
+
+#include <mutex>
+#include <condition_variable>
+#include <thread>
+#include <vector>
+
+namespace iv {
+struct h264rawframedata
+{
+    std::shared_ptr<char> mpstr_ptr;
+    int mdatasize;
+};
+}
+
+class rtspclientdown
+{
+public:
+    rtspclientdown(std::string strrtspserver);
+    ~rtspclientdown();
+
+private:
+    std::thread * mpthread;
+    bool mbthreadrun = true;
+
+    std::vector<iv::h264rawframedata> mvectorframe;
+    std::mutex mmutexframe;
+    std::mutex mmutexcv;
+    std::condition_variable mcv;
+
+private:
+    void threadrtspdown(std::string strrtspserver);
+
+public:
+    int Getrtspframe(iv::h264rawframedata & xframe,int nwaitms);
+};
+
+#endif // RTSPCLIENTDOWN_H