Gnash 0.8.9
|
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