diff --git a/plugins/channelrx/demoddatv/CMakeLists.txt b/plugins/channelrx/demoddatv/CMakeLists.txt
index 00bb84c8b..d1fefa3c5 100644
--- a/plugins/channelrx/demoddatv/CMakeLists.txt
+++ b/plugins/channelrx/demoddatv/CMakeLists.txt
@@ -40,7 +40,8 @@ include_directories(
${AVCODEC_INCLUDE_DIRS}
${AVFORMAT_INCLUDE_DIRS}
${AVUTIL_INCLUDE_DIRS}
- ${SWSCALE_INCLUDE_DIRS}
+ ${SWSCALE_INCLUDE_DIRS}
+ ${SWRESAMPLE_INCLUDE_DIRS}
)
#include(${QT_USE_FILE})
@@ -64,7 +65,8 @@ target_link_libraries(demoddatv
${AVCODEC_LIBRARIES}
${AVFORMAT_LIBRARIES}
${AVUTIL_LIBRARIES}
- ${SWSCALE_LIBRARIES}
+ ${SWSCALE_LIBRARIES}
+ ${SWRESAMPLE_LIBRARIES}
)
find_package(Qt5MultimediaWidgets 5.0 REQUIRED)
diff --git a/plugins/channelrx/demoddatv/datvideorender.cpp b/plugins/channelrx/demoddatv/datvideorender.cpp
index b4f026601..55d6899cc 100644
--- a/plugins/channelrx/demoddatv/datvideorender.cpp
+++ b/plugins/channelrx/demoddatv/datvideorender.cpp
@@ -15,6 +15,12 @@
// along with this program. If not, see . //
///////////////////////////////////////////////////////////////////////////////////
+extern "C"
+{
+#include
+}
+
+#include "audio/audiofifo.h"
#include "datvideorender.h"
DATVideoRender::DATVideoRender(QWidget *parent) : TVScreen(true, parent)
@@ -31,6 +37,8 @@ DATVideoRender::DATVideoRender(QWidget *parent) : TVScreen(true, parent)
m_audioBuffer.resize(1 << 14);
m_audioBufferFill = 0;
m_audioFifo = nullptr;
+ m_audioSWR = nullptr;
+ m_audioSampleRate = 48000;
m_videoStreamIndex = -1;
m_audioStreamIndex = -1;
@@ -275,6 +283,14 @@ bool DATVideoRender::PreprocessStream()
{
m_audioDecoderCtx = m_formatCtx->streams[m_audioStreamIndex]->codec;
+ qDebug() << "DATVideoProcess::PreprocessStream: audio: "
+ << " channels: " << m_audioDecoderCtx->channels
+ << " channel_layout: " << m_audioDecoderCtx->channel_layout
+ << " sample_rate: " << m_audioDecoderCtx->sample_rate
+ << " sample_fmt: " << m_audioDecoderCtx->sample_fmt
+ << " codec_name: "<< QString(m_audioDecoderCtx->codec_name)
+ << " codec_id: "<< m_audioDecoderCtx->codec_id;
+
audioCodec = avcodec_find_decoder(m_audioDecoderCtx->codec_id);
if (audioCodec == nullptr)
@@ -284,11 +300,18 @@ bool DATVideoRender::PreprocessStream()
}
else
{
+ qDebug() << "DATVideoProcess::PreprocessStream: audio CODEC found: " << audioCodec->name;
+
if (avcodec_open2(m_audioDecoderCtx, audioCodec, nullptr) < 0)
{
qDebug() << "DATVideoProcess::PreprocessStream cannot open associated audio CODEC";
m_audioStreamIndex = -1; // invalidate audio
}
+ else
+ {
+ setResampler();
+ }
+
}
}
@@ -520,8 +543,28 @@ bool DATVideoRender::RenderStream()
}
}
// Audio channel
- else if (packet.stream_index == m_audioStreamIndex)
+ else if ((packet.stream_index == m_audioStreamIndex) && (m_audioFifo) && (swr_is_initialized(m_audioSWR)))
{
+ memset(m_frame, 0, sizeof(AVFrame));
+ av_frame_unref(m_frame);
+ gotFrame = 0;
+
+ if (avcodec_decode_audio4(m_audioDecoderCtx, m_frame, &gotFrame, &packet) >= 0)
+ {
+ if (gotFrame)
+ {
+ uint16_t *audioBuffer;
+ av_samples_alloc((uint8_t**) &audioBuffer, nullptr, 2, m_frame->nb_samples, AV_SAMPLE_FMT_S16, 0);
+ int frame_count = swr_convert(m_audioSWR, (uint8_t**) &audioBuffer, m_frame->nb_samples, (const uint8_t**) m_frame->data, m_frame->nb_samples);
+ int res = m_audioFifo->write((const quint8*)&m_audioBuffer[0], frame_count);
+
+ if (res != frame_count)
+ {
+ qDebug("DATVideoRender::RenderStream: %u/%u audio samples written", res, frame_count);
+ m_audioFifo->clear();
+ }
+ }
+ }
}
av_packet_unref(&packet);
@@ -533,6 +576,20 @@ bool DATVideoRender::RenderStream()
return true;
}
+void DATVideoRender::setResampler()
+{
+ m_audioSWR = swr_alloc();
+ av_opt_set_int(m_audioSWR, "in_channel_count", m_audioDecoderCtx->channels, 0);
+ av_opt_set_int(m_audioSWR, "out_channel_count", 2, 0);
+ av_opt_set_int(m_audioSWR, "in_channel_layout", m_audioDecoderCtx->channel_layout, 0);
+ av_opt_set_int(m_audioSWR, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0);
+ av_opt_set_int(m_audioSWR, "in_sample_rate", m_audioDecoderCtx->sample_rate, 0);
+ av_opt_set_int(m_audioSWR, "out_sample_rate", m_audioSampleRate, 0);
+ av_opt_set_sample_fmt(m_audioSWR, "in_sample_fmt", m_audioDecoderCtx->sample_fmt, 0);
+ av_opt_set_sample_fmt(m_audioSWR, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
+ swr_init(m_audioSWR);
+}
+
bool DATVideoRender::CloseStream(QIODevice *device)
{
diff --git a/plugins/channelrx/demoddatv/datvideorender.h b/plugins/channelrx/demoddatv/datvideorender.h
index 9bcee44f8..01138f26d 100644
--- a/plugins/channelrx/demoddatv/datvideorender.h
+++ b/plugins/channelrx/demoddatv/datvideorender.h
@@ -114,6 +114,8 @@ class DATVideoRender : public TVScreen
AudioVector m_audioBuffer;
uint32_t m_audioBufferFill;
AudioFifo *m_audioFifo;
+ struct SwrContext* m_audioSWR;
+ int m_audioSampleRate;
uint8_t *m_pbytDecodedData[4];
int m_pintDecodedLineSize[4];
@@ -134,6 +136,9 @@ class DATVideoRender : public TVScreen
protected:
virtual bool eventFilter(QObject *obj, QEvent *event);
+ private:
+ void setResampler();
+
signals:
void onMetaDataChanged(DataTSMetaData2 *metaData);
};