I'm processing a bunch of frames from an RTSP stream using ffmpeg. I end up doing a lot of processing on these frames, which means that I'm not always pulling in real-time. If the buffer gets full, the process hangs. I'm wondering if one of the following solutions is feasible/fixes the problem, and if so, how I would implement it using the ffmpeg libraries:
1) Is there a way to clear the buffer if I ever reach a point where it's hanging? (I can determine when it's hung, I just don't know what to do about it).
2) Is there a way to make the buffer overwrite the old data, and just always read the most recent data? It doesn't matter to me if I lose frames.
3) I've already discovered that I can make the buffer arbtrarily large with: av_dict_set(&avd, "buffer_size", "655360", 0);
. This could be a solution, but I don't know how large/small it needs to be, because I don't know how long the stream will post video for?
4) Is this just a bug that I need to bring up with the ffmpeg people?
5) Something else I haven't considered?
while(av_read_frame(context, &(packet)) >= 0 && fcount < fps*SECONDS) {
clock_t start, end;
int ret = avcodec_send_packet(codec_context, packet);
if(!(packet->stream_index == video_stream_index)) {
continue;
}
if (ret == AVERROR(EAGAIN) || ret == AVERROR(EINVAL)) {
continue;
} else if (ret < 0) {
cerr << "Error while decoding frame " << fcount << endl;
exit(1);
}
ret = avcodec_receive_frame(codec_context, frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR(EINVAL)) {
continue;
} else if (ret < 0) {
cerr << "Error while decoding frame " << fcount << endl;
exit(1);
}
sws_scale(img_convert_ctx, frame->data, frame->linesize, 0,
codec_context->height, picture_rgb->data, picture_rgb->linesize);
if(!frame) {
cerr << "Could not allocate video frame" << endl;
exit(1);
}
if(codec_context == NULL) {
cerr << "Cannot initialize the conversion context!" << endl;
exit(1);
}
// Do something with the frame here
fcount++;
av_packet_unref(&(packet));
}
I have added the code that causes the program to hang.