MNG is now written when -mngwrite is used together with -aviwrite [Oliver Stöneberg]

This commit is contained in:
Oliver Stöneberg 2014-04-07 09:27:43 +00:00
parent d63e60a4c8
commit 9a49c214e3
2 changed files with 112 additions and 70 deletions

View File

@ -101,10 +101,13 @@ video_manager::video_manager(running_machine &machine)
m_snap_native(true),
m_snap_width(0),
m_snap_height(0),
m_avifile(NULL),
m_movie_frame_period(attotime::zero),
m_movie_next_frame_time(attotime::zero),
m_movie_frame(0)
m_mng_frame_period(attotime::zero),
m_mng_next_frame_time(attotime::zero),
m_mng_frame(0),
m_avi_file(NULL),
m_avi_frame_period(attotime::zero),
m_avi_next_frame_time(attotime::zero),
m_avi_frame(0)
{
// request a callback upon exiting
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(video_manager::exit), this));
@ -359,19 +362,19 @@ void video_manager::save_active_screen_snapshots()
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)
{
// 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
avi_movie_info info;
info.video_format = 0;
@ -400,9 +403,6 @@ void video_manager::begin_recording(const char *name, movie_format format)
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();
@ -410,39 +410,55 @@ void video_manager::begin_recording(const char *name, movie_format format)
if (filerr == FILERR_NONE)
{
// compute the frame time
m_avi_frame_period = attotime::from_seconds(1000) / info.video_timescale;
// create the file and free the string
avi_error avierr = avi_create(fullpath, &info, &m_avifile);
avi_error avierr = avi_create(fullpath, &info, &m_avi_file);
if (avierr != AVIERR_NONE)
{
mame_printf_error("Error creating AVI: %s\n", avi_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_mngfile.reset(global_alloc(emu_file(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS)));
m_mng_file.reset(global_alloc(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);
filerr = m_mng_file->open(name);
else
filerr = open_next(*m_mngfile, "mng");
filerr = open_next(*m_mng_file, "mng");
if (filerr == FILERR_NONE)
{
// start the capture
int rate = (machine().first_screen() != NULL) ? ATTOSECONDS_TO_HZ(machine().first_screen()->frame_period().attoseconds) : screen_device::DEFAULT_FRAME_RATE;
png_error pngerr = mng_capture_start(*m_mngfile, m_snap_bitmap, rate);
png_error pngerr = mng_capture_start(*m_mng_file, m_snap_bitmap, rate);
if (pngerr != PNGERR_NONE)
return end_recording();
{
mame_printf_error("Error capturing MNG, png_error=%d\n", pngerr);
return end_recording(format);
}
// compute the frame time
m_movie_frame_period = attotime::from_hz(rate);
m_mng_frame_period = attotime::from_hz(rate);
}
else
{
mame_printf_error("Error creating MNG\n");
m_mngfile.reset();
mame_printf_error("Error creating MNG, file_error=%d\n", filerr);
m_mng_file.reset();
}
}
}
@ -452,24 +468,32 @@ void video_manager::begin_recording(const char *name, movie_format format)
// end_recording - stop recording of a movie
//-------------------------------------------------
void video_manager::end_recording()
void video_manager::end_recording(movie_format format)
{
// close the file if it exists
if (m_avifile != NULL)
if (format == MF_AVI)
{
avi_close(m_avifile);
m_avifile = NULL;
// close the file if it exists
if (m_avi_file != NULL)
{
avi_close(m_avi_file);
m_avi_file = NULL;
// reset the state
m_avi_frame = 0;
}
}
// close the file if it exists
if (m_mngfile != NULL)
else if (format == MF_MNG)
{
mng_capture_stop(*m_mngfile);
m_mngfile.reset();
}
// close the file if it exists
if (m_mng_file != NULL)
{
mng_capture_stop(*m_mng_file);
m_mng_file.reset();
// reset the state
m_movie_frame = 0;
// reset the state
m_mng_frame = 0;
}
}
}
@ -481,16 +505,16 @@ void video_manager::end_recording()
void video_manager::add_sound_to_recording(const INT16 *sound, int numsamples)
{
// only record if we have a file
if (m_avifile != NULL)
if (m_avi_file != 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);
avi_error avierr = avi_append_sound_samples(m_avi_file, 0, sound + 0, numsamples, 1);
if (avierr == AVIERR_NONE)
avierr = avi_append_sound_samples(m_avifile, 1, sound + 1, numsamples, 1);
avierr = avi_append_sound_samples(m_avi_file, 1, sound + 1, numsamples, 1);
if (avierr != AVIERR_NONE)
end_recording();
end_recording(MF_AVI);
g_profiler.stop();
}
@ -505,7 +529,8 @@ void video_manager::add_sound_to_recording(const INT16 *sound, int numsamples)
void video_manager::exit()
{
// stop recording any movie
end_recording();
end_recording(MF_AVI);
end_recording(MF_MNG);
// free the snapshot target
machine().render().target_free(m_snap_target);
@ -541,7 +566,8 @@ void video_manager::screenless_update_callback(void *ptr, int param)
void video_manager::postload()
{
m_movie_next_frame_time = machine().time();
m_avi_next_frame_time = machine().time();
m_mng_next_frame_time = machine().time();
}
@ -1189,7 +1215,7 @@ file_error video_manager::open_next(emu_file &file, const char *extension)
void video_manager::record_frame()
{
// ignore if nothing to do
if (m_mngfile == NULL && m_avifile == NULL)
if (m_mng_file == NULL && m_avi_file == NULL)
return;
// start the profiler and get the current time
@ -1199,27 +1225,36 @@ void video_manager::record_frame()
// 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_avi_file != NULL)
{
// handle an AVI recording
if (m_avifile != NULL)
// loop until we hit the right time
while (m_avi_next_frame_time <= curtime)
{
// write the next frame
avi_error avierr = avi_append_video_frame(m_avifile, m_snap_bitmap);
avi_error avierr = avi_append_video_frame(m_avi_file, m_snap_bitmap);
if (avierr != AVIERR_NONE)
{
g_profiler.stop();
return end_recording();
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_mngfile != NULL)
}
// handle a MNG recording
if (m_mng_file != NULL)
{
// 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 = { 0 };
if (m_movie_frame == 0)
if (m_mng_frame == 0)
{
astring text1(emulator_info::get_appname(), " ", build_version);
astring text2(machine().system().manufacturer, " ", machine().system().description);
@ -1230,19 +1265,21 @@ void video_manager::record_frame()
// write the next frame
const rgb_t *palette = (machine().first_screen() !=NULL && machine().first_screen()->palette() != NULL) ? machine().first_screen()->palette()->palette()->entry_list_adjusted() : NULL;
int entries = (machine().first_screen() !=NULL && machine().first_screen()->palette() != NULL) ? machine().first_screen()->palette()->entries() : 0;
png_error error = mng_capture_frame(*m_mngfile, &pnginfo, m_snap_bitmap, entries, palette);
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();
return end_recording();
end_recording(MF_MNG);
break;
}
// advance time
m_mng_next_frame_time += m_mng_frame_period;
m_mng_frame++;
}
// advance time
m_movie_next_frame_time += m_movie_frame_period;
m_movie_frame++;
}
g_profiler.stop();
}
@ -1264,12 +1301,12 @@ void video_manager::toggle_record_movie()
{
if (!is_recording())
{
begin_recording(NULL, video_manager::MF_MNG);
begin_recording(NULL, MF_MNG);
popmessage("REC START");
}
else
{
end_recording();
end_recording(MF_MNG);
popmessage("REC STOP");
}
}

View File

@ -64,7 +64,7 @@ public:
bool throttled() const { return m_throttled; }
float throttle_rate() const { return m_throttle_rate; }
bool fastforward() const { return m_fastforward; }
bool is_recording() const { return (m_mngfile != NULL || m_avifile != NULL); }
bool is_recording() const { return (m_mng_file != NULL || m_avi_file != NULL); }
// setters
void set_frameskip(int frameskip);
@ -89,8 +89,8 @@ public:
void save_active_screen_snapshots();
// movies
void begin_recording(const char *name, movie_format format = MF_AVI);
void end_recording();
void begin_recording(const char *name, movie_format format);
void end_recording(movie_format format);
void add_sound_to_recording(const INT16 *sound, int numsamples);
private:
@ -165,12 +165,17 @@ private:
INT32 m_snap_width; // width of snapshots (0 == auto)
INT32 m_snap_height; // height of snapshots (0 == auto)
// movie recording
auto_pointer<emu_file> m_mngfile; // handle to the open movie file
avi_file * m_avifile; // handle to the open movie file
attotime m_movie_frame_period; // period of a single movie frame
attotime m_movie_next_frame_time; // time of next frame
UINT32 m_movie_frame; // current movie frame number
// movie recording - MNG
auto_pointer<emu_file> m_mng_file; // handle to the open movie file
attotime m_mng_frame_period; // period of a single movie frame
attotime m_mng_next_frame_time; // time of next frame
UINT32 m_mng_frame; // current movie frame number
// movie recording - AVI
avi_file * m_avi_file; // handle to the open movie file
attotime m_avi_frame_period; // period of a single movie frame
attotime m_avi_next_frame_time; // time of next frame
UINT32 m_avi_frame; // current movie frame number
static const UINT8 s_skiptable[FRAMESKIP_LEVELS][FRAMESKIP_LEVELS];