Commit a07c84f7 by 景炳强

1.音视频同步

parent 46675251
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -29,7 +29,7 @@ class DeckLinkOutputDevice : public QObject, public IDeckLinkVideoOutputCallback
using ScheduledFramesList = std::list<ComPtr<DeckLinkOutputVideoFrame>>;
public:
DeckLinkOutputDevice(ComPtr<IDeckLink>& decklink, int videoPrerollSize);
DeckLinkOutputDevice(ComPtr<IDeckLink>& decklink, int videoPrerollSize,int index);
virtual ~DeckLinkOutputDevice() = default;
// IUnknown interface
......@@ -95,4 +95,9 @@ private:
void outputAudioFrameFunc(void);
bool waitForReferenceSignalToLock(void);
void checkEndOfPreroll(void);
//
int64_t current_video_time = 0;
int64_t current_sleep_ms = 0;
qint32 Index;
};
......@@ -35,9 +35,10 @@ public:
DeckLinkOpenGLWidget* GetPreviewView(void) const { return PreviewView; }
ComPtr<DeckLinkOutputDevice> GetSelectedDevice(void) const { return SelectedDevice; }
void BindInputPage(DeckLinkInputPage* inputPage, std::shared_ptr<ProcessThread> process) {
void BindInputPage(DeckLinkInputPage* inputPage, std::shared_ptr<ProcessThread> process,int index) {
BindingInputPage = inputPage;
Process = process;
Index = index;
}
......@@ -63,6 +64,7 @@ private:
DeckLinkInputPage* BindingInputPage;
std::shared_ptr<ProcessThread> Process;
qint32 Index;
ComPtr<DeckLinkOutputDevice> SelectedDevice;
......
......@@ -5,10 +5,11 @@
#include "BlackMagicDesign/ReferenceTime.h"
extern int OutputDeleyTime;
extern int OutputPlayMode;
#define OUTPUT_1080 1
DeckLinkOutputDevice::DeckLinkOutputDevice(ComPtr<IDeckLink>& decklink, int videoPrerollSize)
DeckLinkOutputDevice::DeckLinkOutputDevice(ComPtr<IDeckLink>& decklink, int videoPrerollSize,int index)
: RefCount(1),
state(PlaybackState::Idle),
deckLink(decklink),
......@@ -17,11 +18,13 @@ DeckLinkOutputDevice::DeckLinkOutputDevice(ComPtr<IDeckLink>& decklink, int vide
seenFirstVideoFrame(false),
startPlaybackTime(0),
scheduledFrameCompletedCallback(nullptr),
first_sleep(false)
first_sleep(false),
Index(index)
{
// Check that device has an output interface, this will throw an error if using a capture-only device such as DeckLink Mini Recorder
if (!deckLinkOutput)
throw std::runtime_error("DeckLink device does not have an output interface.");
current_sleep_ms = OutputDeleyTime * 1000;
}
// IUnknown methods
......@@ -120,8 +123,17 @@ HRESULT DeckLinkOutputDevice::ScheduledPlaybackHasStopped()
bool DeckLinkOutputDevice::StartPlayback(BMDDisplayMode displayMode, bool enable3D, BMDPixelFormat pixelFormat, bool requireReferenceLocked, IDeckLinkScreenPreviewCallback* screenPreviewCallback)
{
BMDDisplayMode outputDisplayMode;
#if OUTPUT_1080
outputDisplayMode = displayMode;
switch (OutputPlayMode)
{
case 1:
outputDisplayMode = bmdModeHD1080i50;
break;
default:
outputDisplayMode = displayMode;
break;
}
#else
outputDisplayMode = BMDDisplayMode::bmdModeHD720p50;
#endif
......@@ -302,17 +314,17 @@ bool DeckLinkOutputDevice::getReferenceSignalMode(BMDDisplayMode* mode)
if(outputVideoFrameQueue.WaitFor(outputImage))
{
auto now_time = QDateTime::currentMSecsSinceEpoch();
auto input_time = outputImage->getInputFrameCurTimeStamp();
auto dever_time = now_time - input_time;
qDebug() << "input frame cur time:" << input_time << " now time:" <<now_time << " dever time:"<<dever_time << "\n";
auto dever_time = now_time - outputImage->getInputFrameCurTimeStamp();
qDebug() << "index:"<<Index << "input frame cur time:" << outputImage->getInputFrameCurTimeStamp() << " now time:" << now_time << " dever time:" << dever_time << "\n";
if (dever_time < OutputDeleyTime * 1000)
{
std::this_thread::sleep_for(std::chrono::milliseconds(OutputDeleyTime * 1000 - dever_time));
current_sleep_ms = OutputDeleyTime * 1000 - dever_time;
std::this_thread::sleep_for(std::chrono::milliseconds(current_sleep_ms));
}
END_WAIT_TIME_COUNTER
//std::lock_guard<std::mutex> locker(mutex);
current_video_time = outputImage->getInputFrameCurTimeStamp();
ComPtr<DeckLinkOutputVideoFrame> videoFrame = MakeComPtr<DeckLinkOutputVideoFrame>(outputImage);
// Record the stream time of the first frame, so we can start playing from the point
......@@ -353,6 +365,27 @@ bool DeckLinkOutputDevice::getReferenceSignalMode(BMDDisplayMode* mode)
{
auto data = audio_packet->audio_data.data();
auto sample = audio_packet->sample;
auto audio_tm = audio_packet->frame_time_stamp;
qint32 duration = sample * 1000 / 48000;
while(true)
{
/*if (!current_video_time) {
std::this_thread::sleep_for(std::chrono::milliseconds(current_sleep_ms));
}*/
if(audio_tm > current_video_time && audio_tm - current_video_time > duration)
{
std::this_thread::sleep_for(std::chrono::milliseconds(duration));
}
else if ( (audio_tm > current_video_time && audio_tm - current_video_time <= duration) || audio_tm <= current_video_time)
{
break;
}
else {
qDebug() << "send audio other--------------\n";
}
}
qDebug() << "index:"<<Index << "send sdi audio timestamp:" << audio_tm << ",video timestamp:"<<current_video_time << "\n";
quint32 sampleFramesWritten;
HRESULT ret = deckLinkOutput->WriteAudioSamplesSync(data,sample,&sampleFramesWritten);
if(ret == S_OK)
......
......@@ -245,7 +245,7 @@ void DeckLinkOutputPage::RequestedDeviceGranted(ComPtr<IDeckLink>& device)
{
START_SLOT_TIME_COUNTER
SelectedDevice = MakeComPtr<DeckLinkOutputDevice>(device, 1);
SelectedDevice = MakeComPtr<DeckLinkOutputDevice>(device, 1,Index);
// Register profile callback with newly selected device`s profile manager
......
......@@ -14,6 +14,7 @@
int OutputDeleyTime = 5;
int FrameRate = 50;
int PrvwFlag = 0;
int OutputPlayMode = 0;
qint64 StartTimeStamp = 0;
MomentaMedia::MomentaMedia(QWidget *parent)
: QMainWindow(parent)
......@@ -71,7 +72,7 @@ MomentaMedia::MomentaMedia(QWidget *parent)
if( i < InputDevicePages.size())
{
OutputDevicePages[i]->BindInputPage(InputDevicePages[i], ProcessThreads[i]);
OutputDevicePages[i]->BindInputPage(InputDevicePages[i], ProcessThreads[i],i);
}
connect(OutputDevicePages[i], &DeckLinkOutputPage::RequestDeckLink, this, std::bind(&MomentaMedia::RequestOutputDevice, this, OutputDevicePages[i], std::placeholders::_1));
......@@ -194,9 +195,12 @@ void MomentaMedia::closeEvent(QCloseEvent* event)
// DeckLinkDiscovery->Disable();
// exit(0);
qint64 pid = QCoreApplication::applicationPid();
QString cmd = QString("TASKKILL /PID %1 /F").arg(pid);//Windows 系统下,杀死当前进程命令,不杀死其开启的子进程
WinExec(cmd.toLocal8Bit().data(), SW_HIDE);//SW_HIDE:控制运行cmd时,不弹出cmd运行窗口
//qint64 pid = QCoreApplication::applicationPid();
//QString cmd = QString("TASKKILL /PID %1 /F").arg(pid);//Windows 系统下,杀死当前进程命令,不杀死其开启的子进程
//WinExec(cmd.toLocal8Bit().data(), SW_HIDE);//SW_HIDE:控制运行cmd时,不弹出cmd运行窗口
HANDLE hself = GetCurrentProcess();
TerminateProcess(hself, 0);
}
......@@ -509,6 +513,8 @@ void MomentaMedia::ReadSettings()
FrameRate = settings.value("FRAME_RATE", "").toInt();
if (FrameRate < 25) FrameRate = 25;
PrvwFlag = settings.value("PRVW_FLAG", "").toInt();
OutputPlayMode = settings.value("OUTPUT_PLAY_MODE", "").toInt();
//qDebug() << "deleyTime=" << deleyTime << endl;
settings.endGroup();
}
\ No newline at end of file
......@@ -402,6 +402,7 @@ void ProcessThread::WorkCutImage(std::shared_ptr<Image>& pImage, RoiMessage& roi
libyuv::ConvertToARGB(pImage->GetBytes(), (1920 * 1080 << 2), buff1, (roi.Height() << 2),
roi.X(), roi.Y(), 1920, 1080, roi.Width(), roi.Height(),
libyuv::kRotate90, libyuv::FOURCC_ARGB);
uint8_t* buff2 = new uint8_t[1440 * 1080 << 2];
libyuv::ARGBScale(buff1, (roi.Height() << 2), roi.Height(), roi.Width(),
......
[DELEYTIME]
DELEY_TIME=10
\ No newline at end of file
DELEY_TIME=2
FRAME_RATE=25
PRVW_FLAG=0
OUTPUT_PLAY_MODE=0
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
[DELEYTIME]
DELEY_TIME=5
DELEY_TIME=2
FRAME_RATE=25
PRVW_FLAG=0
PRVW_FLAG=1
OUTPUT_PLAY_MODE=0
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment