Explorando e Utilizando a Biblioteca LIVE555

A biblioteca LIVE555 é um conjunto de software C++ para streaming de mídia em tempo real sobre redes IP. Ela suporta protocolos como RTSP, RTP, RTCP e SDP.

Compilação e Teste no Windows

Para compilar a biblioteca LIVE555 no Windows, é necessário configurar os caminhos de inclusão para os diretórios liveMedia, UsageEnvironment, groupsock e BasicUsageEnvironment.


..\UsageEnvironment\include
..\liveMedia\include
..\groupsock\include
..\BasicUsageEnvironment\include
   

O projeto mediaServer requer a mesma configuração de inclusão de cabeçalhos e a adição dos arquivos-fonte apropriados.

Solução de Erros de Compilação

Durante a compilação, podem surgir erros relacionados a funcionalidades seguras da CRT e a funções obsoletas do Winsock. Para resolvê-los:

  • Adicione _CRT_SECURE_NO_WARNINGS às definições do pré-processador.
  • Adicione _WINSOCK_DEPRECATED_NO_WARNINGS às definições do pré-processador.

Um erro comum ocorre na função BitVector::get_expGolombSigned:


int BitVector::get_expGolombSigned() {
 unsigned codeNum = get_expGolomb();

 if ((codeNum&1) == 0) { // even
   return -(codeNum/2);  // Erro C4146: operador unário de negação aplicado a tipo sem sinal
 } else { // odd
   return (codeNum+1)/2;
 }
}
   

Para corrigir o erro C4146, é necessário um cast explícito:


int BitVector::get_expGolombSigned() {
 unsigned codeNum = get_expGolomb();

 if ((codeNum & 1) == 0) { // even
   return static_cast<int>(codeNum / 2); // Corrigido para lidar com tipos sem sinal
 } else { // odd
   return static_cast<int>((codeNum + 1) / 2);
 }
}
   </int></int>

Outra configuração importante é desativar a verificação SDL nas propriedades do projeto (Propriedades do Projeto -> Propriedades de Configuração -> C/C++ -> Verificação SDL, defina como 'Não').

Erros de Linker no MediaServer

Após compilar as bibliotecas base, ao tentar compilar o mediaServer, podem ocorrer erros de linker devido a símbolos externos não resolvidos, como _initializeWinsockIfNecessary, _our_inet_addr, _our_srandom e _our_random.

Para resolver esses erros, certifique-se de que os arquivos inet.c (em groupsock) e rtcp_from_spec.c (em liveMedia) estejam incluídos no projeto mediaServer.

Além disso, adicione as seguintes diretivas #pragma comment(lib, ...) ao arquivo live555MediaServer.cpp para linkar as bibliotecas corretamente:


#ifdef _DEBUG
   #pragma comment (lib, "../Debug/BasicUsageEnvironment.lib")
   #pragma comment (lib, "../Debug/groupsock.lib")
   #pragma comment (lib, "../Debug/liveMedia.lib")
   #pragma comment (lib, "../Debug/UsageEnvironment.lib")
#else
   #pragma comment (lib, "../Release/BasicUsageEnvironment.lib")
   #pragma comment (lib, "../Release/groupsock.lib")
   #pragma comment (lib, "../Release/liveMedia.lib")
   #pragma comment (lib, "../Release/UsageEnvironment.lib")
#endif
   

Utilizando os Exemplos Fornecidos

A pasta testProgs na distribuição da LIVE555 contém exemplos úteis para testar a funcionalidade da biblioteca:

  • testRTSPClient e openRTSP: Clientes RTSP para conectar a servidores de streaming.
  • testOnDemandRTSPServer: Um servidor RTSP básico para servir mídia sob demanda.

Exemplo de Uso do testRTSPClient

Para testar a conexão com um fluxo RTSP:


./testRTSPClient rtsp://admin:senha@192.168.1.68:554/h264/ch1/main/av_stream
   

