1、下载vlc-2.2.1.32-2013-master,使用VS2013编译
2、我关注的主要是两点,一是代码在什么地方获取rtsp流,二是H264解码部分
3、通过抓包分析,发现RTSP最后一个命令是“PLAY”,在代码中搜索“play"并下断点,运行程序,
在BasicTaskScheduler.cpp中有
void BasicTaskScheduler::SingleStep(unsigned maxDelayTime) {
//...
while ((handler = iter.next()) != NULL) {
int sock = handler->socketNum; // alias
int resultConditionSet = 0;
if (FD_ISSET(sock, &readSet) && FD_ISSET(sock, &fReadSet)/*sanity check*/) resultConditionSet |= SOCKET_READABLE;
if (FD_ISSET(sock, &writeSet) && FD_ISSET(sock, &fWriteSet)/*sanity check*/) resultConditionSet |= SOCKET_WRITABLE;
if (FD_ISSET(sock, &exceptionSet) && FD_ISSET(sock, &fExceptionSet)/*sanity check*/) resultConditionSet |= SOCKET_EXCEPTION;
if ((resultConditionSet&handler->conditionSet) != 0 && handler->handlerProc != NULL) {
fLastHandledSocketNum = sock;
// Note: we set "fLastHandledSocketNum" before calling the handler,
// in case the handler calls "doEventLoop()" reentrantly.
// 获取TCP数据
(*handler->handlerProc)(handler->clientData, resultConditionSet);
break;
}
}
//...
}
4、在 RTPInterface.cpp
void SocketDescriptor::tcpReadHandler1(int mask) {
// We expect the following data over the TCP channel:
// optional RTSP command or response bytes (before the first '$' character)
// a '$' character
// a 1-byte channel id
// a 2-byte packet size (in network byte order)
// the packet data.
// However, because the socket is being read asynchronously, this data might arrive in pieces.
u_int8_t c;
struct sockaddr_in fromAddress;
if (fTCPReadingState != AWAITING_PACKET_DATA) {
// 读取数据
int result = readSocket(fEnv, fOurSocketNum, &c, 1, fromAddress);
if (result != 1) { // error reading TCP socket, or no more data available
if (result < 0) { // error
fEnv.taskScheduler().turnOffBackgroundReadHandling(fOurSocketNum); // stops further calls to us
}
return;
}
}
//省略...
}
5、解码在decoder.c
static void *DecoderThread( void *p_data )
{
decoder_t *p_dec = (decoder_t *)p_data;
decoder_owner_sys_t *p_owner = p_dec->p_owner;
/* The decoder's main loop */
for( ;; )
{
block_t *p_block = block_FifoGet( p_owner->p_fifo );
/* Make sure there is no cancellation point other than this one^^.
* If you need one, be sure to push cleanup of p_block. */
bool end_wait = !p_block || p_block->i_flags & BLOCK_FLAG_CORE_EOS;
DecoderSignalWait( p_dec, end_wait );
if (end_wait)
input_DecoderStopWait( p_dec );
if( p_block )
{
int canc = vlc_savecancel();
if( p_block->i_flags & BLOCK_FLAG_CORE_EOS )
{
/* calling DecoderProcess() with NULL block will make
* decoders/packetizers flush their buffers */
block_Release( p_block );
p_block = NULL;
}
DecoderProcess( p_dec, p_block );
vlc_restorecancel( canc );
}
}
return NULL;
}