From: K.Ohta Date: Mon, 15 Aug 2016 14:29:58 +0000 (+0900) Subject: [Qt][OSD][MOVIE_SAVER] Maybe correctness frame(s) counting with 60fps ヽ(=´▽=)ノ X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=b85e1cb6051fe2bf2390ab2f74bebfddc7c69ba6;p=csp-qt%2Fcommon_source_project-fm7.git [Qt][OSD][MOVIE_SAVER] Maybe correctness frame(s) counting with 60fps ヽ(=´▽=)ノ [MOVIE_SAVER] Fix sometimes crashing when stop to save movie. [GENERAL] Update SO versions. --- diff --git a/source/src/qt/CMakeLists.txt b/source/src/qt/CMakeLists.txt index 563e3100e..3e40df1c1 100644 --- a/source/src/qt/CMakeLists.txt +++ b/source/src/qt/CMakeLists.txt @@ -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() diff --git a/source/src/qt/avio/CMakeLists.txt b/source/src/qt/avio/CMakeLists.txt index 4a0fda29d..f81ff6eb3 100644 --- a/source/src/qt/avio/CMakeLists.txt +++ b/source/src/qt/avio/CMakeLists.txt @@ -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() diff --git a/source/src/qt/avio/movie_saver.cpp b/source/src/qt/avio/movie_saver.cpp index 52dfea3f7..19bc1bc99 100644 --- a/source/src/qt/avio/movie_saver.cpp +++ b/source/src/qt/avio/movie_saver.cpp @@ -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; diff --git a/source/src/qt/avio/movie_saver.h b/source/src/qt/avio/movie_saver.h index a4f930957..483fcd461 100644 --- a/source/src/qt/avio/movie_saver.h +++ b/source/src/qt/avio/movie_saver.h @@ -14,6 +14,7 @@ #include #include #include +#include #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 video_data_queue; + QQueue video_data_queue; QQueue 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); diff --git a/source/src/qt/avio/movie_saver_audio.cpp b/source/src/qt/avio/movie_saver_audio.cpp index 94c40d54c..4a75ed98b 100644 --- a/source/src/qt/avio/movie_saver_audio.cpp +++ b/source/src/qt/avio/movie_saver_audio.cpp @@ -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, diff --git a/source/src/qt/avio/movie_saver_fileio.cpp b/source/src/qt/avio/movie_saver_fileio.cpp index 429bf91d9..6f70d952a 100644 --- a/source/src/qt/avio/movie_saver_fileio.cpp +++ b/source/src/qt/avio/movie_saver_fileio.cpp @@ -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; } } diff --git a/source/src/qt/common/qt_utils.cpp b/source/src/qt/common/qt_utils.cpp index 0ae185a3e..bd5e5d11c 100644 --- a/source/src/qt/common/qt_utils.cpp +++ b/source/src/qt/common/qt_utils.cpp @@ -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())); diff --git a/source/src/qt/osd_base.h b/source/src/qt/osd_base.h index 0927733bd..0f554c1e5 100644 --- a/source/src/qt/osd_base.h +++ b/source/src/qt/osd_base.h @@ -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); diff --git a/source/src/qt/osd_screen.cpp b/source/src/qt/osd_screen.cpp index 6eff36682..97ab9d27d 100644 --- a/source/src/qt/osd_screen.cpp +++ b/source/src/qt/osd_screen.cpp @@ -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); }