live555 rtsp 傳輸問題記錄

最近用rtsp 傳視頻vlc 播放總是出現閃屏,一段時間就卡灰屏一下 ,因爲視頻幀不是直接從機器獲取,通過網絡傳輸過來,幀率不是很穩定,調試後發現幀率一直爲25幀,機器實際只有20幀左右。查找原因是因爲H264or5VideoStreamParser::parse() 中解析SPS 的時候沒有解析出num_units_in_ticktime_scale 所以只能設置默認值或者根據幀的類型計算 nal_unit_type =0x1 爲普通幀,nal_unit_type=0x7 爲SPS這樣可以實時計算出幀率。

所以在 H264or5VideoStreamParser::parse() 中添加 CALCULATE_FPS 區代碼計算幀率。

if (fHNumber == 264) {
      nal_unit_type = fFirstByteOfNALUnit&0x1F;
#ifdef DEBUG
      u_int8_t nal_ref_idc = (fFirstByteOfNALUnit&0x60)>>5;
      fprintf(stderr, "Parsed %d-byte NAL-unit (nal_ref_idc: %d, nal_unit_type: %d (\"%s\"))\n",
	      curFrameSize()-fOutputStartCodeSize, nal_ref_idc, nal_unit_type, nal_unit_type_description_h264[nal_unit_type]);
#endif
    } else { // 265
      nal_unit_type = (fFirstByteOfNALUnit&0x7E)>>1;
#ifdef DEBUG
      fprintf(stderr, "Parsed %d-byte NAL-unit (nal_unit_type: %d (\"%s\"))\n",
	      curFrameSize()-fOutputStartCodeSize, nal_unit_type, nal_unit_type_description_h265[nal_unit_type]);
#endif
    }
   // usingSource()->fFrameRate = fParsedFrameRate = 20.0;
#ifdef CALCULATE_FPS    
    if(nal_unit_type == 0x1 && m_frameSum < 256) m_frameSum++;
#endif    

//    printf("%sfParsedFrameRate =%f nalType = 0x%x m_frameSum =%d\n",__func__,fParsedFrameRate,nal_unit_type,m_frameSum);
    // Now that we have found (& copied) a NAL unit, process it if it's of special interest to us:
    if (isVPS(nal_unit_type)) { // Video parameter set
      // First, save a copy of this NAL unit, in case the downstream object wants to see it:
      usingSource()->saveCopyOfVPS(fStartOfFrame + fOutputStartCodeSize, curFrameSize() - fOutputStartCodeSize);
      if (fParsedFrameRate == 0.0) {
	// We haven't yet parsed a frame rate from the stream.
	// So parse this NAL unit to check whether frame rate information is present:
	unsigned num_units_in_tick, time_scale;
	analyze_video_parameter_set_data(num_units_in_tick, time_scale);
	if (time_scale > 0 && num_units_in_tick > 0) {
	  usingSource()->fFrameRate = fParsedFrameRate = time_scale/(DeltaTfiDivisor*num_units_in_tick);
      
 //  printf("Set frame rate to %f fps fParsedFrameRate =%f time_scale =%d Delta=f\n",usingSource()->fFrameRate,fParsedFrameRate ,time_scale,(DeltaTfiDivisor*num_units_in_tick));   
#ifdef DEBUG
	  fprintf(stderr, "Set frame rate to %f fps\n", usingSource()->fFrameRate);
#endif
	} else {
#ifdef DEBUG
	  fprintf(stderr, "\tThis \"Video Parameter Set\" NAL unit contained no frame rate information, so we use a default frame rate of %f fps\n", usingSource()->fFrameRate);
#endif
	}
      }
    } else if (isSPS(nal_unit_type)) { // Sequence parameter set
      // First, save a copy of this NAL unit, in case the downstream object wants to see it:
      usingSource()->saveCopyOfSPS(fStartOfFrame + fOutputStartCodeSize, curFrameSize() - fOutputStartCodeSize);

// xu add for analyze_seq_parameter_set_data() can't get num_units_in_tick & time_scale 

#ifdef CALCULATE_FPS 
        m_frameSum ++;
        struct timeval tmpTs;
        gettimeofday(&tmpTs, NULL);
        double curTs= (((double)tmpTs.tv_sec*1000 +(double)tmpTs.tv_usec/1000)/1000);
        double durTs = curTs - m_lastGopTs;
        if(durTs > 0 && durTs <3.0)
        {
            usingSource()->fFrameRate = fParsedFrameRate = m_frameSum/durTs;
       //    printf("Set frame rate to %f fps,durTs =%f sum=%d lastTs =%f curTs=%fs\n" ,((double)m_frameSum/durTs),durTs,(int)m_frameSum ,m_lastGopTs,curTs);
        }        
        m_lastGopTs = curTs;        
        m_frameSum = 0;
#endif      
      if (fParsedFrameRate == 0.0) {
	// We haven't yet parsed a frame rate from the stream.
	// So parse this NAL unit to check whether frame rate information is present:
	unsigned num_units_in_tick, time_scale;
	analyze_seq_parameter_set_data(num_units_in_tick, time_scale);

參考:https://blog.csdn.net/caoshangpa/article/details/53083410?utm_source=blogxgwz0

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章