Merge pull request #1345 from sgadrat/fix-avidump-framerate
Fix timing of AVI files dumped on Linux
This commit is contained in:
commit
b13ba0680c
|
@ -14,6 +14,7 @@
|
|||
#include "Common/Logging/Log.h"
|
||||
|
||||
#include "Core/CoreTiming.h"
|
||||
#include "Core/HW/SystemTimers.h"
|
||||
#include "Core/HW/VideoInterface.h" //for TargetRefreshRate
|
||||
#include "VideoCommon/AVIDump.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
|
@ -29,7 +30,6 @@
|
|||
|
||||
#include "Core/ConfigManager.h" // for EuRGB60
|
||||
#include "Core/CoreTiming.h"
|
||||
#include "Core/HW/SystemTimers.h"
|
||||
|
||||
static HWND s_emu_wnd;
|
||||
static LONG s_byte_buffer;
|
||||
|
@ -335,6 +335,7 @@ static int s_height;
|
|||
static int s_size;
|
||||
static u64 s_last_frame;
|
||||
bool b_start_dumping = false;
|
||||
static u64 s_last_pts;
|
||||
|
||||
static void InitAVCodec()
|
||||
{
|
||||
|
@ -352,6 +353,7 @@ bool AVIDump::Start(int w, int h)
|
|||
s_height = h;
|
||||
|
||||
s_last_frame = CoreTiming::GetTicks();
|
||||
s_last_pts = 0;
|
||||
|
||||
InitAVCodec();
|
||||
bool success = CreateFile();
|
||||
|
@ -416,14 +418,6 @@ static void PreparePacket(AVPacket* pkt)
|
|||
av_init_packet(pkt);
|
||||
pkt->data = nullptr;
|
||||
pkt->size = 0;
|
||||
if (s_stream->codec->coded_frame->pts != AV_NOPTS_VALUE)
|
||||
{
|
||||
pkt->pts = av_rescale_q(s_stream->codec->coded_frame->pts,
|
||||
s_stream->codec->time_base, s_stream->time_base);
|
||||
}
|
||||
if (s_stream->codec->coded_frame->key_frame)
|
||||
pkt->flags |= AV_PKT_FLAG_KEY;
|
||||
pkt->stream_index = s_stream->index;
|
||||
}
|
||||
|
||||
void AVIDump::AddFrame(const u8* data, int width, int height)
|
||||
|
@ -448,11 +442,45 @@ void AVIDump::AddFrame(const u8* data, int width, int height)
|
|||
// Encode and write the image.
|
||||
AVPacket pkt;
|
||||
PreparePacket(&pkt);
|
||||
int got_packet;
|
||||
int error = avcodec_encode_video2(s_stream->codec, &pkt, s_scaled_frame, &got_packet);
|
||||
int got_packet = 0;
|
||||
int error = 0;
|
||||
u64 delta;
|
||||
s64 last_pts;
|
||||
if (!b_start_dumping && s_last_frame <= SystemTimers::GetTicksPerSecond())
|
||||
{
|
||||
delta = CoreTiming::GetTicks();
|
||||
last_pts = AV_NOPTS_VALUE;
|
||||
b_start_dumping = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
delta = CoreTiming::GetTicks() - s_last_frame;
|
||||
last_pts = (s_last_pts * s_stream->codec->time_base.den) / SystemTimers::GetTicksPerSecond();
|
||||
}
|
||||
u64 pts_in_ticks = s_last_pts + delta;
|
||||
s_scaled_frame->pts = (pts_in_ticks * s_stream->codec->time_base.den) / SystemTimers::GetTicksPerSecond();
|
||||
if (s_scaled_frame->pts != last_pts)
|
||||
{
|
||||
s_last_frame = CoreTiming::GetTicks();
|
||||
s_last_pts = pts_in_ticks;
|
||||
error = avcodec_encode_video2(s_stream->codec, &pkt, s_scaled_frame, &got_packet);
|
||||
}
|
||||
while (!error && got_packet)
|
||||
{
|
||||
// Write the compressed frame in the media file.
|
||||
if (pkt.pts != AV_NOPTS_VALUE)
|
||||
{
|
||||
pkt.pts = av_rescale_q(pkt.pts,
|
||||
s_stream->codec->time_base, s_stream->time_base);
|
||||
}
|
||||
if (pkt.dts != AV_NOPTS_VALUE)
|
||||
{
|
||||
pkt.dts = av_rescale_q(pkt.dts,
|
||||
s_stream->codec->time_base, s_stream->time_base);
|
||||
}
|
||||
if (s_stream->codec->coded_frame->key_frame)
|
||||
pkt.flags |= AV_PKT_FLAG_KEY;
|
||||
pkt.stream_index = s_stream->index;
|
||||
av_interleaved_write_frame(s_format_context, &pkt);
|
||||
|
||||
// Handle delayed frames.
|
||||
|
|
Loading…
Reference in New Issue