DATV demod: pre-process audio stream

pull/326/head
f4exb 2019-03-20 00:07:05 +01:00
rodzic b83b7eec06
commit 8001f9c1c6
3 zmienionych plików z 123 dodań i 100 usunięć

Wyświetl plik

@ -939,7 +939,7 @@ void DATVDemod::applySettings(const DATVDemodSettings& settings, bool force)
{ {
AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager(); AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
int audioDeviceIndex = audioDeviceManager->getOutputDeviceIndex(settings.m_audioDeviceName); int audioDeviceIndex = audioDeviceManager->getOutputDeviceIndex(settings.m_audioDeviceName);
audioDeviceManager->addAudioSink(&m_audioFifo, getInputMessageQueue(), audioDeviceIndex); audioDeviceManager->addAudioSink(&m_audioFifo, getInputMessageQueue(), audioDeviceIndex); // removes from current if necessary
// uint32_t audioSampleRate = audioDeviceManager->getOutputSampleRate(audioDeviceIndex); // uint32_t audioSampleRate = audioDeviceManager->getOutputSampleRate(audioDeviceIndex);
// if (m_audioSampleRate != audioSampleRate) { // if (m_audioSampleRate != audioSampleRate) {

Wyświetl plik

@ -26,20 +26,20 @@ DATVideoRender::DATVideoRender(QWidget * parent):
m_blnIsFFMPEGInitialized = false; m_blnIsFFMPEGInitialized = false;
m_blnIsOpen = false; m_blnIsOpen = false;
m_objFormatCtx = nullptr; m_formatCtx = nullptr;
m_objDecoderCtx = nullptr; m_videoDecoderCtx = nullptr;
m_objSwsCtx = nullptr; m_objSwsCtx = nullptr;
m_audioBuffer.resize(1<<14); m_audioBuffer.resize(1<<14);
m_audioBufferFill = 0; m_audioBufferFill = 0;
m_audioFifo = nullptr; m_audioFifo = nullptr;
m_intVideoStreamIndex = -1; m_videoStreamIndex = -1;
m_audioStreamIndex = -1; m_audioStreamIndex = -1;
m_intCurrentRenderWidth=-1; m_intCurrentRenderWidth=-1;
m_intCurrentRenderHeight=-1; m_intCurrentRenderHeight=-1;
m_objFrame=nullptr; m_frame=nullptr;
m_intFrameCount=-1; m_frameCount=-1;
} }
bool DATVideoRender::eventFilter(QObject *obj, QEvent *event) bool DATVideoRender::eventFilter(QObject *obj, QEvent *event)
@ -145,37 +145,37 @@ bool DATVideoRender::InitializeFFMPEG()
bool DATVideoRender::PreprocessStream() bool DATVideoRender::PreprocessStream()
{ {
AVDictionary *objOpts = nullptr; AVDictionary *opts = nullptr;
AVCodec *objCodec = nullptr; AVCodec *videoCodec = nullptr;
AVCodec *audioCodec = nullptr;
int intRet=-1; int intRet=-1;
char *objBuffer=nullptr; char *buffer=nullptr;
//Identify stream //Identify stream
if (avformat_find_stream_info(m_objFormatCtx, nullptr) < 0) if (avformat_find_stream_info(m_formatCtx, nullptr) < 0)
{ {
avformat_close_input(&m_objFormatCtx); avformat_close_input(&m_formatCtx);
m_objFormatCtx=nullptr; m_formatCtx = nullptr;
qDebug() << "DATVideoProcess::PreprocessStream cannot find stream info"; qDebug() << "DATVideoProcess::PreprocessStream cannot find stream info";
return false; return false;
} }
//Find video stream //Find video stream
intRet = av_find_best_stream(m_objFormatCtx, AVMEDIA_TYPE_VIDEO, -1, -1, nullptr, 0); intRet = av_find_best_stream(m_formatCtx, AVMEDIA_TYPE_VIDEO, -1, -1, nullptr, 0);
if (intRet < 0) if (intRet < 0)
{ {
avformat_close_input(&m_objFormatCtx); avformat_close_input(&m_formatCtx);
qDebug() << "DATVideoProcess::PreprocessStream cannot find video stream"; qDebug() << "DATVideoProcess::PreprocessStream cannot find video stream";
return false; return false;
} }
m_intVideoStreamIndex = intRet; m_videoStreamIndex = intRet;
//Find audio stream //Find audio stream
intRet = av_find_best_stream(m_objFormatCtx, AVMEDIA_TYPE_AUDIO, -1, -1, nullptr, 0); intRet = av_find_best_stream(m_formatCtx, AVMEDIA_TYPE_AUDIO, -1, -1, nullptr, 0);
if (intRet < 0) { if (intRet < 0) {
qDebug() << "DATVideoProcess::PreprocessStream cannot find audio stream"; qDebug() << "DATVideoProcess::PreprocessStream cannot find audio stream";
@ -183,87 +183,110 @@ bool DATVideoRender::PreprocessStream()
m_audioStreamIndex = intRet; m_audioStreamIndex = intRet;
//Prepare Codec and extract meta data // Prepare Video Codec and extract meta data
// FIXME: codec is depreecated but replacement fails // FIXME: codec is depreecated but replacement fails
// AVCodecParameters *parms = m_objFormatCtx->streams[m_intVideoStreamIndex]->codecpar; // AVCodecParameters *parms = m_formatCtx->streams[m_videoStreamIndex]->codecpar;
// m_objDecoderCtx = new AVCodecContext(); // m_videoDecoderCtx = new AVCodecContext();
// avcodec_parameters_to_context(m_objDecoderCtx, parms); // avcodec_parameters_to_context(m_videoDecoderCtx, parms);
m_objDecoderCtx = m_objFormatCtx->streams[m_intVideoStreamIndex]->codec; m_videoDecoderCtx = m_formatCtx->streams[m_videoStreamIndex]->codec;
//Meta Data //Meta Data
MetaData.PID = m_objFormatCtx->streams[m_intVideoStreamIndex]->id; MetaData.PID = m_formatCtx->streams[m_videoStreamIndex]->id;
MetaData.CodecID = m_objDecoderCtx->codec_id; MetaData.CodecID = m_videoDecoderCtx->codec_id;
MetaData.OK_TransportStream = true; MetaData.OK_TransportStream = true;
MetaData.Program=""; MetaData.Program = "";
MetaData.Stream=""; MetaData.Stream = "";
if(m_objFormatCtx->programs) if (m_formatCtx->programs)
{ {
objBuffer=nullptr; buffer = nullptr;
av_dict_get_string(m_objFormatCtx->programs[m_intVideoStreamIndex]->metadata,&objBuffer,':','\n'); av_dict_get_string(m_formatCtx->programs[m_videoStreamIndex]->metadata, &buffer, ':', '\n');
if(objBuffer!=nullptr) { if (buffer != nullptr) {
MetaData.Program = QString("%1").arg(objBuffer); MetaData.Program = QString("%1").arg(buffer);
} }
} }
objBuffer=nullptr; buffer = nullptr;
av_dict_get_string(m_objFormatCtx->streams[m_intVideoStreamIndex]->metadata,&objBuffer,':','\n'); av_dict_get_string(m_formatCtx->streams[m_videoStreamIndex]->metadata, &buffer, ':', '\n');
if (objBuffer != nullptr) { if (buffer != nullptr) {
MetaData.Stream = QString("%1").arg(objBuffer); MetaData.Stream = QString("%1").arg(buffer);
} }
emit onMetaDataChanged(&MetaData); emit onMetaDataChanged(&MetaData);
//Decoder //Decoder
objCodec = avcodec_find_decoder(m_objDecoderCtx->codec_id); videoCodec = avcodec_find_decoder(m_videoDecoderCtx->codec_id);
if (objCodec == nullptr) if (videoCodec == nullptr)
{ {
avformat_close_input(&m_objFormatCtx); avformat_close_input(&m_formatCtx);
m_objFormatCtx=nullptr; m_formatCtx = nullptr;
qDebug() << "DATVideoProcess::PreprocessStream cannot find associated CODEC"; qDebug() << "DATVideoProcess::PreprocessStream cannot find associated video CODEC";
return false; return false;
} }
av_dict_set(&objOpts, "refcounted_frames", "1", 0); av_dict_set(&opts, "refcounted_frames", "1", 0);
if (avcodec_open2(m_objDecoderCtx, objCodec, &objOpts) < 0) if (avcodec_open2(m_videoDecoderCtx, videoCodec, &opts) < 0)
{ {
avformat_close_input(&m_objFormatCtx); avformat_close_input(&m_formatCtx);
m_objFormatCtx=nullptr; m_formatCtx=nullptr;
qDebug() << "DATVideoProcess::PreprocessStream cannot open associated CODEC"; qDebug() << "DATVideoProcess::PreprocessStream cannot open associated video CODEC";
return false; return false;
} }
//Allocate Frame //Allocate Frame
m_objFrame = av_frame_alloc(); m_frame = av_frame_alloc();
if (!m_objFrame) if (!m_frame)
{ {
avformat_close_input(&m_objFormatCtx); avformat_close_input(&m_formatCtx);
m_objFormatCtx=nullptr; m_formatCtx=nullptr;
qDebug() << "DATVideoProcess::PreprocessStream cannot allocate frame"; qDebug() << "DATVideoProcess::PreprocessStream cannot allocate frame";
return false; return false;
} }
m_intFrameCount=0; m_frameCount = 0;
MetaData.Width=m_objDecoderCtx->width; MetaData.Width = m_videoDecoderCtx->width;
MetaData.Height=m_objDecoderCtx->height; MetaData.Height = m_videoDecoderCtx->height;
MetaData.BitRate= m_objDecoderCtx->bit_rate; MetaData.BitRate = m_videoDecoderCtx->bit_rate;
MetaData.Channels=m_objDecoderCtx->channels; MetaData.Channels = m_videoDecoderCtx->channels;
MetaData.CodecDescription= QString("%1").arg(objCodec->long_name); MetaData.CodecDescription = QString("%1").arg(videoCodec->long_name);
MetaData.OK_VideoStream = true; MetaData.OK_VideoStream = true;
emit onMetaDataChanged(&MetaData); emit onMetaDataChanged(&MetaData);
// Prepare Audio Codec
if (m_audioStreamIndex >= 0)
{
m_audioDecoderCtx = m_formatCtx->streams[m_audioStreamIndex]->codec;
audioCodec = avcodec_find_decoder(m_audioDecoderCtx->codec_id);
if (audioCodec == nullptr)
{
qDebug() << "DATVideoProcess::PreprocessStream cannot find associated audio CODEC";
m_audioStreamIndex = -1; // invalidate audio
}
else
{
if (avcodec_open2(m_audioDecoderCtx, audioCodec, nullptr) < 0)
{
qDebug() << "DATVideoProcess::PreprocessStream cannot open associated audio CODEC";
m_audioStreamIndex = -1; // invalidate audio
}
}
}
return true; return true;
} }
@ -321,9 +344,9 @@ bool DATVideoRender::OpenStream(DATVideostream *objDevice)
//Connect QIODevice to FFMPEG Reader //Connect QIODevice to FFMPEG Reader
m_objFormatCtx = avformat_alloc_context(); m_formatCtx = avformat_alloc_context();
if (m_objFormatCtx == nullptr) if (m_formatCtx == nullptr)
{ {
qDebug() << "DATVideoProcess::OpenStream cannot alloc format FFMPEG context"; qDebug() << "DATVideoProcess::OpenStream cannot alloc format FFMPEG context";
m_blnRunning = false; m_blnRunning = false;
@ -340,10 +363,10 @@ bool DATVideoRender::OpenStream(DATVideostream *objDevice)
nullptr, nullptr,
&SeekFunction); &SeekFunction);
m_objFormatCtx->pb = objIOCtx; m_formatCtx->pb = objIOCtx;
m_objFormatCtx->flags |= AVFMT_FLAG_CUSTOM_IO; m_formatCtx->flags |= AVFMT_FLAG_CUSTOM_IO;
if (avformat_open_input(&m_objFormatCtx, nullptr , nullptr, nullptr) < 0) if (avformat_open_input(&m_formatCtx, nullptr , nullptr, nullptr) < 0)
{ {
qDebug() << "DATVideoProcess::OpenStream cannot open stream"; qDebug() << "DATVideoProcess::OpenStream cannot open stream";
m_blnRunning=false; m_blnRunning=false;
@ -383,7 +406,7 @@ bool DATVideoRender::RenderStream()
//********** Rendering ********** //********** Rendering **********
if (av_read_frame(m_objFormatCtx, &objPacket) < 0) if (av_read_frame(m_formatCtx, &objPacket) < 0)
{ {
qDebug() << "DATVideoProcess::RenderStream reading packet error"; qDebug() << "DATVideoProcess::RenderStream reading packet error";
m_blnRunning=false; m_blnRunning=false;
@ -391,27 +414,27 @@ bool DATVideoRender::RenderStream()
} }
//Video channel //Video channel
if (objPacket.stream_index == m_intVideoStreamIndex) if (objPacket.stream_index == m_videoStreamIndex)
{ {
memset(m_objFrame, 0, sizeof(AVFrame)); memset(m_frame, 0, sizeof(AVFrame));
av_frame_unref(m_objFrame); av_frame_unref(m_frame);
intGotFrame = 0; intGotFrame = 0;
if (new_decode( m_objDecoderCtx, m_objFrame, &intGotFrame, &objPacket)<0) if (new_decode(m_videoDecoderCtx, m_frame, &intGotFrame, &objPacket) < 0)
{ {
qDebug() << "DATVideoProcess::RenderStream decoding packet error"; qDebug() << "DATVideoProcess::RenderStream decoding video packet error";
m_blnRunning=false; m_blnRunning = false;
return false; return false;
} }
if (intGotFrame) if (intGotFrame)
{ {
//Rendering and RGB Converter setup //Rendering and RGB Converter setup
blnNeedRenderingSetup=(m_intFrameCount==0); blnNeedRenderingSetup=(m_frameCount==0);
blnNeedRenderingSetup|=(m_objSwsCtx==nullptr); blnNeedRenderingSetup|=(m_objSwsCtx==nullptr);
if ((m_intCurrentRenderWidth!=m_objFrame->width) || (m_intCurrentRenderHeight!=m_objFrame->height)) { if ((m_intCurrentRenderWidth!=m_frame->width) || (m_intCurrentRenderHeight!=m_frame->height)) {
blnNeedRenderingSetup=true; blnNeedRenderingSetup=true;
} }
@ -426,12 +449,12 @@ bool DATVideoRender::RenderStream()
//Convertisseur YUV -> RGB //Convertisseur YUV -> RGB
m_objSwsCtx = sws_alloc_context(); m_objSwsCtx = sws_alloc_context();
av_opt_set_int(m_objSwsCtx,"srcw",m_objFrame->width,0); av_opt_set_int(m_objSwsCtx,"srcw",m_frame->width,0);
av_opt_set_int(m_objSwsCtx,"srch",m_objFrame->height,0); av_opt_set_int(m_objSwsCtx,"srch",m_frame->height,0);
av_opt_set_int(m_objSwsCtx,"src_format",m_objFrame->format,0); av_opt_set_int(m_objSwsCtx,"src_format",m_frame->format,0);
av_opt_set_int(m_objSwsCtx,"dstw",m_objFrame->width,0); av_opt_set_int(m_objSwsCtx,"dstw",m_frame->width,0);
av_opt_set_int(m_objSwsCtx,"dsth",m_objFrame->height,0); av_opt_set_int(m_objSwsCtx,"dsth",m_frame->height,0);
av_opt_set_int(m_objSwsCtx,"dst_format",AV_PIX_FMT_RGB24 ,0); av_opt_set_int(m_objSwsCtx,"dst_format",AV_PIX_FMT_RGB24 ,0);
av_opt_set_int(m_objSwsCtx,"sws_flag", SWS_FAST_BILINEAR /* SWS_BICUBIC*/,0); av_opt_set_int(m_objSwsCtx,"sws_flag", SWS_FAST_BILINEAR /* SWS_BICUBIC*/,0);
@ -450,7 +473,7 @@ bool DATVideoRender::RenderStream()
//av_freep(&m_pintDecodedLineSize[0]); //av_freep(&m_pintDecodedLineSize[0]);
} }
if (av_image_alloc(m_pbytDecodedData, m_pintDecodedLineSize,m_objFrame->width, m_objFrame->height, AV_PIX_FMT_RGB24, 1)<0) if (av_image_alloc(m_pbytDecodedData, m_pintDecodedLineSize,m_frame->width, m_frame->height, AV_PIX_FMT_RGB24, 1)<0)
{ {
qDebug() << "DATVideoProcess::RenderStream cannont init video image buffer"; qDebug() << "DATVideoProcess::RenderStream cannont init video image buffer";
sws_freeContext(m_objSwsCtx); sws_freeContext(m_objSwsCtx);
@ -461,22 +484,22 @@ bool DATVideoRender::RenderStream()
//Rendering device setup //Rendering device setup
resizeTVScreen(m_objFrame->width,m_objFrame->height); resizeTVScreen(m_frame->width,m_frame->height);
update(); update();
resetImage(); resetImage();
m_intCurrentRenderWidth=m_objFrame->width; m_intCurrentRenderWidth=m_frame->width;
m_intCurrentRenderHeight=m_objFrame->height; m_intCurrentRenderHeight=m_frame->height;
MetaData.Width = m_objFrame->width; MetaData.Width = m_frame->width;
MetaData.Height = m_objFrame->height; MetaData.Height = m_frame->height;
MetaData.OK_Decoding = true; MetaData.OK_Decoding = true;
emit onMetaDataChanged(&MetaData); emit onMetaDataChanged(&MetaData);
} }
//Frame rendering //Frame rendering
if (sws_scale(m_objSwsCtx, m_objFrame->data, m_objFrame->linesize, 0, m_objFrame->height, m_pbytDecodedData, m_pintDecodedLineSize)<0) if (sws_scale(m_objSwsCtx, m_frame->data, m_frame->linesize, 0, m_frame->height, m_pbytDecodedData, m_pintDecodedLineSize)<0)
{ {
qDebug() << "DATVideoProcess::RenderStream error converting video frame to RGB"; qDebug() << "DATVideoProcess::RenderStream error converting video frame to RGB";
m_blnRunning=false; m_blnRunning=false;
@ -484,13 +507,13 @@ bool DATVideoRender::RenderStream()
} }
renderImage(m_pbytDecodedData[0]); renderImage(m_pbytDecodedData[0]);
av_frame_unref(m_objFrame); av_frame_unref(m_frame);
m_intFrameCount ++; m_frameCount ++;
} }
} }
// Audio channel
else if (objPacket.stream_index == m_audioStreamIndex) else if (objPacket.stream_index == m_audioStreamIndex)
{ {
} }
av_packet_unref(&objPacket); av_packet_unref(&objPacket);
@ -521,7 +544,7 @@ bool DATVideoRender::CloseStream(QIODevice *objDevice)
return false; return false;
} }
if (!m_objFormatCtx) if (!m_formatCtx)
{ {
qDebug() << "DATVideoProcess::CloseStream FFMEG Context is not initialized"; qDebug() << "DATVideoProcess::CloseStream FFMEG Context is not initialized";
return false; return false;
@ -531,19 +554,19 @@ bool DATVideoRender::CloseStream(QIODevice *objDevice)
m_blnRunning=true; m_blnRunning=true;
// maybe done in the avcodec_close // maybe done in the avcodec_close
// avformat_close_input(&m_objFormatCtx); // avformat_close_input(&m_formatCtx);
// m_objFormatCtx=nullptr; // m_formatCtx=nullptr;
if (m_objDecoderCtx) if (m_videoDecoderCtx)
{ {
avcodec_close(m_objDecoderCtx); avcodec_close(m_videoDecoderCtx);
m_objDecoderCtx = nullptr; m_videoDecoderCtx = nullptr;
} }
if (m_objFrame) if (m_frame)
{ {
av_frame_unref(m_objFrame); av_frame_unref(m_frame);
av_frame_free(&m_objFrame); av_frame_free(&m_frame);
} }
if (m_objSwsCtx != nullptr) if (m_objSwsCtx != nullptr)

Wyświetl plik

@ -95,7 +95,7 @@ public:
bool CloseStream(QIODevice *objDevice); bool CloseStream(QIODevice *objDevice);
void setAudioFIFO(AudioFifo *fifo) { m_audioFifo = fifo; } void setAudioFIFO(AudioFifo *fifo) { m_audioFifo = fifo; }
int getVideoStreamIndex() const { return m_intVideoStreamIndex; } int getVideoStreamIndex() const { return m_videoStreamIndex; }
int getAudioStreamIndex() const { return m_audioStreamIndex; } int getAudioStreamIndex() const { return m_audioStreamIndex; }
struct DataTSMetaData2 MetaData; struct DataTSMetaData2 MetaData;
@ -108,10 +108,10 @@ private:
bool m_blnIsOpen; bool m_blnIsOpen;
SwsContext *m_objSwsCtx; SwsContext *m_objSwsCtx;
AVFormatContext *m_objFormatCtx; AVFormatContext *m_formatCtx;
AVCodecContext *m_objDecoderCtx; AVCodecContext *m_videoDecoderCtx;
AVFrame *m_objFrame; AVCodecContext *m_audioDecoderCtx;
AVFrame *m_frame;
AudioVector m_audioBuffer; AudioVector m_audioBuffer;
uint32_t m_audioBufferFill; uint32_t m_audioBufferFill;
AudioFifo *m_audioFifo; AudioFifo *m_audioFifo;
@ -119,8 +119,8 @@ private:
uint8_t *m_pbytDecodedData[4]; uint8_t *m_pbytDecodedData[4];
int m_pintDecodedLineSize[4]; int m_pintDecodedLineSize[4];
int m_intFrameCount; int m_frameCount;
int m_intVideoStreamIndex; int m_videoStreamIndex;
int m_audioStreamIndex; int m_audioStreamIndex;
int m_intCurrentRenderWidth; int m_intCurrentRenderWidth;