OSDN Git Service

[Qt][OSD][MOVIE_SAVER] Maybe correctness frame(s) counting with 60fps ヽ(=´▽=)ノ
authorK.Ohta <whatisthis.sowhat@gmail.com>
Mon, 15 Aug 2016 14:29:58 +0000 (23:29 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Mon, 15 Aug 2016 14:29:58 +0000 (23:29 +0900)
[MOVIE_SAVER] Fix sometimes crashing when stop to save movie.
[GENERAL] Update SO versions.

source/src/qt/CMakeLists.txt
source/src/qt/avio/CMakeLists.txt
source/src/qt/avio/movie_saver.cpp
source/src/qt/avio/movie_saver.h
source/src/qt/avio/movie_saver_audio.cpp
source/src/qt/avio/movie_saver_fileio.cpp
source/src/qt/common/qt_utils.cpp
source/src/qt/osd_base.h
source/src/qt/osd_screen.cpp

index 563e310..3e40df1 100644 (file)
@@ -64,8 +64,8 @@ target_link_libraries(CSPosd PUBLIC
          )
   
   set_target_properties(CSPosd PROPERTIES 
-     SOVERSION 2.1.1
-     VERSION 2.1.1
+     SOVERSION 2.2.0
+     VERSION 2.2.0
   )
   INSTALL(TARGETS CSPosd DESTINATION ${LIBCSP_INSTALL_DIR})
 endif()
index 4a0fda2..f81ff6e 100644 (file)
@@ -61,8 +61,8 @@ target_link_libraries(CSPavio PUBLIC
          )
 
 set_target_properties(CSPavio PROPERTIES 
-                            SOVERSION 2.2.1
-                            VERSION 2.2.1
+                            SOVERSION 2.3.0
+                            VERSION 2.3.0
                             )
 INSTALL(TARGETS CSPavio DESTINATION ${LIBCSP_INSTALL_DIR})
 endif()
index 52dfea3..19bc1bc 100644 (file)
@@ -50,7 +50,7 @@ MOVIE_SAVER::MOVIE_SAVER(int width, int height, int fps, OSD *osd, config_t *cfg
        video_geometry = QSize(640, 480);
        video_encode_threads = 4;
 //     audio_enqueue_count = 0;
-
+       left_frames = 0;
        req_close = false;
        req_stop = false;
        bRunThread = false;
@@ -115,16 +115,16 @@ void MOVIE_SAVER::log_packet(const void *_fmt_ctx, const void *_pkt)
 }
 
 
-void MOVIE_SAVER::enqueue_video(QImage *p)
+void MOVIE_SAVER::enqueue_video(int frames, int width, int height, QImage *p)
 {
 #if defined(USE_MOVIE_SAVER)
        if(!recording) return;
        if(p == NULL) return;
        if(req_stop) return;
        uint32_t *pq;
-       QImage *pp = new QImage(*p);
-       //AGAR_DebugLog(AGAR_LOG_DEBUG, "Movie: Enqueue video data %d bytes %dx%d", pp->byteCount(), pp->width(), pp->height());
-       video_data_queue.enqueue(pp);
+       VIDEO_DATA *px = new VIDEO_DATA(frames, width, height, p);
+       //AGAR_DebugLog(AGAR_LOG_DEBUG, "Movie: Enqueue video data %dx%d %d bytes %dx%d", width, height, p->byteCount(), p->width(), p->height());
+       video_data_queue.enqueue(px);
 #endif   
 }
 
@@ -133,24 +133,29 @@ bool MOVIE_SAVER::dequeue_video(uint32_t *p)
        //if(!recording) return false;
        if(p == NULL) return false;
 
-       QImage *pp = video_data_queue.dequeue();
+       VIDEO_DATA *pp = video_data_queue.dequeue();
 #if defined(USE_MOVIE_SAVER)
        if(pp == NULL) return false;
        int y;
        int x;
        uint32_t *pq;
-       for(y = 0; y < _height; y++) {
-               if(y >= pp->height()) break;
-               pq = (uint32_t *)(pp->constScanLine(y));
-               memcpy(&(p[_width * y]), pq, ((_width * sizeof(uint32_t)) > pp->bytesPerLine()) ? pp->bytesPerLine() : _width * sizeof(uint32_t));
+       QImage *pp_i = &(pp->frame_data);
+       left_frames = pp->frames;
+       _width = pp->_width;
+       _height = pp->_height;
+       if((left_frames > 0) && (pp_i != NULL)){ 
+               for(y = 0; y < _height; y++) {
+                       if(y >= pp_i->height()) break;
+                       pq = (uint32_t *)(pp_i->constScanLine(y));
+                       memcpy(&(p[_width * y]), pq, ((_width * sizeof(uint32_t)) > pp_i->bytesPerLine()) ? pp_i->bytesPerLine() : _width * sizeof(uint32_t));
+               }
+               video_size = _width * y;
+               //AGAR_DebugLog(AGAR_LOG_DEBUG, "Movie: Dequeue video data %d bytes", pp->byteCount());
        }
-       video_size = _width * y;
-       //AGAR_DebugLog(AGAR_LOG_DEBUG, "Movie: Dequeue video data %d bytes", pp->byteCount());
 #else
        video_size = 0;
 #endif   
        if(pp != NULL) delete pp;
-       
        return true;
 }
 
@@ -222,6 +227,7 @@ void MOVIE_SAVER::run()
        n_encode_video = 0;
        req_close = false;
        req_stop = false;
+       left_frames = 0;
        while(bRunThread) {
                if(recording) {
                        if(!bRunThread) break;
@@ -236,7 +242,8 @@ void MOVIE_SAVER::run()
                                audio_count = 0;
                                req_close = false;
                                req_stop = false;
-                               printf("*\n");
+                               //printf("*\n");
+                               left_frames = 0;
                                if(!do_open_main()) {
                                        recording = false;
                                        goto _next_turn;
@@ -258,7 +265,8 @@ void MOVIE_SAVER::run()
                                v_f = video_data_queue.isEmpty();
                                if(v_f)
                                        goto _write_frame;
-                               dequeue_video(video_frame_buf);
+                               if(left_frames <= 0) dequeue_video(video_frame_buf);
+                               left_frames--;
                                video_remain = video_size;
                                video_offset = 0;
                                need_video_transcode = true;
index a4f9309..483fcd4 100644 (file)
@@ -14,6 +14,7 @@
 #include <QStringList>
 #include <QThread>
 #include <QSize>
+#include <QImage>
 #include "config.h"
 
 #if defined(USE_LIBAV)
@@ -74,6 +75,22 @@ typedef struct OutputStream {
 class OSD;
 
 QT_BEGIN_NAMESPACE
+class VIDEO_DATA {
+
+public:
+       int frames;
+       int _width;
+       int _height;
+       QImage frame_data;
+       VIDEO_DATA(int n_frames, int width, int height, QImage *pp) {
+               frame_data = QImage(*pp);
+               frames = n_frames;
+               _width = width;
+               _height = height;
+       };
+       ~VIDEO_DATA() {};
+};
+
 class MOVIE_SAVER: public QThread
 {
        Q_OBJECT
@@ -129,11 +146,12 @@ protected:
        uint64_t totalSrcFrame;
        uint64_t totalDstFrame;
        uint64_t totalAudioFrame;
-
+       int left_frames;
+       
        int16_t audio_frame_buf[2 * 48000 * sizeof(int16_t)]; // 1Sec
        uint32_t video_frame_buf[1280 * 1024 * sizeof(uint32_t)]; // 1 frame : right?
 
-       QQueue<QImage *> video_data_queue;
+       QQueue<VIDEO_DATA *> video_data_queue;
        QQueue<QByteArray *> audio_data_queue;
        int64_t audio_remain;
        int64_t video_remain;
@@ -201,7 +219,7 @@ public:
 
 public slots:
        void run();
-       void enqueue_video(QImage *p);
+       void enqueue_video(int frames, int width, int height, QImage *p);
        void enqueue_audio(int16_t *p, int size);
        void do_close();
        void do_open(QString filename, int _fps, int sample_rate);
index 94c40d5..4a75ed9 100644 (file)
@@ -190,7 +190,8 @@ int MOVIE_SAVER::write_audio_frame()
 
        frame_src = (AVFrame *)get_audio_frame();
        //if(req_close) return 1;
-       if (frame_src) {
+       if (frame_src == NULL) return 0;
+       {
                /* convert samples from native format to destination codec format, using the resampler */
                /* compute destination number of samples */
                dst_nb_samples = av_rescale_rnd(swr_get_delay(ost->swr_ctx, c->sample_rate) + frame_src->nb_samples,
index 429bf91..6f70d95 100644 (file)
@@ -337,7 +337,8 @@ void MOVIE_SAVER::do_close_main()
                        {
                                v_f = video_data_queue.isEmpty();
                                if(!v_f) {
-                                       dequeue_video(video_frame_buf);
+                                       if(left_frames <= 0) dequeue_video(video_frame_buf);
+                                       left_frames--;
                                        video_remain = video_size;
                                        video_offset = 0;
                                }
@@ -395,9 +396,9 @@ void MOVIE_SAVER::do_close_main()
        audio_data_queue.clear();
 
        while(!video_data_queue.isEmpty()) {
-               QImage *pp = video_data_queue.dequeue();
+               VIDEO_DATA *pp = video_data_queue.dequeue();
                if(pp != NULL) {
-                       leftq_v++;
+                       if(pp->frames >= 0) leftq_v += pp->frames;
                        delete pp;
                }
        }
index 0ae185a..bd5e5d1 100644 (file)
@@ -342,7 +342,8 @@ void Ui_MainWindow::LaunchEmuThread(void)
        connect(emu->get_osd(), SIGNAL(sig_movie_set_height(int)), hSaveMovieThread, SLOT(do_set_height(int)));
    
        connect(emu->get_osd(), SIGNAL(sig_enqueue_audio(int16_t*, int)), hSaveMovieThread, SLOT(enqueue_audio(int16_t *, int)));
-       connect(emu->get_osd(), SIGNAL(sig_enqueue_video(QImage *)), hSaveMovieThread, SLOT(enqueue_video(QImage *)));
+       connect(emu->get_osd(), SIGNAL(sig_enqueue_video(int, int, int, QImage *)),
+                       hSaveMovieThread, SLOT(enqueue_video(int, int, int, QImage *)));
        connect(glv->extfunc, SIGNAL(sig_push_image_to_movie(QImage *)), hSaveMovieThread, SLOT(enqueue_video(QImage *)));
        connect(this, SIGNAL(sig_quit_movie_thread()), hSaveMovieThread, SLOT(do_exit()));
 
index 0927733..0f554c1 100644 (file)
@@ -144,7 +144,7 @@ protected:
        int base_window_width, base_window_height;
        int vm_screen_width, vm_screen_height;
        int draw_screen_width, draw_screen_height;
-       int64_t rec_video_nsec, rec_video_fps_nsec;
+       int rec_video_nsec, rec_video_fps_nsec;
        
        _TCHAR video_file_name[_MAX_PATH];
        int rec_video_fps;
@@ -438,7 +438,7 @@ signals:
        int sig_resize_vm_screen(QImage *, int, int);
        int sig_put_string_debugger(QString);
        int sig_console_input_string(QString);
-       int sig_enqueue_video(QImage *); 
+       int sig_enqueue_video(int, int, int, QImage *); 
        int sig_enqueue_audio(int16_t *data, int size);
        int sig_movie_set_width(int);
        int sig_movie_set_height(int);
index 6eff366..97ab9d2 100644 (file)
@@ -62,8 +62,8 @@ void OSD_BASE::set_vm_screen_size(int screen_width, int screen_height, int windo
                vm_window_height_aspect = window_height_aspect;
                
                // change the window size
-               emit sig_movie_set_width(screen_width);
-               emit sig_movie_set_height(screen_height);
+               //emit sig_movie_set_width(screen_width);
+               //emit sig_movie_set_height(screen_height);
                emit sig_resize_vm_screen(&(vm_screen_buffer.pImage), screen_width, screen_height);
        }
 }
@@ -93,8 +93,8 @@ int OSD_BASE::draw_screen()
        screen_mutex->lock();
        lock_vm();
        if(vm_screen_buffer.width != vm_screen_width || vm_screen_buffer.height != vm_screen_height) {
-               emit sig_movie_set_width(vm_screen_width);
-               emit sig_movie_set_height(vm_screen_height);
+               //emit sig_movie_set_width(vm_screen_width);
+               //emit sig_movie_set_height(vm_screen_height);
                initialize_screen_buffer(&vm_screen_buffer, vm_screen_width, vm_screen_height, 0);
        }
        this->vm_draw_screen();
@@ -148,8 +148,8 @@ void OSD_BASE::initialize_screen_buffer(bitmap_t *buffer, int width, int height,
        QColor fillcolor;
        fillcolor.setRgb(0, 0, 0, 255);
        buffer->pImage.fill(fillcolor);
-       emit sig_movie_set_width(width);
-       emit sig_movie_set_height(height);
+       //emit sig_movie_set_width(width);
+       //emit sig_movie_set_height(height);
        emit sig_resize_vm_screen(&(buffer->pImage), width, height);
 }
 
@@ -186,7 +186,7 @@ bool OSD_BASE::start_record_video(int fps)
 {
        if(fps > 0) {
                rec_video_fps = fps;
-               rec_video_fps_nsec = (uint64_t)(1.0e9 / (double)fps);
+               rec_video_fps_nsec = (int)(1.0e9 / (double)fps);
                rec_video_nsec = 0;
        }
 
@@ -226,7 +226,8 @@ void OSD_BASE::restart_record_video()
 void OSD_BASE::add_extra_frames(int extra_frames)
 {
        //rec_video_run_frames += extra_frames;
-       rec_video_nsec += (int64_t)(1.0e9 / vm_frame_rate()) * (int64_t)extra_frames;
+       rec_video_nsec += ((int)(1.0e9 / vm_frame_rate()) * extra_frames);
+       if(rec_video_nsec < 0) rec_video_nsec = 0;
        //emit sig_send_wxita_frames(extra_frames);
 }
 
@@ -300,7 +301,7 @@ int OSD_BASE::add_video_frames()
        int counter = 0;
        static double prev_vm_fps = -1;
        double vm_fps = vm_frame_rate();
-       int64_t delta_ns = (int64_t)(1.0e9 / vm_fps);
+       int delta_ns = (int)(1.0e9 / vm_fps);
        if(rec_video_fps_nsec >= delta_ns) {
                rec_video_nsec += delta_ns;
                while(rec_video_nsec >= rec_video_fps_nsec) {
@@ -308,14 +309,18 @@ int OSD_BASE::add_video_frames()
                        counter++;
                }
        } else {
-               rec_video_nsec = rec_video_nsec + delta_ns - rec_video_fps_nsec;
-               counter = 1;
-               while(rec_video_nsec > rec_video_fps_nsec) {
+               rec_video_nsec += delta_ns;
+               if(rec_video_nsec > (rec_video_fps_nsec * 2)) {
+                       rec_video_nsec -= rec_video_fps_nsec;
+               } else if(rec_video_nsec < (rec_video_fps_nsec * -2)) {
+                       rec_video_nsec += rec_video_fps_nsec;
+               }
+               while(rec_video_nsec >= rec_video_fps_nsec) {
                        counter++;
                        rec_video_nsec -= rec_video_fps_nsec;
                }
        }
-               
+       
        if(using_flags->is_use_one_board_computer()) {
                int size = vm_screen_buffer.pImage.byteCount();
                int i = counter;
@@ -340,20 +345,20 @@ int OSD_BASE::add_video_frames()
 #endif                         
                        }
                }
-               while(i > 0) {
+               if(i > 0) {
                        // Enqueue to frame.
-                       emit sig_enqueue_video(&rec_image_buffer);
-                       i--;
+                       emit sig_enqueue_video(i, background_image.width(), background_image.height(), &rec_image_buffer);
+                       //i--;
                }
        } else {
                int size = vm_screen_buffer.pImage.byteCount();
                int i = counter;
                // Rescaling
                QImage video_result = QImage(vm_screen_buffer.pImage);
-               while(i > 0) {
+               if(i > 0) {
                        // Enqueue to frame.
-                       emit sig_enqueue_video(&video_result);
-                       i--;
+                       emit sig_enqueue_video(i, vm_screen_width, vm_screen_height, &video_result);
+                       //i--;
                }
                //AGAR_DebugLog(AGAR_LOG_DEBUG, "Push Video %d frames\n", counter);
        }