sync audio and video

This commit is contained in:
sirius 2019-10-26 19:54:25 +08:00
parent b175a6fd42
commit 9866a73b1c
5 changed files with 34 additions and 6 deletions

View file

@ -86,6 +86,7 @@ static int s_WVBufferPosition = 0;
static int s_WVBufferSize = 0;
const int DefaultDistance = 1500;
int m_LastBreak = 0;
// TODO: there should be a faster way todo this
static short Int2Short(int i)
@ -239,6 +240,11 @@ static void Mix(short *pFinalOut, unsigned Frames)
pInR += Step;
v->m_Tick++;
}
#if defined(CONF_VIDEORECORDER)
if(IVideo::Current())
if(m_LastBreak > IVideo::Current()->GetBreak())
v->m_Tick -= End;
#endif
// free voice if not used any more
if(v->m_Tick == v->m_pSample->m_NumFrames)
@ -280,7 +286,13 @@ static void Mix(short *pFinalOut, unsigned Frames)
#if defined(CONF_VIDEORECORDER)
if (IVideo::Current())
IVideo::Current()->nextAudioFrame(pFinalOut);
{
if(m_LastBreak <= IVideo::Current()->GetBreak()+0.005)
{
IVideo::Current()->nextAudioFrame(pFinalOut);
m_LastBreak += 1;
}
}
#endif
}

View file

@ -147,6 +147,7 @@ void CVideo::start()
m_Recording = true;
m_Started = true;
ms_Time = time_get();
m_Break = 0;
}
void CVideo::stop()
@ -166,7 +167,10 @@ void CVideo::stop()
close_stream(&m_VideoStream);
if (m_HasAudio)
{
close_stream(&m_AudioStream);
fclose(m_dbgfile);
}
if (!(m_pFormat->flags & AVFMT_NOFILE))
avio_closep(&m_pFormatContext->pb);
@ -236,7 +240,7 @@ void CVideo::nextAudioFrame(short* pData)
{
m_ProcessingAudioFrame = true;
m_AudioStream.frame->pts = m_AudioStream.enc->frame_number;
// dbg_msg("video_recorder", "aframe: %d", m_AudioStream.enc->frame_number);
dbg_msg("video_recorder", "aframe: %d", m_AudioStream.enc->frame_number);
// memcpy(m_AudioStream.tmp_frame->data[0], pData, sizeof(int16_t) * m_SndBufferSize * 2);
//
@ -258,6 +262,7 @@ void CVideo::nextAudioFrame(short* pData)
// );
// dbg_msg("video_recorder", "dst_nb_samples: %d", dst_nb_samples);
fwrite(pData, sizeof(short), 1024, m_dbgfile);
av_samples_fill_arrays(
(uint8_t**)m_AudioStream.tmp_frame->data,
@ -265,7 +270,7 @@ void CVideo::nextAudioFrame(short* pData)
(const uint8_t*)pData,
2, // channels
m_AudioStream.tmp_frame->nb_samples,
AV_SAMPLE_FMT_S16P,
AV_SAMPLE_FMT_S16,
0 // align
);
@ -457,6 +462,7 @@ void CVideo::open_audio()
c = m_AudioStream.enc;
/* open it */
m_dbgfile = fopen("/tmp/pcm_dbg", "wb");
av_dict_copy(&opt, m_pOptDict, 0);
ret = avcodec_open2(c, m_AudioCodec, &opt);
av_dict_free(&opt);
@ -475,7 +481,7 @@ void CVideo::open_audio()
m_AudioStream.frame = alloc_audio_frame(c->sample_fmt, c->channel_layout, c->sample_rate, nb_samples);
m_AudioStream.tmp_frame = alloc_audio_frame(AV_SAMPLE_FMT_S16P, AV_CH_LAYOUT_STEREO, g_Config.m_SndRate, m_SndBufferSize);
m_AudioStream.tmp_frame = alloc_audio_frame(AV_SAMPLE_FMT_S16, AV_CH_LAYOUT_STEREO, g_Config.m_SndRate, m_SndBufferSize);
/* copy the stream parameters to the muxer */
ret = avcodec_parameters_from_context(m_AudioStream.st->codecpar, c);
@ -494,7 +500,7 @@ void CVideo::open_audio()
/* set options */
av_opt_set_int (m_AudioStream.swr_ctx, "in_channel_count", 2, 0);
av_opt_set_int (m_AudioStream.swr_ctx, "in_sample_rate", g_Config.m_SndRate, 0);
av_opt_set_sample_fmt(m_AudioStream.swr_ctx, "in_sample_fmt", AV_SAMPLE_FMT_S16P, 0);
av_opt_set_sample_fmt(m_AudioStream.swr_ctx, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
av_opt_set_int (m_AudioStream.swr_ctx, "out_channel_count", c->channels, 0);
av_opt_set_int (m_AudioStream.swr_ctx, "out_sample_rate", c->sample_rate, 0);
av_opt_set_sample_fmt(m_AudioStream.swr_ctx, "out_sample_fmt", c->sample_fmt, 0);
@ -576,7 +582,7 @@ void CVideo::add_stream(OutputStream *ost, AVFormatContext *oc, AVCodec **codec,
c->bit_rate = 400000;
/* Resolution must be a multiple of two. */
c->width = m_Width;
c->height = m_Height;
c->height = m_Height%2==0?m_Height:m_Height-1;
/* timebase: This is the fundamental unit of time (in seconds) in terms
* of which frame timestamps are represented. For fixed-fps content,
* timebase should be 1/framerate and timestamp increments should be

View file

@ -31,6 +31,7 @@ extern "C"
#include <base/system.h>
#include <engine/shared/video.h>
#include <engine/shared/demo.h>
// a wrapper around a single output AVStream
@ -92,6 +93,7 @@ private:
int m_Width;
int m_Height;
char m_Name[256];
FILE *m_dbgfile;
int m_FPS;

View file

@ -935,6 +935,10 @@ int CDemoPlayer::Update(bool RealTime)
break;
// do one more tick
#if defined(CONF_VIDEORECORDER)
if(IVideo::Current())
IVideo::Current()->SetBreak((double)m_Info.m_Info.m_Speed);
#endif
DoTick();
if(m_Info.m_Info.m_Paused)

View file

@ -25,12 +25,16 @@ public:
static void SetLocalStartTime(int64 LocalStartTime) { ms_LocalStartTime = LocalStartTime; }
static void SetFPS(int fps) { ms_TickTime = time_freq() / fps; }
void SetBreak(double Speed) { m_Break += 4.0/Speed; } // I think this 4 is related to `Len/2/2` in `Mix` function of /expand/teeworlds/demo/video_3/src/engine/client/sound.cpp
double GetBreak() { return m_Break; }
protected:
static IVideo* ms_pCurrentVideo;
static int64 ms_Time;
static int64 ms_LocalStartTime;
static float ms_LocalTime;
static int64 ms_TickTime;
double m_Break;
};