1. 程式人生 > >【視訊開發】【Live555】live555實現h264碼流RTSP傳輸

【視訊開發】【Live555】live555實現h264碼流RTSP傳輸

1.概述

liveMedia 庫中有一系列類,基類是Medium,這些類針對不同的流媒體型別和編碼。 其中的StreamFrame類檔案(如MPEG4VideoStreamFramer)為流傳輸關鍵。

2 重要概念:

StreamFrame類:該類繼承FramedSource基類,實現資料流的控制和傳輸。

StreamFrame(H264VideoStreamFramer) -->FramedFilter--> FramedSource----> MediaSource

   FramedSource 派繼承MediaSource父類,一幀碼流的實現。

  注意:

unsigned char* fTo;為指向傳送的碼流的指標,採集到視訊資料後填充到該指標中即可實現碼流的傳輸。

主要步驟:1.定義自己的StreamFramer類,實現getNextFrame重寫。

 getNextFrame函式來自live\liveMedia\FramedSource檔案,程式碼見下

  1. void FramedSource::getNextFrame(unsignedchar* to, unsigned maxSize,  
  2.                 afterGettingFunc*afterGettingFunc,  
  3.                 void
    *afterGettingClientData,  
  4.                 onCloseFunc*onCloseFunc,  
  5.                 void*onCloseClientData) {  
  6.   // Make sure we're not already beingread:
  7.   if (fIsCurrentlyAwaitingData){  
  8.     envir() <<"FramedSource[" <<this <<"]::getNextFrame(): attempting to read more than once at the sametime!\n"
    ;  
  9.     envir().internalError();  
  10.   }  
  11.   fTo = to;  
  12.   fMaxSize = maxSize;  
  13.   fNumTruncatedBytes = 0; // by default;could be changed by doGetNextFrame()
  14.   fDurationInMicroseconds = 0; // bydefault; could be changed by doGetNextFrame()
  15.   fAfterGettingFunc = afterGettingFunc;  
  16.   fAfterGettingClientData =afterGettingClientData;  
  17.   fOnCloseFunc = onCloseFunc;  
  18.   fOnCloseClientData = onCloseClientData;  
  19.   fIsCurrentlyAwaitingData = True;  
  20.   doGetNextFrame();  
  21. }  


其中最後的doGetNextFrame(); 是一個虛擬函式,具體各種編碼模式,我們可以根據自己的碼流型別定義一個派生自FramedSource的類(本工程H264FramedLiveSource類), 重新再定義doGetNextFrame如何獲得下一幀的碼流,在自己重定義的doGetNextFrame() 中將fTo指向要傳送的快取即可。這樣我們就實現了流的傳輸而非檔案傳輸。

本工程中doGetNextFrame()程式碼如下:

  1. voidH264FramedLiveSource::doGetNextFrame()  
  2. {  
  3.     printf("doGetNextFrame\n");  
  4.     if( filesize(fp) >  fMaxSize)  
  5.       fFrameSize = fread(fTo,1,fMaxSize,fp);  
  6.     else
  7.     {  
  8.         fFrameSize =fread(fTo,1,filesize(fp),fp);  
  9.         fseek(fp, 0, SEEK_SET);  
  10.     }  
  11.     //fFrameSize = fMaxSize;
  12.     nextTask() =envir().taskScheduler().scheduleDelayedTask( 0,  
  13.         (TaskFunc*)FramedSource::afterGetting, this);  
  14.     return;  
  15. }  


2.實現fTO與會話連線,自定義ServerMediaSubsession

定義ServerMediaSubsession類H264LiveVideoServerMediaSubssion,該類由ServerMediaSubsession 派生而來。該類中有私有函式virtual FramedSource* createNewStreamSource,在該函式中進行重新定義即可實現。

  1. FramedSource*H264LiveVideoServerMediaSubssion::createNewStreamSource( unsignedclientSessionId, unsigned& estBitrate )  
  2. {  
  3.     /* Remain to do : assign estBitrate */
  4.     estBitrate = 1000; // kbps, estimate
  5.     // Create the video source:
  6.     H264FramedLiveSource* liveSource =H264FramedLiveSource::createNew(envir(), fFileName);  
  7.     if (liveSource == NULL)  
  8.     {  
  9.         return NULL;  
  10.     }  
  11.     // Create a framer for the Video ElementaryStream:
  12.     returnH264VideoStreamFramer::createNew(envir(), liveSource);  
  13. }  


主要最後返回的H264VideoStreamFramer繼承自FramedSource,定義了從檔案獲取source的方法,從而將ServerMedia 與source聯絡起來。

程式碼為vs2008工程,採用VLC測試,測試結果如下圖所示

 

 程式碼見http://download.csdn.NET/detail/xiahua882/9619900

注:工程中CaremaLive為該部落格程式碼,MediaServer為live555標準伺服器工程也可以執行。程式碼工程圖見下