From 9866a73b1cebe51a2a997cc527287e34ec0b0172 Mon Sep 17 00:00:00 2001 From: sirius Date: Sat, 26 Oct 2019 19:54:25 +0800 Subject: [PATCH] sync audio and video --- src/engine/client/sound.cpp | 14 +++++++++++++- src/engine/client/video.cpp | 16 +++++++++++----- src/engine/client/video.h | 2 ++ src/engine/shared/demo.cpp | 4 ++++ src/engine/shared/video.h | 4 ++++ 5 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/engine/client/sound.cpp b/src/engine/client/sound.cpp index f9d7ab9bd..6b2fddc57 100644 --- a/src/engine/client/sound.cpp +++ b/src/engine/client/sound.cpp @@ -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 } diff --git a/src/engine/client/video.cpp b/src/engine/client/video.cpp index 052cb4c54..597df9edd 100644 --- a/src/engine/client/video.cpp +++ b/src/engine/client/video.cpp @@ -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 diff --git a/src/engine/client/video.h b/src/engine/client/video.h index 77f519ff8..f778085e2 100644 --- a/src/engine/client/video.h +++ b/src/engine/client/video.h @@ -31,6 +31,7 @@ extern "C" #include #include +#include // 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; diff --git a/src/engine/shared/demo.cpp b/src/engine/shared/demo.cpp index c757ffe22..a6c036141 100644 --- a/src/engine/shared/demo.cpp +++ b/src/engine/shared/demo.cpp @@ -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) diff --git a/src/engine/shared/video.h b/src/engine/shared/video.h index 72dedab26..78ac24fd3 100644 --- a/src/engine/shared/video.h +++ b/src/engine/shared/video.h @@ -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; };