RTMPdump(libRTMP) 源代码分析 9: 接收消息(Message)(接收视音频数据)
前一篇文章分析了RTMPdump(libRTMP) 的发送消息(Message)方面的源代码:RTMPdump(libRTMP) 源代码分析 8: 发送消息(Message)
在这里在研究研究接收消息(Message)的源代码,接收消息最典型的应用就是接收视音频数据了,因为视频和音频分别都属于RTMP协议规范中的一种消息。在这里主要分析接收视音频数据。
RTMPdump中完成视音频数据的接收(也可以说是视音频数据的下载)的函数是:RTMP_Read()。
RTMPdump主程序中的Download()函数就是通过调用RTMP_Read()完成数据接收,从而实现下载的。
那么我们马上开始吧,首先看看RTMP_Read()函数:
//调用Socket编程中的recv()函数,接收数据intRTMPSockBuf_Fill(RTMPSockBuf *sb){ int nBytes; if (!sb->sb_size) sb->sb_start = sb->sb_buf; while (1) {//缓冲区长度:总长-未处理字节-已处理字节//|-----已处理--------|-----未处理--------|---------缓冲区----------|//sb_buf sb_start sb_size nBytes = sizeof(sb->sb_buf) - sb->sb_size - (sb->sb_start - sb->sb_buf);#if defined(CRYPTO) && !defined(NO_SSL) if (sb->sb_ssl){ nBytes = TLS_read((SSL *)sb->sb_ssl, sb->sb_start + sb->sb_size, nBytes);} else#endif{//int recv( SOCKET s, char * buf, int len, int flags);//s:一个标识已连接套接口的描述字。//buf:用于接收数据的缓冲区。 //len:缓冲区长度。//flags:指定调用方式。//从sb_start(待处理的下一字节) + sb_size()还未处理的字节开始buffer为空,可以存储nBytes = recv(sb->sb_socket, sb->sb_start + sb->sb_size, nBytes, 0);} if (nBytes != -1){//未处理的字节又多了 sb->sb_size += nBytes;} else{ int sockerr = GetSockError(); RTMP_Log(RTMP_LOGDEBUG, "%s, recv returned %d. GetSockError(): %d (%s)", __FUNCTION__, nBytes, sockerr, strerror(sockerr)); if (sockerr == EINTR && !RTMP_ctrlC) continue; if (sockerr == EWOULDBLOCK || sockerr == EAGAIN) { sb->sb_timedout = TRUE; nBytes = 0; }} break; } return nBytes;}