[Libav-user] How can I over come error "No decoder surfaces left"
Steve Ha
steveha at u2sr.com
Tue Feb 4 10:40:11 EET 2020
Hello!
I have trouble in using ffmpeg to decode h264 stream sent from IP cameras
through a busy network.
In most cases, broken data causes the avcodec_send_packet() function
returns error:
"Invalid data found when processing input", and the subsequent error
called back via ffmpeg log is "[h264 @ AVCodecContext] level= 16, no frame!"
But sometimes, in an unpredictable way, broken data causes many errors like
below:
...
[::DecodeFrame] avcodec_send_packet: Invalid data found when processing
input
11:51:12.573 [warning] [h264 @ AVCodecContext] level= 16, No decoder
surfaces left
11:51:12.603 [warning] Decoder 0: pts 1580784584791558 diff 66,400, P,
codedNum: 5394 prev: 5391 diff: 2.
[::DecodeFrame] avcodec_send_packet: Invalid data found when processing
input
11:51:12.936 [warning] [h264 @ AVCodecContext] level= 16, No decoder
surfaces left
11:51:12.971 [warning] Decoder 0: pts 1580784585158158 diff 66,600, P,
codedNum: 5406 prev: 5403 diff: 2.
[::DecodeFrame] avcodec_send_packet: Invalid data found when processing
input
11:51:13.304 [warning] [h264 @ AVCodecContext] level= 16, No decoder
surfaces left
11:51:13.337 [warning] Decoder 0: pts 1580784585524858 diff 66,700, P,
codedNum: 5418 prev: 5415 diff: 2.
...
I searched in ffmpeg's source and found "No decoder surfaces left" is
originated from
the function below:
int ff_nvdec_start_frame(AVCodecContext *avctx, AVFrame *frame)
{
...
cf->idx_ref = av_buffer_pool_get(ctx->decoder_pool);
if (!cf->idx_ref) {
av_log(avctx, AV_LOG_ERROR, "No decoder surfaces left\n");
ret = AVERROR(ENOMEM);
goto fail;
}
...
}
Version: tag n4.2.2
avcodec-58.54.100
avformat-58.29.100
avutil-56.31.100
swscale-5.5.100
This is how decoder functions are used:
bool DecodeFrame(AVPacket* pkt)
{
auto TraceFFmpegErr = [this](int ret, const char* msg) {
if (ret)
{
char szErr[256] {};
av_strerror(ret, szErr, sizeof(szErr));
log (msg, szErr);
}
};
int ret = 0;
try {
ret = avcodec_send_packet(m_pAVContxt, pkt);
}
catch (std::exception& e) {
log("avcodec_send_packet has an exception error: {}\n", e.what());
}
if (ret < 0) {
TraceFFmpegErr(ret, "avcodec_send_packet");
if (ret == AVERROR_INVALIDDATA || ret== AVERROR_UNKNOWN) {
//
}
return false;
}
while (!ret)
{
AVFrame* pFrame = m_pAVFrame;
try {
ret = avcodec_receive_frame(m_pAVContxt, pFrame);
}
catch (std::exception& e) {
log("avcodec_receive_frame has an exception error {}\n", e.what());
}
if (ret < 0)
{
if (ret == AVERROR(EAGAIN)) {
//
}
if (ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) {
TraceFFmpegErr(ret, "avcodec_receive_frame");
}
break;
}
if (AVMEDIA_TYPE_VIDEO == m_pAVContxt->codec_type) {
// handles frame.
}
else {
log("unhandled media type\n");
}
}
}
I would like to know if the calls to functions to decode stream are
incorrect and how can I over come the trouble.
Thanks.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://ffmpeg.org/pipermail/libav-user/attachments/20200204/1ed0b15a/attachment.html>
More information about the Libav-user
mailing list