Previous 199869 Revisions Next

r29411 Monday 7th April, 2014 at 09:27:43 UTC by Oliver Stöneberg
MNG is now written when -mngwrite is used together with -aviwrite [Oliver Stöneberg]
[src/emu]video.c video.h

trunk/src/emu/video.c
r29410r29411
101101      m_snap_native(true),
102102      m_snap_width(0),
103103      m_snap_height(0),
104      m_avifile(NULL),
105      m_movie_frame_period(attotime::zero),
106      m_movie_next_frame_time(attotime::zero),
107      m_movie_frame(0)
104      m_mng_frame_period(attotime::zero),
105      m_mng_next_frame_time(attotime::zero),
106      m_mng_frame(0),
107      m_avi_file(NULL),
108      m_avi_frame_period(attotime::zero),
109      m_avi_next_frame_time(attotime::zero),
110      m_avi_frame(0)
108111{
109112   // request a callback upon exiting
110113   machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(video_manager::exit), this));
r29410r29411
359362
360363void video_manager::begin_recording(const char *name, movie_format format)
361364{
362   // stop any existign recording
363   end_recording();
364
365365   // create a snapshot bitmap so we know what the target size is
366366   create_snapshot_bitmap(NULL);
367367
368   // reset the state
369   m_movie_frame = 0;
370   m_movie_next_frame_time = machine().time();
371
372368   // start up an AVI recording
373369   if (format == MF_AVI)
374370   {
371      // stop any existing recording
372      end_recording(format);
373
374      // reset the state
375      m_avi_frame = 0;
376      m_avi_next_frame_time = machine().time();
377   
375378      // build up information about this new movie
376379      avi_movie_info info;
377380      info.video_format = 0;
r29410r29411
400403         else
401404            filerr = open_next(tempfile, "avi");
402405
403         // compute the frame time
404         m_movie_frame_period = attotime::from_seconds(1000) / info.video_timescale;
405
406406         // if we succeeded, make a copy of the name and create the real file over top
407407         if (filerr == FILERR_NONE)
408408            fullpath = tempfile.fullpath();
r29410r29411
410410
411411      if (filerr == FILERR_NONE)
412412      {
413         // compute the frame time
414         m_avi_frame_period = attotime::from_seconds(1000) / info.video_timescale;
415     
413416         // create the file and free the string
414         avi_error avierr = avi_create(fullpath, &info, &m_avifile);
417         avi_error avierr = avi_create(fullpath, &info, &m_avi_file);
415418         if (avierr != AVIERR_NONE)
419         {
416420            mame_printf_error("Error creating AVI: %s\n", avi_error_string(avierr));
421            return end_recording(format);
422         }
417423      }
418424   }
419425
420426   // start up a MNG recording
421427   else if (format == MF_MNG)
422428   {
429      // stop any existing recording
430      end_recording(format);
431   
432      // reset the state
433      m_mng_frame = 0;
434      m_mng_next_frame_time = machine().time();   
435   
423436      // create a new movie file and start recording
424      m_mngfile.reset(global_alloc(emu_file(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS)));
437      m_mng_file.reset(global_alloc(emu_file(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS)));
425438      file_error filerr;
426439      if (name != NULL)
427         filerr = m_mngfile->open(name);
440         filerr = m_mng_file->open(name);
428441      else
429         filerr = open_next(*m_mngfile, "mng");
442         filerr = open_next(*m_mng_file, "mng");
430443
431444      if (filerr == FILERR_NONE)
432445      {
433446         // start the capture
434447         int rate = (machine().first_screen() != NULL) ? ATTOSECONDS_TO_HZ(machine().first_screen()->frame_period().attoseconds) : screen_device::DEFAULT_FRAME_RATE;
435         png_error pngerr = mng_capture_start(*m_mngfile, m_snap_bitmap, rate);
448         png_error pngerr = mng_capture_start(*m_mng_file, m_snap_bitmap, rate);
436449         if (pngerr != PNGERR_NONE)
437            return end_recording();
450         {
451            mame_printf_error("Error capturing MNG, png_error=%d\n", pngerr);
452            return end_recording(format);
453         }
438454
439455         // compute the frame time
440         m_movie_frame_period = attotime::from_hz(rate);
456         m_mng_frame_period = attotime::from_hz(rate);
441457      }
442458      else
443459      {
444         mame_printf_error("Error creating MNG\n");
445         m_mngfile.reset();
460         mame_printf_error("Error creating MNG, file_error=%d\n", filerr);
461         m_mng_file.reset();
446462      }
447463   }
448464}
r29410r29411
452468//  end_recording - stop recording of a movie
453469//-------------------------------------------------
454470
455void video_manager::end_recording()
471void video_manager::end_recording(movie_format format)
456472{
457   // close the file if it exists
458   if (m_avifile != NULL)
473   if (format == MF_AVI)
459474   {
460      avi_close(m_avifile);
461      m_avifile = NULL;
475      // close the file if it exists
476      if (m_avi_file != NULL)
477      {
478         avi_close(m_avi_file);
479         m_avi_file = NULL;
480         
481         // reset the state
482         m_avi_frame = 0;
483      }
462484   }
485   else if (format == MF_MNG)
486   {
487      // close the file if it exists
488      if (m_mng_file != NULL)
489      {
490         mng_capture_stop(*m_mng_file);
491         m_mng_file.reset();
463492
464   // close the file if it exists
465   if (m_mngfile != NULL)
466   {
467      mng_capture_stop(*m_mngfile);
468      m_mngfile.reset();
493         // reset the state
494         m_mng_frame = 0;
495      }
469496   }
470
471   // reset the state
472   m_movie_frame = 0;
473497}
474498
475499
r29410r29411
481505void video_manager::add_sound_to_recording(const INT16 *sound, int numsamples)
482506{
483507   // only record if we have a file
484   if (m_avifile != NULL)
508   if (m_avi_file != NULL)
485509   {
486510      g_profiler.start(PROFILER_MOVIE_REC);
487511
488512      // write the next frame
489      avi_error avierr = avi_append_sound_samples(m_avifile, 0, sound + 0, numsamples, 1);
513      avi_error avierr = avi_append_sound_samples(m_avi_file, 0, sound + 0, numsamples, 1);
490514      if (avierr == AVIERR_NONE)
491         avierr = avi_append_sound_samples(m_avifile, 1, sound + 1, numsamples, 1);
515         avierr = avi_append_sound_samples(m_avi_file, 1, sound + 1, numsamples, 1);
492516      if (avierr != AVIERR_NONE)
493         end_recording();
517         end_recording(MF_AVI);
494518
495519      g_profiler.stop();
496520   }
r29410r29411
505529void video_manager::exit()
506530{
507531   // stop recording any movie
508   end_recording();
532   end_recording(MF_AVI);
533   end_recording(MF_MNG);
509534
510535   // free the snapshot target
511536   machine().render().target_free(m_snap_target);
r29410r29411
541566
542567void video_manager::postload()
543568{
544   m_movie_next_frame_time = machine().time();
569   m_avi_next_frame_time = machine().time();
570   m_mng_next_frame_time = machine().time();
545571}
546572
547573
r29410r29411
11891215void video_manager::record_frame()
11901216{
11911217   // ignore if nothing to do
1192   if (m_mngfile == NULL && m_avifile == NULL)
1218   if (m_mng_file == NULL && m_avi_file == NULL)
11931219      return;
11941220
11951221   // start the profiler and get the current time
r29410r29411
11991225   // create the bitmap
12001226   create_snapshot_bitmap(NULL);
12011227
1202   // loop until we hit the right time
1203   while (m_movie_next_frame_time <= curtime)
1228   // handle an AVI recording
1229   if (m_avi_file != NULL)
12041230   {
1205      // handle an AVI recording
1206      if (m_avifile != NULL)
1231      // loop until we hit the right time
1232      while (m_avi_next_frame_time <= curtime)
12071233      {
12081234         // write the next frame
1209         avi_error avierr = avi_append_video_frame(m_avifile, m_snap_bitmap);
1235         avi_error avierr = avi_append_video_frame(m_avi_file, m_snap_bitmap);
12101236         if (avierr != AVIERR_NONE)
12111237         {
12121238            g_profiler.stop();
1213            return end_recording();
1239            end_recording(MF_AVI);
1240            break;
12141241         }
1242         
1243         // advance time
1244         m_avi_next_frame_time += m_avi_frame_period;
1245         m_avi_frame++;
12151246      }
1216
1217      // handle a MNG recording
1218      if (m_mngfile != NULL)
1247   }
1248   
1249   // handle a MNG recording
1250   if (m_mng_file != NULL)
1251   {
1252      // loop until we hit the right time
1253      while (m_mng_next_frame_time <= curtime)
12191254      {
12201255         // set up the text fields in the movie info
12211256         png_info pnginfo = { 0 };
1222         if (m_movie_frame == 0)
1257         if (m_mng_frame == 0)
12231258         {
12241259            astring text1(emulator_info::get_appname(), " ", build_version);
12251260            astring text2(machine().system().manufacturer, " ", machine().system().description);
r29410r29411
12301265         // write the next frame
12311266         const rgb_t *palette = (machine().first_screen() !=NULL && machine().first_screen()->palette() != NULL) ? machine().first_screen()->palette()->palette()->entry_list_adjusted() : NULL;
12321267         int entries = (machine().first_screen() !=NULL && machine().first_screen()->palette() != NULL) ? machine().first_screen()->palette()->entries() : 0;
1233         png_error error = mng_capture_frame(*m_mngfile, &pnginfo, m_snap_bitmap, entries, palette);
1268         png_error error = mng_capture_frame(*m_mng_file, &pnginfo, m_snap_bitmap, entries, palette);
12341269         png_free(&pnginfo);
12351270         if (error != PNGERR_NONE)
12361271         {
12371272            g_profiler.stop();
1238            return end_recording();
1273            end_recording(MF_MNG);
1274            break;
12391275         }
1276         
1277         // advance time
1278         m_mng_next_frame_time += m_mng_frame_period;
1279         m_mng_frame++;
12401280      }
1241
1242      // advance time
1243      m_movie_next_frame_time += m_movie_frame_period;
1244      m_movie_frame++;
12451281   }
1282   
12461283   g_profiler.stop();
12471284}
12481285
r29410r29411
12641301{
12651302   if (!is_recording())
12661303   {
1267      begin_recording(NULL, video_manager::MF_MNG);
1304      begin_recording(NULL, MF_MNG);
12681305      popmessage("REC START");
12691306   }
12701307   else
12711308   {
1272      end_recording();
1309      end_recording(MF_MNG);
12731310      popmessage("REC STOP");
12741311   }
12751312}
trunk/src/emu/video.h
r29410r29411
6464   bool throttled() const { return m_throttled; }
6565   float throttle_rate() const { return m_throttle_rate; }
6666   bool fastforward() const { return m_fastforward; }
67   bool is_recording() const { return (m_mngfile != NULL || m_avifile != NULL); }
67   bool is_recording() const { return (m_mng_file != NULL || m_avi_file != NULL); }
6868
6969   // setters
7070   void set_frameskip(int frameskip);
r29410r29411
8989   void save_active_screen_snapshots();
9090
9191   // movies
92   void begin_recording(const char *name, movie_format format = MF_AVI);
93   void end_recording();
92   void begin_recording(const char *name, movie_format format);
93   void end_recording(movie_format format);
9494   void add_sound_to_recording(const INT16 *sound, int numsamples);
9595
9696private:
r29410r29411
165165   INT32               m_snap_width;               // width of snapshots (0 == auto)
166166   INT32               m_snap_height;              // height of snapshots (0 == auto)
167167
168   // movie recording
169   auto_pointer<emu_file> m_mngfile;               // handle to the open movie file
170   avi_file *          m_avifile;                  // handle to the open movie file
171   attotime            m_movie_frame_period;       // period of a single movie frame
172   attotime            m_movie_next_frame_time;    // time of next frame
173   UINT32              m_movie_frame;              // current movie frame number
168   // movie recording - MNG
169   auto_pointer<emu_file> m_mng_file;              // handle to the open movie file
170   attotime            m_mng_frame_period;         // period of a single movie frame
171   attotime            m_mng_next_frame_time;      // time of next frame
172   UINT32              m_mng_frame;                // current movie frame number
173   
174   // movie recording - AVI
175   avi_file *          m_avi_file;                 // handle to the open movie file
176   attotime            m_avi_frame_period;         // period of a single movie frame
177   attotime            m_avi_next_frame_time;      // time of next frame
178   UINT32              m_avi_frame;                // current movie frame number
174179
175180   static const UINT8      s_skiptable[FRAMESKIP_LEVELS][FRAMESKIP_LEVELS];
176181

Previous 199869 Revisions Next


© 1997-2024 The MAME Team