Do not log an error for missing Video info in DefineVideo, as that's fine when Vide...
[gnash.git] / libmedia / FLVParser.h
blobae4ee9f06d28e6ea41b0f532e08589d4d4a43c5f
1 // FLVParser.h: Flash Video file format parser, for Gnash.
2 //
3 // Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 // Information about the FLV format can be found at http://osflash.org/flv
23 #ifndef GNASH_FLVPARSER_H
24 #define GNASH_FLVPARSER_H
26 #include "dsodefs.h"
27 #include "MediaParser.h" // for inheritance
28 #include "SimpleBuffer.h"
30 #include <set>
31 #include <memory>
32 #include <map>
34 #include <boost/thread/mutex.hpp>
36 namespace gnash {
37 namespace media {
39 /// Extra video info found in some FLV embedded streams
41 /// This is basically composed by an header for the audio stream
42 ///
43 class ExtraVideoInfoFlv : public VideoInfo::ExtraInfo
45 public:
47 /// Construct an ExtraVideoInfoFlv
49 /// @param extradata
50 /// Video header data. Ownership transferred.
51 ///
52 /// @param datasize
53 /// Video header data size
54 ///
55 /// @todo take a SimpleBuffer by auto_ptr
56 ///
57 ExtraVideoInfoFlv(boost::uint8_t* extradata, size_t datasize)
59 data(extradata),
60 size(datasize)
64 /// Video stream header
65 boost::scoped_array<boost::uint8_t> data;
67 /// Video stream header size
68 size_t size;
71 /// Extra audoi info found in some FLV embedded streams
73 /// This is basically composed by an header for the audio stream
74 ///
75 class ExtraAudioInfoFlv : public AudioInfo::ExtraInfo
77 public:
79 /// Construct an ExtraAudioInfoFlv
81 /// @param extradata
82 /// Audio header data. Ownership transferred.
83 ///
84 /// @param datasize
85 /// Audio header data size
86 ///
87 /// @todo take a SimpleBuffer by auto_ptr
88 ///
89 ExtraAudioInfoFlv(boost::uint8_t* extradata, size_t datasize)
91 data(extradata),
92 size(datasize)
96 /// Audio stream header
97 boost::scoped_array<boost::uint8_t> data;
99 /// Audio stream header size
100 size_t size;
103 /// The FLVParser class parses FLV streams
104 class DSOEXPORT FLVParser : public MediaParser
107 public:
109 /// The size of padding for all buffers that might be read by FFMPEG.
111 /// This possibly also applies to other media handlers (gst).
112 /// Ideally this would be taken from the current Handler, but we don't
113 /// know about it here.
114 static const size_t paddingBytes = 8;
116 /// \brief
117 /// Create an FLV parser reading input from
118 /// the given IOChannel
120 /// @param lt
121 /// IOChannel to use for input.
122 /// Ownership transferred.
124 FLVParser(std::auto_ptr<IOChannel> lt);
126 /// Kills the parser...
127 ~FLVParser();
129 // see dox in MediaParser.h
130 virtual bool seek(boost::uint32_t&);
132 // see dox in MediaParser.h
133 virtual bool parseNextChunk();
135 // see dox in MediaParser.h
136 boost::uint64_t getBytesLoaded() const;
138 // see dox in MediaParser.h
139 bool indexingCompleted() const
141 return _indexingCompleted;
144 /// Retrieve any parsed metadata tags up to a specified timestamp.
146 /// This copies pointers to a SimpleBuffer of AMF data from _metaTags,
147 /// then removes those pointers from the MetaTags map. Any metadata later
148 /// than the timestamp is kept until fetchMetaTags is called again (or
149 /// the dtor is called).
151 /// @param ts The latest timestamp to retrieve metadata for.
152 /// @param tags This is filled with shared pointers to metatags in
153 /// timestamp order. Ownership of the data is shared. It
154 /// is destroyed automatically along with the last owner.
156 virtual void fetchMetaTags(OrderedMetaTags& tags, boost::uint64_t ts);
158 private:
160 enum tagType
162 FLV_AUDIO_TAG = 0x08,
163 FLV_VIDEO_TAG = 0x09,
164 FLV_META_TAG = 0x12
167 struct FLVTag : public boost::noncopyable
169 FLVTag(boost::uint8_t* stream)
171 type(stream[0]),
172 body_size(getUInt24(stream+1)),
173 timestamp(getUInt24(stream+4) | (stream[7] << 24) )
176 /// Equals tagType
177 boost::uint8_t type;
178 boost::uint32_t body_size;
179 boost::uint32_t timestamp;
182 struct FLVAudioTag : public boost::noncopyable
184 FLVAudioTag(const boost::uint8_t& byte)
186 codec( (byte & 0xf0) >> 4 ),
187 samplerate( flv_audio_rates[(byte & 0x0C) >> 2] ),
188 samplesize( 1 + ((byte & 0x02) >> 1)),
189 stereo( (byte & 0x01) )
193 /// Equals audioCodecType
194 boost::uint8_t codec;
196 boost::uint16_t samplerate;
198 /// Size of each sample, in bytes
199 boost::uint8_t samplesize;
201 bool stereo;
203 private:
205 static const boost::uint16_t flv_audio_rates[];
209 enum frameType
211 FLV_VIDEO_KEYFRAME = 1,
212 FLV_VIDEO_INTERLACED = 2,
213 FLV_VIDEO_DISPOSABLE = 3
216 struct FLVVideoTag : public boost::noncopyable
218 FLVVideoTag(const boost::uint8_t& byte)
220 frametype( (byte & 0xf0) >> 4 ),
221 codec( byte & 0x0f )
224 /// Equals frameType
225 boost::uint8_t frametype;
226 /// Equals videoCodecType
227 boost::uint8_t codec;
230 /// Parses next tag from the file
232 /// Returns true if something was parsed, false otherwise.
233 /// Sets _parsingComplete=true on end of file.
235 bool parseNextTag(bool index_only);
237 std::auto_ptr<EncodedAudioFrame> parseAudioTag(const FLVTag& flvtag,
238 const FLVAudioTag& audiotag, boost::uint32_t thisTagPos);
240 std::auto_ptr<EncodedVideoFrame> parseVideoTag(const FLVTag& flvtag,
241 const FLVVideoTag& videotag, boost::uint32_t thisTagPos);
243 void indexAudioTag(const FLVTag& tag, boost::uint32_t thisTagPos);
245 void indexVideoTag(const FLVTag& tag, const FLVVideoTag& videotag,
246 boost::uint32_t thisTagPos);
248 /// Parses the header of the file
249 bool parseHeader();
251 /// Reads three bytes in FLV (big endian) byte order.
252 /// @param in Pointer to read 3 bytes from.
253 /// @return 24-bit integer.
254 static boost::uint32_t getUInt24(boost::uint8_t* in);
256 /// The position where the parsing should continue from.
257 /// Will be reset on seek, and will be protected by the _streamMutex
258 boost::uint64_t _lastParsedPosition;
260 /// Position of next tag to index
261 boost::uint64_t _nextPosToIndex;
263 /// Audio frame cursor position
265 /// This is the video frame number that will
266 /// be referenced by nextVideoFrame and nextVideoFrameTimestamp
268 size_t _nextAudioFrame;
270 /// Video frame cursor position
272 /// This is the video frame number that will
273 /// be referenced by nextVideoFrame and nextVideoFrameTimestamp
275 size_t _nextVideoFrame;
277 /// Audio stream is present
278 bool _audio;
280 /// Audio stream is present
281 bool _video;
283 std::auto_ptr<EncodedAudioFrame>
284 readAudioFrame(boost::uint32_t dataSize, boost::uint32_t timestamp);
286 std::auto_ptr<EncodedVideoFrame>
287 readVideoFrame(boost::uint32_t dataSize, boost::uint32_t timestamp);
289 /// Position in input stream for each cue point
290 /// first: timestamp
291 /// second: position in input stream
292 typedef std::map<boost::uint64_t, long> CuePointsMap;
293 CuePointsMap _cuePoints;
295 bool _indexingCompleted;
297 MetaTags _metaTags;
299 boost::mutex _metaTagsMutex;
302 } // end of gnash::media namespace
303 } // end of gnash namespace
305 #endif