[MOVIE_SAVER] Fix sometimes crashing when stop to save movie.
[GENERAL] Update SO versions.
)
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()
)
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()
video_geometry = QSize(640, 480);
video_encode_threads = 4;
// audio_enqueue_count = 0;
-
+ left_frames = 0;
req_close = false;
req_stop = false;
bRunThread = false;
}
-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
}
//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;
}
n_encode_video = 0;
req_close = false;
req_stop = false;
+ left_frames = 0;
while(bRunThread) {
if(recording) {
if(!bRunThread) break;
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;
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;
#include <QStringList>
#include <QThread>
#include <QSize>
+#include <QImage>
#include "config.h"
#if defined(USE_LIBAV)
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
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;
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);
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,
{
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;
}
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;
}
}
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()));
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;
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);
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);
}
}
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();
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);
}
{
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;
}
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);
}
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) {
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;
#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);
}