void video_manager::record_frame() { // ignore if nothing to do if (m_mngfile == NULL && m_avifile == NULL) return; // start the profiler and get the current time g_profiler.start(PROFILER_MOVIE_REC); attotime curtime = machine().time(); // create the bitmap create_snapshot_bitmap(NULL); // loop until we hit the right time while (m_movie_next_frame_time <= curtime) { // handle an AVI recording if (m_avifile != NULL) { // write the next frame avi_error avierr = avi_append_video_frame(m_avifile, m_snap_bitmap); if (avierr != AVIERR_NONE) { g_profiler.stop(); return end_recording(); } } // handle a MNG recording if (m_mngfile != NULL) { // set up the text fields in the movie info png_info pnginfo = { 0 }; if (m_movie_frame == 0) { astring text1(emulator_info::get_appname(), " ", build_version); astring text2(machine().system().manufacturer, " ", machine().system().description); png_add_text(&pnginfo, "Software", text1); png_add_text(&pnginfo, "System", text2); } // write the next frame const rgb_t *palette = (machine().palette != NULL) ? palette_entry_list_adjusted(machine().palette) : NULL; png_error error = mng_capture_frame(*m_mngfile, &pnginfo, m_snap_bitmap, machine().total_colors(), palette); png_free(&pnginfo); if (error != PNGERR_NONE) { g_profiler.stop(); return end_recording(); } } // advance time m_movie_next_frame_time += m_movie_frame_period; m_movie_frame++; } g_profiler.stop(); }
void video_manager::exit() { // stop recording any movie end_recording(MF_AVI); end_recording(MF_MNG); // free the snapshot target machine().render().target_free(m_snap_target); m_snap_bitmap.reset(); // print a final result if we have at least 2 seconds' worth of data if (m_overall_emutime.seconds() >= 1) { osd_ticks_t tps = osd_ticks_per_second(); double final_real_time = (double)m_overall_real_seconds + (double)m_overall_real_ticks / (double)tps; double final_emu_time = m_overall_emutime.as_double(); osd_printf_info("Average speed: %.2f%% (%d seconds)\n", 100 * final_emu_time / final_real_time, (m_overall_emutime + attotime(0, ATTOSECONDS_PER_SECOND / 2)).seconds()); } }
void video_manager::toggle_record_movie() { if (!is_recording()) { begin_recording(nullptr, MF_MNG); machine().popmessage("REC START"); } else { end_recording(MF_MNG); machine().popmessage("REC STOP"); } }
void video_manager::toggle_record_movie(movie_format format) { if (!is_recording()) { begin_recording(nullptr, format); machine().popmessage("REC START (%s)", format == MF_MNG ? "MNG" : "AVI"); } else { end_recording(format); machine().popmessage("REC STOP (%s)", format == MF_MNG ? "MNG" : "AVI"); } }
int do_sound_options(int sel) { int old = recording; menu = new TSoundDlg(_("Sound options"), sound_menu); menu->execute(); delete menu; if (recording == 2) monitoring = 1; else monitoring = 0; if (old && !recording) end_recording(); return 0; }
void video_manager::add_sound_to_recording(const INT16 *sound, int numsamples) { // only record if we have a file if (m_avi_file != nullptr) { g_profiler.start(PROFILER_MOVIE_REC); // write the next frame avi_file::error avierr = m_avi_file->append_sound_samples(0, sound + 0, numsamples, 1); if (avierr == avi_file::error::NONE) avierr = m_avi_file->append_sound_samples(1, sound + 1, numsamples, 1); if (avierr != avi_file::error::NONE) end_recording(MF_AVI); g_profiler.stop(); } }
void video_manager::add_sound_to_recording(const INT16 *sound, int numsamples) { // only record if we have a file if (m_avifile != NULL) { g_profiler.start(PROFILER_MOVIE_REC); // write the next frame avi_error avierr = avi_append_sound_samples(m_avifile, 0, sound + 0, numsamples, 1); if (avierr == AVIERR_NONE) avierr = avi_append_sound_samples(m_avifile, 1, sound + 1, numsamples, 1); if (avierr != AVIERR_NONE) end_recording(); g_profiler.stop(); } }
void video_manager::exit() { // stop recording any movie end_recording(); // free all the graphics elements for (int i = 0; i < MAX_GFX_ELEMENTS; i++) gfx_element_free(machine().gfx[i]); // free the snapshot target machine().render().target_free(m_snap_target); m_snap_bitmap.reset(); // print a final result if we have at least 2 seconds' worth of data if (m_overall_emutime.seconds >= 1) { osd_ticks_t tps = osd_ticks_per_second(); double final_real_time = (double)m_overall_real_seconds + (double)m_overall_real_ticks / (double)tps; double final_emu_time = m_overall_emutime.as_double(); mame_printf_info("Average speed: %.2f%% (%d seconds)\n", 100 * final_emu_time / final_real_time, (m_overall_emutime + attotime(0, ATTOSECONDS_PER_SECOND / 2)).seconds); } }
void video_manager::begin_recording(const char *name, movie_format format) { // create a snapshot bitmap so we know what the target size is create_snapshot_bitmap(nullptr); // start up an AVI recording if (format == MF_AVI) { // stop any existing recording end_recording(format); // reset the state m_avi_frame = 0; m_avi_next_frame_time = machine().time(); // build up information about this new movie screen_device *screen = machine().first_screen(); avi_file::movie_info info; info.video_format = 0; info.video_timescale = 1000 * ((screen != nullptr) ? ATTOSECONDS_TO_HZ(screen->frame_period().attoseconds()) : screen_device::DEFAULT_FRAME_RATE); info.video_sampletime = 1000; info.video_numsamples = 0; info.video_width = m_snap_bitmap.width(); info.video_height = m_snap_bitmap.height(); info.video_depth = 24; info.audio_format = 0; info.audio_timescale = machine().sample_rate(); info.audio_sampletime = 1; info.audio_numsamples = 0; info.audio_channels = 2; info.audio_samplebits = 16; info.audio_samplerate = machine().sample_rate(); // create a new temporary movie file osd_file::error filerr; std::string fullpath; { emu_file tempfile(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); if (name != nullptr) filerr = tempfile.open(name); else filerr = open_next(tempfile, "avi"); // if we succeeded, make a copy of the name and create the real file over top if (filerr == osd_file::error::NONE) fullpath = tempfile.fullpath(); } if (filerr == osd_file::error::NONE) { // compute the frame time m_avi_frame_period = attotime::from_seconds(1000) / info.video_timescale; // create the file and free the string avi_file::error avierr = avi_file::create(fullpath, info, m_avi_file); if (avierr != avi_file::error::NONE) { osd_printf_error("Error creating AVI: %s\n", avi_file::error_string(avierr)); return end_recording(format); } } } // start up a MNG recording else if (format == MF_MNG) { // stop any existing recording end_recording(format); // reset the state m_mng_frame = 0; m_mng_next_frame_time = machine().time(); // create a new movie file and start recording m_mng_file = std::make_unique<emu_file>(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); osd_file::error filerr; if (name != nullptr) filerr = m_mng_file->open(name); else filerr = open_next(*m_mng_file, "mng"); if (filerr == osd_file::error::NONE) { // start the capture screen_device *screen = machine().first_screen(); int rate = (screen != nullptr) ? ATTOSECONDS_TO_HZ(screen->frame_period().attoseconds()) : screen_device::DEFAULT_FRAME_RATE; png_error pngerr = mng_capture_start(*m_mng_file, m_snap_bitmap, rate); if (pngerr != PNGERR_NONE) { osd_printf_error("Error capturing MNG, png_error=%d\n", pngerr); return end_recording(format); } // compute the frame time m_mng_frame_period = attotime::from_hz(rate); } else { osd_printf_error("Error creating MNG, osd_file::error=%d\n", int(filerr)); m_mng_file.reset(); } } }
void video_manager::record_frame() { // ignore if nothing to do if (m_mng_file == nullptr && m_avi_file == nullptr && !m_dummy_recording) return; // start the profiler and get the current time g_profiler.start(PROFILER_MOVIE_REC); attotime curtime = machine().time(); // create the bitmap create_snapshot_bitmap(nullptr); // handle an AVI recording if (m_avi_file != nullptr) { // loop until we hit the right time while (m_avi_next_frame_time <= curtime) { // write the next frame avi_file::error avierr = m_avi_file->append_video_frame(m_snap_bitmap); if (avierr != avi_file::error::NONE) { g_profiler.stop(); end_recording(MF_AVI); break; } // advance time m_avi_next_frame_time += m_avi_frame_period; m_avi_frame++; } } // handle a MNG recording if (m_mng_file != nullptr) { // loop until we hit the right time while (m_mng_next_frame_time <= curtime) { // set up the text fields in the movie info png_info pnginfo = { nullptr }; if (m_mng_frame == 0) { std::string text1 = std::string(emulator_info::get_appname()).append(" ").append(build_version); std::string text2 = std::string(machine().system().manufacturer).append(" ").append(machine().system().description); png_add_text(&pnginfo, "Software", text1.c_str()); png_add_text(&pnginfo, "System", text2.c_str()); } // write the next frame screen_device *screen = machine().first_screen(); const rgb_t *palette = (screen != nullptr && screen->has_palette()) ? screen->palette().palette()->entry_list_adjusted() : nullptr; int entries = (screen != nullptr && screen->has_palette()) ? screen->palette().entries() : 0; png_error error = mng_capture_frame(*m_mng_file, &pnginfo, m_snap_bitmap, entries, palette); png_free(&pnginfo); if (error != PNGERR_NONE) { g_profiler.stop(); end_recording(MF_MNG); break; } // advance time m_mng_next_frame_time += m_mng_frame_period; m_mng_frame++; } } g_profiler.stop(); }
void video_manager::begin_recording(const char *name, movie_format format) { // stop any existign recording end_recording(); // create a snapshot bitmap so we know what the target size is create_snapshot_bitmap(NULL); // reset the state m_movie_frame = 0; m_movie_next_frame_time = machine().time(); // start up an AVI recording if (format == MF_AVI) { // build up information about this new movie avi_movie_info info; info.video_format = 0; info.video_timescale = 1000 * ((machine().primary_screen != NULL) ? ATTOSECONDS_TO_HZ(machine().primary_screen->frame_period().attoseconds) : screen_device::DEFAULT_FRAME_RATE); info.video_sampletime = 1000; info.video_numsamples = 0; info.video_width = m_snap_bitmap.width(); info.video_height = m_snap_bitmap.height(); info.video_depth = 24; info.audio_format = 0; info.audio_timescale = machine().sample_rate(); info.audio_sampletime = 1; info.audio_numsamples = 0; info.audio_channels = 2; info.audio_samplebits = 16; info.audio_samplerate = machine().sample_rate(); // create a new temporary movie file file_error filerr; astring fullpath; { emu_file tempfile(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); if (name != NULL) filerr = tempfile.open(name); else filerr = open_next(tempfile, "avi"); // compute the frame time m_movie_frame_period = attotime::from_seconds(1000) / info.video_timescale; // if we succeeded, make a copy of the name and create the real file over top if (filerr == FILERR_NONE) fullpath = tempfile.fullpath(); } if (filerr == FILERR_NONE) { // create the file and free the string avi_error avierr = avi_create(fullpath, &info, &m_avifile); if (avierr != AVIERR_NONE) mame_printf_error("Error creating AVI: %s\n", avi_error_string(avierr)); } } // start up a MNG recording else if (format == MF_MNG) { // create a new movie file and start recording m_mngfile = auto_alloc(machine(), emu_file(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS)); file_error filerr; if (name != NULL) filerr = m_mngfile->open(name); else filerr = open_next(*m_mngfile, "mng"); if (filerr == FILERR_NONE) { // start the capture int rate = (machine().primary_screen != NULL) ? ATTOSECONDS_TO_HZ(machine().primary_screen->frame_period().attoseconds) : screen_device::DEFAULT_FRAME_RATE; png_error pngerr = mng_capture_start(*m_mngfile, m_snap_bitmap, rate); if (pngerr != PNGERR_NONE) return end_recording(); // compute the frame time m_movie_frame_period = attotime::from_hz(rate); } else { mame_printf_error("Error creating MNG\n"); global_free(m_mngfile); m_mngfile = NULL; } } }