I'm trying to create a small app which will save frames from inoming h264 stream.
I took a testRTSP programm as example and made several changes in DummySink::afterGettingFrame function to decode frames with the help of ffmpeg library.
As I understand from frameSize, my first two frames are SPS units, so I concatenate them with my third frame and then send new big frame to ffmpeg decoder. But that doesnt work. ffmpeg tells me that my first frame is too big for SPS and then it tells me that there is no frame... I dont know what I need to change here.
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();