kopia lustrzana https://github.com/f4exb/sdrangel
Merge pull request #593 from Vort/atv_double_buffering
ATV Demodulator: implement double bufferingpull/601/head
commit
aa8f9f6805
|
@ -484,7 +484,7 @@ void ATVDemodSink::applyChannelSettings(int channelSampleRate, int channelFreque
|
|||
m_samplesPerLine - m_numberSamplesPerLineSignals,
|
||||
m_settings.m_nbLines - m_numberOfBlackLines
|
||||
);
|
||||
m_tvScreenData = m_registeredTVScreen->getData();
|
||||
m_tvScreenBuffer = m_registeredTVScreen->getBackBuffer();
|
||||
}
|
||||
|
||||
m_fieldIndex = 0;
|
||||
|
@ -576,7 +576,7 @@ void ATVDemodSink::applySettings(const ATVDemodSettings& settings, bool force)
|
|||
m_samplesPerLine - m_numberSamplesPerLineSignals,
|
||||
m_settings.m_nbLines - m_numberOfBlackLines
|
||||
);
|
||||
m_tvScreenData = m_registeredTVScreen->getData();
|
||||
m_tvScreenBuffer = m_registeredTVScreen->getBackBuffer();
|
||||
}
|
||||
|
||||
m_fieldIndex = 0;
|
||||
|
|
|
@ -109,7 +109,7 @@ private:
|
|||
|
||||
//*************** ATV PARAMETERS ***************
|
||||
TVScreenAnalog *m_registeredTVScreen;
|
||||
std::shared_ptr<TVScreenAnalogData> m_tvScreenData;
|
||||
std::shared_ptr<TVScreenAnalogBuffer> m_tvScreenBuffer;
|
||||
|
||||
//int m_intNumberSamplePerLine;
|
||||
int m_numberSamplesPerHTopNom; //!< number of samples per horizontal synchronization pulse (pulse in ultra-black) - nominal value
|
||||
|
@ -199,7 +199,7 @@ private:
|
|||
inline void processSample(float& sample, int& sampleVideo)
|
||||
{
|
||||
// Filling pixel on the current line - reference index 0 at start of sync pulse
|
||||
m_tvScreenData->setSampleValue(m_sampleOffset - m_numberSamplesPerHSync, sampleVideo);
|
||||
m_tvScreenBuffer->setSampleValue(m_sampleOffset - m_numberSamplesPerHSync, sampleVideo);
|
||||
|
||||
if (m_settings.m_hSync)
|
||||
{
|
||||
|
@ -278,7 +278,7 @@ private:
|
|||
{
|
||||
if (m_lineIndex == m_numberOfVSyncLines + 3 && m_fieldIndex == 0)
|
||||
{
|
||||
m_registeredTVScreen->renderImage();
|
||||
m_tvScreenBuffer = m_registeredTVScreen->swapBuffers();
|
||||
}
|
||||
|
||||
if (m_vSyncDetectSampleCount > m_vSyncDetectThreshold &&
|
||||
|
@ -311,7 +311,7 @@ private:
|
|||
if (m_interleaved)
|
||||
rowIndex = rowIndex * 2 - m_fieldIndex;
|
||||
|
||||
m_tvScreenData->selectRow(rowIndex, m_sampleOffsetFrac);
|
||||
m_tvScreenBuffer->selectRow(rowIndex, m_sampleOffsetFrac);
|
||||
}
|
||||
|
||||
// Vertical sync is obtained by skipping horizontal sync on the line that triggers vertical sync (new frame)
|
||||
|
@ -320,11 +320,11 @@ private:
|
|||
if ((m_sampleOffsetDetected > (3 * m_samplesPerLine) / 2) // Vertical sync is first horizontal sync after skip (count at least 1.5 line length)
|
||||
|| (!m_settings.m_vSync && (m_lineIndex >= m_settings.m_nbLines))) // Vsync ignored and reached nominal number of lines per frame
|
||||
{
|
||||
m_registeredTVScreen->renderImage();
|
||||
m_tvScreenBuffer = m_registeredTVScreen->swapBuffers();
|
||||
m_lineIndex = 0;
|
||||
}
|
||||
|
||||
m_tvScreenData->selectRow(m_lineIndex, m_sampleOffsetFrac);
|
||||
m_tvScreenBuffer->selectRow(m_lineIndex, m_sampleOffsetFrac);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -68,10 +68,11 @@ TVScreenAnalog::TVScreenAnalog(QWidget *parent)
|
|||
: QGLWidget(parent)
|
||||
{
|
||||
m_isDataChanged = false;
|
||||
m_data = std::make_shared<TVScreenAnalogData>(5, 1);
|
||||
m_frontBuffer = std::make_shared<TVScreenAnalogBuffer>(5, 1);
|
||||
m_backBuffer = std::make_shared<TVScreenAnalogBuffer>(5, 1);
|
||||
|
||||
connect(&m_objTimer, SIGNAL(timeout()), this, SLOT(tick()));
|
||||
m_objTimer.start(40); // capped at 25 FPS
|
||||
connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(tick()));
|
||||
m_updateTimer.start(40); // capped at 25 FPS
|
||||
}
|
||||
|
||||
void TVScreenAnalog::cleanup()
|
||||
|
@ -81,9 +82,9 @@ void TVScreenAnalog::cleanup()
|
|||
m_lineShiftsTexture = nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<TVScreenAnalogData> TVScreenAnalog::getData()
|
||||
std::shared_ptr<TVScreenAnalogBuffer> TVScreenAnalog::getBackBuffer()
|
||||
{
|
||||
return m_data;
|
||||
return m_backBuffer;
|
||||
}
|
||||
|
||||
void TVScreenAnalog::resizeTVScreen(int intCols, int intRows)
|
||||
|
@ -91,8 +92,12 @@ void TVScreenAnalog::resizeTVScreen(int intCols, int intRows)
|
|||
qDebug("TVScreen::resizeTVScreen: cols: %d, rows: %d", intCols, intRows);
|
||||
|
||||
int colsAdj = intCols + 4;
|
||||
if (m_data->getWidth() != colsAdj || m_data->getHeight() != intRows)
|
||||
m_data = std::make_shared<TVScreenAnalogData>(colsAdj, intRows);
|
||||
QMutexLocker lock(&m_buffersMutex);
|
||||
if (m_frontBuffer->getWidth() != colsAdj || m_frontBuffer->getHeight() != intRows)
|
||||
{
|
||||
m_frontBuffer = std::make_shared<TVScreenAnalogBuffer>(colsAdj, intRows);
|
||||
m_backBuffer = std::make_shared<TVScreenAnalogBuffer>(colsAdj, intRows);
|
||||
}
|
||||
}
|
||||
|
||||
void TVScreenAnalog::resizeGL(int intWidth, int intHeight)
|
||||
|
@ -143,12 +148,12 @@ void TVScreenAnalog::initializeGL()
|
|||
m_texelHeightLoc = m_shader->uniformLocation("tlh");
|
||||
}
|
||||
|
||||
void TVScreenAnalog::initializeTextures()
|
||||
void TVScreenAnalog::initializeTextures(std::shared_ptr<TVScreenAnalogBuffer> buffer)
|
||||
{
|
||||
m_imageTexture = std::make_shared<QOpenGLTexture>(QOpenGLTexture::Target2D);
|
||||
m_lineShiftsTexture = std::make_shared<QOpenGLTexture>(QOpenGLTexture::Target2D);
|
||||
m_imageTexture->setSize(m_data->getWidth(), m_data->getHeight());
|
||||
m_lineShiftsTexture->setSize(1, m_data->getHeight());
|
||||
m_imageTexture->setSize(buffer->getWidth(), buffer->getHeight());
|
||||
m_lineShiftsTexture->setSize(1, buffer->getHeight());
|
||||
m_imageTexture->setFormat(QOpenGLTexture::RGBA8_UNorm);
|
||||
m_lineShiftsTexture->setFormat(QOpenGLTexture::RGBA8_UNorm);
|
||||
m_imageTexture->setAutoMipMapGenerationEnabled(false);
|
||||
|
@ -166,9 +171,12 @@ void TVScreenAnalog::initializeTextures()
|
|||
m_lineShiftsTexture->setWrapMode(QOpenGLTexture::DirectionT, QOpenGLTexture::ClampToEdge);
|
||||
}
|
||||
|
||||
void TVScreenAnalog::renderImage()
|
||||
std::shared_ptr<TVScreenAnalogBuffer> TVScreenAnalog::swapBuffers()
|
||||
{
|
||||
QMutexLocker lock(&m_buffersMutex);
|
||||
std::swap(m_frontBuffer, m_backBuffer);
|
||||
m_isDataChanged = true;
|
||||
return m_backBuffer;
|
||||
}
|
||||
|
||||
void TVScreenAnalog::tick()
|
||||
|
@ -190,15 +198,17 @@ void TVScreenAnalog::paintGL()
|
|||
return;
|
||||
}
|
||||
|
||||
std::shared_ptr<TVScreenAnalogBuffer> buffer = m_frontBuffer;
|
||||
|
||||
if (!m_imageTexture ||
|
||||
m_imageTexture->width() != m_data->getWidth() ||
|
||||
m_imageTexture->height() != m_data->getHeight())
|
||||
m_imageTexture->width() != buffer->getWidth() ||
|
||||
m_imageTexture->height() != buffer->getHeight())
|
||||
{
|
||||
initializeTextures();
|
||||
initializeTextures(buffer);
|
||||
}
|
||||
|
||||
float imageWidth = m_data->getWidth();
|
||||
float imageHeight = m_data->getHeight();
|
||||
float imageWidth = buffer->getWidth();
|
||||
float imageHeight = buffer->getHeight();
|
||||
float texelWidth = 1.0f / imageWidth;
|
||||
float texelHeight = 1.0f / imageHeight;
|
||||
|
||||
|
@ -213,12 +223,12 @@ void TVScreenAnalog::paintGL()
|
|||
glActiveTexture(GL_TEXTURE0);
|
||||
m_imageTexture->bind();
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
|
||||
m_data->getWidth(), m_data->getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, m_data->getImageData());
|
||||
buffer->getWidth(), buffer->getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, buffer->getImageData());
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
m_lineShiftsTexture->bind();
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
|
||||
1, m_data->getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, m_data->getLineShiftData());
|
||||
1, buffer->getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, buffer->getLineShiftData());
|
||||
|
||||
float rectHalfWidth = 1.0f + 4.0f / (imageWidth - 4.0f);
|
||||
GLfloat vertices[] =
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include <memory>
|
||||
#include <algorithm>
|
||||
|
||||
#include <QImage>
|
||||
#include <QMutex>
|
||||
#include <QTimer>
|
||||
#include <QGLWidget>
|
||||
|
@ -36,10 +35,10 @@
|
|||
#include <QOpenGLFunctions>
|
||||
#include <QOpenGLShaderProgram>
|
||||
|
||||
class TVScreenAnalogData
|
||||
class TVScreenAnalogBuffer
|
||||
{
|
||||
public:
|
||||
TVScreenAnalogData(int width, int height)
|
||||
TVScreenAnalogBuffer(int width, int height)
|
||||
{
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
|
@ -53,7 +52,7 @@ public:
|
|||
std::fill(m_lineShiftData, m_lineShiftData + height, 127);
|
||||
}
|
||||
|
||||
~TVScreenAnalogData()
|
||||
~TVScreenAnalogBuffer()
|
||||
{
|
||||
delete[] m_imageData;
|
||||
delete[] m_lineShiftData;
|
||||
|
@ -116,7 +115,7 @@ class SDRGUI_API TVScreenAnalog : public QGLWidget, protected QOpenGLFunctions
|
|||
{
|
||||
Q_OBJECT
|
||||
|
||||
QTimer m_objTimer;
|
||||
QTimer m_updateTimer;
|
||||
|
||||
bool m_isDataChanged;
|
||||
|
||||
|
@ -129,7 +128,9 @@ class SDRGUI_API TVScreenAnalog : public QGLWidget, protected QOpenGLFunctions
|
|||
int m_vertexAttribIndex;
|
||||
int m_texCoordAttribIndex;
|
||||
|
||||
std::shared_ptr<TVScreenAnalogData> m_data;
|
||||
QMutex m_buffersMutex;
|
||||
std::shared_ptr<TVScreenAnalogBuffer> m_frontBuffer;
|
||||
std::shared_ptr<TVScreenAnalogBuffer> m_backBuffer;
|
||||
|
||||
std::shared_ptr<QOpenGLShaderProgram> m_shader;
|
||||
std::shared_ptr<QOpenGLTexture> m_imageTexture;
|
||||
|
@ -138,12 +139,12 @@ class SDRGUI_API TVScreenAnalog : public QGLWidget, protected QOpenGLFunctions
|
|||
public:
|
||||
TVScreenAnalog(QWidget *parent);
|
||||
|
||||
std::shared_ptr<TVScreenAnalogData> getData();
|
||||
std::shared_ptr<TVScreenAnalogBuffer> getBackBuffer();
|
||||
std::shared_ptr<TVScreenAnalogBuffer> swapBuffers();
|
||||
void resizeTVScreen(int intCols, int intRows);
|
||||
void renderImage();
|
||||
|
||||
private:
|
||||
void initializeTextures();
|
||||
void initializeTextures(std::shared_ptr<TVScreenAnalogBuffer> buffer);
|
||||
void initializeGL() override;
|
||||
void paintGL() override;
|
||||
void resizeGL(int width, int height);
|
||||
|
|
Ładowanie…
Reference in New Issue