1. 程式人生 > >Dump h264 raw data from LIVE555 client

Dump h264 raw data from LIVE555 client


      Maybe lots persons encounter the same circumstances : after the succession of building LIVE555, and execute the testRTSPClient to connect a rtsp server: the debug log  seems be pettey good; But when we damp the h264 data to be played by VLC or ffplay, that is unplayable. Of cource, if we deliver the h264 data to a h264 decoder directly
, there would occur error always.

   I found there is no article being concise with complete code  in the website, I fill it in here.
The code base on LIVE555\testProgs\testRTSPClient.cpp.

modify the constructor and destructor of DummySink as below, it is about line 479:


unsigned char *pH264 = NULL;

DummySink
::DummySink(UsageEnvironment& env, MediaSubsession& subsession, char const* streamId) : MediaSink(env), fSubsession(subsession) { fStreamId = strDup(streamId); fReceiveBuffer = new u_int8_t[DUMMY_SINK_RECEIVE_BUFFER_SIZE]; pH264 = (unsigned char*)malloc(256*1024); } DummySink::~DummySink()
{ delete[] fReceiveBuffer; delete[] fStreamId; if(NULL != pH264) free(pH264); }



And modify afterGettingFrame (the one with debug log ) as


void DummySink::afterGettingFrame(unsigned frameSize, unsigned numTruncatedBytes,
      struct timeval presentationTime, unsigned /*durationInMicroseconds*/) {
#if(0)
  // We've just received a frame of data.  (Optionally) print out information about it:
#ifdef DEBUG_PRINT_EACH_RECEIVED_FRAME
  if (fStreamId != NULL) envir() << "Stream \"" << fStreamId << "\"; ";
  envir() << fSubsession.mediumName() << "/" << fSubsession.codecName() << ":\tReceived " << frameSize << " bytes";
  if (numTruncatedBytes > 0) envir() << " (with " << numTruncatedBytes << " bytes truncated)";
  char uSecsStr[6+1]; // used to output the 'microseconds' part of the presentation time
  sprintf(uSecsStr, "%06u", (unsigned)presentationTime.tv_usec);
  envir() << ".\tPresentation time: " << (int)presentationTime.tv_sec << "." << uSecsStr;
  if (fSubsession.rtpSource() != NULL && !fSubsession.rtpSource()->hasBeenSynchronizedUsingRTCP()) {
    envir() << "!"; // mark the debugging output to indicate that this presentation time is not RTCP-synchronized
  }
#ifdef DEBUG_PRINT_NPT
  envir() << "\tNPT: " << fSubsession.getNormalPlayTime(presentationTime);
#endif
  envir() << "\n";
#endif
#else
  printf("__FUNCTION__  = %s\n", __FUNCTION__ );
 if(0 == strncmp(fSubsession.codecName(), "H264", 16))
 { 
  unsigned char nalu_header[4] = { 0, 0, 0, 1 };   
  unsigned char extraData[256]; 
  unsigned int num = 0;    
  
  SPropRecord *pSPropRecord;
  pSPropRecord = parseSPropParameterSets(fSubsession.fmtp_spropparametersets(), num);  
  
  unsigned int extraLen;
  extraLen = 0;

  //p_record[0] is sps 
  //p+record[1] is pps
  for(unsigned int i = 0; i < num; i++){ 
   memcpy(&extraData[extraLen], &nalu_header[0], 4);
   extraLen += 4;
   memcpy(&extraData[extraLen], pSPropRecord[i].sPropBytes, pSPropRecord[i].sPropLength);
   extraLen += pSPropRecord[i].sPropLength;
  }/*for i*/

  memcpy(&extraData[extraLen], &nalu_header[0], 4);
  extraLen += 4;

  delete[] pSPropRecord ;  

  memcpy(pH264, &extraData[0], extraLen);
  memcpy(pH264 + extraLen, fReceiveBuffer, frameSize); 
  
  int totalSize;
  totalSize = extraLen + frameSize;

  static FILE *fp = fopen("saved.h264", "wb");

  fwrite(pH264, 1,  totalSize, fp);
  fflush(fp);
  printf("\tsaved %d bytes\n", totalSize);
 }/*if 0 == strncmp(fSubsession.codecName(), "H264", 16)*/
#endif  
  // Then continue, to request the next frame of data:
  continuePlaying();
}



That is, LIVE555 server  omits the SPS(Sequence Parameter Set) and PPS(Picture Parameter Set) parser information of each h264 slice.

Here  I compliment SPS and PPS  flag, which be "0x00 0x00 0x00 0x01".
You could refer to here for more detail about SPS and PPS.

