gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] /srv/bzr/gnash/trunk r10075: Allow late hot-plugging of a


From: Sandro Santilli
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r10075: Allow late hot-plugging of audio and video streams for NetStream.
Date: Fri, 24 Oct 2008 15:29:22 +0200
User-agent: Bazaar (1.5)

------------------------------------------------------------
revno: 10075
committer: Sandro Santilli <address@hidden>
branch nick: trunk
timestamp: Fri 2008-10-24 15:29:22 +0200
message:
  Allow late hot-plugging of audio and video streams for NetStream.
  Should fix bug #24628 and bug #24540.
  Might also allow dropping the MediaParser probe completely, but
  can't tell until I take a look at the Sound class...
modified:
  libcore/asobj/NetStream_as.cpp
  libcore/asobj/NetStream_as.h
=== modified file 'libcore/asobj/NetStream_as.cpp'
--- a/libcore/asobj/NetStream_as.cpp    2008-10-23 14:23:04 +0000
+++ b/libcore/asobj/NetStream_as.cpp    2008-10-24 13:29:22 +0000
@@ -668,19 +668,6 @@
        _clockOffset = 0; // _clockSource->elapsed();
 }
 
-void
-PlayHead::init(bool hasVideo, bool hasAudio)
-{
-       boost::uint64_t now = _clockSource->elapsed();
-       if ( hasVideo ) _availableConsumers |= CONSUMER_VIDEO;
-       if ( hasAudio ) _availableConsumers |= CONSUMER_AUDIO;
-       _positionConsumers = 0;
-
-       _position = 0;
-       _clockOffset = now;
-       assert(now-_clockOffset == _position);
-}
-
 PlayHead::PlaybackStatus
 PlayHead::setState(PlaybackStatus newState)
 {
@@ -922,47 +909,47 @@
 }
 
 void
-NetStream_as::initVideoDecoder(media::MediaParser& parser)
+NetStream_as::initVideoDecoder(const media::VideoInfo& info)
 {
-       // Get video info from the parser
-       media::VideoInfo* videoInfo = parser.getVideoInfo();
-       if (!videoInfo) {
-               log_debug("No video in NetStream stream");
-               return;
-       }
-
        assert ( _mediaHandler ); // caller should check this
+       assert ( !_videoInfoKnown ); // caller should check this
+       assert ( !_videoDecoder.get() ); // caller should check this
+
+       _videoInfoKnown = true; 
 
        try {
-           _videoDecoder = _mediaHandler->createVideoDecoder(*videoInfo);
+           _videoDecoder = _mediaHandler->createVideoDecoder(info);
+            assert ( _videoDecoder.get() ); // PARANOIA_LEVEL ?
        }
        catch (MediaException& e) {
            log_error("NetStream: Could not create Video decoder: %s", 
e.what());
        }
 
+    log_debug("NetStream_as::initVideoDecoder: hot-plugging video consumer");
+    _playHead.setVideoConsumerAvailable();
 }
 
 
 /* private */
 void
-NetStream_as::initAudioDecoder(media::MediaParser& parser)
+NetStream_as::initAudioDecoder(const media::AudioInfo& info)
 {
-       // Get audio info from the parser
-       media::AudioInfo* audioInfo =  parser.getAudioInfo();
-       if (!audioInfo) {
-               log_debug("No audio in NetStream input");
-               return;
-       }
-
        assert ( _mediaHandler ); // caller should check this
+       assert ( !_audioInfoKnown ); // caller should check this
+       assert ( !_audioDecoder.get() ); // caller should check this
+
+       _audioInfoKnown = true; 
 
        try {
-           _audioDecoder = _mediaHandler->createAudioDecoder(*audioInfo);
+           _audioDecoder = _mediaHandler->createAudioDecoder(info);
+            assert ( _audioDecoder.get() ); // PARANOIA_LEVE ?
        }
        catch (MediaException& e) {
            log_error("Could not create Audio decoder: %s", e.what());
        }
 
+    log_debug("NetStream_as::initAudioDecoder: hot-plugging audio consumer");
+    _playHead.setAudioConsumerAvailable();
 }
 
 
@@ -1001,19 +988,11 @@
        // for stream contents.
        //
 
-       // The following sleep is a silly device for debugging
-       // http://savannah.gnu.org/bugs/index.php?24628
-       //sleep(2);
-
-       initVideoDecoder(*m_parser); 
-       initAudioDecoder(*m_parser); 
-
-       _playHead.init(_videoDecoder.get(), _audioDecoder.get());
-       _playHead.setState(PlayHead::PLAY_PLAYING);
-
        decodingStatus(DEC_BUFFERING);
        _playbackClock->pause(); // NOTE: should be paused already
 
+       _playHead.setState(PlayHead::PLAY_PLAYING);
+
        // Register ::advance callback
        startAdvanceTimer();
 
@@ -1407,16 +1386,19 @@
                }
 
                // case 2: here comes the audio !
-               _audioInfoKnown = true;
-
-               // TODO: try to create an AudioDecoder!
-
-               log_unimpl("NetStream_as::pushDecodedAudioFrames: just found 
new audio, "
-                       "should try to create an audio decoder "
-                       "and plug an audio consumer to PlayHead here."
-                       " See http://savannah.gnu.org/bugs/index.php?24540";);
-
-               return;
+
+               // try to create an AudioDecoder!
+               initAudioDecoder(*audioInfo);
+
+               // Don't go ahead if audio decoder construction failed
+               if ( ! _audioDecoder.get() )
+               {
+                       // TODO: we should still flush any existing Audio frame
+                       //       in the encoded queue...
+                       //       (or rely on next call)
+
+                       return; 
+               }
        }
 
        bool consumed = false;
