liveMedia ライブラリを使用して、RTSP 経由でビデオとオーディオをストリーミングするマルチメディア アプリケーションを開発しています。カメラから生のビデオ フレームを読み取り、libx264 を使用してエンコードし、tbb::concurrent_queue に保存して、RTSP サーバーを実行します。RTSP モジュールを作成する例として DynamicRTSPServer.cpp と live555MediaServer.cpp を使用していますが、問題があります - 1 つのスレッド ( BasicTaskScheduler::doEventLoop を実行する) があまりにも多くのプロセッサ時間を使用します - 1 つのプロセッサ コアの 80-90% 以上 (私が持っている)インテル デュアルコア T3100)。そして、私のビデオストリームでは長い遅延があり、VLC はエラーでビデオストリームを再生できません (オーディオストリームは正常に再生されます): 主な警告: 画像を表示するには遅すぎます (3780 ミリ秒がありません)遅い動画 ->
サーバーのログ ファイルを読んだところ、空のキューから新しいデータを読み取ろうとして多くの失敗したことがわかりました。これは私のログ ファイルの一部です (デバッグ メッセージの時間を見てください - FramedSource::doGetNextFrame の別の呼び出しです)
[10:49:7:621]: videoframe readed. size: 0
[10:49:7:622]: videoframe readed. size: 0
[10:49:7:622]: videoframe readed. size: 0
[10:49:7:622]: videoframe readed. size: 0
[10:49:7:622]: videoframe readed. size: 0
[10:49:7:622]: videoframe readed. size: 0
[10:49:7:623]: videoframe readed. size: 0
[10:49:7:623]: videoframe readed. size: 0
[10:49:7:623]: videoframe readed. size: 0
[10:49:7:623]: videoframe readed. size: 0
[10:49:7:623]: videoframe readed. size: 0
[10:49:7:624]: videoframe readed. size: 0
ビデオ ストリームのフレームレートが低く (カメラは 8 fps 以下しか使用できません)、doGetNextFrame が呼び出されたときに、バッファのキューにエンコードされたフレームがまだありません。私はこの試みで次のコールスタックを持っています:
ConcurrentQueueBuffer::doGetNextFrame()
FramedSource::getNextFrame(unsigned char* to, unsigned maxSize,
afterGettingFunc* afterGettingFunc,
void* afterGettingClientData,
onCloseFunc* onCloseFunc,
void* onCloseClientData)
StreamParser::ensureValidBytes1(unsigned numBytesNeeded)
StreamParser::ensureValidBytes(unsigned numBytesNeeded)
StreamParser::test4Bytes()
H264VideoStreamParser::parse()
MPEGVideoStreamFramer::continueReadProcessing()
MPEGVideoStreamFramer::continueReadProcessing(void* clientData,
unsigned char* /*ptr*/, unsigned /*size*/,
struct timeval /*presentationTime*/)
StreamParser::afterGettingBytes1(unsigned numBytesRead, struct timeval presentationTime)
StreamParser::afterGettingBytes(void* clientData,
unsigned numBytesRead,
unsigned /*numTruncatedBytes*/,
struct timeval presentationTime,
unsigned /*durationInMicroseconds*/)
FramedSource::afterGetting(FramedSource* source)
AlarmHandler::handleTimeout()
...
エンコーダーが新しいフレームを提供している間、バッファーとロックスレッドのロジックを変更しようとしましたが、この場合、オーディオストリームにも非常に長い遅延があります。バッファにデータを保存するためにサーバーの起動時に遅延をほとんど設定しませんでしたが、ライブメディアはバッファからデータをより速く読み取り、エンコーダーでエンコードします:(
この問題の原因は何ですか? また、liveMedia は FramedSource からの読み取り試行の頻度をどのように検出するのでしょうか?
私の H264BufferMediaSubsession は、liveMedia の H264VideoFileServerMediaSubsession を継承し、createNewStreamSource() 仮想メソッドのみをオーバーライドします。ここで、バッファからデータを読み取る FramedSource を作成します。