gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] /srv/bzr/gnash/rtmp r9919: fix the split() method to be l


From: rob
Subject: [Gnash-commit] /srv/bzr/gnash/rtmp r9919: fix the split() method to be less complex.
Date: Sun, 28 Dec 2008 12:06:41 -0700
User-agent: Bazaar (1.5)

------------------------------------------------------------
revno: 9919
committer: address@hidden
branch nick: rtmp
timestamp: Sun 2008-12-28 12:06:41 -0700
message:
  fix the split() method to be less complex.
modified:
  libnet/rtmp.cpp
  libnet/rtmp.h
=== modified file 'libnet/rtmp.cpp'
--- a/libnet/rtmp.cpp   2008-12-28 02:44:43 +0000
+++ b/libnet/rtmp.cpp   2008-12-28 19:06:41 +0000
@@ -659,7 +659,6 @@
         if (el == 0) {
            break;
        }
-       el->dump();
        msg->addObject(el);
        if (status) {
            msg->checkStatus(el);
@@ -1067,8 +1066,15 @@
 RTMP::split(amf::Buffer &buf)
 {
     GNASH_REPORT_FUNCTION;
-
-    if (buf.reference() == 0) {
+    return split(buf.reference(), buf.allocated());
+}
+
+RTMP::queues_t *
+RTMP::split(boost::uint8_t *data, size_t size)
+{
+    GNASH_REPORT_FUNCTION;
+
+    if (data == 0) {
        log_error("Buffer pointer is invalid.");
     }
     
@@ -1078,29 +1084,47 @@
     size_t pktsize = 0;
     size_t nbytes = 0;
     
-    ptr = buf.reference();
+    ptr = data;
     boost::shared_ptr<amf::Buffer> chunk;
-    while ((ptr - buf.reference()) < static_cast<int>(buf.size())) {
+    // There may be multiple messages in this Buffer, so we walk a
+    // temp pointer through the contents of the Buffer.
+    while ((ptr - data) < static_cast<int>(size)) {
+       // Decode the header of the packet to get the header size, the
+       // body size, and the channel, all of which we need.
        rthead = decodeHeader(ptr);
+       // System channel messages are always on channel 2, and get
+       // processed differently.
+       // FIXME: skip system messages for now!
        if (rthead->channel == RTMP_SYSTEM_CHANNEL) {
-           log_debug("Got a message on the system channel");
-           ptr += rthead->head_size + rthead->bodysize;
-           continue;
+           log_debug("FIXME: %s: Got a message on the system channel!", 
__FUNCTION__);
+//         ptr += rthead->head_size + rthead->bodysize;
+//         continue;
        }
-       // Make sure the header size is in range
+       // Make sure the header size we just got is in range. We can
+       // proceed as long as it is in range, but if it is out of
+       // range, we can't really continue.
        if (rthead->head_size <= RTMP_MAX_HEADER_SIZE) {
-           // Any packet with a size greater than 1 is a new header, so create
-           // a new Buffer to hold all the data.
+           // Any packet with a header size greater than 1 is a
+           // always a new RTMP message, so create a new Buffer to
+           // hold all the data.
            if ((rthead->head_size > 1)) {
                cerr << "New packet for channel #" << rthead->channel << " of 
size "
                     << (rthead->head_size + rthead->bodysize) << endl;
+               // give it some memory to store data in. We store
                chunk.reset(new Buffer(rthead->bodysize + rthead->head_size));
-               chunk->clear(); // FIXME: temporary debug only, should be 
unnecessary
+               // Each RTMP connection has 64 channels, so we store
+               // the header with the data so that info is accessible
+               // via the Buffer for processing later. All the data
+               // goes in a queue for each channel.
                _queues[rthead->channel].push(chunk);
            } else {
-               // Use the existing Buffer for this pkt
+               // Use the existing Buffer for this packet, as it's a
+               // continuation messages for an existing packet. Leave
+               // the message in the queue, we just want access to
+               // the Buffer.
                chunk = _queues[rthead->channel].peek();
            }
+#if 1
            // Red5 version 5 sends out PING messages with a 1 byte header. I 
think this
            // may be a bug in Red5, but we should handle it anyway.
            if (chunk == 0) {
@@ -1109,32 +1133,44 @@
                chunk->clear(); // FIXME: temporary debug only, should be 
unnecessary
                _queues[rthead->channel].push(chunk);
            }
-           
-           // Many RTMP messages are smaller than the chunksize
+#endif    
+           // Many RTMP messages are smaller than the chunksize, so
+           // they're easy. Each channel may have a different
+           // chunksize, just to keep things interesting. The
+           // chunksize for a channel is changed by the Chunksize
+           // RTMP command.
            if (chunk->size() <= _chunksize[rthead->channel]) {
-               // a single byte header has no length field. As these are often
-               // used as continuation packets, the body size is the same as 
the
-               // previous header with a length field.
-               if ((rthead->head_size > 1)) {
-                   pktsize = chunk->size();
-               } else {
-                   pktsize = rthead->head_size + rthead->bodysize - 
chunk->size();
-               }
-           } else { // this RTMP message is larger than the chunksize
+               // Since the total RTMP message size is less than the
+               // chunksize for this channel, the packet size is the
+               // total message size.
+               pktsize = chunk->size();
+           } else {
+               // This RTMP message is larger than the chunksize for
+               // this channel, so the packet size is smaller than
+               // the total message size. The header bytes aren't
+               // counted as part of the message size, so we read the
+               // header plus all the data up to the channel chunksize.
                if (rthead->head_size > 1) {
                    pktsize = rthead->head_size + _chunksize[rthead->channel];
                } else {
-                   if ((rthead->head_size + chunk->size()) < 
_chunksize[rthead->channel]) {
-                       pktsize = rthead->head_size + chunk->size();
+                   // One byte headers are continuation messages for
+                   // existing data. There may be multiple
+                   // continuation messages to complete the RTMP
+                   // messagem, so all packets are read up to the
+                   // chunksize but the last packet of the sequence.
+                   if (chunk->spaceLeft() < _chunksize[rthead->channel]) {
+                       // don't store the continutation header,jusdt
+                       // append the data,
+                       pktsize = chunk->spaceLeft();
                    } else {
                        pktsize = rthead->head_size + (chunk->size() - 
_chunksize[rthead->channel]);
                    }
                }
            }
            
-           // Range check the size of the packet
+           // Now that we calculated the packet size, range check it
+           // for sanity.
            if (pktsize <= (_chunksize[rthead->channel] + 
RTMP_MAX_HEADER_SIZE)) {
-               nbytes += pktsize;
                // Skip the header for all but the first packet. The rest are 
just to
                // complete all the data up to the body size from the header.
 //             cerr << _queues[rthead->channel].size() << " messages in queue 
for channel "
@@ -1144,13 +1180,16 @@
                    cerr << "Space Left in buffer for channel " << 
rthead->channel << " is: "
                         << chunk->spaceLeft() << endl;
                    ptr += rthead->head_size;
-                   pktsize -= rthead->head_size;
-//             } else {
-//                 cerr << "FIRST PACKET!" << " for channel " << 
rthead->channel << endl;
+               } else {
+                   cerr << "FIRST PACKET!" << " for channel " << 
rthead->channel << endl;
                }
-               // This is a queue of channels with active messages
+               // This is a queue of channels with active messages. This is a
+               // much smaller list to traverse when processing data than all 
64 channels.
                _channels.push_back(&_queues[rthead->channel]);
                if (pktsize < 0xffffff) {
+//                 cerr << "FIXME5: " << hexify(ptr, pktsize, true) << endl;
+                   // If the packet size is in range, then append the
+                   // data to the existing data to complete the message.
                    chunk->append(ptr, pktsize);
                    cerr << "Adding data to existing packet for channel #" << 
rthead->channel
                         << ", read " << pktsize << " bytes." << endl;

=== modified file 'libnet/rtmp.h'
--- a/libnet/rtmp.h     2008-12-28 01:44:57 +0000
+++ b/libnet/rtmp.h     2008-12-28 19:06:41 +0000
@@ -294,6 +294,7 @@
     // bytes another 1 byte RTMP header. The header itself is not part of the 
byte
     // count.
     queues_t *split(amf::Buffer &buf);
+    queues_t *split(boost::uint8_t *data, size_t size);
 
     CQue &operator[] (size_t x) { return _queues[x]; }
     void dump();


reply via email to

[Prev in Thread] Current Thread [Next in Thread]