返回-135

时间:2015-04-23 18:58:47

标签: c++ ffmpeg video-streaming rtsp pelco

我有一个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收到错误。它返回-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作者声称这是一个DLL加载问题错误。我不确定是什么让他想到这一点,但我遵循了建议并使用了依赖性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打印了错误消息,但找不到错误,而是返回了我的预设错误消息。

我的下一步是在我的连接尝试和VLC连接尝试上连接wireshark并试图找出导致问题的差异(如果有的话)以及我可以做些什么来使ffmpeg使其工作。正如我所说,我内部有十几台使用RTSP的相机,它们与我的DLL配合使用。有些人也使用用户名/密码/等(所以我知道这不是问题)。

另外,我的运行日志:

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时,它必须是由辅助方法的返回代码而不是直接在 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

对此的回应是我在初始阶段可以检测到的第一个“错误”。

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来自哪里。

1 个答案:

答案 0 :(得分:1)

解决方案结果是这个特定的相机不支持RTSP over TCP传输。它想要UDP。

我更新了代码以尝试TCP,如果失败,可以使用一组备用的UDP选项和另一个调用尝试打开的东西。

if ((errCode = av_dict_set(&opts, "rtsp_transport", "udp", 0)) < 0)

像魅力一样工作。仍然关注-135和-22错误代码的来源,它们没有出现在error.h文件中。也许是一个ffmpeg错误,允许通过错误代码。