gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] /srv/bzr/gnash/trunk r10041: More cleanups and refactorin


From: Bastiaan Jacques
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r10041: More cleanups and refactoring. Restore indexing broken by last commit.
Date: Tue, 21 Oct 2008 22:20:52 +0200
User-agent: Bazaar (1.5)

------------------------------------------------------------
revno: 10041
committer: Bastiaan Jacques <address@hidden>
branch nick: trunk
timestamp: Tue 2008-10-21 22:20:52 +0200
message:
  More cleanups and refactoring. Restore indexing broken by last commit.
modified:
  libmedia/FLVParser.cpp
  libmedia/FLVParser.h
=== modified file 'libmedia/FLVParser.cpp'
--- a/libmedia/FLVParser.cpp    2008-10-21 15:24:43 +0000
+++ b/libmedia/FLVParser.cpp    2008-10-21 20:20:52 +0000
@@ -62,6 +62,9 @@
 namespace gnash {
 namespace media {
 
+
+const boost::uint16_t FLVParser::FLVAudioTag::flv_audio_rates [] = {5500, 
11000, 22050, 44100};
+
 FLVParser::FLVParser(std::auto_ptr<IOChannel> lt)
        :
        MediaParser(lt),
@@ -155,45 +158,38 @@
 }
 
 // would be called by parser thread
-bool
-FLVParser::indexTag(const boost::uint8_t* tag, boost::uint32_t timestamp, 
boost::uint32_t thisTagPos)
-{
-       if (tag[0] == FLV_AUDIO_TAG)
-       {
-               if ( ! _video) // if we have video we let that drive cue points
-               {
-                       // we can theoretically seek anywhere, but
-                       // let's just keep 5 seconds of distance
-                       CuePointsMap::iterator it = 
_cuePoints.lower_bound(timestamp);
-                       if ( it == _cuePoints.end() || it->first - timestamp >= 
5000)
-                       {
-                               //log_debug("Added cue point at timestamp %d 
and position %d (audio frame)", timestamp, thisTagPos);
-                               _cuePoints[timestamp] = thisTagPos; 
-                       }
-               }
-       }
-       else if (tag[0] == FLV_VIDEO_TAG)
-       {
-               // 1:keyframe, 2:interlacedFrame, 3:disposableInterlacedFrame
-               int frameType = (tag[11] & 0xf0) >> 4;
-               
-               bool isKeyFrame = (frameType == 1);
-               if ( isKeyFrame )
-               {
-                       //log_debug("Added cue point at timestamp %d and 
position %d (key video frame)", timestamp, thisTagPos);
-                       _cuePoints[timestamp] = thisTagPos;
-               }
-       }
-       else
-       {
-               log_debug("FLVParser::indexNextTag: tag %d is neither audio nor 
video", (int)tag[0]);
-       }
-
-       return true;
-}
+void
+FLVParser::indexAudioTag(const FLVTag& tag, boost::uint32_t thisTagPos)
+{
+       if ( _video) {
+               // if we have video we let that drive cue points
+               return;
+       }
+
+       // we can theoretically seek anywhere, but
+       // let's just keep 5 seconds of distance
+       CuePointsMap::iterator it = _cuePoints.lower_bound(tag.timestamp);
+       if ( it == _cuePoints.end() || it->first - tag.timestamp >= 5000)
+       {
+               //log_debug("Added cue point at timestamp %d and position %d 
(audio frame)", timestamp, thisTagPos);
+               _cuePoints[tag.timestamp] = thisTagPos; 
+       }
+}
+
+void
+FLVParser::indexVideoTag(const FLVTag& tag, const FLVVideoTag& videotag, 
boost::uint32_t thisTagPos)
+{
+       if ( videotag.frametype != FLV_VIDEO_KEYFRAME ) {
+               return;
+       }
+
+       //log_debug("Added cue point at timestamp %d and position %d (key video 
frame)", timestamp, thisTagPos);
+       _cuePoints[tag.timestamp] = thisTagPos;
+}
+
 
 std::auto_ptr<EncodedAudioFrame>
-FLVParser::parseAudioTag(boost::uint32_t bodyLength, boost::uint32_t 
timestamp, boost::uint32_t thisTagPos, const boost::uint8_t* tag)
+FLVParser::parseAudioTag(const FLVTag& flvtag, const FLVAudioTag& audiotag, 
boost::uint32_t thisTagPos)
 {
        std::auto_ptr<EncodedAudioFrame> frame;
 
@@ -202,17 +198,16 @@
                _audio = true; // TOCHECK: is this safe ?
        }
 
-       boost::uint8_t codec = (tag[11] & 0xf0) >> 4;
-
        bool header = false;
+       boost::uint32_t bodyLength = flvtag.body_size;
 
-       if (codec == AUDIO_CODEC_AAC) {
+       if (audiotag.codec == AUDIO_CODEC_AAC) {
                boost::uint8_t packettype = _stream->read_byte();
                header = (packettype == 0);
                --bodyLength;
        }
 
-       frame = readAudioFrame(bodyLength-1, timestamp);
+       frame = readAudioFrame(bodyLength-1, flvtag.timestamp);
        if ( ! frame.get() ) {
                log_error("could not read audio frame?");
        }
@@ -221,17 +216,7 @@
        // audio format has been noted, so we do that now
        if ( !_audioInfo.get() )
        {
-               int samplerate = (tag[11] & 0x0C) >> 2;
-               if (samplerate == 0) samplerate = 5500;
-               else if (samplerate == 1) samplerate = 11000;
-               else if (samplerate == 2) samplerate = 22050;
-               else if (samplerate == 3) samplerate = 44100;
-
-               int samplesize = (tag[11] & 0x02) >> 1;
-               if (samplesize == 0) samplesize = 1;
-               else samplesize = 2;
-
-               _audioInfo.reset( new AudioInfo(codec, samplerate, samplesize, 
(tag[11] & 0x01) >> 0, 0, FLASH) );
+               _audioInfo.reset( new AudioInfo(audiotag.codec, 
audiotag.samplerate, audiotag.samplesize, audiotag.stereo, 0, FLASH) );
                if (header) {
                        boost::uint8_t* newbuf = new 
boost::uint8_t[frame->dataSize];
                        memcpy(newbuf, frame->data.get(), frame->dataSize);
@@ -250,51 +235,51 @@
 }
 
 std::auto_ptr<EncodedVideoFrame>
-FLVParser::parseVideoTag(boost::uint32_t bodyLength, boost::uint32_t 
timestamp, boost::uint32_t thisTagPos, const boost::uint8_t* tag)
+FLVParser::parseVideoTag(const FLVTag& flvtag, const FLVVideoTag& videotag, 
boost::uint32_t thisTagPos)
 {
        if ( ! _video ) {
                log_error(_("Unexpected video tag found at offset %d of FLV 
stream advertising no video in header. We'll warn only once per FLV, expecting 
any further video tag."), thisTagPos);
                _video = true; // TOCHECK: is this safe ?
        }
-       // 1:keyframe, 2:interlacedFrame, 3:disposableInterlacedFrame
-       int frameType = (tag[11] & 0xf0) >> 4;
-
-       boost::uint16_t codec = (tag[11] & 0x0f) >> 0;
-
-       if (codec == VIDEO_CODEC_VP6 || codec == VIDEO_CODEC_VP6A)
-       {
-               _stream->read_byte();
-               --bodyLength;
-       }
 
        bool header = false;
-
-       if (codec == VIDEO_CODEC_H264) {
-               boost::uint8_t packettype = _stream->read_byte();
-               IF_VERBOSE_PARSE( log_debug(_("AVC packet type: %d"), 
(unsigned)packettype) );
-
-               header = (packettype == 0);
-
-               // 24-bits value for composition time offset ignored for now.
-               boost::uint8_t tmp[3];
-               _stream->read(tmp, 3);
-
-               bodyLength -= 4;
+       boost::uint32_t bodyLength = flvtag.body_size;
+
+       switch(videotag.codec) {
+               case VIDEO_CODEC_VP6:
+               case VIDEO_CODEC_VP6A:
+               {
+                       _stream->read_byte();
+                       --bodyLength;
+                       break;
+               }
+               case VIDEO_CODEC_H264:
+               {
+                       boost::uint8_t packettype = _stream->read_byte();
+                       IF_VERBOSE_PARSE( log_debug(_("AVC packet type: %d"), 
(unsigned)packettype) );
+
+                       header = (packettype == 0);
+
+                       // 24-bits value for composition time offset ignored 
for now.
+                       boost::uint8_t tmp[3];
+                       _stream->read(tmp, 3);
+       
+                       bodyLength -= 4;
+                       break;
+               }
+               default:
+                       break;
        }
 
-       size_t dataPosition = _stream->tell();
-
-       std::auto_ptr<EncodedVideoFrame> frame = readVideoFrame(bodyLength-1, 
timestamp);
-       if ( ! frame.get() )
-       {
+       std::auto_ptr<EncodedVideoFrame> frame = readVideoFrame(bodyLength-1, 
flvtag.timestamp);
+       if ( ! frame.get() ) {
                log_error("could not read video frame?");
        }
 
        // If this is the first videoframe no info about the
        // video format has been noted, so we do that now
-       if ( ! _videoInfo.get() )
-       {
-               _videoInfo.reset( new VideoInfo(codec, 0 /* width */, 0 /* 
height */, 0 /*frameRate*/, 0 /*duration*/, FLASH /*codec type*/) );
+       if ( ! _videoInfo.get() ) {
+               _videoInfo.reset( new VideoInfo(videotag.codec, 0 /* width */, 
0 /* height */, 0 /*frameRate*/, 0 /*duration*/, FLASH /*codec type*/) );
 
                if (header) {
                        boost::uint8_t* newbuf = new 
boost::uint8_t[frame->dataSize()];
@@ -323,6 +308,7 @@
        // won't mess with the parser on seek  or on getBytesLoaded
        boost::mutex::scoped_lock streamLock(_streamMutex);
 
+       if ( index_only && _indexingCompleted ) return false; 
        if ( _parsingComplete ) return false;
 
        if ( _seekRequest )
@@ -331,35 +317,42 @@
                _seekRequest = false;
        }
 
-       unsigned long thisTagPos = _lastParsedPosition;
+       uint64_t& position = index_only ? _nextPosToIndex : _lastParsedPosition;
+       bool& completed = index_only ? _indexingCompleted : _parsingComplete;
+
+       unsigned long thisTagPos = position;
 
        // Seek to next frame and skip the tag size 
        //log_debug("FLVParser::parseNextTag seeking to %d", thisTagPos+4);
        if ( _stream->seek(thisTagPos+4) )
        {
                log_error("FLVParser::parseNextTag: can't seek to %d", 
thisTagPos+4);
-               _parsingComplete=true;
+
+               completed = true;
                return false;
        }
        //log_debug("FLVParser::parseNextTag seeked to %d", thisTagPos+4);
 
        // Read the tag info
-       boost::uint8_t tag[12];
-       int actuallyRead = _stream->read(tag, 12);
+       boost::uint8_t chunk[12];
+       int actuallyRead = _stream->read(chunk, 12);
        if ( actuallyRead < 12 )
        {
                if ( actuallyRead )
                        log_error("FLVParser::parseNextTag: can't read tag info 
(needed 12 bytes, only got %d)", actuallyRead);
                // else { assert(_stream->eof(); } ?
-               _parsingComplete=true;
+
+               completed = true;
+
+                // update bytes loaded
+                boost::mutex::scoped_lock lock(_bytesLoadedMutex);
+               _bytesLoaded = _stream->tell(); 
                return false;
        }
 
-       // Extract length and timestamp
-       boost::uint32_t bodyLength = getUInt24(&tag[1]);
-       boost::uint32_t timestamp = getUInt24(&tag[4]);
+       FLVTag flvtag(chunk);
 
-       _lastParsedPosition += 15 + bodyLength;
+        position += 15 + flvtag.body_size;
 
        bool doIndex = (_lastParsedPosition+4 > _nextPosToIndex) || index_only;
        if ( doIndex )
@@ -368,25 +361,28 @@
                _nextPosToIndex = _lastParsedPosition;
        }
 
-       
-       if ( _lastParsedPosition > _bytesLoaded ) {
+
+       if ( position > _bytesLoaded ) {
                boost::mutex::scoped_lock lock(_bytesLoadedMutex);
                _bytesLoaded = _lastParsedPosition;
        }
 
        // check for empty tag
-       if (bodyLength == 0) return true;
-
-       if (doIndex) {
-               indexTag(tag, timestamp, thisTagPos);
-               if (index_only) {
-                       return true;
-               }
-       }
-
-       if (tag[0] == FLV_AUDIO_TAG)
+       if (flvtag.body_size == 0) return true;
+
+       if (flvtag.type == FLV_AUDIO_TAG)
        {
-               std::auto_ptr<EncodedAudioFrame> frame = 
parseAudioTag(bodyLength, timestamp, thisTagPos, tag);
+               FLVAudioTag audiotag(chunk[11]);
+
+               if (doIndex) {
+                       indexAudioTag(flvtag, thisTagPos);
+                       if (index_only) {
+                               return true;
+                       }
+               }
+
+
+               std::auto_ptr<EncodedAudioFrame> frame = parseAudioTag(flvtag, 
audiotag, thisTagPos);
                if (!frame.get()) {
                        return false;
                }
@@ -398,9 +394,18 @@
                streamLock.unlock();
                pushEncodedAudioFrame(frame);
        }
-       else if (tag[0] == FLV_VIDEO_TAG)
+       else if (flvtag.type == FLV_VIDEO_TAG)
        {
-               std::auto_ptr<EncodedVideoFrame> frame = 
parseVideoTag(bodyLength, timestamp, thisTagPos, tag);
+               FLVVideoTag videotag(chunk[11]);
+
+               if (doIndex) {
+                       indexVideoTag(flvtag, videotag, thisTagPos);
+                       if (index_only) {
+                               return true;
+                       }
+               }
+
+               std::auto_ptr<EncodedVideoFrame> frame = parseVideoTag(flvtag, 
videotag, thisTagPos);
                if (!frame.get()) {
                        return false;
                }
@@ -413,31 +418,31 @@
                pushEncodedVideoFrame(frame);
 
        }
-       else if (tag[0] == FLV_META_TAG)
+       else if (flvtag.type == FLV_META_TAG)
        {
-               if ( tag[11] != 2 )
+               if ( chunk[11] != 2 )
                {
                        // ::processTags relies on the first AMF0 value being a 
string...
                        log_unimpl(_("First byte of FLV_META_TAG is %d, 
expected 0x02 (STRING AMF0 type)"),
-                               (int)tag[11]);
+                               (int)chunk[11]);
                }
                // Extract information from the meta tag
-               std::auto_ptr<SimpleBuffer> metaTag(new 
SimpleBuffer(bodyLength-1));
-               size_t actuallyRead = _stream->read(metaTag->data(), 
bodyLength-1);
-               if ( actuallyRead < bodyLength-1 )
+               std::auto_ptr<SimpleBuffer> metaTag(new 
SimpleBuffer(flvtag.body_size-1));
+               size_t actuallyRead = _stream->read(metaTag->data(), 
flvtag.body_size-1);
+               if ( actuallyRead < flvtag.body_size-1 )
                {
                        log_error("FLVParser::parseNextTag: can't read metaTag 
(%d) body (needed %d bytes, only got %d)",
-                               FLV_META_TAG, bodyLength, actuallyRead);
+                               FLV_META_TAG, flvtag.body_size, actuallyRead);
                        return false;
                }
                metaTag->resize(actuallyRead);
 
                boost::mutex::scoped_lock lock(_metaTagsMutex);
-               _metaTags.push_back(new MetaTag(timestamp, metaTag));
+               _metaTags.push_back(new MetaTag(flvtag.timestamp, metaTag));
        }
        else
        {
-               log_error("FLVParser::parseNextTag: unknown FLV tag type %d", 
(int)tag[0]);
+               log_error("FLVParser::parseNextTag: unknown FLV tag type %d", 
(int)chunk[0]);
                return false;
        }
 

=== modified file 'libmedia/FLVParser.h'
--- a/libmedia/FLVParser.h      2008-10-21 15:15:10 +0000
+++ b/libmedia/FLVParser.h      2008-10-21 20:20:52 +0000
@@ -43,7 +43,6 @@
 namespace media {
 
 
-
 class ExtraVideoInfoFlv : public VideoInfo::ExtraInfo
 {
 public:
@@ -83,6 +82,60 @@
                FLV_META_TAG = 0x12
        };
 
+       struct FLVTag : public boost::noncopyable
+       {
+               FLVTag(boost::uint8_t* stream)
+               : type(stream[0]),
+                 body_size(getUInt24(stream+1)),
+                 timestamp(getUInt24(stream+4) | (stream[7] << 24) )
+               {}
+
+               /// Equals tagType
+               boost::uint8_t type;
+               boost::uint32_t body_size;
+               boost::uint32_t timestamp;
+       };
+
+       struct FLVAudioTag : public boost::noncopyable
+       {
+               FLVAudioTag(const boost::uint8_t& byte)
+               : codec( (byte & 0xf0) >> 4 ),
+                 samplerate( flv_audio_rates[(byte & 0x0C) >> 2] ),
+                 samplesize( 1 + ((byte & 0x02) >> 1)),
+                 stereo( (byte & 0x01) )
+               {
+               }
+
+               /// Equals audioCodecType
+               boost::uint8_t codec;
+               boost::uint16_t samplerate;
+               boost::uint8_t samplesize;
+               bool stereo;
+       private:
+               static const boost::uint16_t flv_audio_rates[];
+       };
+
+       enum frameType
+       {
+               FLV_VIDEO_KEYFRAME = 1,
+               FLV_VIDEO_INTERLACED = 2,
+               FLV_VIDEO_DISPOSABLE = 3
+       };
+
+       struct FLVVideoTag : public boost::noncopyable
+       {
+               FLVVideoTag(const boost::uint8_t& byte)
+               : frametype( (byte & 0xf0) >> 4 ),
+                 codec( byte & 0x0f )
+               {}
+
+               /// Equals frameType
+               boost::uint8_t frametype;
+               /// Equals videoCodecType
+               boost::uint8_t codec;
+       };
+
+
 
        /// \brief
        /// Create an FLV parser reading input from
@@ -123,12 +176,11 @@
        ///
        bool parseNextTag(bool index_only);
 
-       std::auto_ptr<EncodedAudioFrame> parseAudioTag(boost::uint32_t 
bodyLength, boost::uint32_t timestamp, boost::uint32_t thisTagPos,
-               const boost::uint8_t* tag);
-       std::auto_ptr<EncodedVideoFrame> parseVideoTag(boost::uint32_t 
bodyLength, boost::uint32_t timestamp, boost::uint32_t thisTagPos,
-               const boost::uint8_t* tag);
+       std::auto_ptr<EncodedAudioFrame> parseAudioTag(const FLVTag& flvtag, 
const FLVAudioTag& audiotag, boost::uint32_t thisTagPos);
+       std::auto_ptr<EncodedVideoFrame> parseVideoTag(const FLVTag& flvtag, 
const FLVVideoTag& videotag, boost::uint32_t thisTagPos);
 
-       bool indexTag(const boost::uint8_t* tag, boost::uint32_t timestamp, 
boost::uint32_t thisTagPos);
+       void indexAudioTag(const FLVTag& tag, boost::uint32_t thisTagPos);
+       void indexVideoTag(const FLVTag& tag, const FLVVideoTag& videotag, 
boost::uint32_t thisTagPos);
 
        /// Parses the header of the file
        bool parseHeader();
@@ -136,7 +188,7 @@
        /// Reads three bytes in FLV (big endian) byte order.
        /// @param in Pointer to read 3 bytes from.
        /// @return 24-bit integer.
-       inline boost::uint32_t getUInt24(boost::uint8_t* in);
+       static boost::uint32_t getUInt24(boost::uint8_t* in);
 
        /// The position where the parsing should continue from.
        /// Will be reset on seek, and will be protected by the _streamMutex


reply via email to

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