avformat_open_input 返回 -135 的 FFMPEG 错误
FFMPEG error with avformat_open_input returning -135
我的一个应用程序使用一个 DLL 来接收来自 RTSP 摄像机的视频。在幕后,DLL 使用此版本 zip 中的 FFMPEG 库:
ffmpeg-20141022-git-6dc99fd-win64-shared.7z
我们家里有各种各样的摄像头,大多数都工作得很好。但是,对于一个特定的 Pelco 型号:IXE20DN-OCP,我无法连接。我在 VLC 上测试了相机和 rtsp 连接字符串,它可以很好地连接到相机。
我在这里找到了连接字符串:http://www.ispyconnect.com/man.aspx?n=Pelco
rtsp://IPADDRESS:554/1/stream1
奇怪的是,即使我不使用 VLC 端口,它也会连接,所以我猜它是默认的 RTSP 端口,或者 VLC 根据您的输入尝试各种操作。
无论如何,当我尝试连接时,我从 av_format_open_input 收到错误消息。它 return 是一个代码 -135。当我查看错误代码列表时,我没有看到列出的内容。为了更好地衡量,我打印了 error.h 中的所有错误,只是为了看看它们的值是多少。
DumpErrorCodes - Error Code : AVERROR_BSF_NOT_FOUND = -1179861752
DumpErrorCodes - Error Code : AVERROR_BUG = -558323010
DumpErrorCodes - Error Code : AVERROR_BUFFER_TOO_SMALL = -1397118274
DumpErrorCodes - Error Code : AVERROR_DECODER_NOT_FOUND = -1128613112
DumpErrorCodes - Error Code : AVERROR_DEMUXER_NOT_FOUND = -1296385272
DumpErrorCodes - Error Code : AVERROR_ENCODER_NOT_FOUND = -1129203192
DumpErrorCodes - Error Code : AVERROR_EOF = -541478725
DumpErrorCodes - Error Code : AVERROR_EXIT = -1414092869
DumpErrorCodes - Error Code : AVERROR_EXTERNAL = -542398533
DumpErrorCodes - Error Code : AVERROR_FILTER_NOT_FOUND = -1279870712
DumpErrorCodes - Error Code : AVERROR_INVALIDDATA = -1094995529
DumpErrorCodes - Error Code : AVERROR_MUXER_NOT_FOUND = -1481985528
DumpErrorCodes - Error Code : AVERROR_OPTION_NOT_FOUND = -1414549496
DumpErrorCodes - Error Code : AVERROR_PATCHWELCOME = -1163346256
DumpErrorCodes - Error Code : AVERROR_PROTOCOL_NOT_FOUND = -1330794744
DumpErrorCodes - Error Code : AVERROR_STREAM_NOT_FOUND = -1381258232
DumpErrorCodes - Error Code : AVERROR_BUG2 = -541545794
DumpErrorCodes - Error Code : AVERROR_UNKNOWN = -1313558101
DumpErrorCodes - Error Code : AVERROR_EXPERIMENTAL = -733130664
DumpErrorCodes - Error Code : AVERROR_INPUT_CHANGED = -1668179713
DumpErrorCodes - Error Code : AVERROR_OUTPUT_CHANGED = -1668179714
DumpErrorCodes - Error Code : AVERROR_HTTP_BAD_REQUEST = -808465656
DumpErrorCodes - Error Code : AVERROR_HTTP_UNAUTHORIZED = -825242872
DumpErrorCodes - Error Code : AVERROR_HTTP_FORBIDDEN = -858797304
DumpErrorCodes - Error Code : AVERROR_HTTP_NOT_FOUND = -875574520
DumpErrorCodes - Error Code : AVERROR_HTTP_OTHER_4XX = -1482175736
DumpErrorCodes - Error Code : AVERROR_HTTP_SERVER_ERROR = -1482175992
甚至接近 -135。我确实发现了这个错误,有点像堆栈溢出,在这里 runtime error when linking ffmpeg libraries in qt creator where the author claims it is a DLL loading problem error. I'm not sure what led him to think that, but I followed the advice and used the dependency walker (http://www.dependencywalker.com/) 检查它认为我的 DLL 需要哪些依赖项。它列出了一些,但它们已经在我的安装包中提供了。
为了确保它正在拾取它们,我手动将它们从安装中删除,并观察到程序行为发生了根本变化(即我的 DLL 根本没有加载并开始 运行)。
所以,我有一些初始化代码:
void FfmpegInitialize()
{
av_lockmgr_register(&LockManagerCb);
av_register_all();
LOG_DEBUG0("av_register_all returned\n");
}
然后我有了主要的打开连接例程...
int RTSPConnect(const char *URL, int width, int height, frameReceived callbackFunction)
{
int errCode =0;
if ((errCode = avformat_network_init()) != 0)
{
LOG_ERROR1("avformat_network_init returned error code %d\n", errCode);
}
LOG_DEBUG0("avformat_network_init returned\n");
//Allocate space and setup the the object to be used for storing all info needed for this connection
fContextReadFrame = avformat_alloc_context(); // free'd in the Close method
if (fContextReadFrame == 0)
{
LOG_ERROR1("Unable to set rtsp_transport options. Error code = %d\n", errCode);
return FFMPEG_OPTION_SET_FAILURE;
}
LOG_DEBUG1("avformat_alloc_context returned %p\n", fContextReadFrame);
AVDictionary *opts = 0;
if ((errCode = av_dict_set(&opts, "rtsp_transport", "tcp", 0)) < 0)
{
LOG_ERROR1("Unable to set rtsp_transport options. Error code = %d\n", errCode);
return FFMPEG_OPTION_SET_FAILURE;
}
LOG_DEBUG1("av_dict_set returned %d\n", errCode);
//open rtsp
DumpErrorCodes();
if ((errCode = avformat_open_input(&fContextReadFrame, URL, NULL, &opts)) < 0)
{
LOG_ERROR2("Unable to open avFormat RF inputs. URL = %s, and Error code = %d\n", URL, errCode);
LOG_ERROR2("Error Code %d = %s\n", errCode, errMsg(errCode));
// NOTE context is free'd on failure.
return FFMPEG_FORMAT_OPEN_FAILURE;
}
...
为了确保我没有误解错误代码,我打印了来自 ffmpeg 的错误消息,但未找到错误,而是 return 编辑了我的预设错误消息。
我的下一步是在我的连接尝试和 VLC 连接尝试上连接 wireshark,并试图找出导致问题的差异(如果有的话)以及我可以对 ffmpeg 做些什么来实现它工作。正如我所说,我家里还有十几个使用 RTSP 的其他摄像机,它们与我的 DLL 一起工作。有些人也使用 usernames/passwords/etc(所以我知道这不是问题所在)。
此外,我的 运行 日志:
FfmpegInitialize - av_register_all returned
Open - Open called. Pointers valid, passing control.
Rtsp::RtspInterface::Open - Rtsp::RtspInterface::Open called
Rtsp::RtspInterface::Open - VideoSourceString(35) = rtsp://192.168.14.60:554/1/stream1
Rtsp::RtspInterface::Open - Base URL = (192.168.14.60:554/1/stream1)
Rtsp::RtspInterface::Open - Attempting to open (rtsp://192.168.14.60:554/1/stream1) for WxH(320x240) video
RTSPSetFormatH264 - RTSPSetFormatH264
RTSPConnect - Called
LockManagerCb - LockManagerCb invoked for op 1
LockManagerCb - LockManagerCb invoked for op 2
RTSPConnect - avformat_network_init returned
RTSPConnect - avformat_alloc_context returned 019E6000
RTSPConnect - av_dict_set returned 0
DumpErrorCodes - Error Code : AVERROR_BSF_NOT_FOUND = -1179861752
...
DumpErrorCodes - Error Code : AVERROR_HTTP_SERVER_ERROR = -1482175992
RTSPConnect - Unable to open avFormat RF inputs. URL = rtsp://192.168.14.60:554/1/stream1, and Error code = -135
RTSPConnect - Error Code -135 = No Error Message Available
我将继续使用 wireshark,但想知道来自 ffmpeg 的 -135 错误代码的来源。当我查看代码时,如果 'ret' 设置为 -135,它一定是辅助方法中 return 代码的结果,而不是直接在 avformat_open_input方法。
https://www.ffmpeg.org/doxygen/2.5/libavformat_2utils_8c_source.html#l00398
升级到最新的每日 ffmpeg 构建后,我在 wireshark 上获取数据。实时流协议:
Request: SETUP rtsp://192.168.14.60/stream1/track1 RTSP/1.0\r\n
Method: SETUP
URL: rtsp://192.168.14.60/stream1/track1
Transport: RTP/AVP/TCP;unicast;interleaved=0-1
CSeq: 3\r\n
User-Agent: Lavf56.31.100\r\n
\r\n
对此的回应是我在启动中可以检测到的第一个 'error'。
Response: RTSP/1.0 461 Unsupported Transport\r\n
Status: 461
CSeq: 3\r\n
Date: Sun, Jan 04 1970 16:03:05 GMT\r\n
\r\n
我猜...这意味着我们选择的传输不受支持。我快速检查了代码,发现我选择了 'tcp'。查看对 DESCRIBE 命令的回复,显示:
Media Protocol: RTP/AVP
此外,当FFmpeg发出SETUP时,它指定:
Transport: RTP/AVP/TCP;unicast;interleaved=0-1
我会尝试,如果这里失败,请选择另一种传输类型,看看它是如何工作的。仍然不知道 -135 来自哪里。
解决方案原来是这个特定的相机不支持 RTSP over TCP 传输。它想要UDP。
我更新了代码以尝试 TCP,如果失败,则使用一组替代的 UDP 选项和另一个调用来尝试打开东西。
if ((errCode = av_dict_set(&opts, "rtsp_transport", "udp", 0)) < 0)
很有魅力。仍然关注未出现在 error.h 文件中的 -135 和 -22 错误代码的来源。可能是 ffmpeg 错误,其中允许杂散错误代码通过。
我的一个应用程序使用一个 DLL 来接收来自 RTSP 摄像机的视频。在幕后,DLL 使用此版本 zip 中的 FFMPEG 库:
ffmpeg-20141022-git-6dc99fd-win64-shared.7z
我们家里有各种各样的摄像头,大多数都工作得很好。但是,对于一个特定的 Pelco 型号:IXE20DN-OCP,我无法连接。我在 VLC 上测试了相机和 rtsp 连接字符串,它可以很好地连接到相机。
我在这里找到了连接字符串:http://www.ispyconnect.com/man.aspx?n=Pelco
rtsp://IPADDRESS:554/1/stream1
奇怪的是,即使我不使用 VLC 端口,它也会连接,所以我猜它是默认的 RTSP 端口,或者 VLC 根据您的输入尝试各种操作。
无论如何,当我尝试连接时,我从 av_format_open_input 收到错误消息。它 return 是一个代码 -135。当我查看错误代码列表时,我没有看到列出的内容。为了更好地衡量,我打印了 error.h 中的所有错误,只是为了看看它们的值是多少。
DumpErrorCodes - Error Code : AVERROR_BSF_NOT_FOUND = -1179861752
DumpErrorCodes - Error Code : AVERROR_BUG = -558323010
DumpErrorCodes - Error Code : AVERROR_BUFFER_TOO_SMALL = -1397118274
DumpErrorCodes - Error Code : AVERROR_DECODER_NOT_FOUND = -1128613112
DumpErrorCodes - Error Code : AVERROR_DEMUXER_NOT_FOUND = -1296385272
DumpErrorCodes - Error Code : AVERROR_ENCODER_NOT_FOUND = -1129203192
DumpErrorCodes - Error Code : AVERROR_EOF = -541478725
DumpErrorCodes - Error Code : AVERROR_EXIT = -1414092869
DumpErrorCodes - Error Code : AVERROR_EXTERNAL = -542398533
DumpErrorCodes - Error Code : AVERROR_FILTER_NOT_FOUND = -1279870712
DumpErrorCodes - Error Code : AVERROR_INVALIDDATA = -1094995529
DumpErrorCodes - Error Code : AVERROR_MUXER_NOT_FOUND = -1481985528
DumpErrorCodes - Error Code : AVERROR_OPTION_NOT_FOUND = -1414549496
DumpErrorCodes - Error Code : AVERROR_PATCHWELCOME = -1163346256
DumpErrorCodes - Error Code : AVERROR_PROTOCOL_NOT_FOUND = -1330794744
DumpErrorCodes - Error Code : AVERROR_STREAM_NOT_FOUND = -1381258232
DumpErrorCodes - Error Code : AVERROR_BUG2 = -541545794
DumpErrorCodes - Error Code : AVERROR_UNKNOWN = -1313558101
DumpErrorCodes - Error Code : AVERROR_EXPERIMENTAL = -733130664
DumpErrorCodes - Error Code : AVERROR_INPUT_CHANGED = -1668179713
DumpErrorCodes - Error Code : AVERROR_OUTPUT_CHANGED = -1668179714
DumpErrorCodes - Error Code : AVERROR_HTTP_BAD_REQUEST = -808465656
DumpErrorCodes - Error Code : AVERROR_HTTP_UNAUTHORIZED = -825242872
DumpErrorCodes - Error Code : AVERROR_HTTP_FORBIDDEN = -858797304
DumpErrorCodes - Error Code : AVERROR_HTTP_NOT_FOUND = -875574520
DumpErrorCodes - Error Code : AVERROR_HTTP_OTHER_4XX = -1482175736
DumpErrorCodes - Error Code : AVERROR_HTTP_SERVER_ERROR = -1482175992
甚至接近 -135。我确实发现了这个错误,有点像堆栈溢出,在这里 runtime error when linking ffmpeg libraries in qt creator where the author claims it is a DLL loading problem error. I'm not sure what led him to think that, but I followed the advice and used the dependency walker (http://www.dependencywalker.com/) 检查它认为我的 DLL 需要哪些依赖项。它列出了一些,但它们已经在我的安装包中提供了。
为了确保它正在拾取它们,我手动将它们从安装中删除,并观察到程序行为发生了根本变化(即我的 DLL 根本没有加载并开始 运行)。
所以,我有一些初始化代码:
void FfmpegInitialize()
{
av_lockmgr_register(&LockManagerCb);
av_register_all();
LOG_DEBUG0("av_register_all returned\n");
}
然后我有了主要的打开连接例程...
int RTSPConnect(const char *URL, int width, int height, frameReceived callbackFunction)
{
int errCode =0;
if ((errCode = avformat_network_init()) != 0)
{
LOG_ERROR1("avformat_network_init returned error code %d\n", errCode);
}
LOG_DEBUG0("avformat_network_init returned\n");
//Allocate space and setup the the object to be used for storing all info needed for this connection
fContextReadFrame = avformat_alloc_context(); // free'd in the Close method
if (fContextReadFrame == 0)
{
LOG_ERROR1("Unable to set rtsp_transport options. Error code = %d\n", errCode);
return FFMPEG_OPTION_SET_FAILURE;
}
LOG_DEBUG1("avformat_alloc_context returned %p\n", fContextReadFrame);
AVDictionary *opts = 0;
if ((errCode = av_dict_set(&opts, "rtsp_transport", "tcp", 0)) < 0)
{
LOG_ERROR1("Unable to set rtsp_transport options. Error code = %d\n", errCode);
return FFMPEG_OPTION_SET_FAILURE;
}
LOG_DEBUG1("av_dict_set returned %d\n", errCode);
//open rtsp
DumpErrorCodes();
if ((errCode = avformat_open_input(&fContextReadFrame, URL, NULL, &opts)) < 0)
{
LOG_ERROR2("Unable to open avFormat RF inputs. URL = %s, and Error code = %d\n", URL, errCode);
LOG_ERROR2("Error Code %d = %s\n", errCode, errMsg(errCode));
// NOTE context is free'd on failure.
return FFMPEG_FORMAT_OPEN_FAILURE;
}
...
为了确保我没有误解错误代码,我打印了来自 ffmpeg 的错误消息,但未找到错误,而是 return 编辑了我的预设错误消息。
我的下一步是在我的连接尝试和 VLC 连接尝试上连接 wireshark,并试图找出导致问题的差异(如果有的话)以及我可以对 ffmpeg 做些什么来实现它工作。正如我所说,我家里还有十几个使用 RTSP 的其他摄像机,它们与我的 DLL 一起工作。有些人也使用 usernames/passwords/etc(所以我知道这不是问题所在)。
此外,我的 运行 日志:
FfmpegInitialize - av_register_all returned
Open - Open called. Pointers valid, passing control.
Rtsp::RtspInterface::Open - Rtsp::RtspInterface::Open called
Rtsp::RtspInterface::Open - VideoSourceString(35) = rtsp://192.168.14.60:554/1/stream1
Rtsp::RtspInterface::Open - Base URL = (192.168.14.60:554/1/stream1)
Rtsp::RtspInterface::Open - Attempting to open (rtsp://192.168.14.60:554/1/stream1) for WxH(320x240) video
RTSPSetFormatH264 - RTSPSetFormatH264
RTSPConnect - Called
LockManagerCb - LockManagerCb invoked for op 1
LockManagerCb - LockManagerCb invoked for op 2
RTSPConnect - avformat_network_init returned
RTSPConnect - avformat_alloc_context returned 019E6000
RTSPConnect - av_dict_set returned 0
DumpErrorCodes - Error Code : AVERROR_BSF_NOT_FOUND = -1179861752
...
DumpErrorCodes - Error Code : AVERROR_HTTP_SERVER_ERROR = -1482175992
RTSPConnect - Unable to open avFormat RF inputs. URL = rtsp://192.168.14.60:554/1/stream1, and Error code = -135
RTSPConnect - Error Code -135 = No Error Message Available
我将继续使用 wireshark,但想知道来自 ffmpeg 的 -135 错误代码的来源。当我查看代码时,如果 'ret' 设置为 -135,它一定是辅助方法中 return 代码的结果,而不是直接在 avformat_open_input方法。
https://www.ffmpeg.org/doxygen/2.5/libavformat_2utils_8c_source.html#l00398
升级到最新的每日 ffmpeg 构建后,我在 wireshark 上获取数据。实时流协议:
Request: SETUP rtsp://192.168.14.60/stream1/track1 RTSP/1.0\r\n
Method: SETUP
URL: rtsp://192.168.14.60/stream1/track1
Transport: RTP/AVP/TCP;unicast;interleaved=0-1
CSeq: 3\r\n
User-Agent: Lavf56.31.100\r\n
\r\n
对此的回应是我在启动中可以检测到的第一个 'error'。
Response: RTSP/1.0 461 Unsupported Transport\r\n
Status: 461
CSeq: 3\r\n
Date: Sun, Jan 04 1970 16:03:05 GMT\r\n
\r\n
我猜...这意味着我们选择的传输不受支持。我快速检查了代码,发现我选择了 'tcp'。查看对 DESCRIBE 命令的回复,显示:
Media Protocol: RTP/AVP
此外,当FFmpeg发出SETUP时,它指定:
Transport: RTP/AVP/TCP;unicast;interleaved=0-1
我会尝试,如果这里失败,请选择另一种传输类型,看看它是如何工作的。仍然不知道 -135 来自哪里。
解决方案原来是这个特定的相机不支持 RTSP over TCP 传输。它想要UDP。
我更新了代码以尝试 TCP,如果失败,则使用一组替代的 UDP 选项和另一个调用来尝试打开东西。
if ((errCode = av_dict_set(&opts, "rtsp_transport", "udp", 0)) < 0)
很有魅力。仍然关注未出现在 error.h 文件中的 -135 和 -22 错误代码的来源。可能是 ffmpeg 错误,其中允许杂散错误代码通过。