在VS2005下使用Jrtplib傳送H263視頻(using OpenCV2.2)

 

在VS2005下使用Jrtplib傳送H263視頻(using OpenCV2.2)

分類: 流媒體傳輸 opencv 807人閱讀 評論(9) 收藏 舉報

         終於搗鼓出點東西了!高興啊~~~哈哈哈哈,首先感謝網絡上的資源的幫助。

         1、RFC3550,3551,2190--ENU,http://www.faqs.org/rfcs/rfc3551.html

         2、CodeProject上的VideoNet:http://www.codeproject.com/KB/IP/videonet.aspx

         3、RFC3550--CHS,http://www.rosoo.net/a/201001/8356.html

         4、CSDN以及Rosoo上的關於時間戳的講解;

               CSDN: http://blog.csdn.net/ldd909/article/details/6183439

               Rosoo:http://www.rosoo.net/a/201102/10965.html

        5、關於RTP的協議分析:http://blog.csdn.net/bripengandre/article/details/2238818

        6、關於H.263介紹:http://blog.csdn.net/menuconfig/article/details/2649041

        7、百度百科的RTP/RTCP的詞條介紹:http://baike.baidu.com/view/1149098.html

下面是程序的main源文件,需要的配置是VS2005+opencv2.2+jrtplib+h.263的編解碼,所有的庫文件等在壓縮包中都有,整個工程的下載:http://download.csdn.net/source/3497956

