Gnash  0.8.10
NetStream_as.h
Go to the documentation of this file.
00001 // 
00002 //   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
00003 //   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 _bufferTime; }
00273 
00275     long bytesLoaded();
00276 
00278     //
00281     long bytesTotal();
00282 
00285     //
00289     long bufferLength();
00290 
00292     //
00296     std::auto_ptr<image::GnashImage> get_video();
00297     
00299     void setInvalidatedVideo(DisplayObject* ch)
00300     {
00301         _invalidatedVideoCharacter = ch;
00302     }
00303 
00304     virtual void markReachableResources() const;
00305 
00307     //
00313     static unsigned int audio_streamer(void *udata, boost::int16_t* samples,
00314             unsigned int nSamples, bool& eof);
00315 
00316 private:
00317     
00319     enum StatusCode {
00320     
00321         // Internal status, not a valid ActionScript value
00322         invalidStatus,
00323 
00325         bufferEmpty,
00326 
00328         bufferFull,
00329 
00331         bufferFlush,
00332 
00334         playStart,
00335 
00337         playStop,
00338 
00340         seekNotify,
00341 
00343         streamNotFound,
00344 
00346         invalidTime
00347     };
00348 
00349     enum DecodingState {
00350         DEC_NONE,
00351         DEC_STOPPED,
00352         DEC_DECODING,
00353         DEC_BUFFERING
00354     };
00355 
00356     typedef std::pair<std::string, std::string> NetStreamStatus;
00357 
00359     //
00363     void getStatusCodeInfo(StatusCode code, NetStreamStatus& info);
00364 
00366     as_object* getStatusObject(StatusCode code);
00367 
00369     //
00372     void initVideoDecoder(const media::VideoInfo& info);
00373 
00375     //
00378     void initAudioDecoder(const media::AudioInfo& parser);
00379 
00380     // Setups the playback
00381     bool startPlayback();
00382 
00383     // Pauses the playhead 
00384     //
00385     // Users:
00386     //  - ::decodeFLVFrame() 
00387     //  - ::pause() 
00388     //  - ::play() 
00389     //
00390     void pausePlayback();
00391 
00392     // Resumes the playback 
00393     //
00394     // Users:
00395     //  - ::av_streamer() 
00396     //  - ::play() 
00397     //  - ::startPlayback() 
00398     //  - ::advance() 
00399     //
00400     void unpausePlayback();
00401 
00403     //
00416     void refreshVideoFrame(bool alsoIfPaused = false);
00417 
00420     void refreshAudioBuffer();
00421 
00423     //
00426     std::auto_ptr<image::GnashImage> decodeNextVideoFrame();
00427 
00429     //
00432     BufferedAudioStreamer::CursoredBuffer* decodeNextAudioFrame();
00433 
00437     void pushDecodedAudioFrames(boost::uint32_t ts);
00438 
00440     //
00449     std::auto_ptr<image::GnashImage> getDecodedVideoFrame(boost::uint32_t ts);
00450 
00451     DecodingState decodingStatus(DecodingState newstate = DEC_NONE);
00452 
00456     void parseNextChunk();
00457 
00459     //
00476     void setStatus(StatusCode code);
00477 
00481     //
00488     void processStatusNotifications();
00489 
00491     void stopAdvanceTimer();
00492 
00494     void startAdvanceTimer();
00495 
00496     NetConnection_as* _netCon;
00497 
00498     boost::scoped_ptr<CharacterProxy> _audioController;
00499     
00500     // The size of the buffer in milliseconds
00501     boost::uint32_t _bufferTime;
00502 
00503     // Mutex to insure we don't corrupt the image
00504     boost::mutex image_mutex;
00505 
00506     // The image/videoframe which is given to the renderer
00507     std::auto_ptr<image::GnashImage> _imageframe;
00508 
00509     // The video URL
00510     std::string url;
00511 
00512     // The input media parser
00513     std::auto_ptr<media::MediaParser> _parser;
00514 
00515     // The position in the inputfile, only used when not playing a FLV
00516     long _inputPos;
00517 
00519     DisplayObject* _invalidatedVideoCharacter;
00520 
00521     DecodingState _decoding_state;
00522 
00523     // Mutex protecting _playback_state and _decoding_state
00524     // (not sure a single one is appropriate)
00525     boost::mutex _state_mutex;
00526     
00528     std::auto_ptr<media::VideoDecoder> _videoDecoder;
00529 
00531     bool _videoInfoKnown;
00532 
00534     std::auto_ptr<media::AudioDecoder> _audioDecoder;
00535 
00537     bool _audioInfoKnown;
00538 
00540     boost::scoped_ptr<InterruptableVirtualClock> _playbackClock;
00541 
00543     PlayHead _playHead;
00544 
00545     // Current sound handler
00546     sound::sound_handler* _soundHandler;
00547 
00548     // Current media handler
00549     media::MediaHandler* _mediaHandler;
00550 
00552     //
00556     std::auto_ptr<IOChannel> _inputStream;
00557 
00559     BufferedAudioStreamer _audioStreamer;
00560 
00562     StatusCode _statusCode;
00563 
00565     boost::mutex _statusMutex;
00566 
00567 };
00568 
00569 void netstream_class_init(as_object& global, const ObjectURI& uri);
00570 
00571 void registerNetStreamNative(as_object& global);
00572 
00573 } // gnash namespace
00574 
00575 #endif
00576