gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] gnash/server/asobj NetStream.cpp NetStream.h


From: Vitaly Alexeev
Subject: [Gnash-commit] gnash/server/asobj NetStream.cpp NetStream.h
Date: Fri, 24 Nov 2006 10:38:26 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Vitaly Alexeev <alexeev>        06/11/24 10:38:26

Modified files:
        server/asobj   : NetStream.cpp NetStream.h 

Log message:
                * backend\render_handler_ogl.cpp: added "class YUV_video_ogl_NV"
                that uses opengl extensions for fast video rendering
                * server\swf\tag_loaders.cpp: fixed case of "sound_id < 0"
                * server\button_character_instance.cpp: fixed case of "sound_id 
< 0"
                * backend\sound_handler_sdl.cpp: sound is stereo now
                * server\asobj\NetStream (cpp, h): added "pause" & fixed bugs, 
                video is tested on FC4
                * win32\VC8\gnash.vcproj: added server\am dir
                * testsuite\samples\player.swf: added pause

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/NetStream.cpp?cvsroot=gnash&r1=1.17&r2=1.18
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/NetStream.h?cvsroot=gnash&r1=1.13&r2=1.14

Patches:
Index: NetStream.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/NetStream.cpp,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -b -r1.17 -r1.18
--- NetStream.cpp       8 Nov 2006 15:55:48 -0000       1.17
+++ NetStream.cpp       24 Nov 2006 10:38:26 -0000      1.18
@@ -18,7 +18,7 @@
 //
 //
 
