<div dir="ltr"><div>Hello!</div><div><br>I have trouble in using ffmpeg to decode h264 stream sent from IP cameras through a busy network.<br><br>In most cases, broken data causes the avcodec_send_packet() function returns error:<br>     "Invalid data found when processing input", and the subsequent error <br>       called back via ffmpeg log is "[h264 @ AVCodecContext] level= 16, no frame!"<br><br>But sometimes, in an unpredictable way, broken data causes many errors like below:<br><br>...<br>[::DecodeFrame] avcodec_send_packet: Invalid data found when processing input<br>11:51:12.573 [warning] [h264 @ AVCodecContext] level= 16, No decoder surfaces left<br>11:51:12.603 [warning] Decoder 0: pts 1580784584791558 diff 66,400, P, codedNum: 5394 prev: 5391 diff: 2.<br>[::DecodeFrame] avcodec_send_packet: Invalid data found when processing input<br>11:51:12.936 [warning] [h264 @ AVCodecContext] level= 16, No decoder surfaces left<br>11:51:12.971 [warning] Decoder 0: pts 1580784585158158 diff 66,600, P, codedNum: 5406 prev: 5403 diff: 2.<br>[::DecodeFrame] avcodec_send_packet: Invalid data found when processing input<br>11:51:13.304 [warning] [h264 @ AVCodecContext] level= 16, No decoder surfaces left<br>11:51:13.337 [warning] Decoder 0: pts 1580784585524858 diff 66,700, P, codedNum: 5418 prev: 5415 diff: 2.</div><div>...<br><br>I searched in ffmpeg's source and found "No decoder surfaces left" is originated from <br>the function below:<br><br>int ff_nvdec_start_frame(AVCodecContext *avctx, AVFrame *frame)<br>{<br>    ...<br>    cf->idx_ref = av_buffer_pool_get(ctx->decoder_pool);<br>    if (!cf->idx_ref) {<br>        av_log(avctx, AV_LOG_ERROR, "No decoder surfaces left\n");<br>        ret = AVERROR(ENOMEM);<br>        goto fail;<br>    }<br>...<br>}<br><br><br>Version: tag n4.2.2<br>   avcodec-58.54.100<br>     avformat-58.29.100<br>    avutil-56.31.100<br>      swscale-5.5.100<br><div><br></div><div><p style="margin:0px;padding:0px">This is how decoder functions are used:</p><p style="margin:0px;padding:0px"><br class="gmail-Apple-interchange-newline">bool<span style="white-space:pre">        </span>DecodeFrame(AVPacket* pkt)</p><p style="margin:0px;padding:0px">{</p><p style="margin:0px;padding:0px"><span style="white-space:pre">  </span>auto TraceFFmpegErr = [this](int ret, const char* msg) {</p><p style="margin:0px;padding:0px"><span style="white-space:pre">         </span>if (ret)</p><p style="margin:0px;padding:0px"><span style="white-space:pre">         </span>{</p><p style="margin:0px;padding:0px"><span style="white-space:pre">                        </span>char szErr[256] {};</p><p style="margin:0px;padding:0px"><span style="white-space:pre">                      </span>av_strerror(ret, szErr, sizeof(szErr));</p><p style="margin:0px;padding:0px"><span style="white-space:pre">                  </span>log (msg, szErr);</p><p style="margin:0px;padding:0px"><span style="white-space:pre">                </span>}</p><p style="margin:0px;padding:0px"><span style="white-space:pre">        </span>};</p><p style="margin:0px;padding:0px"><br></p><p style="margin:0px;padding:0px"><span style="white-space:pre"> </span>int ret = 0;</p><p style="margin:0px;padding:0px"><span style="white-space:pre">     </span>try {</p><p style="margin:0px;padding:0px"><span style="white-space:pre">            </span>ret = avcodec_send_packet(m_pAVContxt, pkt);</p><p style="margin:0px;padding:0px"><span style="white-space:pre">     </span>}</p><p style="margin:0px;padding:0px"><span style="white-space:pre">        </span>catch (std::exception& e) {</p><p style="margin:0px;padding:0px"><span style="white-space:pre">          </span>log("avcodec_send_packet has an exception error: {}\n", e.what());</p><p style="margin:0px;padding:0px"><span style="white-space:pre">     </span>}</p><p style="margin:0px;padding:0px"><span style="white-space:pre">        </span></p><p style="margin:0px;padding:0px"><span style="white-space:pre"> </span>if (ret < 0) {</p><p style="margin:0px;padding:0px"><span style="white-space:pre">                </span>TraceFFmpegErr(ret, "avcodec_send_packet");</p><p style="margin:0px;padding:0px"><span style="white-space:pre">            </span></p><p style="margin:0px;padding:0px"><span style="white-space:pre">         </span>if (ret == AVERROR_INVALIDDATA || ret== AVERROR_UNKNOWN) {</p><p style="margin:0px;padding:0px"><span style="white-space:pre">                       </span>//</p><p style="margin:0px;padding:0px"><span style="white-space:pre">               </span>}</p><p style="margin:0px;padding:0px"><span style="white-space:pre">                </span>return false;</p><p style="margin:0px;padding:0px"><span style="white-space:pre">    </span>}</p><p style="margin:0px;padding:0px"><br></p><p style="margin:0px;padding:0px"><span style="white-space:pre">  </span>while (!ret)</p><p style="margin:0px;padding:0px"><span style="white-space:pre">     </span>{</p><p style="margin:0px;padding:0px"><span style="white-space:pre">                </span>AVFrame* pFrame = m_pAVFrame;</p><p style="margin:0px;padding:0px"><br></p><p style="margin:0px;padding:0px"><span style="white-space:pre">              </span>try {</p><p style="margin:0px;padding:0px"><span style="white-space:pre">                    </span>ret = avcodec_receive_frame(m_pAVContxt, pFrame);</p><p style="margin:0px;padding:0px"><span style="white-space:pre">                </span>}</p><p style="margin:0px;padding:0px"><span style="white-space:pre">                </span>catch (std::exception& e) {</p><p style="margin:0px;padding:0px"><span style="white-space:pre">                  </span>log("avcodec_receive_frame has an exception error {}\n", e.what());</p><p style="margin:0px;padding:0px"><span style="white-space:pre">            </span>}</p><p style="margin:0px;padding:0px"><br></p><p style="margin:0px;padding:0px"><span style="white-space:pre">          </span>if (ret < 0)</p><p style="margin:0px;padding:0px"><span style="white-space:pre">          </span>{</p><p style="margin:0px;padding:0px"><span style="white-space:pre">                        </span>if (ret == AVERROR(EAGAIN)) {</p><p style="margin:0px;padding:0px"><span style="white-space:pre">                            </span>// </p><p style="margin:0px;padding:0px"><span style="white-space:pre">                     </span>}</p><p style="margin:0px;padding:0px"><span style="white-space:pre">                        </span></p><p style="margin:0px;padding:0px"><span style="white-space:pre">                 </span>if (ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) {</p><p style="margin:0px;padding:0px"><span style="white-space:pre">                              </span>TraceFFmpegErr(ret, "avcodec_receive_frame");</p><p style="margin:0px;padding:0px"><span style="white-space:pre">                  </span>}</p><p style="margin:0px;padding:0px"><span style="white-space:pre">                        </span>break;</p><p style="margin:0px;padding:0px"><span style="white-space:pre">           </span>}</p><p style="margin:0px;padding:0px"><br></p><p style="margin:0px;padding:0px"><span style="white-space:pre">          </span>if (AVMEDIA_TYPE_VIDEO == m_pAVContxt->codec_type) {</p><p style="margin:0px;padding:0px"><span style="white-space:pre">                  </span></p><p style="margin:0px;padding:0px"><span style="white-space:pre">                 </span>//<span style="white-space:pre">   </span>handles frame.</p><p style="margin:0px;padding:0px"><span style="white-space:pre">           </span>}</p><p style="margin:0px;padding:0px"><span style="white-space:pre">                </span>else {</p><p style="margin:0px;padding:0px"><span style="white-space:pre">                   </span>log("unhandled media type\n");</p><p style="margin:0px;padding:0px"><span style="white-space:pre">         </span>}</p><p style="margin:0px;padding:0px"><span style="white-space:pre">        </span>}</p><p style="margin:0px;padding:0px">}</p><div><br></div></div></div><div>I would like to know if the calls to functions to decode stream are incorrect and how can I over come the trouble.</div><div><br></div><div>Thanks.</div><div> <br></div><div><br></div></div>