调用av_read_frame返回的错误码

本文列举了FFmpeg中常见的错误代码及其对应的含义,包括解码器未找到、过滤器未找到等错误,并提供了部分错误代码的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原博客:https://blog.youkuaiyun.com/lipengshiwo/article/details/52610168

首先上代码:

[cpp]  view plain  copy
  1. #include <stdio.h>  
  2.   
  3. #define MKTAG(a,b,c,d) ((a) | ((b) << 8) | ((c) << 16) | ((unsigned)(d) << 24))  
  4.   
  5.   
  6. #define FFERRTAG(a, b, c, d) (-(int)MKTAG(a, b, c, d))  
  7.   
  8. #define AVERROR_BSF_NOT_FOUND      FFERRTAG(0xF8,'B','S','F') ///< Bitstream filter not found  
  9. #define AVERROR_BUG                FFERRTAG( 'B','U','G','!') ///< Internal bug, also see AVERROR_BUG2  
  10. #define AVERROR_BUFFER_TOO_SMALL   FFERRTAG( 'B','U','F','S') ///< Buffer too small  
  11. #define AVERROR_DECODER_NOT_FOUND  FFERRTAG(0xF8,'D','E','C') ///< Decoder not found  
  12. #define AVERROR_DEMUXER_NOT_FOUND  FFERRTAG(0xF8,'D','E','M') ///< Demuxer not found  
  13. #define AVERROR_ENCODER_NOT_FOUND  FFERRTAG(0xF8,'E','N','C') ///< Encoder not found  
  14. #define AVERROR_EOF                FFERRTAG( 'E','O','F',' ') ///< End of file  
  15. #define AVERROR_EXIT               FFERRTAG( 'E','X','I','T') ///< Immediate exit was requested; the called function should not be restarted  
  16. #define AVERROR_EXTERNAL           FFERRTAG( 'E','X','T',' ') ///< Generic error in an external library  
  17. #define AVERROR_FILTER_NOT_FOUND   FFERRTAG(0xF8,'F','I','L') ///< Filter not found  
  18. #define AVERROR_INVALIDDATA        FFERRTAG( 'I','N','D','A') ///< Invalid data found when processing input  
  19. #define AVERROR_MUXER_NOT_FOUND    FFERRTAG(0xF8,'M','U','X') ///< Muxer not found  
  20. #define AVERROR_OPTION_NOT_FOUND   FFERRTAG(0xF8,'O','P','T') ///< Option not found  
  21. #define AVERROR_PATCHWELCOME       FFERRTAG( 'P','A','W','E') ///< Not yet implemented in FFmpeg, patches welcome  
  22. #define AVERROR_PROTOCOL_NOT_FOUND FFERRTAG(0xF8,'P','R','O') ///< Protocol not found  
  23.   
  24. #define AVERROR_STREAM_NOT_FOUND   FFERRTAG(0xF8,'S','T','R') ///< Stream not found  
  25.   
  26.   
  27. int main(void)  
  28. {  
  29.     printf("AVERROR_BSF_NOT_FOUND: %d\n", AVERROR_BSF_NOT_FOUND);  
  30.     printf("AVERROR_BUG: %d\n", AVERROR_BUG);  
  31.     printf("AVERROR_BUFFER_TOO_SMALL: %d\n",AVERROR_BUFFER_TOO_SMALL);  
  32.     printf("AVERROR_DECODER_NOT_FOUND: %d\n", AVERROR_DECODER_NOT_FOUND);  
  33.     printf("AVERROR_DEMUXER_NOT_FOUND: %d\n", AVERROR_DEMUXER_NOT_FOUND);  
  34.     printf("AVERROR_ENCODER_NOT_FOUND: %d\n", AVERROR_ENCODER_NOT_FOUND);  
  35.     printf("AVERROR_EOF: %d\n", AVERROR_EOF);  
  36.     printf("AVERROR_EXIT: %d\n", AVERROR_EXIT);  
  37.     printf("AVERROR_EXTERNAL: %d\n", AVERROR_EXTERNAL);  
  38.     printf("AVERROR_FILTER_NOT_FOUND: %d\n", AVERROR_FILTER_NOT_FOUND);  
  39.     printf("AVERROR_INVALIDDATA: %d\n", AVERROR_INVALIDDATA);  
  40.     printf("AVERROR_MUXER_NOT_FOUND: %d\n", AVERROR_MUXER_NOT_FOUND);  
  41.     printf("AVERROR_OPTION_NOT_FOUND: %d\n", AVERROR_OPTION_NOT_FOUND);  
  42.     printf("AVERROR_PATCHWELCOME: %d\n", AVERROR_PATCHWELCOME);  
  43.     printf("AVERROR_PROTOCOL_NOT_FOUND: %d\n", AVERROR_PROTOCOL_NOT_FOUND);  
  44.     printf("AVERROR_STREAM_NOT_FOUND: %d\n", AVERROR_STREAM_NOT_FOUND);  
  45.     return 0;  
  46. }  


