linux系統RTMPdump(libRTMP) 通過RTMP 發布H264資料__linux

來源:互聯網
上載者:User

    關於RTMPdump的使用介紹,很多的都是在Windows平台的應用,雷神有做一個系列的分析,但是雷神的也主要是以Windows平台為主。本文主要的工作是將雷神《最簡單的基於librtmp的樣本:發布H.264(H.264通過RTMP發布)》中的工程移植到linux系統,同時修複一些問題並且添加一部分說明。

在使用該工程之前,應該有搭建好一個RTMP伺服器,同時對H264資料格式有一個較好的瞭解。可以參考:

    nginx 搭建rtmp流媒體伺服器

    H264文法結構及編碼原理

整個軟體的流程圖如下:


    仔細分析RTMP264_Send 函數

/** * 將記憶體中的一段H.264編碼的視頻資料利用RTMP協議發送到伺服器 * * @param read_buffer 回呼函數,當資料不足的時候,系統會自動調用該函數擷取輸入資料。 *2個參數功能: *uint8_t *buf:外部資料送至該地址 *int buf_size:外部資料大小 *傳回值:成功讀取的記憶體大小 * @成功則返回1 , 失敗則返回0 */ int RTMP264_Send(int (*read_buffer)(unsigned char *buf, int buf_size))  {    int ret;uint32_t now,last_update;  memset(&metaData,0,sizeof(RTMPMetadata));memset(m_pFileBuf,0,BUFFER_SIZE);if((ret=read_buffer(m_pFileBuf,m_nFileBufSize))<0){return FALSE;}NaluUnit naluUnit;  // 讀取SPS幀   ReadFirstNaluFromBuf(naluUnit,read_buffer);  metaData.nSpsLen = naluUnit.size;  metaData.Sps=NULL;metaData.Sps=(unsigned char*)malloc(naluUnit.size);memcpy(metaData.Sps,naluUnit.data,naluUnit.size);// 讀取PPS幀   ReadOneNaluFromBuf(naluUnit,read_buffer);  metaData.nPpsLen = naluUnit.size; metaData.Pps=NULL;metaData.Pps=(unsigned char*)malloc(naluUnit.size);memcpy(metaData.Pps,naluUnit.data,naluUnit.size);// 解碼SPS,擷取視頻映像寬、高資訊   int width = 0,height = 0, fps=0;  h264_decode_sps(metaData.Sps,metaData.nSpsLen,width,height,fps);  //metaData.nWidth = width;  //metaData.nHeight = height;  if(fps)metaData.nFrameRate = fps; elsemetaData.nFrameRate = 25;//發送PPS,SPS//ret=SendVideoSpsPps(metaData.Pps,metaData.nPpsLen,metaData.Sps,metaData.nSpsLen);//if(ret!=1)//return FALSE;unsigned int tick = 0;  unsigned int tick_gap = 1000/metaData.nFrameRate; //printf(" nFrameRate = %d \n ",metaData.nFrameRate);ReadOneNaluFromBuf(naluUnit,read_buffer);int bKeyframe  = (naluUnit.type == 0x05) ? TRUE : FALSE;while(SendH264Packet(naluUnit.data,naluUnit.size,bKeyframe,tick))  {    got_sps_pps://if(naluUnit.size==8581)printf("NALU size:%8d\n",naluUnit.size);last_update=RTMP_GetTime();if(!ReadOneNaluFromBuf(naluUnit,read_buffer))goto end;if(naluUnit.type == 0x07 || naluUnit.type == 0x08)goto got_sps_pps;bKeyframe  = (naluUnit.type == 0x05) ? TRUE : FALSE;tick +=tick_gap;now=RTMP_GetTime();//msleep(tick_gap-now+last_update);//printf("now = %d, last_update = %d, now - last_update = %d \n",now,last_update,now - last_update);  msleep(tick_gap);}  end:free(metaData.Sps);free(metaData.Pps);return TRUE;  }  
    在開始迴圈擷取資料之前,先讀取h264檔案的SPS和PPS。SPS是序列參數集,PPS是映像參數集。在SPS序列參數集中可以解析出映像的寬,高和幀率等資訊。而在h264檔案中,最開始的兩幀資料就是SPS和PPS,這個h264檔案只存在一個SPS幀和一個PPS幀。在做RTMP 傳輸的時候,它需要在每次發送H264的I幀之前,發送SPS序列參數集幀和PPS映像參數集幀。在我們這裡的處理方式是,先提取出SPS和PPS幀,然後儲存起來,然後每次發送I幀之前都發送一次SPS和PPS幀。SPS幀和PPS幀如下:


    工程檔案如下:

lcb@ubuntu:~/test/RTMP/rtmp_push_h264$ tree.├── cuc_ieschool.h264├── include│   ├── librtmp│   │   ├── amf.h│   │   ├── bytes.h│   │   ├── dhgroups.h│   │   ├── dh.h│   │   ├── handshake.h│   │   ├── http.h│   │   ├── log.h│   │   ├── rtmp.h│   │   └── rtmp_sys.h│   ├── librtmp_send264.h│   └── sps_decode.h├── lib│   ├── librtmp.a│   ├── librtmp.so│   └── librtmp.so.0├── librtmp_send264.cpp├── Makefile├── simplest_librtmp_send264.cpp└── src

    完整的工程下載地址: RTMPdump(libRTMP) 通過RTMP 發布H264資料

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.