A saída do log demonstra a troca de mensagens RTSP (DESCRIBE, SETUP, PLAY) e o recebimento de pacotes RTP. Note que o cliente pode lidar com pacotes truncados se o buffer de recebimento for insuficiente.

Análise do Código Fonte (testRTSPClient)

O ponto de entrada principal é a função main:


int main(int argc, char** argv) {
 // Configura o ambiente de uso:
 TaskScheduler* scheduler = BasicTaskScheduler::createNew();
 UsageEnvironment* env = BasicUsageEnvironment::createNew(*scheduler);

 if (argc < 2) {
   usage(*env, argv[0]);
   return 1;
 }

 // Abre e inicia o streaming para cada URL fornecida:
 for (int i = 1; i <= argc-1; ++i) {
   openURL(*env, argv[0], argv[i]);
 }

 // Inicia o loop de eventos:
 env->taskScheduler().doEventLoop(&eventLoopWatchVariable);

 return 0;
}
   

A função openURL é responsável por criar um cliente RTSP e enviar o comando DESCRIBE:


void openURL(UsageEnvironment& env, char const* progName, char const* rtspURL) {
 RTSPClient* rtspClient = ourRTSPClient::createNew(env, rtspURL, RTSP_CLIENT_VERBOSITY_LEVEL, progName);
 if (rtspClient == NULL) {
   env << "Falha ao criar cliente RTSP para URL \"" << rtspURL << "\": " << env.getResultMsg() << "\n";
   return;
 }

 ++rtspClientCount;
 rtspClient->sendDescribeCommand(continueAfterDESCRIBE);
}
   

A lógica para obter os próximos quadros de dados está em FramedSource::getNextFrame e MultiFramedRTPSource::doGetNextFrame, que gerenciam a leitura de pacotes RTP, incluindo o reordenamento e o processamento de cabeçalhos específicos do formato.

Compilação e Teste no Linux

Para compilar no Linux:

  1. Baixe e descompacte o código-fonte: tar -xvf live555-latest.tar.gz
  2. Gere os Makefiles: ./genMakefiles linux-64bit (ou a variante apropriada para seu sistema)
  3. Compile: make

Por padrão, a compilação gera bibliotecas estáticas (.a). Para gerar bibliotecas dinâmicas (.so), use:

  1. Gere os Makefiles para bibliotecas compartilhadas: ./genMakefiles linux-with-shared-libraries
  2. Compile: make

Após a compilação, os executáveis de teste (testRTSPClient, openRTSP, etc.) estarão disponíveis no diretório testProgs.

Teste de Streaming no Linux

Execute o testRTSPClient com a URL do fluxo:


./testRTSPClient rtsp://admin:jyzbyj306@192.168.3.229:554/h264/ch1/main/av_stream
   

O log exibirá a sequência de comunicação RTSP e o recebimento de pacotes RTP.

Extração de Pacotes RTP

Para cenários onde um único fluxo de câmera precisa ser acessado por múltiplos clientes ou decodificadores, é necessário implementar uma solução de software. A LIVE555 pode ser usada para capturar pacotes RTP de um fluxo RTSP.

A função DummySink::afterGettingFrame no testRTSPClient é um exemplo de como os quadros RTP recebidos são processados. O método MultiFramedRTPSource::doGetNextFrame1 é crucial para o processamento desses quadros, lidando com a fragmentação e a possível perda de pacotes.

A leitura de dados em baixo nível é realizada pela função readSocket, que utiliza a chamada de sistema recvfrom (ou read em sockets TCP).

Embora o testRTSPClient receba dados que parecem ser pacotes RTP, o processamento exato desses pacotes e a lógica para retransmiti-los ou decodificá-los podem exigir manipulação adicional, pois os dados brutos podem não ser diretamente compatíveis com todos os decodificadores sem o contexto correto do RTP.

Tags: live555 RTSP RTP C++ streaming

Publicado em 6-20 23:11