summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/render/aviwrite.cpp
diff options
context:
space:
mode:
author therealmogminer@gmail.com <therealmogminer@gmail.com>2016-04-17 19:15:58 +0200
committer therealmogminer@gmail.com <therealmogminer@gmail.com>2016-04-17 19:16:14 +0200
commit250a5cc805a41409cbd6b8a1bfcb33e002e3f6f0 (patch)
treeb767b65a8ccc667bd22a70f8f2fadead6f72b206 /src/osd/modules/render/aviwrite.cpp
parent9d8c3cb34178347bb1751da2d6f496a935fa35a6 (diff)
Add AVI writing to bgfx, nw
Diffstat (limited to 'src/osd/modules/render/aviwrite.cpp')
-rw-r--r--src/osd/modules/render/aviwrite.cpp161
1 files changed, 161 insertions, 0 deletions
diff --git a/src/osd/modules/render/aviwrite.cpp b/src/osd/modules/render/aviwrite.cpp
new file mode 100644
index 00000000000..6a27c567a43
--- /dev/null
+++ b/src/osd/modules/render/aviwrite.cpp
@@ -0,0 +1,161 @@
+// license:BSD-3-Clause
+// copyright-holders:Ryan Holtz
+//============================================================
+//
+// aviwrite.cpp - AVI screenshot writer class
+//
+//============================================================
+
+#include "aviwrite.h"
+#include "modules/lib/osdobj_common.h"
+
+avi_write::avi_write(running_machine& machine, uint32_t width, uint32_t height)
+ : m_machine(machine)
+ , m_recording(false)
+ , m_width(width)
+ , m_height(height)
+ , m_output_file(nullptr)
+ , m_frame(0)
+{
+}
+
+avi_write::~avi_write()
+{
+ if (m_recording)
+ {
+ stop();
+ }
+}
+
+void avi_write::record(std::string name)
+{
+ if (m_recording)
+ {
+ end_avi_recording();
+ }
+
+ if (name != "")
+ {
+ begin_avi_recording(name);
+ }
+}
+
+void avi_write::stop()
+{
+ osd_printf_info("Stopping AVI recording after %d frames.\n", m_frame);
+ end_avi_recording();
+}
+
+void avi_write::begin_avi_recording(std::string name)
+{
+ // stop any existing recording
+ end_avi_recording();
+
+ // reset the state
+ m_frame = 0;
+ m_next_frame_time = m_machine.time();
+
+ // build up information about this new movie
+ avi_file::movie_info info;
+ info.video_format = 0;
+ info.video_timescale = 1000 * ((m_machine.first_screen() != nullptr) ? ATTOSECONDS_TO_HZ(m_machine.first_screen()->frame_period().m_attoseconds) : screen_device::DEFAULT_FRAME_RATE);
+ info.video_sampletime = 1000;
+ info.video_numsamples = 0;
+ info.video_width = m_width;
+ info.video_height = m_height;
+ info.video_depth = 24;
+
+ info.audio_format = 0;
+ info.audio_timescale = m_machine.sample_rate();
+ info.audio_sampletime = 1;
+ info.audio_numsamples = 0;
+ info.audio_channels = 2;
+ info.audio_samplebits = 16;
+ info.audio_samplerate = m_machine.sample_rate();
+
+ // create a new temporary movie file
+ osd_file::error filerr;
+ std::string fullpath;
+ {
+ emu_file tempfile(m_machine.options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
+ filerr = tempfile.open(name.c_str());
+
+ // compute the frame time
+ m_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 == osd_file::error::NONE)
+ {
+ fullpath = tempfile.fullpath();
+ }
+ }
+
+ if (filerr == osd_file::error::NONE)
+ {
+ // create the file and free the string
+ avi_file::error avierr = avi_file::create(fullpath, info, m_output_file);
+ if (avierr != avi_file::error::NONE)
+ {
+ osd_printf_error("Error creating AVI: %s\n", avi_file::error_string(avierr));
+ }
+ else
+ {
+ m_recording = true;
+ }
+ }
+}
+
+void avi_write::end_avi_recording()
+{
+ if (m_output_file)
+ {
+ m_output_file.reset();
+ }
+
+ m_recording = false;
+ m_output_file = nullptr;
+ m_frame = 0;
+}
+
+void avi_write::video_frame(bitmap_rgb32& snap)
+{
+ // get the current time
+ attotime curtime = m_machine.time();
+
+ // loop until we hit the right time
+ while (m_next_frame_time <= curtime)
+ {
+ // handle an AVI recording
+ // write the next frame
+ avi_file::error avierr = m_output_file->append_video_frame(snap);
+ if (avierr != avi_file::error::NONE)
+ {
+ osd_printf_error("Error while logging AVI video frame: %s\n", avi_file::error_string(avierr));
+ osd_printf_error("Stopping AVI recording.\n");
+ end_avi_recording();
+ return;
+ }
+
+ // advance time
+ m_next_frame_time += m_frame_period;
+ m_frame++;
+ }
+}
+
+void avi_write::audio_frame(const INT16 *buffer, int samples_this_frame)
+{
+ // only record if we have a file
+ if (m_output_file != nullptr)
+ {
+ // write the next frame
+ avi_file::error avierr = m_output_file->append_sound_samples(0, buffer + 0, samples_this_frame, 1);
+ if (avierr == avi_file::error::NONE)
+ avierr = m_output_file->append_sound_samples(1, buffer + 1, samples_this_frame, 1);
+ if (avierr != avi_file::error::NONE)
+ {
+ osd_printf_error("Error while logging AVI audio frame: %s\n", avi_file::error_string(avierr));
+ osd_printf_error("Stopping AVI recording.\n");
+ end_avi_recording();
+ }
+ }
+} \ No newline at end of file