-/* $Id: NetStream.cpp,v 1.17 2006/11/08 15:55:48 alexeev Exp $ */
+/* $Id: NetStream.cpp,v 1.18 2006/11/24 10:38:26 alexeev Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -34,9 +34,9 @@
 
 #if defined(_WIN32) || defined(WIN32)
        #include <Windows.h>    // for sleep()
-       #define sleep Sleep
+       #define usleep(x) Sleep(x/1000)
 #else
-  #include "unistd.h" // for sleep()
+  #include "unistd.h" // for usleep()
 #endif
 
 namespace gnash {
@@ -60,7 +60,9 @@
 #endif
        m_go(false),
        m_yuv(NULL),
-       m_video_clock(0)
+       m_video_clock(0),
+       m_pause(false),
+       m_unqueued_data(NULL)
 {
 }
 
@@ -69,6 +71,28 @@
        close();
 }
 
+// called from avstreamer thread
+void NetStream::set_status(const char* code)
+{
+       if (m_netstream_object)
+       {
+//             m_netstream_object->set_member("onStatus_Code", code);
+//             push_video_event(m_netstream_object);
+       }
+}
+
+void NetStream::pause(int mode)
+{
+       if (mode == -1)
+       {
+               m_pause = ! m_pause;
+       }
+       else
+       {
+               m_pause = (mode == 0) ? true : false;
+       }
+}
+
 void NetStream::close()
 {
        if (m_go)
@@ -145,7 +169,7 @@
 #ifdef USE_FFMPEG
 
        // Is it already playing ?
-       if (m_FormatCtx)
+       if (m_go)
        {
                return 0;
        }
@@ -156,9 +180,11 @@
        // The last three parameters specify the file format, buffer size and 
format parameters;
        // by simply specifying NULL or 0 we ask libavformat to auto-detect the 
format 
        // and use a default buffer size
+
        if (av_open_input_file(&m_FormatCtx, c_url, NULL, 0, NULL) != 0)
        {
          log_error("Couldn't open file '%s'", c_url);
+               set_status("NetStream.Play.StreamNotFound");
                return -1;
        }
 
@@ -169,16 +195,17 @@
     log_error("Couldn't find stream information from '%s'", c_url);
                return -1;
        }
-       m_FormatCtx->pb.eof_reached = 0;
 
-       av_read_play(m_FormatCtx);
+//     m_FormatCtx->pb.eof_reached = 0;
+//     av_read_play(m_FormatCtx);
 
        // Find the first video & audio stream
        m_video_index = -1;
        m_audio_index = -1;
        for (int i = 0; i < m_FormatCtx->nb_streams; i++)
        {
-               AVCodecContext *enc = m_FormatCtx->streams[i]->codec;
+               AVCodecContext* enc = m_FormatCtx->streams[i]->codec; 
+
                switch (enc->codec_type)
                {
                        case CODEC_TYPE_AUDIO:
@@ -196,6 +223,10 @@
                                        m_video_stream = 
m_FormatCtx->streams[i];
                                }
                                break;
+                       case CODEC_TYPE_DATA:
+                       case CODEC_TYPE_SUBTITLE:
+                       case CODEC_TYPE_UNKNOWN:
+                               break;
     }
        }
 
@@ -229,7 +260,6 @@
        // Determine required buffer size and allocate buffer
        m_yuv = render::create_YUV_video(m_VCodecCtx->width,    
m_VCodecCtx->height);
 
-
        sound_handler* s = get_sound_handler();
        if (m_audio_index >= 0 && s != NULL)
        {
@@ -255,13 +285,17 @@
 
        }
 
-#endif
+       m_pause = false;
 
        if (pthread_create(&m_thread, NULL, NetStream::av_streamer, this) != 0)
        {
                return -1;
        };
 
+#else
+       log_error("FFMPEG is needed to play video");
+#endif
+
        return 0;
 }
 
@@ -269,21 +303,38 @@
 void* NetStream::av_streamer(void* arg)
 {
        NetStream* ns = static_cast<NetStream*>(arg);
-       raw_videodata_t* unqueued_data = NULL;
+       ns->set_status("NetStream.Play.Start");
+
        raw_videodata_t* video = NULL;
 
        ns->m_video_clock = 0;
 
        int delay = 0;
-       double start_clock = tu_timer::ticks_to_seconds(tu_timer::get_ticks());
+       ns->m_start_clock = tu_timer::ticks_to_seconds(tu_timer::get_ticks());
        ns->m_go = true;
+       ns->m_unqueued_data = NULL;
        while (ns->m_go)
        {
-               unqueued_data = ns->read_frame(unqueued_data);
+               if (ns->m_pause)
+               {
+                       double t = 
tu_timer::ticks_to_seconds(tu_timer::get_ticks());
+                       usleep(100000);
+                       ns->m_start_clock += 
tu_timer::ticks_to_seconds(tu_timer::get_ticks()) - t;
+                       continue;
+               }
+
+               if (ns->read_frame() == false)
+               {
+                       if (ns->m_qvideo.size() == 0)
+                       {
+                               break;
+                       }
+               }
+
                if (ns->m_qvideo.size() > 0)
                {
                        video = ns->m_qvideo.front();
-                       double clock = 
tu_timer::ticks_to_seconds(tu_timer::get_ticks()) - start_clock;
+                       double clock = 
tu_timer::ticks_to_seconds(tu_timer::get_ticks()) - ns->m_start_clock;
                        double video_clock = video->m_pts;
 
                        if (clock >= video_clock)
@@ -295,26 +346,20 @@
                        }
                        else
                        {
-                               delay = int(1000 * (video_clock - clock));
+                               delay = int(video_clock - clock);
                        }
 
                        // Don't hog the CPU.
                        // Queues have filled, video frame have shown
                        // now it is possible and to have a rest
-                       if (unqueued_data && delay > 0)
+                       if (ns->m_unqueued_data && delay > 0)
                        {
-                               sleep(delay);
-                       }
-
+                               usleep(delay);
                }
-               else
-               if (ns->m_qaudio.size() == 0)
-               {
-                       // video & audio queues are empty
-                       // video is shown
-                       break;
                }
        }
+
+       ns->set_status("NetStream.Play.Stop");
        return 0;
 }
 
@@ -342,62 +387,65 @@
        }
 }
 
-raw_videodata_t* NetStream::read_frame(raw_videodata_t* unqueued_data)
+bool NetStream::read_frame()
 {
-       raw_videodata_t* ret = NULL;
-       if (unqueued_data)
+//     raw_videodata_t* ret = NULL;
+       if (m_unqueued_data)
        {
-               if (unqueued_data->m_stream_index == m_audio_index)
+               if (m_unqueued_data->m_stream_index == m_audio_index)
                {
                        sound_handler* s = get_sound_handler();
                        if (s)
                        {
-                               ret = m_qaudio.push(unqueued_data) ? NULL : 
unqueued_data;
+                               m_unqueued_data = 
m_qaudio.push(m_unqueued_data) ? NULL : m_unqueued_data;
                        }
                }
                else
+               if (m_unqueued_data->m_stream_index == m_video_index)
                {
-                       ret = m_qvideo.push(unqueued_data) ? NULL : 
unqueued_data;
+                       m_unqueued_data = m_qvideo.push(m_unqueued_data) ? NULL 
: m_unqueued_data;
+               }
+               else
+               {
+                       printf("read_frame: not audio & video stream\n");
                }
 
-               return ret;
+               return true;
        }
 
 #ifdef USE_FFMPEG
 
        AVPacket packet;
-       if (av_read_frame(m_FormatCtx, &packet) >= 0)
+       int rc = av_read_frame(m_FormatCtx, &packet);
+       if (rc >= 0)
        {
                if (packet.stream_index == m_audio_index)
                {
-                       int frame_size;
-                       uint8_t* ptr = (uint8_t*) 
malloc((AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2);
-                 if (avcodec_decode_audio(m_ACodecCtx, (int16_t *)ptr, 
&frame_size, packet.data, packet.size) >= 0)
-                       {
                                sound_handler* s = get_sound_handler();
                                if (s)
                                {
+                               int frame_size;
+                               uint8_t* ptr = (uint8_t*) 
malloc((AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2);
+                               if (avcodec_decode_audio(m_ACodecCtx, 
(int16_t*) ptr, &frame_size, packet.data, packet.size) >= 0)
+                               {
 
                                        int16_t*        adjusted_data = 0;
                                        int n = 0;
 
                                        bool stereo = m_ACodecCtx->channels > 1 
? true : false;
-                                       s->convert_raw_data(&adjusted_data, &n, 
ptr, frame_size >> 1, 2, m_ACodecCtx->sample_rate, stereo);
-                           raw_videodata_t* samples = new raw_videodata_t;
-                                       samples->m_data = (uint8_t*) 
adjusted_data;
-                                       samples->m_ptr = samples->m_data;
-                                       samples->m_size = n;
-                                       samples->m_stream_index = m_audio_index;
-
-//                                     samples->m_pts = m_audio_clock;
-//                                     n = 2 * m_audio_stream->codec->channels;
-//                                     m_audio_clock += (double) frame_size / 
(double)(n * m_audio_stream->codec->sample_rate);
+                                       int samples = stereo ? frame_size >> 2 
: frame_size >> 1;
+                                       s->convert_raw_data(&adjusted_data, &n, 
ptr, samples, 2, m_ACodecCtx->sample_rate, stereo);
+                           raw_videodata_t* raw = new raw_videodata_t;
+                                       raw->m_data = (uint8_t*) adjusted_data;
+                                       raw->m_ptr = raw->m_data;
+                                       raw->m_size = n;
+                                       raw->m_stream_index = m_audio_index;
 
-                                       ret = m_qaudio.push(samples) ? NULL : 
samples;
-                               }
+                                       m_unqueued_data = m_qaudio.push(raw) ? 
NULL : raw;
                        }
                        free(ptr);
                }
+               }
                else
                if (packet.stream_index == m_video_index)
                {
@@ -458,15 +506,18 @@
                                        }
                                }
                                video->m_size = copied;
-                               ret = m_qvideo.push(video) ? NULL : video;
+                               m_unqueued_data = m_qvideo.push(video) ? NULL : 
video;
                        }
                }
                av_free_packet(&packet);
        }
-
+       else
+       {
+               return false;
+       }
 #endif
 
-       return ret;
+       return true;
 }
 
 
@@ -508,8 +559,18 @@
        ns->obj.close();
 }
 
-void netstream_pause(const fn_call& /*fn*/) {
-    log_msg("%s:unimplemented \n", __FUNCTION__);
+void netstream_pause(const fn_call& fn)
+{
+       assert(dynamic_cast<netstream_as_object*>(fn.this_ptr));
+       netstream_as_object* ns = 
static_cast<netstream_as_object*>(fn.this_ptr);
+       
+       // mode: -1 ==> toogle, 0==> pause, 1==> play
+       int mode = -1;
+       if (fn.nargs > 0)
+       {
+               mode = fn.arg(0).to_bool() ? 0 : 1;
+       }
+       ns->obj.pause(mode);    // toggle mode
 }
 
 void netstream_play(const fn_call& fn)

Index: NetStream.h
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/NetStream.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -b -r1.13 -r1.14
--- NetStream.h 3 Nov 2006 16:10:26 -0000       1.13
+++ NetStream.h 24 Nov 2006 10:38:26 -0000      1.14
@@ -18,7 +18,7 @@
 //
 //
 
-/*  $Id: NetStream.h,v 1.13 2006/11/03 16:10:26 nihilus Exp $ */
+/*  $Id: NetStream.h,v 1.14 2006/11/24 10:38:26 alexeev Exp $ */
 
 #ifndef __NETSTREAM_H__
 #define __NETSTREAM_H__
@@ -75,12 +75,14 @@
 
     ~multithread_queue()
                {
+                       lock();
                        while (m_queue.size() > 0)
                        {
                                T x = m_queue.front();
                                m_queue.pop();
                                delete x;
                        }
+                       unlock();
 
                        pthread_mutex_destroy(&m_mutex);
                }
@@ -97,7 +99,7 @@
                {
                        bool rc = false;
                        lock();
-                       if (m_queue.size() < 40)        // hack
+                       if (m_queue.size() < 20)        // hack
                        {
                                m_queue.push(member);
                                rc = true;
@@ -144,17 +146,20 @@
                std::queue < T > m_queue;
 };
 
+class netstream_as_object;
+
 class NetStream {
 public:
     NetStream();
     ~NetStream();
    void close();
-   void pause();
+       void pause(int mode);
    int play(const char* source);
    void seek();
    void setBufferTime();
+       void set_status(const char* code);
 
-        raw_videodata_t* read_frame(raw_videodata_t* vd);
+       bool read_frame();
         YUV_video* get_video();
 
         inline bool playing()
@@ -162,6 +167,11 @@
                 return m_go;
         }
 
+        inline void set_parent(netstream_as_object* ns)
+        {
+                m_netstream_object = ns;
+        }
+
 #ifdef USE_FFMPEG
        inline double as_double(AVRational time)
        {
@@ -202,12 +212,29 @@
                pthread_t m_thread;
                multithread_queue <raw_videodata_t*> m_qaudio;
                multithread_queue <raw_videodata_t*> m_qvideo;
+               bool m_pause;
+               double m_start_clock;
+               netstream_as_object* m_netstream_object;
+               raw_videodata_t* m_unqueued_data;
 };
 
 class netstream_as_object : public as_object
 {
-public:
+       public:
+       
+       netstream_as_object()
+       {
+               obj.set_parent(this);
+       }
+
+       ~netstream_as_object()
+       {
+       }
+
     NetStream obj;
+
+//     virtual void set_member(const tu_stringi& name, const as_value& val);
+//     virtual bool get_member(const tu_stringi& name, as_value* val);
 };
 
 void netstream_new(const fn_call& fn);




reply via email to

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