Gnash  0.8.10
FLVParser.h
Go to the documentation of this file.
00001 // FLVParser.h:  Flash Video file format parser, for Gnash.
00002 //
00003 //   Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012
00004 //   Free Software Foundation, Inc.
00005 //
00006 // This program is free software; you can redistribute it and/or modify
00007 // it under the terms of the GNU General Public License as published by
00008 // the Free Software Foundation; either version 3 of the License, or
00009 // (at your option) any later version.
00010 //
00011 // This program is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU General Public License
00017 // along with this program; if not, write to the Free Software
00018 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00019 //
00020 
00021 
00022 // Information about the FLV format can be found at http://osflash.org/flv
00023 
00024 #ifndef GNASH_FLVPARSER_H
00025 #define GNASH_FLVPARSER_H
00026 
00027 #include "dsodefs.h"
00028 #include "MediaParser.h" // for inheritance
00029 #include "SimpleBuffer.h" 
00030 
00031 #include <set>
00032 #include <memory>
00033 #include <map>
00034 
00035 #include <boost/thread/mutex.hpp>
00036 
00037 namespace gnash {
00038 namespace media {
00039 
00041 //
00044 class ExtraVideoInfoFlv : public VideoInfo::ExtraInfo
00045 {
00046 public:
00047 
00049     //
00058     ExtraVideoInfoFlv(boost::uint8_t* extradata, size_t datasize)
00059         :
00060         data(extradata),
00061         size(datasize)
00062     {
00063     }
00064 
00066     boost::scoped_array<boost::uint8_t> data;
00067 
00069     size_t size;
00070 };
00071 
00073 //
00076 class ExtraAudioInfoFlv : public AudioInfo::ExtraInfo
00077 {
00078 public:
00079 
00081     //
00090     ExtraAudioInfoFlv(boost::uint8_t* extradata, size_t datasize)
00091         :
00092         data(extradata),
00093         size(datasize)
00094     {
00095     }
00096 
00098     boost::scoped_array<boost::uint8_t> data;
00099 
00101     size_t size;
00102 };
00103 
00105 class DSOEXPORT FLVParser : public MediaParser
00106 {
00107 
00108 public:
00109 
00111     //
00115     static const size_t paddingBytes = 8;
00116 
00120         //
00125         FLVParser(std::auto_ptr<IOChannel> lt);
00126 
00128         ~FLVParser();
00129 
00130         // see dox in MediaParser.h
00131         virtual bool seek(boost::uint32_t&);
00132 
00133         // see dox in MediaParser.h
00134         virtual bool parseNextChunk();
00135 
00136         // see dox in MediaParser.h
00137         boost::uint64_t getBytesLoaded() const;
00138 
00139         // see dox in MediaParser.h
00140         bool indexingCompleted() const
00141         {
00142                 return _indexingCompleted;
00143         }
00144 
00146     //
00151     //
00156     //
00157     virtual void fetchMetaTags(OrderedMetaTags& tags, boost::uint64_t ts);
00158 
00159 private:
00160 
00161         enum tagType
00162         {
00163                 FLV_AUDIO_TAG = 0x08,
00164                 FLV_VIDEO_TAG = 0x09,
00165                 FLV_META_TAG = 0x12
00166         };
00167 
00168         struct FLVTag : public boost::noncopyable
00169         {
00170                 FLVTag(boost::uint8_t* stream)
00171                     :
00172             type(stream[0]),
00173             body_size(getUInt24(stream+1)),
00174             timestamp(getUInt24(stream+4) | (stream[7] << 24) )
00175                 {}
00176 
00178                 boost::uint8_t type;
00179                 boost::uint32_t body_size;
00180                 boost::uint32_t timestamp;
00181         };
00182 
00183         struct FLVAudioTag : public boost::noncopyable
00184         {
00185                 FLVAudioTag(const boost::uint8_t& byte)
00186                     :
00187             codec( (byte & 0xf0) >> 4 ),
00188                     samplerate( flv_audio_rates[(byte & 0x0C) >> 2] ),
00189                     samplesize( 1 + ((byte & 0x02) >> 1)),
00190                     stereo( (byte & 0x01) )
00191                 {
00192                 }
00193 
00195                 boost::uint8_t codec;
00196 
00197                 boost::uint16_t samplerate;
00198 
00200                 boost::uint8_t samplesize;
00201 
00202                 bool stereo;
00203 
00204     private:
00205         
00206         static const boost::uint16_t flv_audio_rates[];
00207         
00208     };
00209 
00210         enum frameType
00211         {
00212                 FLV_VIDEO_KEYFRAME = 1,
00213                 FLV_VIDEO_INTERLACED = 2,
00214                 FLV_VIDEO_DISPOSABLE = 3
00215         };
00216 
00217         struct FLVVideoTag : public boost::noncopyable
00218         {
00219                 FLVVideoTag(const boost::uint8_t& byte)
00220             :
00221             frametype( (byte & 0xf0) >> 4 ),
00222                     codec( byte & 0x0f )
00223                 {}
00224 
00226                 boost::uint8_t frametype;
00228                 boost::uint8_t codec;
00229         };
00230 
00232         //
00236         bool parseNextTag(bool index_only);
00237 
00238         std::auto_ptr<EncodedAudioFrame> parseAudioTag(const FLVTag& flvtag,
00239             const FLVAudioTag& audiotag, boost::uint32_t thisTagPos);
00240         
00241     std::auto_ptr<EncodedVideoFrame> parseVideoTag(const FLVTag& flvtag,
00242             const FLVVideoTag& videotag, boost::uint32_t thisTagPos);
00243 
00244         void indexAudioTag(const FLVTag& tag, boost::uint32_t thisTagPos);
00245         
00246     void indexVideoTag(const FLVTag& tag, const FLVVideoTag& videotag,
00247             boost::uint32_t thisTagPos);
00248 
00250         bool parseHeader();
00251 
00255         static boost::uint32_t getUInt24(boost::uint8_t* in);
00256 
00259         boost::uint64_t _lastParsedPosition;
00260 
00262         boost::uint64_t _nextPosToIndex;
00263 
00265         //
00269         size_t _nextAudioFrame;
00270 
00272         //
00276         size_t _nextVideoFrame;
00277 
00279         bool _audio;
00280 
00282         bool _video;
00283 
00284         std::auto_ptr<EncodedAudioFrame>
00285         readAudioFrame(boost::uint32_t dataSize, boost::uint32_t timestamp);
00286 
00287         std::auto_ptr<EncodedVideoFrame>
00288         readVideoFrame(boost::uint32_t dataSize, boost::uint32_t timestamp);
00289 
00293         typedef std::map<boost::uint64_t, long> CuePointsMap;
00294         CuePointsMap _cuePoints;
00295 
00296         bool _indexingCompleted;
00297 
00298     MetaTags _metaTags;
00299 
00300     boost::mutex _metaTagsMutex;
00301 };
00302 
00303 } // end of gnash::media namespace
00304 } // end of gnash namespace
00305 
00306 #endif