Gnash 0.8.9

NetStream_as.h

Go to the documentation of this file.
00001 // 
00002 //   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010,
00003 //   2011 Free Software Foundation, Inc
00004 // 
00005 // This program is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation; either version 3 of the License, or
00008 // (at your option) any later version.
00009 // 
00010 // This program is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with this program; if not, write to the Free Software
00017 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018 
00019 
00020 #ifndef GNASH_NETSTREAM_H
00021 #define GNASH_NETSTREAM_H
00022 
00023 
00024 #ifndef __STDC_CONSTANT_MACROS
00025 #define __STDC_CONSTANT_MACROS
00026 #endif
00027 
00028 #include <boost/intrusive_ptr.hpp>
00029 #include <string>
00030 #include <boost/ptr_container/ptr_deque.hpp>
00031 #include <boost/scoped_ptr.hpp>
00032 
00033 #include "MediaParser.h"
00034 #include "PlayHead.h" // for composition
00035 #include "VideoDecoder.h" // for visibility of dtor
00036 #include "AudioDecoder.h" // for visibility of dtor
00037 #include "VirtualClock.h"
00038 #include "Relay.h" // for ActiveRelay inheritance
00039 
00040 // Forward declarations
00041 namespace gnash {
00042     class CharacterProxy;
00043     class IOChannel;
00044     class NetConnection_as;
00045     class as_function;
00046     class DisplayObject;
00047     struct ObjectURI;
00048     namespace media {
00049         class MediaHandler;
00050     }
00051     namespace sound {
00052         class sound_handler;
00053         class InputStream;
00054     }
00055 }
00056 
00057 namespace gnash {
00058 
00060 //
00069 class BufferedAudioStreamer {
00070 public:
00071 
00075     BufferedAudioStreamer(sound::sound_handler* handler);
00076 
00078     //
00082     class CursoredBuffer
00083     {
00084     public:
00085         CursoredBuffer()
00086             :
00087             m_size(0),
00088             m_data(NULL),
00089             m_ptr(NULL)
00090         {}
00091 
00092         ~CursoredBuffer()
00093         {
00094             delete [] m_data;
00095         }
00096 
00098         boost::uint32_t m_size;
00099 
00101         //
00104         boost::uint8_t* m_data;
00105 
00107         boost::uint8_t* m_ptr;
00108     };
00109 
00110     typedef boost::ptr_deque<CursoredBuffer> AudioQueue;
00111 
00112     // Delete all samples in the audio queue.
00113     void cleanAudioQueue();
00114 
00115     sound::sound_handler* _soundHandler;
00116 
00119     AudioQueue _audioQueue;
00120 
00122     size_t _audioQueueSize;
00123 
00126     boost::mutex _audioQueueMutex;
00127 
00128     // Id of an attached audio streamer, 0 if none
00129     sound::InputStream* _auxStreamer;
00130 
00132     //
00136     void attachAuxStreamer();
00137 
00139     //
00143     void detachAuxStreamer();
00144 
00146     unsigned int fetch(boost::int16_t* samples, unsigned int nSamples,
00147                     bool& eof);
00148 
00150     static unsigned int fetchWrapper(void* owner, boost::int16_t* samples,
00151                     unsigned int nSamples, bool& eof);
00152 
00154     //
00160     void push(CursoredBuffer* audio);
00161 
00162 };
00163 
00164 // -----------------------------------------------------------------
00165 
00167 //
00171 class NetStream_as : public ActiveRelay
00172 {
00173 
00174 public:
00175 
00176     enum PauseMode {
00177       pauseModeToggle = -1,
00178       pauseModePause = 0,
00179       pauseModeUnPause = 1  
00180     };
00181 
00182     NetStream_as(as_object* owner);
00183 
00184     ~NetStream_as();
00185 
00186     PlayHead::PlaybackStatus playbackState() const {
00187         return _playHead.getState();
00188     }
00189 
00191     //
00195     int videoHeight() const;
00196 
00198     //
00202     int videoWidth() const;
00203 
00206     void close();
00207 
00209     void setAudioController(DisplayObject* controller);
00210  
00212     //
00215     void pause(PauseMode mode);
00216 
00218     //
00222     void play(const std::string& source);
00223 
00225     //
00230     void seek(boost::uint32_t pos);
00231 
00233     //
00236     boost::int32_t time();
00237 
00242     void update();
00243     
00245     double getCurrentFPS()  { return 0; }
00246 
00248     //
00252     void setNetCon(NetConnection_as* nc) {
00253         _netCon = nc;
00254     }
00255 
00257     bool isConnected() const { return (_netCon); }
00258 
00261     //
00265     void setBufferTime(boost::uint32_t time);
00266 
00269     //
00272     boost::uint32_t bufferTime() { return m_bufferTime; }
00273 
00275     long bytesLoaded();
00276 
00278     //
00281     long bytesTotal();
00282 
00285     //
00289     long bufferLength();
00290 
00292     //
00294     bool newFrameReady();
00295 
00297     //
00301     std::auto_ptr<image::GnashImage> get_video();
00302     
00304     void setInvalidatedVideo(DisplayObject* ch)
00305     {
00306         _invalidatedVideoCharacter = ch;
00307     }
00308 
00309     virtual void markReachableResources() const;
00310 
00312     //
00318     static unsigned int audio_streamer(void *udata, boost::int16_t* samples,
00319             unsigned int nSamples, bool& eof);
00320 
00321 protected:
00322     
00324     enum StatusCode {
00325     
00326         // Internal status, not a valid ActionScript value
00327         invalidStatus,
00328 
00330         bufferEmpty,
00331 
00333         bufferFull,
00334 
00336         bufferFlush,
00337 
00339         playStart,
00340 
00342         playStop,
00343 
00345         seekNotify,
00346 
00348         streamNotFound,
00349 
00351         invalidTime
00352     };
00353 
00354     NetConnection_as* _netCon;
00355 
00356     boost::scoped_ptr<CharacterProxy> _audioController;
00357 
00359     //
00376     void setStatus(StatusCode code);
00377 
00381     //
00388     void processStatusNotifications();
00389     
00390     // The size of the buffer in milliseconds
00391     boost::uint32_t m_bufferTime;
00392 
00393     // Are a new frame ready to be returned?
00394     volatile bool m_newFrameReady;
00395 
00396     // Mutex to insure we don't corrupt the image
00397     boost::mutex image_mutex;
00398 
00399     // The image/videoframe which is given to the renderer
00400     std::auto_ptr<image::GnashImage> m_imageframe;
00401 
00402     // The video URL
00403     std::string url;
00404 
00405     // The input media parser
00406     std::auto_ptr<media::MediaParser> m_parser;
00407 
00408     // The position in the inputfile, only used when not playing a FLV
00409     long inputPos;
00410 
00412     void stopAdvanceTimer();
00413 
00415     void startAdvanceTimer();
00416 
00418     DisplayObject* _invalidatedVideoCharacter;
00419 
00420 private:
00421 
00422     enum DecodingState {
00423         DEC_NONE,
00424         DEC_STOPPED,
00425         DEC_DECODING,
00426         DEC_BUFFERING
00427     };
00428 
00429     typedef std::pair<std::string, std::string> NetStreamStatus;
00430 
00432     //
00436     void getStatusCodeInfo(StatusCode code, NetStreamStatus& info);
00437 
00439     as_object* getStatusObject(StatusCode code);
00440 
00442     //
00445     void initVideoDecoder(const media::VideoInfo& info);
00446 
00448     //
00451     void initAudioDecoder(const media::AudioInfo& parser);
00452 
00453     // Setups the playback
00454     bool startPlayback();
00455 
00456     // Pauses the playhead 
00457     //
00458     // Users:
00459     //  - ::decodeFLVFrame() 
00460     //  - ::pause() 
00461     //  - ::play() 
00462     //
00463     void pausePlayback();
00464 
00465     // Resumes the playback 
00466     //
00467     // Users:
00468     //  - ::av_streamer() 
00469     //  - ::play() 
00470     //  - ::startPlayback() 
00471     //  - ::advance() 
00472     //
00473     void unpausePlayback();
00474 
00476     //
00489     void refreshVideoFrame(bool alsoIfPaused = false);
00490 
00493     void refreshAudioBuffer();
00494 
00496     //
00499     std::auto_ptr<image::GnashImage> decodeNextVideoFrame();
00500 
00502     //
00505     BufferedAudioStreamer::CursoredBuffer* decodeNextAudioFrame();
00506 
00510     void pushDecodedAudioFrames(boost::uint32_t ts);
00511 
00513     //
00522     std::auto_ptr<image::GnashImage> getDecodedVideoFrame(boost::uint32_t ts);
00523 
00524     DecodingState decodingStatus(DecodingState newstate = DEC_NONE);
00525 
00529     void parseNextChunk();
00530 
00531     DecodingState _decoding_state;
00532 
00533     // Mutex protecting _playback_state and _decoding_state
00534     // (not sure a single one is appropriate)
00535     boost::mutex _state_mutex;
00536     
00538     std::auto_ptr<media::VideoDecoder> _videoDecoder;
00539 
00541     bool _videoInfoKnown;
00542 
00544     std::auto_ptr<media::AudioDecoder> _audioDecoder;
00545 
00547     bool _audioInfoKnown;
00548 
00550     boost::scoped_ptr<InterruptableVirtualClock> _playbackClock;
00551 
00553     PlayHead _playHead;
00554 
00555     // Current sound handler
00556     sound::sound_handler* _soundHandler;
00557 
00558     // Current media handler
00559     media::MediaHandler* _mediaHandler;
00560 
00562     //
00566     std::auto_ptr<IOChannel> _inputStream;
00567 
00569     BufferedAudioStreamer _audioStreamer;
00570 
00572     StatusCode _statusCode;
00573 
00575     boost::mutex statusMutex;
00576 
00577 };
00578 
00579 void netstream_class_init(as_object& global, const ObjectURI& uri);
00580 
00581 void registerNetStreamNative(as_object& global);
00582 
00583 } // gnash namespace
00584 
00585 #endif
00586