RTMPdump(libRTMP) 源代码分析 9: 接收消息(Message)(接收视音频数据)(三)
cketType == 0x12)
{
//获取metadata
AMFObject metaObj;
int nRes =
AMF_Decode(&metaObj, packetBody, nPacketLen, FALSE);
if (nRes >= 0)
{
AVal metastring;
AMFProp_GetString(AMF_GetProp(&metaObj, NULL, 0),
&metastring);
if (AVMATCH(&metastring, &av_onMetaData))
{
/* compare */
if ((r->m_read.nMetaHeaderSize != nPacketLen) ||
(memcmp
(r->m_read.metaHeader, packetBody,
r->m_read.nMetaHeaderSize) != 0))
{
ret = RTMP_READ_ERROR;
}
}
AMF_Reset(&metaObj);
if (ret == RTMP_READ_ERROR)
break;
}
}
/* check first keyframe to make sure we got the right position
* in the stream! (the first non ignored frame)
*/
if (r->m_read.nInitialFrameSize > 0)
{
/* video or audio data */
if (packet.m_packetType == r->m_read.initialFrameType
&& r->m_read.nInitialFrameSize == nPacketLen)
{
/* we don't compare the sizes since the packet can
* contain several FLV packets, just make sure the
* first frame is our keyframe (which we are going
* to rewrite)
*/
if (memcmp
(r->m_read.initialFrame, packetBody,
r->m_read.nInitialFrameSize) == 0)
{
RTMP_Log(RTMP_LOGDEBUG, "Checked keyframe successfully!");
r->m_read.flags |= RTMP_READ_GOTKF;
/* ignore it! (what about audio data after it it is
* handled by ignoring all 0ms frames, see below)
*/
ret = RTMP_READ_IGNORE;
break;
}
}
/* hande FLV streams, even though the server resends the
* keyframe as an extra video packet it is also included
* in the first FLV stream chunk and we have to compare
* it and filter it out !!
*/
//MessageID=22,聚合消息
if (packet.m_packetType == 0x16)
{
/* basically we have to find the keyframe with the
* correct TS being nResumeTS
*/
unsigned int pos = 0;
uint32_t ts = 0;
while (pos + 11 < nPacketLen)
{
/* size without header (11) and prevTagSize (4) */
uint32_t dataSize =
AMF_DecodeInt24(packetBody + pos + 1);
ts = AMF_DecodeInt24(packetBody + pos + 4);
ts |= (packetBody[pos + 7] << 24);
#ifdef _DEBUG
RTMP_Log(RTMP_LOGDEBUG,
"keyframe search: FLV Packet: type %02X, dataSize: %d, timeStamp: %d ms",
packetBody[pos], dataSize, ts);
#endif
/* ok, is it a keyframe :
* well doesn't work for audio!
*/
if (packetBody[pos /*6928, test 0 */ ] ==
r->m_read.initialFrameType
/* && (packetBody[11]&0xf0) == 0x10 */ )
{
if (ts == r->m_read.nResumeTS)
{
RTMP_Log(RTMP_LOGDEBUG,
"Found keyframe with resume-keyframe timestamp!");
if (r->m_read.nInitialFrameSize != dataSize
|| memcmp(r->m_read.initialFrame,