@@ -1648,15 +1630,19 @@
                }
 
                // case 2: here comes the video !
-               _videoInfoKnown = true;
-
-               // TODO: try to create a videoDecoder!
-
-               log_unimpl("NetStream_as::refreshVideoFrame: just found new 
video, "
-                       "should try to create a video decoder "
-                       "and plug a video consumer to PlayHead here."
-                       " See http://savannah.gnu.org/bugs/index.php?24540";);
-               return;
+
+               // Try to initialize the video decoder 
+               initVideoDecoder(*videoInfo);
+
+               // Don't go ahead if video decoder construction failed
+               if ( ! _videoDecoder.get() )
+               {
+                       // TODO: we should still flush any existing Video frame
+                       //       in the encoded queue...
+                       //       (or rely on next call)
+
+                       return; 
+               }
 
        }
 
@@ -1811,6 +1797,7 @@
                        // reguardless bufferLength...
                        if ( ! m_imageframe.get() && _playHead.getState() != 
PlayHead::PLAY_PAUSED )
                        {
+                log_debug("refreshing video frame for the first time");
                                refreshVideoFrame(true);
                        }
 
@@ -1836,6 +1823,10 @@
        // up to current playhead
        refreshAudioBuffer();
 
+    // Advance PlayeHead position if current one was consumed
+    // by all available consumers
+    _playHead.advanceIfConsumed();
+
        // Process media tags
        m_parser->processTags(_playHead.getPosition(), this, getVM());
 }

=== modified file 'libcore/asobj/NetStream_as.h'
--- a/libcore/asobj/NetStream_as.h      2008-10-23 14:23:04 +0000
+++ b/libcore/asobj/NetStream_as.h      2008-10-24 13:29:22 +0000
@@ -80,15 +80,25 @@
        ///
        PlayHead(VirtualClock* clockSource);
 
-       /// Initialize playhead 
-       //
-       /// @param hasVideo
-       ///     Whether video consumer is available
-       ///
-       /// @param hasAudio
-       ///     Whether video consumer is available
-       ///
-       void init(bool hasVideo, bool hasAudio);
+    /// Set a video consumer as available
+    //
+    /// This should be completely fine to do during
+    /// PlayHead lifetime.
+    ///
+    void setVideoConsumerAvailable()
+    {
+        _availableConsumers |= CONSUMER_VIDEO;
+    }
+
+    /// Set an audio consumer as available
+    //
+    /// This should be completely fine to do during
+    /// PlayHead lifetime.
+    ///
+    void setAudioConsumerAvailable()
+    {
+        _availableConsumers |= CONSUMER_AUDIO;
+    }
 
        /// Get current playhead position (milliseconds)
        boost::uint64_t getPosition() { return _position; }
@@ -108,13 +118,10 @@
                return (_positionConsumers & CONSUMER_VIDEO);
        }
 
-       /// \brief
-       /// Mark current position as being consumed by video consumer,
-       /// advancing if needed
+       /// Mark current position as being consumed by video consumer
        void setVideoConsumed()
        {
                _positionConsumers |= CONSUMER_VIDEO;
-               advanceIfConsumed();
        }
 
        /// Return true if audio of current position have been consumed
@@ -123,13 +130,10 @@
                return (_positionConsumers & CONSUMER_AUDIO);
        }
 
-       /// \brief
-       /// Mark current position as being consumed by audio consumer,
-       /// advancing if needed.
+       /// Mark current position as being consumed by audio consumer
        void setAudioConsumed()
        {
                _positionConsumers |= CONSUMER_AUDIO;
-               advanceIfConsumed();
        }
 
        /// Change current position to the given time.
@@ -146,9 +150,7 @@
        ///
        void seekTo(boost::uint64_t position);
 
-private:
-
-       /// Advance position if all consumers consumed the current one
+       /// Advance position if all available consumers consumed the current one
        //
        /// Clock source will be used to determine the amount
        /// of milliseconds to advance position to.
@@ -161,6 +163,9 @@
        ///
        void advanceIfConsumed();
                
+
+private:
+
        /// Flags for consumers state
        enum ConsumerFlag {
                CONSUMER_VIDEO = 1,
@@ -501,17 +506,17 @@
                DEC_BUFFERING
        };
 
-       /// Gets video info from the parser and initializes _videoDecoder
+       /// Initialize video decoder and (if successful) PlayHead consumer 
        //
-       /// @param parser the parser to use to get video information.
+       /// @param info Video codec information
        ///
-       void initVideoDecoder(media::MediaParser& parser);
+       void initVideoDecoder(const media::VideoInfo& info);
 
-       /// Gets audio info from the parser and initializes _audioDecoder
+       /// Initialize audio decoder and (if successful) a PlayHead consumer 
        //
-       /// @param parser the parser to use to get audio information.
+       /// @param info Audio codec information
        ///
-       void initAudioDecoder(media::MediaParser& parser);
+       void initAudioDecoder(const media::AudioInfo& parser);
 
        DecodingState _decoding_state;
 


reply via email to

[Prev in Thread] Current Thread [Next in Thread]