返回值信息:

[html]  view plain  copy
  1. AVERROR_BSF_NOT_FOUND: -1179861752  
  2. AVERROR_BUG: -558323010  
  3. AVERROR_BUFFER_TOO_SMALL: -1397118274  
  4. AVERROR_DECODER_NOT_FOUND: -1128613112  
  5. AVERROR_DEMUXER_NOT_FOUND: -1296385272  
  6. AVERROR_ENCODER_NOT_FOUND: -1129203192  
  7. AVERROR_EOF: -541478725  
  8. AVERROR_EXIT: -1414092869  
  9. AVERROR_EXTERNAL: -542398533  
  10. AVERROR_FILTER_NOT_FOUND: -1279870712  
  11. AVERROR_INVALIDDATA: -1094995529  
  12. AVERROR_MUXER_NOT_FOUND: -1481985528  
  13. AVERROR_OPTION_NOT_FOUND: -1414549496  
  14. AVERROR_PATCHWELCOME: -1163346256  
  15. AVERROR_PROTOCOL_NOT_FOUND: -1330794744  
  16. AVERROR_STREAM_NOT_FOUND: -1381258232  

补充一部分报错信息:

[html]  view plain  copy
  1. </pre><p><pre name="code" class="html">DumpErrorCodes - Error Code : AVERROR_BUG2 = -541545794  
  2. DumpErrorCodes - Error Code : AVERROR_UNKNOWN = -1313558101  
  3. DumpErrorCodes - Error Code : AVERROR_EXPERIMENTAL = -733130664  
  4. DumpErrorCodes - Error Code : AVERROR_INPUT_CHANGED = -1668179713  
  5. DumpErrorCodes - Error Code : AVERROR_OUTPUT_CHANGED = -1668179714  
  6. DumpErrorCodes - Error Code : AVERROR_HTTP_BAD_REQUEST = -808465656  
  7. DumpErrorCodes - Error Code : AVERROR_HTTP_UNAUTHORIZED = -825242872  
  8. DumpErrorCodes - Error Code : AVERROR_HTTP_FORBIDDEN = -858797304  
  9. DumpErrorCodes - Error Code : AVERROR_HTTP_NOT_FOUND = -875574520  
  10. DumpErrorCodes - Error Code : AVERROR_HTTP_OTHER_4XX = -1482175736  
  11. DumpErrorCodes - Error Code : AVERROR_HTTP_SERVER_ERROR = -1482175992  
