Я использую FFMPEG для декодирования потока RTSP H264 (или H265).
В моей системе 2 программы: Сервер и Клиент
Server: Read frames from RTSP stream --> Forward frames to Client
Client: Receive frames from Server --> Decode --> Render
Я реализовал, и все работало нормально,но есть случай, чтобы моя система работала плохо.То есть, когда интернет с сервера-клиента работает медленно, кадры не могут передавать клиенту в режиме реального времени.
В настоящее время я имею дело с этой проблемой, пропуская некоторые кадры (не отправляемые клиенту), когда в очереди достигнут предел количества.Ниже приведен мой сводный код
//At Server Software (include 2 threads A and B)
//Thread A: Read AVPacket and forward to Client
while(true)
{
AVPacket packet;
av_init_packet(&packet);
packet.size = 0;
packet.data = NULL;
int ret = AVERROR(EAGAIN);
while (AVERROR(EAGAIN) == ret)
ret = av_read_frame(pFormatCtx, &packet);
if(packet.size > 0)
{
if(mySendQueue.count < 120) //limit 120 packet in queue
mySendQueue.Enqueue(packet); ////Thread B will read from this queue, to send packets to Client via TCP socket
else
;//SkipThisFrame ***: No send
}
}
//Thread B: Send To Client via TCP Socket
While(true)
{
AVPacket packet;
if(mySendQueue.Dequeue(packet))
{
SendPacketToClient(packet);
}
}
//At Server Software : Receive AVPacket from Server --> Decode --> Render
While(true)
{
AVPacket packet;
AVFrame frame;
ReadPacketFromServer(packet);
if (av_decode_asyn(pCodecCtx, &frame, &frameFinished, &packet) == RS_OK)
{
if (frameFinished)
{
RenderFrame(frame);
}
}
}
UINT32 __clrcall av_decode_asyn(AVCodecContext *pCodecCtx, AVFrame *frame, int *frameFinished, AVPacket *packet)
{
int ret = -1;
*frameFinished = 0;
if (packet)
{
ret = avcodec_send_packet(pCodecCtx, packet);
// In particular, we don't expect AVERROR(EAGAIN), because we read all
// decoded frames with avcodec_receive_frame() until done.
if (ret < 0 && ret != AVERROR_EOF)
return RS_NOT_OK;
}
ret = avcodec_receive_frame(pCodecCtx, frame);
if (ret < 0 && ret != AVERROR(EAGAIN))
{
return RS_NOT_OK;
}
if (ret >= 0)
*frameFinished = 1;
return RS_OK;
}
Мой вопрос заключается в фокусировке в строке кода SkipThisFrame ***
, этот алгоритм непрерывно пропускает кадр, поэтому возможно, что в декодере на клиенте произойдет непредвиденная ошибка или сбой?
А когда пропустить такой кадр, сделать Client Render кадров не нормально?
А кто-нибудь позвонит и покажет мне правильный алгоритм пропуска кадров в моем случае?
Спасибо большое!