[rtmpdump] r328 - trunk/rtmpgw.c
hyc
subversion at mplayerhq.hu
Wed Mar 10 20:23:11 CET 2010
Author: hyc
Date: Wed Mar 10 20:23:10 2010
New Revision: 328
Log:
Cache initial packets, don't write header till we know the dataType
Modified:
trunk/rtmpgw.c
Modified: trunk/rtmpgw.c
==============================================================================
--- trunk/rtmpgw.c Wed Mar 10 19:53:24 2010 (r327)
+++ trunk/rtmpgw.c Wed Mar 10 20:23:10 2010 (r328)
@@ -105,7 +105,6 @@ typedef struct
uint32_t dStartOffset;
uint32_t dStopOffset;
- uint32_t nTimeStamp;
unsigned char hash[HASHLEN];
} RTMP_REQUEST;
@@ -292,21 +291,30 @@ WriteHeader(char **buf, // target point
return size;
}
+typedef struct WSargs {
+ RTMP *rtmp;
+ char *buf; // target pointer, maybe preallocated
+ unsigned int buflen; // length of buffer if preallocated
+ uint32_t nTimeStamp; // timestamp of last packet returned
+ uint8_t dataType; // type of stream for FLV header
+} WSargs;
+
int
-WriteStream(RTMP * rtmp, char **buf, // target pointer, maybe preallocated
- unsigned int len, // length of buffer if preallocated
- uint32_t * nTimeStamp)
+WriteStream(WSargs *ws)
{
uint32_t prevTagSize = 0;
int rtnGetNextMediaPacket = 0, ret = -1;
RTMPPacket packet = { 0 };
- rtnGetNextMediaPacket = RTMP_GetNextMediaPacket(rtmp, &packet);
+ rtnGetNextMediaPacket = RTMP_GetNextMediaPacket(ws->rtmp, &packet);
while (rtnGetNextMediaPacket)
{
char *packetBody = packet.m_body;
unsigned int nPacketLen = packet.m_nBodySize;
+ // set data type
+ ws->dataType |= (((packet.m_packetType == 0x08)<<2)|(packet.m_packetType == 0x09));
+
// skip video info/command packets
if (packet.m_packetType == 0x09 &&
nPacketLen == 2 && ((*packetBody & 0xf0) == 0x50))
@@ -343,33 +351,31 @@ WriteStream(RTMP * rtmp, char **buf, //
|| packet.m_packetType == 0x12) ? 11 : 0) + (packet.m_packetType !=
0x16 ? 4 : 0);
- if (size + 4 > len)
+ if (size + 4 > ws->buflen)
{ // the extra 4 is for the case of an FLV stream without a last prevTagSize (we need extra 4 bytes to append it)
- *buf = (char *) realloc(*buf, size + 4);
- if (*buf == 0)
+ ws->buf = realloc(ws->buf, size + 4);
+ if (ws->buf == 0)
{
Log(LOGERROR, "Couldn't reallocate memory!");
ret = -1; // fatal error
break;
}
+ ws->buflen = size + 4;
}
- char *ptr = *buf, *pend = ptr + size+4;
+ char *ptr = ws->buf, *pend = ptr + size+4;
// audio (0x08), video (0x09) or metadata (0x12) packets :
// construct 11 byte header then add rtmp packet's data
if (packet.m_packetType == 0x08 || packet.m_packetType == 0x09
|| packet.m_packetType == 0x12)
{
- // set data type
- //*dataType |= (((packet.m_packetType == 0x08)<<2)|(packet.m_packetType == 0x09));
-
- (*nTimeStamp) = packet.m_nTimeStamp;
+ ws->nTimeStamp = packet.m_nTimeStamp;
prevTagSize = 11 + nPacketLen;
*ptr++ = packet.m_packetType;
ptr = AMF_EncodeInt24(ptr, pend, nPacketLen);
- ptr = AMF_EncodeInt24(ptr, pend, *nTimeStamp);
- *ptr = (char) (((*nTimeStamp) & 0xFF000000) >> 24);
+ ptr = AMF_EncodeInt24(ptr, pend, ws->nTimeStamp);
+ *ptr = (char) (((ws->nTimeStamp) & 0xFF000000) >> 24);
ptr++;
// stream id
@@ -387,11 +393,11 @@ WriteStream(RTMP * rtmp, char **buf, //
while (pos + 11 < nPacketLen)
{
uint32_t dataSize = AMF_DecodeInt24(packetBody + pos + 1); // size without header (11) and without prevTagSize (4)
- *nTimeStamp = AMF_DecodeInt24(packetBody + pos + 4);
- *nTimeStamp |= (packetBody[pos + 7] << 24);
+ ws->nTimeStamp = AMF_DecodeInt24(packetBody + pos + 4);
+ ws->nTimeStamp |= (packetBody[pos + 7] << 24);
// set data type
- //*dataType |= (((*(packetBody+pos) == 0x08)<<2)|(*(packetBody+pos) == 0x09));
+ ws->dataType |= (((*(packetBody+pos) == 0x08)<<2)|(*(packetBody+pos) == 0x09));
if (pos + 11 + dataSize + 4 > nPacketLen)
{
@@ -420,7 +426,7 @@ WriteStream(RTMP * rtmp, char **buf, //
Log(LOGDEBUG,
"FLV Packet: type %02X, dataSize: %lu, tagSize: %lu, timeStamp: %lu ms",
(unsigned char) packetBody[pos], dataSize, prevTagSize,
- *nTimeStamp);
+ ws->nTimeStamp);
#endif
if (prevTagSize != (dataSize + 11))
@@ -532,6 +538,7 @@ void processTCPrequest(STREAMING_SERVER
char *ptr = NULL; // header pointer
size_t nRead = 0;
+ int doHeader = 1;
char srvhead[] =
"\r\nServer:HTTP-RTMP Stream Server \r\nContent-Type: Video/MPEG \r\n\r\n";
@@ -540,6 +547,7 @@ void processTCPrequest(STREAMING_SERVER
RTMP rtmp = { 0 };
uint32_t dSeek = 0; // can be used to start from a later point in the stream
+ WSargs ws;
// reset RTMP options to defaults specified upon invokation of streams
RTMP_REQUEST req;
@@ -720,6 +728,11 @@ void processTCPrequest(STREAMING_SERVER
// send the packets
buffer = (char *) calloc(PACKET_SIZE, 1);
+ ws.rtmp = &rtmp;
+ ws.buf = buffer;
+ ws.buflen = PACKET_SIZE;
+ ws.nTimeStamp = dSeek;
+ ws.dataType = 0;
// User defined seek offset
if (req.dStartOffset > 0)
@@ -733,7 +746,7 @@ void processTCPrequest(STREAMING_SERVER
if (dSeek != 0)
{
- LogPrintf("Starting at TS: %d ms\n", req.nTimeStamp);
+ LogPrintf("Starting at TS: %d ms\n", ws.nTimeStamp);
}
Log(LOGDEBUG, "Setting buffer time to: %dms", req.bufferTime);
@@ -767,14 +780,8 @@ void processTCPrequest(STREAMING_SERVER
nRead = WriteHeader(&buffer, PACKET_SIZE);
if (nRead > 0)
{
- nWritten = send(sockfd, buffer, nRead, 0);
- if (nWritten < 0)
- {
- Log(LOGERROR, "%s, sending failed, error: %d", __FUNCTION__,
- GetSockError());
- goto cleanup; // we are in STREAMING_IN_PROGRESS, so we'll go to STREAMING_ACCEPTING
- }
-
+ ws.buf += nRead;
+ ws.buflen -= nRead;
size += nRead;
}
else
@@ -787,13 +794,28 @@ void processTCPrequest(STREAMING_SERVER
// get the rest of the stream
do
{
- nRead = WriteStream(&rtmp, &buffer, PACKET_SIZE, &req.nTimeStamp);
+ nRead = WriteStream(&ws);
if (nRead > 0)
{
- nWritten = send(sockfd, buffer, nRead, 0);
- //Log(LOGDEBUG, "written: %d", nWritten);
- if (nWritten < 0)
+ if (doHeader)
+ {
+ if (ws.nTimeStamp > dSeek)
+ {
+ doHeader = 0;
+ nRead += size;
+ size = 0;
+ ws.buf = buffer;
+ ws.buflen = PACKET_SIZE;
+ buffer[4] = ws.dataType;
+ }
+ else
+ {
+ ws.buf += nRead;
+ ws.buflen -= nRead;
+ }
+ }
+ if (!doHeader && (nWritten = send(sockfd, buffer, nRead, 0)) < 0)
{
Log(LOGERROR, "%s, sending failed, error: %d", __FUNCTION__,
GetSockError());
@@ -809,17 +831,17 @@ void processTCPrequest(STREAMING_SERVER
if (duration > 0)
{
percent =
- ((double) (dSeek + req.nTimeStamp)) / (duration *
+ ((double) (dSeek + ws.nTimeStamp)) / (duration *
1000.0) * 100.0;
percent = ((double) (int) (percent * 10.0)) / 10.0;
LogStatus("\r%.3f KB / %.2f sec (%.1f%%)",
(double) size / 1024.0,
- (double) (req.nTimeStamp) / 1000.0, percent);
+ (double) (ws.nTimeStamp) / 1000.0, percent);
}
else
{
LogStatus("\r%.3f KB / %.2f sec", (double) size / 1024.0,
- (double) (req.nTimeStamp) / 1000.0);
+ (double) (ws.nTimeStamp) / 1000.0);
}
}
#ifdef _DEBUG
@@ -830,7 +852,7 @@ void processTCPrequest(STREAMING_SERVER
#endif
// Force clean close if a specified stop offset is reached
- if (req.dStopOffset && req.nTimeStamp >= req.dStopOffset)
+ if (req.dStopOffset && ws.nTimeStamp >= req.dStopOffset)
{
LogPrintf("\nStop offset has been reached at %.2f seconds\n",
(double) req.dStopOffset / 1000.0);
More information about the rtmpdump
mailing list