<think>好的,用户现在给出了另一个代码片段,询问关于`ret=0`的情况。之前我解释了`AVERROR(EAGAIN)`和`AVERROR_EOF`的错误处理,现在用户可能在调试时发现`ret`返回0,但不确定这意味着什么,或者为什么会出现这种情况。 首先,我需要回忆FFmpeg的API文档。`av_read_frame`的返回值中,0表示成功读取了一个AVPacket。所以当用户看到ret=0时,说明成功读取了一个数据包,应该继续处理这个数据包。用户可能在代码中打印了ret的值,但可能没有正确处理成功的情况,导致虽然数据包被读取了,但后续处理可能有问题。 接下来,用户提供的代码中,在`av_read_frame`之后,如果ret==0,代码会继续执行,但在用户的问题中,终端输出ret=0,但用户可能没有看到预期的结果,或者可能遇到了其他问题。比如,可能没有正确处理数据包,或者数据包处理过程中出现了其他错误。 用户可能没有意识到当`av_read_frame`返回0时,应该处理读取到的packet,然后将packet发送给解码器,否则会导致数据积压或者资源泄漏。比如,在代码中,当ret=0时,用户可能需要调用`avcodec_send_packet`,然后处理解码后的帧,否则packet没有被释放,可能会导致内存泄漏。 此外,用户可能在循环中没有释放packet,每次读取后应该使用`av_packet_unref`来释放资源,否则会导致内存泄漏。虽然用户的问题中没有显示这部分代码,但这是一个常见的问题点。 另外,用户可能在处理完数据包后没有继续循环,导致程序可能提前退出,或者在处理其他错误时没有正确处理。例如,当`av_read_frame`返回AVERROR_EOF时,可能表示文件结束,但用户可能没有处理这种情况,导致无法正确结束循环。 需要检查用户代码中是否有正确处理成功读取的packet,比如发送到解码器,处理帧,然后释放packet。同时,需要确保在循环结束后释放相关资源,如packet和frame,避免内存泄漏。 总结来说,用户的问题在于虽然`av_read_frame`返回0,但可能没有正确处理成功读取的数据包,导致程序没有按预期工作,或者存在资源泄漏的问题。需要指导用户正确处理返回值为0的情况,确保数据包被正确发送到解码器,并释放资源。</think>### **代码解析与处理建议** 你提供的代码片段是一个典型的 FFmpeg 媒体流读取循环,`ret=0` 表示 `av_read_frame()` **成功读取了一个数据包**。但结合代码逻辑和输出结果,可能存在以下问题需要优化: --- ### **1. 关键问题定位** #### **(1) `ret=0` 的含义** - **FFmpeg 返回值规则**: - **`0`**:成功读取一个 `AVPacket`。 - **`AVERROR(EAGAIN)`**:数据未就绪(需重试)。 - **`AVERROR_EOF`**:流已结束。 - **其他负值**:错误码(需处理)。 - **你的代码输出 `ret=0`**:说明 `av_read_frame()` **正确读取了数据包**,但代码逻辑未处理这一情况。 #### **(2) 问题表现** - **未处理成功读取的包**:代码中未对 `ret=0` 的分支进行处理,导致: - **数据包未被释放**:内存泄漏(需调用 `av_packet_unref(packet)`)。 - **解码逻辑缺失**:未将数据包发送给解码器(如 `avcodec_send_packet()`)。 --- ### **2. 修正代码示例** ```cpp AVPacket *packet = av_packet_alloc(); // 初始化数据包 while (1) { ret = av_read_frame(pFormatCtx, packet); qDebug() << "ret:" << ret; if (ret == AVERROR(EAGAIN)) { // 数据未就绪,稍后重试(例如:延迟10ms) QThread::usleep(10 * 1000); // Qt的微秒级延时 continue; } else if (ret < 0) { // 处理错误或EOF if (ret == AVERROR_EOF) { qDebug() << "Stream ended."; } else { char errbuf[AV_ERROR_MAX_STRING_SIZE]; av_strerror(ret, errbuf, sizeof(errbuf)); qDebug() << "Error:" << errbuf; } break; } else if (ret == 0) { // 成功读取数据包,发送到解码器 if (packet->stream_index == video_stream_idx) { ret = avcodec_send_packet(video_codec_ctx, packet); if (ret < 0) { qDebug() << "Failed to send packet to decoder."; } } av_packet_unref(packet); // 必须释放数据包! } } av_packet_free(&packet); // 循环结束后释放资源 ``` --- ### **3. 常见问题与调试** #### **(1) 数据包未释放** - **现象**:内存占用持续增长。 - **解决方案**:每次处理完数据包后调用 `av_packet_unref(packet)`。 ```cpp av_packet_unref(packet); // 重置packet内部指针并释放资源 ``` #### **(2) 解码器未正确处理** - **现象**:解码器队列阻塞,导致后续 `avcodec_send_packet()` 返回 `EAGAIN`。 - **解决方案**:在发送数据包前检查解码器状态: ```cpp while (avcodec_send_packet(codec_ctx, packet) == AVERROR(EAGAIN)) { // 解码器输入队列已满,需先接收帧 AVFrame *frame = av_frame_alloc(); avcodec_receive_frame(codec_ctx, frame); // 处理frame... av_frame_free(&frame); } ``` #### **(3) 流索引不匹配** - **现象**:音频/视频流混淆,导致解码失败。 - **解决方案**:初始化时确定流的索引: ```cpp video_stream_idx = av_find_best_stream(pFormatCtx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0); audio_stream_idx = av_find_best_stream(pFormatCtx, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0); ``` --- ### **4. 流程优化建议** | **步骤** | **操作** | |------------------------|----------------------------------------| | **1. 初始化数据包** | `av_packet_alloc()` | | **2. 循环读取数据** | `av_read_frame()` | | **3. 处理成功数据包** | 发送到解码器 + 释放 `av_packet_unref()`| | **4. 处理错误码** | 区分 `EAGAIN`、`EOF`、其他错误 | | **5. 结束循环** | 释放资源 `av_packet_free()` | --- ### **5. 总结** - **`ret=0` 是正常状态**:表示数据包已成功读取,需继续处理。 - **资源管理**:务必在每次循环中释放数据包,避免内存泄漏。 - **解码器协作**:及时将数据包发送到解码器,并处理输出帧。 - **流索引验证**:确保操作的是目标音频/视频流。 如果需要进一步调试,可以检查 `packet->size` 和 `packet->data` 的合法性,或使用 `ffprobe` 分析输入文件格式是否正常。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值