main源碼如下:是在前面幾篇文章的基礎上修改整合而成,僅用作測試

  1. #include "header_rtph263.h"  
  2.   
  3. using namespace jrtplib;  
  4.   
  5. #ifdef SERVER  
  6. #undef SERVER  
  7. #endif  
  8.   
  9. #define SERVER      //if defined than as a sender, else as a receiver  
  10.   
  11. #ifdef SERVER  
  12. #define PORT_BASE   8000  
  13. #define DEST_PORT   2000  
  14. #else  
  15. #define PORT_BASE   2000  
  16. #define DEST_PORT   3000  
  17. #endif  
  18.   
  19. //#define CAMERA    //if defined open default camera by opencv, else read from avi files  
  20.   
  21. int ByteCount = 0;  
  22. unsigned char cdata[20000];  
  23. int cbuffer_size = 20000;  
  24. unsigned char rgbdata[400000];  
  25. int buffersize = 400000;  
  26.   
  27. //編碼回調  
  28. void OwnWriteFunction(int byte)  
  29. {  
  30.     if(ByteCount<cbuffer_size)  
  31.     {  
  32.         cdata[ByteCount]=(unsigned char)byte;  
  33.         ++ByteCount;  
  34.     }  
  35. }  
  36.   
  37. void checkerror(int rtperr)  
  38. {  
  39.     if (rtperr < 0)  
  40.     {  
  41.         std::cout << "ERROR: " << RTPGetErrorString(rtperr) << std::endl;  
  42.         exit(-1);  
  43.     }  
  44. }  
  45.   
  46. int main(int argc, char **argv)  
  47. {  
  48.     //opencv var  
  49.     Mat frame;  
  50.     Mat temp[3];  
  51.     VideoCapture capture;  
  52.     int frameCount = 0;  
  53.   
  54.     //h263 ----------encoder/decoder init  
  55.     uchar *readData = NULL;  
  56.     uchar *imgBuffer = NULL;  
  57.   
  58.     unsigned int yuv[WIDTH*HEIGHT*3/2];  
  59.     CParam h263Param;  
  60.     Bits bits;  
  61.     InitLookupTable();  
  62.     h263Param.format = PARAM_FORM;  
  63.     InitH263Encoder(&h263Param);  
  64.     WriteByteFunction = OwnWriteFunction;  
  65.     InitH263Decoder();  
  66.   
  67.     //rtp---initialze and creation  
  68.     WSADATA dat;  
  69.     WSAStartup(MAKEWORD(2,2), &dat);  
  70.       
  71.     const size_t MaxPackSize = 20000;  
  72.     RTPSession session;  
  73.     RTPSessionParams sessionparams;  
  74.     sessionparams.SetOwnTimestampUnit(1.0/90000.0); //for video ---see RFC2190  
  75.   
  76.     RTPUDPv4TransmissionParams transparams;  
  77.     transparams.SetPortbase(PORT_BASE);  
  78.   
  79.     int status = session.Create(sessionparams,&transparams);  
  80.     checkerror(status);  
  81.   
  82.     uint8_t localip[]={127, 0, 0, 1};  
  83.     RTPIPv4Address addr(localip, DEST_PORT);  
  84.     status = session.AddDestination(addr);  
  85.     checkerror(status);  
  86.   
  87.     session.SetDefaultPayloadType(34);  //PT for H.263----see RFC2190  
  88.     session.SetDefaultMark(true);       //true or false ?? both ok for my test    
  89.     session.SetDefaultTimestampIncrement(3600); // =90000/25  
  90.     session.SetMaximumPacketSize(MaxPackSize);  
  91.       
  92. #ifdef SERVER  
  93.   
  94. #ifdef CAMERA  
  95.     capture.open(0);  
  96. #else  
  97.     capture.open("d:\\video\\petsc1.avi");  
  98. #endif  
  99.       
  100.     if (!capture.isOpened())  
  101.     {  
  102.         cout<<"open video/camera failed!"<<endl;  
  103.         return -1;  
  104.     }  
  105.     capture>>frame;  
  106.     if (frame.empty())  
  107.     {  
  108.         cout<<"grab frame failed! exit...."<<endl;  
  109.         return -1;  
  110.     }  
  111.     namedWindow("raw", CV_WINDOW_AUTOSIZE);  
  112.   
  113.     while (waitKey(40) != 27)   //25 fps  
  114.     {  
  115.         capture>>frame;  
  116.         if (frame.empty())  
  117.         {  
  118.             cout<<"grab frame failed! exit...."<<endl;  
  119.             return -1;  
  120.         }  
  121.         ++frameCount;  
  122.         resize(frame, temp[0], cv::Size(WIDTH, HEIGHT));    //resize to CIF  
  123.         imshow("raw", temp[0]);  
  124.   
  125. ////---------------------------compress image frames-------------------------//   
  126.         ConvertRGB2YUV(WIDTH, HEIGHT, temp[0].data, yuv);  
  127.         ByteCount = 0;  
  128.         h263Param.format = PARAM_FORM;  
  129.         h263Param.inter = CPARAM_INTRA;  
  130.         h263Param.Q_intra = 8;  
  131.         h263Param.data = yuv;  
  132.         CompressFrame(&h263Param, &bits);  
  133.         cout<<"compressed byte count is: "<<ByteCount<<endl;  
  134. ///-------------------------------------------------------------------------//  
  135.   
  136.         status = session.SendPacket(cdata, ByteCount);  
  137.         checkerror(status);  
  138.   
  139.     }  
  140.   
  141. #else  
  142.     namedWindow("got", CV_WINDOW_AUTOSIZE);  
  143.     int packetNum = 0;  
  144.   
  145.     while(waitKey(40) != 27)    //25fps  
  146.     {  
  147.         session.BeginDataAccess();  
  148.         if (session.GotoFirstSourceWithData())  
  149.         {  
  150.             do   
  151.             {  
  152.                 RTPPacket *packet;  
  153.                 while( (packet = session.GetNextPacket()) != NULL)  
  154.                 {  
  155.                     cout<<"packet count: "<<++packetNum<<endl;  
  156.                     size_t dataLen = packet->GetPayloadLength();  
  157.                     cout<<"payload length: "<<dataLen<<endl;  
  158.                     readData = packet->GetPayloadData();  
  159.                     imgBuffer = new uchar[dataLen];  
  160.                     memcpy(imgBuffer, readData, dataLen);  
  161.   
  162. ///----------------------------decompress--------------------------//  
  163.                     DecompressFrame(imgBuffer, dataLen, rgbdata, buffersize);  
  164. ///----------------------------------------------------------------//  
  165.   
  166.                     Mat GotImg(HEIGHT, WIDTH, CV_8UC3, rgbdata);  
  167.                     if(GotImg.empty())  
  168.                     {  
  169.                         cout<<"got image has no data, exiting...."<<endl;  
  170.                         return -1;  
  171.                     }  
  172.                     imshow("got", GotImg);  
  173.   
  174.                     //release buffers and packet  
  175.                     delete []imgBuffer;  
  176.                     imgBuffer = NULL;  
  177.                     session.DeletePacket(packet);  
  178.                 }  
  179.                   
  180.             } while (session.GotoNextSourceWithData());  
  181.         }  
  182.         session.EndDataAccess();  
  183.   
  184.     }  
  185. #endif  
  186. ///////////////////////////////////////////////////////////////////  
  187.       
  188.     //release resources  
  189.     cvDestroyAllWindows();  
  190.     ExitH263Decoder();  
  191.     ExitH263Encoder(&h263Param);  
  192.   
  193.     RTPTime delay(5.0);  
  194.     session.BYEDestroy(delay, "trans over", 10);  
  195.     WSACleanup();  
  196.   
  197.     return 0;  
  198. }  


          經測試在本機收發正常,在實驗室的兩臺機子上也成功收發。

      需要注意的是,整個程序由宏#define SERVER來控制是作爲接受還是發送,定義了SERVER則程序作爲發送方,否則作爲接受方。如果是發送avi文件的話,可能需要轉換一下格式,有些avi直接使用opencv打不開。

發佈了4 篇原創文章 · 獲贊 4 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章