私は、in2のストリームからフレームを保存する小さなアプリケーションを作成しようとしています。 私は、例としてtestRTSP programmをとり、DummySink::afterGettingFrame
関数をいくつか変更して、ffmpegライブラリの助けを借りてフレームをデコードしました。 私がframeSizeから理解しているように、最初の2つのフレームはSPSユニットなので、3番目のフレームと連結してから、新しい大きなフレームをffmpegデコーダに送ります。しかし、それは動作しません。 ffmpegは、私の最初のフレームがSPSにとって大きすぎることを教えてくれますし、フレームがないことを私に伝えています...私はここで何を変更する必要があるのか分かりません。LIVE555 ffmpeg用のnalユニットを得るためのh264フレーマークラスの使い方
void DummySink::afterGettingFrame(unsigned frameSize, unsigned numTruncatedBytes,
struct timeval presentationTime, unsigned /*durationInMicroseconds*/)
{
u_int8_t start_code[4] = { 0x00, 0x00, 0x00, 0x01 };
int stCodeLen = 4;
if (frameSize == 50)
{
//add start code
memcpy(bufferWithStartCode, start_code, stCodeLen);
shiftPtr += stCodeLen;
memcpy(bufferWithStartCode + shiftPtr, fReceiveBuffer, frameSize);
shiftPtr += frameSize;
}
else if (frameSize == 4)
{
memcpy(bufferWithStartCode + shiftPtr, fReceiveBuffer, frameSize);
shiftPtr += frameSize;
}
else
{
if (shiftPtr == 0)
{
memcpy(bufferWithStartCode, start_code, stCodeLen);
shiftPtr += stCodeLen;
}
memcpy(bufferWithStartCode + shiftPtr, fReceiveBuffer, frameSize);
avpkt.size = frameSize + shiftPtr;
avpkt.data = bufferWithStartCode;
shiftPtr = 0;
if (!avcodec_send_packet(cContext, &avpkt))
{
envir() << "error sending to decoder";
}
if (!avcodec_receive_frame(cContext, picture))
{
envir() << "error rx from decoder";
}
if (picture)
{
FILE *f;
char buffer[32]; // The filename buffer.
snprintf(buffer, sizeof(char) * 32, "file%i.txt", frame_num);
f = fopen(buffer, "w");
fprintf(f, "P5\n%d %d\n%d\n", fSubsession.videoWidth(), fSubsession.videoHeight(), 255);
for (int i = 0;i < fSubsession.videoHeight();i++)
fwrite(picture->data[0] + i * (picture->linesize[0]), 1, fSubsession.videoWidth(), f);
fclose(f);
}
}
envir() << frameSize << "\n";
frame_num++;
// Then continue, to request the next frame of data:
continuePlaying();
SPSおよびPPSのデータは、50および4バイトサイズですか?多分これは私の最初の2つの "フレーム"ですか?そして、私は「エクストラデータ」で2つの異なる変数をどのように参照できますか? – Aleksey
spsとppsのサイズは固定されていないので、削除された答えではサイズに基づいて何も仮定することはできません。実際のNALタイプ(NALユニットの最初のバイトの右端5ビット)を確認する必要があります。'extradata'については、私のメモリが正しい場合は、すでに使用している接頭辞コードで区切られた単一のバッファにそれらを渡し、それに応じて' extradata_size'を設定します。 Btw、ffmpegでストリームをデコードするには、RTSP処理にもffmpeg(avio_open)を使用してください。それで、あなたはこれを気にする必要はなく、すべては内部的に行われます。 –