char *
AMF_EncodeInt16(char *output, char *outend, short nVal)
{
- if (output+2 >= outend)
+ if (output+2 > outend)
return NULL;
output[1] = nVal & 0xff;
char *
AMF_EncodeInt24(char *output, char *outend, int nVal)
{
- if (output+3 >= outend)
+ if (output+3 > outend)
return NULL;
output[2] = nVal & 0xff;
char *
AMF_EncodeInt32(char *output, char *outend, int nVal)
{
- if (output+4 >= outend)
+ if (output+4 > outend)
return NULL;
output[3] = nVal & 0xff;
char *
AMF_EncodeString(char *output, char *outend, const AVal * bv)
{
- if (output + 1 + 2 + bv->av_len >= outend)
+ if (output + 1 + 2 + bv->av_len > outend)
return NULL;
*output++ = AMF_STRING;
char *
AMF_EncodeNumber(char *output, char *outend, double dVal)
{
- if (output+1+8 >= outend)
+ if (output+1+8 > outend)
return NULL;
*output++ = AMF_NUMBER; // type: Number
char *
AMF_EncodeBoolean(char *output, char *outend, bool bVal)
{
- if (output+2 >= outend)
+ if (output+2 > outend)
return NULL;
*output++ = AMF_BOOLEAN;
char *
AMF_EncodeNamedString(char *output, char *outend, const AVal * strName, const AVal * strValue)
{
- if (output+2+strName->av_len >= outend)
+ if (output+2+strName->av_len > outend)
return NULL;
output = AMF_EncodeInt16(output, outend, strName->av_len);
char *
AMF_EncodeNamedNumber(char *output, char *outend, const AVal * strName, double dVal)
{
- if (output+2+strName->av_len >= outend)
+ if (output+2+strName->av_len > outend)
return NULL;
output = AMF_EncodeInt16(output, outend, strName->av_len);
char *
AMF_EncodeNamedBoolean(char *output, char *outend, const AVal * strName, bool bVal)
{
- if (output+2+strName->av_len >= outend)
+ if (output+2+strName->av_len > outend)
return NULL;
output = AMF_EncodeInt16(output, outend, strName->av_len);
bool
RTMP_ReadPacket(RTMP * r, RTMPPacket * packet)
{
- char hbuf[RTMP_MAX_HEADER_SIZE+1] = { 0 }, *header = hbuf;
+ char hbuf[RTMP_MAX_HEADER_SIZE] = { 0 }, *header = hbuf;
Log(LOGDEBUG2, "%s: fd=%d", __FUNCTION__, r->m_socket);
header += 2;
}
- int nSize = packetSize[packet->m_headerType];
+ int nSize = packetSize[packet->m_headerType], hSize;
if (nSize == RTMP_LARGE_HEADER_SIZE) // if we get a full header the timestamp is absolute
packet->m_hasAbsTimestamp = true;
return false;
}
- LogHexString(LOGDEBUG2, hbuf, nSize+(header-hbuf));
+ hSize = nSize+(header-hbuf);
if (nSize >= 3)
{
packet->m_nInfoField2 = DecodeInt32LE(header + 7);
}
}
+ if (packet->m_nInfoField1 == 0xffffff)
+ {
+ if (ReadN(r, header+nSize, 4) != 4)
+ {
+ Log(LOGERROR, "%s, failed to read extended timestamp",
+ __FUNCTION__);
+ return false;
+ }
+ packet->m_nInfoField1 = AMF_DecodeInt32(header+nSize);
+ hSize += 4;
+ }
}
+ LogHexString(LOGDEBUG2, hbuf, hSize);
+
bool didAlloc = false;
if (packet->m_nBodySize > 0 && packet->m_body == NULL)
{
}
else
{
- header = hbuf+2;
+ header = hbuf+6;
hend = hbuf+sizeof(hbuf);
}
hSize += cSize;
}
+ if (nSize > 1 && packet->m_nInfoField1 >= 0xffffff)
+ {
+ header -= 4;
+ hSize += 4;
+ }
+
hptr = header;
c = packet->m_headerType << 6;
switch(cSize)
}
if (nSize > 1)
- hptr = AMF_EncodeInt24(hptr, hend, packet->m_nInfoField1);
+ {
+ int t = packet->m_nInfoField1;
+ if (t > 0xffffff)
+ t = 0xffffff;
+ hptr = AMF_EncodeInt24(hptr, hend, t);
+ }
if (nSize > 4)
{
}
if (nSize > 8)
- EncodeInt32LE(hptr, packet->m_nInfoField2);
+ hptr += EncodeInt32LE(hptr, packet->m_nInfoField2);
+
+ if (nSize > 1 && packet->m_nInfoField1 >= 0xffffff)
+ hptr = AMF_EncodeInt32(hptr, hend, packet->m_nInfoField1);
nSize = packet->m_nBodySize;
char *buffer = packet->m_body;
#define RTMP_PACKET_TYPE_VIDEO 0x09
#define RTMP_PACKET_TYPE_INFO 0x12
-#define RTMP_MAX_HEADER_SIZE 14
+#define RTMP_MAX_HEADER_SIZE 18
typedef unsigned char BYTE;