[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