相關推薦

Dump h264 raw data from LIVE555 client

      Maybe lots persons encounter the same circumstances : after the succession of building LIVE555, and execute the testRTSPClient to

get data from splunk

network hot isp .com etl exe ltsr rom count link: http://dev.splunk.com/view/python-sdk/SP-CAAAER5 download SDK & setup with python

[Nuxt] Load Data from APIs with Nuxt and Vuex

his pro -- http template map https etc not run In a server-rendered application, if you attempt to load data before the page renders and

[Nuxt] Use Vuex Actions to Delete Data from APIs in Nuxt and Vue.js

export begin async delet tin remove todo ras alt You‘ll begin to notice as you build out your actions in Vuex, many of them will look qui

[Angular & Web] Retrieve user data from Session

status rep tor func sid pla erb export key Once user sign up, we store the user data inside cookie in the broswer and also keep a memory

python3 upload data from CSV into Oracle

+= log values encoding utf-8 ade count lin win 1. 使Python可以操作Oracle數據庫,首先需要安裝cx_Oracle包。2. 創建一個簡單的python文件,測試安裝是否成功。 1 #!/usr/bin/env p

docker報Error response from daemon: client is newer than server (client API version: 1.24, server API version: 1.19)

amd64 client export mit als 大堆 server rim rime docker version Client: Version: 17.05.0-ce API version: 1.24 (downgraded from 1.29)

3D Computer Grapihcs Using OpenGL - 07 Passing Data from Vertex to Fragment Shader

vertex 一致性 表示 變量 width src log 兩個 image 上節的最後我們實現了兩個綠色的三角形,而綠色是直接在Fragment Shader中指定的。 這節我們將為這兩個三角形進行更加自由的著色——五個頂點各自使用不同的顏色。 要實現這個目的,我們分兩

kitti raw data development kit的使用

cnblogs tps body tail www png data .com tails run_demoVelodyne.m使用:http://blog.csdn.net/qq_33801763/article/details/78959205             

[MST] Loading Data from the Server using lifecycle hook

del asi con all load() body clas call code Let‘s stop hardcoding our initial state and fetch it from the server instead. In this lesson

Loading Data From Oracle To Hive By ODI 12c

ODI Oracle Hive 本文描述如何通過ODI將Oracle表數據同步到Hive。1、準備工作在hadoop集群的各個節點分別安裝Oracle Big Data Connectors,具體的組件如下圖所示:這裏只需安裝Oracle Loader For Hadoop(oraloader)以

Last_IO_Error: Got fatal error 1236 from master when reading data from binary log

在做最後一個MySQL NBU備份的時候,發現從庫有問題,好奇的是怎麼主從狀態異常沒有告警呢?先不管這麼多了,處理了這個問題再完善告警內容。 一、錯誤資訊 從庫show slave status \G看到的錯誤資訊如下: Slave_IO_Running: NoSlave_SQL_Running: Ye

kafka連zk報錯:Unable to read additional data from server sessionid 0x0...

問題描述: 主機資訊: IP hostname 10.0.0.10 host10 10.0.0.12 host12 10.0.0.13 h

mysql主從同步報錯 Got fatal error 1236 from master when reading data from binary log

突然發現從庫不同步主庫了 ,不知道是什麼原因   來不及分析  只能先恢復 報錯;Got fatal error 1236 from master when reading data from binary log 剛開始怎麼的執行set global sql_slave

USA gov data from Bitly

資料處理中使用函式解析: json.load()與json.loads()的區別 json.loads() #將json string解析為python dictionary json.load() #將json object解析為python d

Sound — An API for playing sound data from applications.

https://docs.oracle.com/javase/tutorial/sound/index.html   The Java Sound API is a low-level API for effecting and controlling the input and

A potentially dangerous Request.Form value was detected from the client

問題描述: ASP.NET has detected data in the request that is potentially dangerous because it might include

Origin and Destination air Traffic Data from DB1B DATABASE

The origin and destination (OD) data are necessary for any analysis of passenger air traffic flows. These data should capture the flow pat

Load data from Flat Files into the SAP Hana Database

Part 1 In the File Menu ,choose import. Expand the SAP HANA Content directory. Select Data from local File and choose Next . The su

從PCD檔案中讀取點雲資料(Reading Point Cloud data from PCD files)

在本教程中,我們將學習如何從PCD檔案中讀取點雲資料。 #程式碼 首先,在你最喜歡的編輯器中建立一個名為pcd_read.cpp的檔案,並在其中放置下面的程式碼: #include <iostream> #include <pcl/io/pcd