1414#include " Common/Logging/Log.h"
1515
1616#include " Core/CoreTiming.h"
17+ #include " Core/HW/SystemTimers.h"
1718#include " Core/HW/VideoInterface.h" // for TargetRefreshRate
1819#include " VideoCommon/AVIDump.h"
1920#include " VideoCommon/VideoConfig.h"
2930
3031#include " Core/ConfigManager.h" // for EuRGB60
3132#include " Core/CoreTiming.h"
32- #include " Core/HW/SystemTimers.h"
3333
3434static HWND s_emu_wnd;
3535static LONG s_byte_buffer;
@@ -335,6 +335,7 @@ static int s_height;
335335static int s_size;
336336static u64 s_last_frame;
337337bool b_start_dumping = false ;
338+ static u64 s_last_pts;
338339
339340static void InitAVCodec ()
340341{
@@ -352,6 +353,7 @@ bool AVIDump::Start(int w, int h)
352353 s_height = h;
353354
354355 s_last_frame = CoreTiming::GetTicks ();
356+ s_last_pts = 0 ;
355357
356358 InitAVCodec ();
357359 bool success = CreateFile ();
@@ -416,14 +418,6 @@ static void PreparePacket(AVPacket* pkt)
416418 av_init_packet (pkt);
417419 pkt->data = nullptr ;
418420 pkt->size = 0 ;
419- if (s_stream->codec ->coded_frame ->pts != AV_NOPTS_VALUE)
420- {
421- pkt->pts = av_rescale_q (s_stream->codec ->coded_frame ->pts ,
422- s_stream->codec ->time_base , s_stream->time_base );
423- }
424- if (s_stream->codec ->coded_frame ->key_frame )
425- pkt->flags |= AV_PKT_FLAG_KEY;
426- pkt->stream_index = s_stream->index ;
427421}
428422
429423void AVIDump::AddFrame (const u8 * data, int width, int height)
@@ -448,11 +442,45 @@ void AVIDump::AddFrame(const u8* data, int width, int height)
448442 // Encode and write the image.
449443 AVPacket pkt;
450444 PreparePacket (&pkt);
451- int got_packet;
452- int error = avcodec_encode_video2 (s_stream->codec , &pkt, s_scaled_frame, &got_packet);
445+ int got_packet = 0 ;
446+ int error = 0 ;
447+ u64 delta;
448+ s64 last_pts;
449+ if (!b_start_dumping && s_last_frame <= SystemTimers::GetTicksPerSecond ())
450+ {
451+ delta = CoreTiming::GetTicks ();
452+ last_pts = AV_NOPTS_VALUE;
453+ b_start_dumping = true ;
454+ }
455+ else
456+ {
457+ delta = CoreTiming::GetTicks () - s_last_frame;
458+ last_pts = (s_last_pts * s_stream->codec ->time_base .den ) / SystemTimers::GetTicksPerSecond ();
459+ }
460+ u64 pts_in_ticks = s_last_pts + delta;
461+ s_scaled_frame->pts = (pts_in_ticks * s_stream->codec ->time_base .den ) / SystemTimers::GetTicksPerSecond ();
462+ if (s_scaled_frame->pts != last_pts)
463+ {
464+ s_last_frame = CoreTiming::GetTicks ();
465+ s_last_pts = pts_in_ticks;
466+ error = avcodec_encode_video2 (s_stream->codec , &pkt, s_scaled_frame, &got_packet);
467+ }
453468 while (!error && got_packet)
454469 {
455470 // Write the compressed frame in the media file.
471+ if (pkt.pts != AV_NOPTS_VALUE)
472+ {
473+ pkt.pts = av_rescale_q (pkt.pts ,
474+ s_stream->codec ->time_base , s_stream->time_base );
475+ }
476+ if (pkt.dts != AV_NOPTS_VALUE)
477+ {
478+ pkt.dts = av_rescale_q (pkt.dts ,
479+ s_stream->codec ->time_base , s_stream->time_base );
480+ }
481+ if (s_stream->codec ->coded_frame ->key_frame )
482+ pkt.flags |= AV_PKT_FLAG_KEY;
483+ pkt.stream_index = s_stream->index ;
456484 av_interleaved_write_frame (s_format_context, &pkt);
457485
458486 // Handle delayed frames.
0 commit comments