Erro FFMPEG com avformat_open_input retornando -135

Eu tenho uma DLL que um dos meus aplicativos usa para receber vídeo de câmeras RTSP. Sob o capô, a DLL usa bibliotecas FFMPEG deste zip de lançamento:

ffmpeg-20141022-git-6dc99fd-win64-shared.7z

Temos uma grande variedade de câmeras em casa e a maioria delas funciona bem. No entanto, em um número de modelo da Pelco específico: IXE20DN-OCP, não consigo conectar. Testei a seqüência de conexão da câmera e rtsp no VLC e ela se conecta à câmera muito bem.

Encontrei a cadeia de conexão aqui:http://www.ispyconnect.com/man.aspx?n=Pelco

rtsp://IPADDRESS:554/1/stream1

Estranhamente, mesmo que eu deixe a porta do VLC, ela se conecta, então acho que é a porta RTSP padrão ou que o VLC tenta várias coisas com base na sua entrada.

De qualquer forma, quando tento conectar, recebo um erro de av_format_open_input. Retorna um código de -135. Quando olhei na lista de códigos de erro, não o vi listado. Para uma boa medida, imprimi todos os erros em error.h apenas para ver quais eram seus valores.

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

Nada nem perto de -135. Eu encontrei esse erro, meio que estouro de pilha, aquierro de tempo de execução ao vincular bibliotecas ffmpeg no qt creator onde o autor afirma que é um erro de carregamento de DLL. Não sei o que o levou a pensar isso, mas segui o conselho e usei o caminhante da dependência (http://www.dependencywalker.com/) para verificar quais dependências achou que minha DLL precisava. Ele listou alguns, mas eles já foram fornecidos no meu pacote de instalação.

Para garantir que ele estava sendo recolhido, eu os removi manualmente da instalação e observei uma mudança radical no comportamento do programa (sendo que minha DLL não foi carregada e nem começou a executar).

Então, eu tenho um pouco de código init:

void FfmpegInitialize()
{
 av_lockmgr_register(&LockManagerCb);
 av_register_all();
 LOG_DEBUG0("av_register_all returned\n");
}

Então eu tenho minha principal rotina de conexão aberta ...

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;
    }
...

Para ter certeza de que não entendi errado o código de erro, imprimi a mensagem de erro do ffmpeg, mas o erro não foi encontrado e minha mensagem de erro fixa é retornada.

Meu próximo passo seria conectar o wireshark na minha tentativa de conexão e na tentativa de conexão VLC e tentar descobrir quais diferenças (se houver) estão causando o problema e o que posso fazer com o ffmpeg para que ele funcione. Como eu disse, tenho uma dúzia de outras câmeras internas que usam RTSP e elas funcionam com minha DLL. Alguns utilizam nomes de usuário / senhas / etc também (então eu sei que esse não é o problema).

Além disso, meus logs de execução:

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

Vou avançar com o wireshark, mas gostaria de saber a origem do código de erro -135 do ffmpeg. Quando olho para o código se 'ret' está sendo definido como -135, isso deve estar acontecendo como resultado do código de retorno de um método auxiliar e não diretamente noavformat_open_input método.

https://www.ffmpeg.org/doxygen/2.5/libavformat_2utils_8c_source.html#l00398

Após a atualização para a versão mais recente do ffmpeg, recebo dados no wireshark. Protocolo de transmissão em tempo real:

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

A resposta para isso é o primeiro 'erro' que posso detectar na iniciação.

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

Acho que ... isso significa que o transporte que selecionamos não é suportado. Uma verificação rápida do código revela que escolhi 'tcp'. Examinando a resposta ao comando DESCRIBE, ele aparece:

Media Protocol: RTP/AVP

Além disso, quando o SETUP é emitido pelo ffmpeg, ele especifica:

Transport: RTP/AVP/TCP;unicast;interleaved=0-1

Vou tentar, em caso de falha aqui, escolher outro tipo de transporte e ver como isso funciona. Ainda não sei de onde vem o -135.

questionAnswers(1)

yourAnswerToTheQuestion