SDRAngel  4.11.5
Developer docs for <a href="https://github.com/f4exb/sdrangel">SDRangel<\a>, an Open Source Qt5 / OpenGL 3.0+ SDR and signal analyzer frontend to various hardware.
Signals | Public Member Functions | Public Attributes | Protected Member Functions | Private Member Functions | Private Attributes | Static Private Attributes | List of all members
DATVideoRender Class Reference

#include <datvideorender.h>

+ Inheritance diagram for DATVideoRender:
+ Collaboration diagram for DATVideoRender:

Signals

void onMetaDataChanged (DataTSMetaData2 *metaData)
 
- Signals inherited from TVScreen
void traceSizeChanged (int)
 
void sampleRateChanged (int)
 

Public Member Functions

 DATVideoRender (QWidget *parent)
 
 ~DATVideoRender ()
 
void SetFullScreen (bool blnFullScreen)
 
bool OpenStream (DATVideostream *objDevice)
 
bool RenderStream ()
 
bool CloseStream (QIODevice *objDevice)
 
void setAudioFIFO (AudioFifo *fifo)
 
int getVideoStreamIndex () const
 
int getAudioStreamIndex () const
 
void setAudioMute (bool audioMute)
 
void setVideoMute (bool videoMute)
 
void setAudioVolume (int audioVolume)
 
bool getAudioDecodeOK () const
 
bool getVideoDecodeOK () const
 
- Public Member Functions inherited from TVScreen
 TVScreen (bool blnColor, QWidget *parent=0)
 
virtual ~TVScreen ()
 
void setColor (bool blnColor)
 
void resizeTVScreen (int intCols, int intRows)
 
void getSize (int &intCols, int &intRows) const
 
void renderImage (unsigned char *objData)
 
QRgb * getRowBuffer (int intRow)
 
void resetImage ()
 
void resetImage (int alpha)
 
bool selectRow (int intLine)
 
bool setDataColor (int intCol, int intRed, int intGreen, int intBlue)
 
bool setDataColor (int intCol, int intRed, int intGreen, int intBlue, int intAlpha)
 
void setAlphaBlend (bool blnAlphaBlend)
 
void setAlphaReset ()
 
void connectTimer (const QTimer &timer)
 

Public Attributes

struct DataTSMetaData2 MetaData
 

Protected Member Functions

virtual bool eventFilter (QObject *obj, QEvent *event)
 

Private Member Functions

bool InitializeFFMPEG ()
 
bool PreprocessStream ()
 
void ResetMetaData ()
 
int new_decode (AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *pkt)
 
void setResampler ()
 

Private Attributes

QWidget * m_parentWidget
 
Qt::WindowFlags m_originalWindowFlags
 
QSize m_originalSize
 
bool m_running
 
bool m_isFullScreen
 
bool m_isFFMPEGInitialized
 
bool m_isOpen
 
SwsContext * m_swsCtx
 
AVFormatContext * m_formatCtx
 
AVCodecContext * m_videoDecoderCtx
 
AVCodecContext * m_audioDecoderCtx
 
AVFrame * m_frame
 
AudioFifom_audioFifo
 
struct SwrContext * m_audioSWR
 
int m_audioSampleRate
 
int16_t m_audioFifoBuffer [m_audioFifoBufferSize *2]
 
int m_audioFifoBufferIndex
 
bool m_audioMute
 
bool m_videoMute
 
float m_audioVolume
 
bool m_updateAudioResampler
 
uint8_tm_pbytDecodedData [4]
 
int m_pintDecodedLineSize [4]
 
int m_frameCount
 
int m_videoStreamIndex
 
int m_audioStreamIndex
 
int m_currentRenderWidth
 
int m_currentRenderHeight
 
bool m_audioDecodeOK
 
bool m_videoDecodeOK
 

Static Private Attributes

static const int m_audioFifoBufferSize = 16000
 

Additional Inherited Members

- Static Public Attributes inherited from TVScreen
static const int TV_COLS =256
 
static const int TV_ROWS =256
 
- Protected Slots inherited from TVScreen
void cleanup ()
 
void tick ()
 

Detailed Description

Definition at line 85 of file datvideorender.h.

Constructor & Destructor Documentation

◆ DATVideoRender()

DATVideoRender::DATVideoRender ( QWidget *  parent)
explicit

Definition at line 32 of file datvideorender.cpp.

References m_audioDecodeOK, m_audioDecoderCtx, m_audioFifo, m_audioFifoBufferIndex, m_audioMute, m_audioSampleRate, m_audioStreamIndex, m_audioSWR, m_audioVolume, m_currentRenderHeight, m_currentRenderWidth, m_formatCtx, m_frame, m_frameCount, m_isFFMPEGInitialized, m_isFullScreen, m_isOpen, m_running, m_swsCtx, m_updateAudioResampler, m_videoDecodeOK, m_videoDecoderCtx, m_videoMute, and m_videoStreamIndex.

32  : TVScreen(true, parent), m_parentWidget(parent)
33 {
34  installEventFilter(this);
35  m_isFullScreen = false;
36  m_running = false;
37 
38  m_isFFMPEGInitialized = false;
39  m_isOpen = false;
40  m_formatCtx = nullptr;
41  m_videoDecoderCtx = nullptr;
42  m_audioDecoderCtx = nullptr;
43  m_swsCtx = nullptr;
44  m_audioFifo = nullptr;
45  m_audioSWR = nullptr;
46  m_audioSampleRate = 48000;
48  m_videoStreamIndex = -1;
49  m_audioStreamIndex = -1;
50  m_audioMute = false;
51  m_videoMute = false;
52  m_audioVolume = 0;
53  m_updateAudioResampler = false;
54 
57 
58  m_frame = nullptr;
59  m_frameCount = -1;
60 
61  m_audioDecodeOK = false;
62  m_videoDecodeOK = false;
63 
64  // for (int i = 0; i < m_audioFifoBufferSize; i++)
65  // {
66  // m_audioFifoBuffer[2*i] = 8192.0f * sin((M_PI * i)/(m_audioFifoBufferSize/1000.0f));
67  // m_audioFifoBuffer[2*i+1] = m_audioFifoBuffer[2*i];
68  // }
69 }
SwsContext * m_swsCtx
AudioFifo * m_audioFifo
bool m_isFFMPEGInitialized
AVCodecContext * m_videoDecoderCtx
bool m_updateAudioResampler
AVCodecContext * m_audioDecoderCtx
TVScreen(bool blnColor, QWidget *parent=0)
Definition: tvscreen.cpp:31
QWidget * m_parentWidget
AVFrame * m_frame
AVFormatContext * m_formatCtx
struct SwrContext * m_audioSWR

◆ ~DATVideoRender()

DATVideoRender::~DATVideoRender ( )

Definition at line 71 of file datvideorender.cpp.

References m_audioSWR.

72 {
73  if (m_audioSWR) {
74  swr_free(&m_audioSWR);
75  }
76 }
struct SwrContext * m_audioSWR

Member Function Documentation

◆ CloseStream()

bool DATVideoRender::CloseStream ( QIODevice *  objDevice)

Definition at line 715 of file datvideorender.cpp.

References m_currentRenderHeight, m_currentRenderWidth, m_formatCtx, m_frame, m_isOpen, m_running, m_swsCtx, m_videoDecoderCtx, MetaData, onMetaDataChanged(), and ResetMetaData().

716 {
717 
718  if (m_running)
719  {
720  return false;
721  }
722 
723  if (!device)
724  {
725  qDebug() << "DATVideoRender::CloseStream QIODevice is nullptr";
726  return false;
727  }
728 
729  if (!m_isOpen)
730  {
731  qDebug() << "DATVideoRender::CloseStream Stream not open";
732  return false;
733  }
734 
735  if (!m_formatCtx)
736  {
737  qDebug() << "DATVideoRender::CloseStream FFMEG Context is not initialized";
738  return false;
739  }
740 
741  //Only once execution
742  m_running = true;
743 
744  // maybe done in the avcodec_close
745  // avformat_close_input(&m_formatCtx);
746  // m_formatCtx=nullptr;
747 
748  if (m_videoDecoderCtx)
749  {
750  avcodec_close(m_videoDecoderCtx);
751  m_videoDecoderCtx = nullptr;
752  }
753 
754  if (m_frame)
755  {
756  av_frame_unref(m_frame);
757  av_frame_free(&m_frame);
758  }
759 
760  if (m_swsCtx != nullptr)
761  {
762  sws_freeContext(m_swsCtx);
763  m_swsCtx = nullptr;
764  }
765 
766  device->close();
767  m_isOpen = false;
768  m_running = false;
771 
772  ResetMetaData();
774 
775  return true;
776 }
SwsContext * m_swsCtx
void onMetaDataChanged(DataTSMetaData2 *metaData)
struct DataTSMetaData2 MetaData
AVCodecContext * m_videoDecoderCtx
AVFrame * m_frame
AVFormatContext * m_formatCtx
+ Here is the call graph for this function:

◆ eventFilter()

bool DATVideoRender::eventFilter ( QObject *  obj,
QEvent *  event 
)
protectedvirtual

Definition at line 78 of file datvideorender.cpp.

References SetFullScreen().

79 {
80  if (event->type() == QEvent::MouseButtonRelease)
81  {
82  SetFullScreen(false);
83  return true;
84  }
85  else
86  {
87  // standard event processing
88  return QObject::eventFilter(obj, event);
89  }
90 }
void SetFullScreen(bool blnFullScreen)
+ Here is the call graph for this function:

◆ getAudioDecodeOK()

bool DATVideoRender::getAudioDecodeOK ( ) const
inline

Definition at line 107 of file datvideorender.h.

Referenced by DATVDemod::audioDecodeOK().

107 { return m_audioDecodeOK; }
+ Here is the caller graph for this function:

◆ getAudioStreamIndex()

int DATVideoRender::getAudioStreamIndex ( ) const
inline

Definition at line 101 of file datvideorender.h.

Referenced by DATVDemod::audioActive().

101 { return m_audioStreamIndex; }
+ Here is the caller graph for this function:

◆ getVideoDecodeOK()

bool DATVideoRender::getVideoDecodeOK ( ) const
inline

Definition at line 108 of file datvideorender.h.

Referenced by DATVDemod::videoDecodeOK().

108 { return m_videoDecodeOK; }
+ Here is the caller graph for this function:

◆ getVideoStreamIndex()

int DATVideoRender::getVideoStreamIndex ( ) const
inline

Definition at line 100 of file datvideorender.h.

Referenced by DATVDemod::videoActive().

100 { return m_videoStreamIndex; }
+ Here is the caller graph for this function:

◆ InitializeFFMPEG()

bool DATVideoRender::InitializeFFMPEG ( )
private

Definition at line 177 of file datvideorender.cpp.

References m_isFFMPEGInitialized, and ResetMetaData().

Referenced by OpenStream().

178 {
179  ResetMetaData();
180 
182  {
183  return false;
184  }
185 
186  avcodec_register_all();
187  av_register_all();
188  av_log_set_level(AV_LOG_FATAL);
189  //av_log_set_level(AV_LOG_ERROR);
190 
191  m_isFFMPEGInitialized = true;
192 
193  return true;
194 }
bool m_isFFMPEGInitialized
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ new_decode()

int DATVideoRender::new_decode ( AVCodecContext *  avctx,
AVFrame *  frame,
int *  got_frame,
AVPacket *  pkt 
)
private

Replacement of deprecated avcodec_decode_video2 with the same signature https://blogs.gentoo.org/lu_zero/2016/03/29/new-avcodec-api/

Definition at line 782 of file datvideorender.cpp.

Referenced by RenderStream().

783 {
784  int ret;
785 
786  *got_frame = 0;
787 
788  if (pkt)
789  {
790  ret = avcodec_send_packet(avctx, pkt);
791  // In particular, we don't expect AVERROR(EAGAIN), because we read all
792  // decoded frames with avcodec_receive_frame() until done.
793  if (ret < 0)
794  {
795  return ret == AVERROR_EOF ? 0 : ret;
796  }
797  }
798 
799  ret = avcodec_receive_frame(avctx, frame);
800 
801  if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
802  {
803  return ret;
804  }
805 
806  if (ret >= 0)
807  {
808  *got_frame = 1;
809  }
810 
811  return 0;
812 }
+ Here is the caller graph for this function:

◆ onMetaDataChanged

void DATVideoRender::onMetaDataChanged ( DataTSMetaData2 metaData)
signal

Referenced by CloseStream(), DATVDemodGUI::DATVDemodGUI(), OpenStream(), PreprocessStream(), RenderStream(), and ResetMetaData().

+ Here is the caller graph for this function:

◆ OpenStream()

bool DATVideoRender::OpenStream ( DATVideostream objDevice)

Definition at line 378 of file datvideorender.cpp.

References DATVideostream::bytesAvailable(), InitializeFFMPEG(), m_formatCtx, m_isFFMPEGInitialized, m_isOpen, m_running, MetaData, DataTSMetaData2::OK_Data, onMetaDataChanged(), and DATVideostream::open().

379 {
380  int ioBufferSize = 32768;
381  unsigned char *ptrIOBuffer = nullptr;
382  AVIOContext *ioCtx = nullptr;
383 
384  if (m_running)
385  {
386  return false;
387  }
388 
389  if (device == nullptr)
390  {
391  qDebug() << "DATVideoRender::OpenStream QIODevice is nullptr";
392  return false;
393  }
394 
395  if (m_isOpen)
396  {
397  qDebug() << "DATVideoRender::OpenStream already open";
398  return false;
399  }
400 
401  if (device->bytesAvailable() <= 0)
402  {
403  qDebug() << "DATVideoRender::OpenStream no data available";
404  MetaData.OK_Data = false;
406  return false;
407  }
408 
409  //Only once execution
410  m_running = true;
411 
412  MetaData.OK_Data = true;
414 
416 
418  {
419  qDebug() << "DATVideoRender::OpenStream FFMPEG not initialized";
420  m_running = false;
421  return false;
422  }
423 
424  if (!device->open(QIODevice::ReadOnly))
425  {
426  qDebug() << "DATVideoRender::OpenStream cannot open QIODevice";
427  m_running = false;
428  return false;
429  }
430 
431  //Connect QIODevice to FFMPEG Reader
432 
433  m_formatCtx = avformat_alloc_context();
434 
435  if (m_formatCtx == nullptr)
436  {
437  qDebug() << "DATVideoRender::OpenStream cannot alloc format FFMPEG context";
438  m_running = false;
439  return false;
440  }
441 
442  ptrIOBuffer = (unsigned char *)av_malloc(ioBufferSize + AV_INPUT_BUFFER_PADDING_SIZE);
443 
444  ioCtx = avio_alloc_context(ptrIOBuffer,
445  ioBufferSize,
446  0,
447  reinterpret_cast<void *>(device),
448  &ReadFunction,
449  nullptr,
450  &SeekFunction);
451 
452  m_formatCtx->pb = ioCtx;
453  m_formatCtx->flags |= AVFMT_FLAG_CUSTOM_IO;
454 
455  if (avformat_open_input(&m_formatCtx, nullptr, nullptr, nullptr) < 0)
456  {
457  qDebug() << "DATVideoRender::OpenStream cannot open stream";
458  m_running = false;
459  return false;
460  }
461 
462  if (!PreprocessStream())
463  {
464  m_running = false;
465  return false;
466  }
467 
468  m_isOpen = true;
469  m_running = false;
470 
471  return true;
472 }
void onMetaDataChanged(DataTSMetaData2 *metaData)
struct DataTSMetaData2 MetaData
bool m_isFFMPEGInitialized
AVFormatContext * m_formatCtx
+ Here is the call graph for this function:

◆ PreprocessStream()

bool DATVideoRender::PreprocessStream ( )
private

Definition at line 196 of file datvideorender.cpp.

References DataTSMetaData2::BitRate, DataTSMetaData2::Channels, DataTSMetaData2::CodecDescription, DataTSMetaData2::CodecID, DataTSMetaData2::Height, m_audioDecoderCtx, m_audioStreamIndex, m_formatCtx, m_frame, m_frameCount, m_videoDecoderCtx, m_videoStreamIndex, MetaData, DataTSMetaData2::OK_TransportStream, DataTSMetaData2::OK_VideoStream, onMetaDataChanged(), DataTSMetaData2::PID, DataTSMetaData2::Program, setResampler(), DataTSMetaData2::Stream, and DataTSMetaData2::Width.

197 {
198  AVDictionary *opts = nullptr;
199  AVCodec *videoCodec = nullptr;
200  AVCodec *audioCodec = nullptr;
201 
202  int intRet = -1;
203  char *buffer = nullptr;
204 
205  //Identify stream
206 
207  if (avformat_find_stream_info(m_formatCtx, nullptr) < 0)
208  {
209  avformat_close_input(&m_formatCtx);
210  m_formatCtx = nullptr;
211  qDebug() << "DATVideoRender::PreprocessStream cannot find stream info";
212  return false;
213  }
214 
215  //Find video stream
216  intRet = av_find_best_stream(m_formatCtx, AVMEDIA_TYPE_VIDEO, -1, -1, nullptr, 0);
217 
218  if (intRet < 0)
219  {
220  avformat_close_input(&m_formatCtx);
221  qDebug() << "DATVideoRender::PreprocessStream cannot find video stream";
222  return false;
223  }
224 
225  m_videoStreamIndex = intRet;
226 
227  //Find audio stream
228  intRet = av_find_best_stream(m_formatCtx, AVMEDIA_TYPE_AUDIO, -1, -1, nullptr, 0);
229 
230  if (intRet < 0)
231  {
232  qDebug() << "DATVideoRender::PreprocessStream cannot find audio stream";
233  }
234 
235  m_audioStreamIndex = intRet;
236 
237  // Prepare Video Codec and extract meta data
238 
239  AVCodecParameters *parms = m_formatCtx->streams[m_videoStreamIndex]->codecpar;
240 
241  if (m_videoDecoderCtx) {
242  avcodec_free_context(&m_videoDecoderCtx);
243  }
244 
245  m_videoDecoderCtx = avcodec_alloc_context3(NULL);
246  avcodec_parameters_to_context(m_videoDecoderCtx, parms);
247 
248  // m_videoDecoderCtx = m_formatCtx->streams[m_videoStreamIndex]->codec; // old style
249 
250  //Meta Data
251 
252  MetaData.PID = m_formatCtx->streams[m_videoStreamIndex]->id;
253  MetaData.CodecID = m_videoDecoderCtx->codec_id;
255  MetaData.Program = "";
256  MetaData.Stream = "";
257 
258  if (m_formatCtx->programs)
259  {
260  buffer = nullptr;
261  av_dict_get_string(m_formatCtx->programs[m_videoStreamIndex]->metadata, &buffer, ':', '\n');
262 
263  if (buffer != nullptr)
264  {
265  MetaData.Program = QString("%1").arg(buffer);
266  }
267  }
268 
269  buffer = nullptr;
270 
271  av_dict_get_string(m_formatCtx->streams[m_videoStreamIndex]->metadata, &buffer, ':', '\n');
272 
273  if (buffer != nullptr)
274  {
275  MetaData.Stream = QString("%1").arg(buffer);
276  }
277 
279 
280  //Decoder
281  videoCodec = avcodec_find_decoder(m_videoDecoderCtx->codec_id);
282 
283  if (videoCodec == nullptr)
284  {
285  avformat_close_input(&m_formatCtx);
286  m_formatCtx = nullptr;
287 
288  qDebug() << "DATVideoRender::PreprocessStream cannot find associated video CODEC";
289  return false;
290  }
291  else
292  {
293  qDebug() << "DATVideoRender::PreprocessStream: video CODEC found: " << videoCodec->name;
294  }
295 
296  av_dict_set(&opts, "refcounted_frames", "1", 0);
297 
298  if (avcodec_open2(m_videoDecoderCtx, videoCodec, &opts) < 0)
299  {
300  avformat_close_input(&m_formatCtx);
301  m_formatCtx = nullptr;
302 
303  qDebug() << "DATVideoRender::PreprocessStream cannot open associated video CODEC";
304  return false;
305  }
306 
307  //Allocate Frame
308  m_frame = av_frame_alloc();
309 
310  if (!m_frame)
311  {
312  avformat_close_input(&m_formatCtx);
313  m_formatCtx = nullptr;
314 
315  qDebug() << "DATVideoRender::PreprocessStream cannot allocate frame";
316  return false;
317  }
318 
319  m_frameCount = 0;
322  MetaData.BitRate = m_videoDecoderCtx->bit_rate;
323  MetaData.Channels = m_videoDecoderCtx->channels;
324  MetaData.CodecDescription = QString("%1").arg(videoCodec->long_name);
325  MetaData.OK_VideoStream = true;
326 
328 
329  // Prepare Audio Codec
330 
331  if (m_audioStreamIndex >= 0)
332  {
333  AVCodecParameters *parms = m_formatCtx->streams[m_audioStreamIndex]->codecpar;
334 
335  if (m_audioDecoderCtx) {
336  avcodec_free_context(&m_audioDecoderCtx);
337  }
338 
339  m_audioDecoderCtx = avcodec_alloc_context3(nullptr);
340  avcodec_parameters_to_context(m_audioDecoderCtx, parms);
341 
342  //m_audioDecoderCtx = m_formatCtx->streams[m_audioStreamIndex]->codec; // old style
343 
344  qDebug() << "DATVideoRender::PreprocessStream: audio: "
345  << " channels: " << m_audioDecoderCtx->channels
346  << " channel_layout: " << m_audioDecoderCtx->channel_layout
347  << " sample_rate: " << m_audioDecoderCtx->sample_rate
348  << " sample_fmt: " << m_audioDecoderCtx->sample_fmt
349  << " codec_id: "<< m_audioDecoderCtx->codec_id;
350 
351  audioCodec = avcodec_find_decoder(m_audioDecoderCtx->codec_id);
352 
353  if (audioCodec == nullptr)
354  {
355  qDebug() << "DATVideoRender::PreprocessStream cannot find associated audio CODEC";
356  m_audioStreamIndex = -1; // invalidate audio
357  }
358  else
359  {
360  qDebug() << "DATVideoRender::PreprocessStream: audio CODEC found: " << audioCodec->name;
361 
362  if (avcodec_open2(m_audioDecoderCtx, audioCodec, nullptr) < 0)
363  {
364  qDebug() << "DATVideoRender::PreprocessStream cannot open associated audio CODEC";
365  m_audioStreamIndex = -1; // invalidate audio
366  }
367  else
368  {
369  setResampler();
370  }
371 
372  }
373  }
374 
375  return true;
376 }
void onMetaDataChanged(DataTSMetaData2 *metaData)
struct DataTSMetaData2 MetaData
QString CodecDescription
AVCodecContext * m_videoDecoderCtx
AVCodecContext * m_audioDecoderCtx
AVFrame * m_frame
AVFormatContext * m_formatCtx
+ Here is the call graph for this function:

◆ RenderStream()

bool DATVideoRender::RenderStream ( )

Definition at line 474 of file datvideorender.cpp.

References DataTSMetaData2::Height, i, m_audioDecodeOK, m_audioDecoderCtx, m_audioFifo, m_audioFifoBuffer, m_audioFifoBufferIndex, m_audioFifoBufferSize, m_audioMute, m_audioStreamIndex, m_audioSWR, m_audioVolume, m_currentRenderHeight, m_currentRenderWidth, m_formatCtx, m_frame, m_frameCount, m_isOpen, m_pbytDecodedData, m_pintDecodedLineSize, m_running, m_swsCtx, m_updateAudioResampler, m_videoDecodeOK, m_videoDecoderCtx, m_videoMute, m_videoStreamIndex, MetaData, new_decode(), DataTSMetaData2::OK_Decoding, onMetaDataChanged(), TVScreen::renderImage(), TVScreen::resetImage(), TVScreen::resizeTVScreen(), setResampler(), DataTSMetaData2::Width, and AudioFifo::write().

475 {
476  AVPacket packet;
477  int gotFrame;
478  bool needRenderingSetup;
479 
480  if (!m_isOpen)
481  {
482  qDebug() << "DATVideoRender::RenderStream Stream not open";
483  return false;
484  }
485 
486  if (m_running)
487  {
488  return false;
489  }
490 
491  //Only once execution
492  m_running = true;
493 
494  //********** Rendering **********
495 
496  if (av_read_frame(m_formatCtx, &packet) < 0)
497  {
498  qDebug() << "DATVideoRender::RenderStream reading packet error";
499  m_running = false;
500  return false;
501  }
502 
503  //Video channel
504  if ((packet.stream_index == m_videoStreamIndex) && (!m_videoMute))
505  {
506  memset(m_frame, 0, sizeof(AVFrame));
507  av_frame_unref(m_frame);
508 
509  gotFrame = 0;
510 
511  if (new_decode(m_videoDecoderCtx, m_frame, &gotFrame, &packet) >= 0)
512  {
513  m_videoDecodeOK = true;
514 
515  if (gotFrame)
516  {
517  //Rendering and RGB Converter setup
518  needRenderingSetup = (m_frameCount == 0);
519  needRenderingSetup |= (m_swsCtx == nullptr);
520 
521  if ((m_currentRenderWidth != m_frame->width) || (m_currentRenderHeight != m_frame->height))
522  {
523  needRenderingSetup = true;
524  }
525 
526  if (needRenderingSetup)
527  {
528  if (m_swsCtx != nullptr)
529  {
530  sws_freeContext(m_swsCtx);
531  m_swsCtx = nullptr;
532  }
533 
534  //Convertisseur YUV -> RGB
535  m_swsCtx = sws_alloc_context();
536 
537  av_opt_set_int(m_swsCtx, "srcw", m_frame->width, 0);
538  av_opt_set_int(m_swsCtx, "srch", m_frame->height, 0);
539  av_opt_set_int(m_swsCtx, "src_format", m_frame->format, 0);
540 
541  av_opt_set_int(m_swsCtx, "dstw", m_frame->width, 0);
542  av_opt_set_int(m_swsCtx, "dsth", m_frame->height, 0);
543  av_opt_set_int(m_swsCtx, "dst_format", AV_PIX_FMT_RGB24, 0);
544 
545  av_opt_set_int(m_swsCtx, "sws_flag", SWS_FAST_BILINEAR /* SWS_BICUBIC*/, 0);
546 
547  if (sws_init_context(m_swsCtx, nullptr, nullptr) < 0)
548  {
549  qDebug() << "DATVideoRender::RenderStream cannont init video data converter";
550  m_swsCtx = nullptr;
551  m_running = false;
552  return false;
553  }
554 
555  if ((m_currentRenderHeight > 0) && (m_currentRenderWidth > 0))
556  {
557  //av_freep(&m_pbytDecodedData[0]);
558  //av_freep(&m_pintDecodedLineSize[0]);
559  }
560 
561  if (av_image_alloc(m_pbytDecodedData, m_pintDecodedLineSize, m_frame->width, m_frame->height, AV_PIX_FMT_RGB24, 1) < 0)
562  {
563  qDebug() << "DATVideoRender::RenderStream cannont init video image buffer";
564  sws_freeContext(m_swsCtx);
565  m_swsCtx = nullptr;
566  m_running = false;
567  return false;
568  }
569 
570  //Rendering device setup
571 
572  resizeTVScreen(m_frame->width, m_frame->height);
573  update();
574  resetImage();
575 
576  m_currentRenderWidth = m_frame->width;
577  m_currentRenderHeight = m_frame->height;
578 
579  MetaData.Width = m_frame->width;
580  MetaData.Height = m_frame->height;
581  MetaData.OK_Decoding = true;
583  }
584 
585  //Frame rendering
586 
587  if (sws_scale(m_swsCtx, m_frame->data, m_frame->linesize, 0, m_frame->height, m_pbytDecodedData, m_pintDecodedLineSize) < 0)
588  {
589  qDebug() << "DATVideoRender::RenderStream error converting video frame to RGB";
590  m_running = false;
591  return false;
592  }
593 
595  av_frame_unref(m_frame);
596  m_frameCount++;
597  }
598  }
599  else
600  {
601  m_videoDecodeOK = false;
602  // qDebug() << "DATVideoRender::RenderStream video decode error";
603  }
604  }
605  // Audio channel
606  else if ((packet.stream_index == m_audioStreamIndex) && (m_audioFifo) && (swr_is_initialized(m_audioSWR)) && (!m_audioMute))
607  {
609  {
610  setResampler();
611  m_updateAudioResampler = false;
612  }
613 
614  memset(m_frame, 0, sizeof(AVFrame));
615  av_frame_unref(m_frame);
616  gotFrame = 0;
617 
618  if (new_decode(m_audioDecoderCtx, m_frame, &gotFrame, &packet) >= 0)
619  {
620  m_audioDecodeOK = true;
621 
622  if (gotFrame)
623  {
624  int16_t *audioBuffer;
625  av_samples_alloc((uint8_t**) &audioBuffer, nullptr, 2, m_frame->nb_samples, AV_SAMPLE_FMT_S16, 0);
626  int frame_count = swr_convert(m_audioSWR, (uint8_t**) &audioBuffer, m_frame->nb_samples, (const uint8_t**) m_frame->data, m_frame->nb_samples);
627 
628  // direct writing:
629  // int ret = m_audioFifo->write((const quint8*) &audioBuffer[0], frame_count);
630 
631  // if (ret < frame_count) {
632  // qDebug("DATVideoRender::RenderStream: audio frames missing %d vs %d", ret, frame_count);
633  // }
634 
635  // buffered writing:
636  // if (m_audioFifoBufferIndex + frame_count < m_audioFifoBufferSize)
637  // {
638  // std::copy(&audioBuffer[0], &audioBuffer[2*frame_count], &m_audioFifoBuffer[2*m_audioFifoBufferIndex]);
639  // m_audioFifoBufferIndex += frame_count;
640  // }
641  // else
642  // {
643  // int remainder = m_audioFifoBufferSize - m_audioFifoBufferIndex;
644  // std::copy(&audioBuffer[0], &audioBuffer[2*remainder], &m_audioFifoBuffer[2*m_audioFifoBufferIndex]);
645  // m_audioFifo->write((const quint8*) &m_audioFifoBuffer[0], m_audioFifoBufferSize);
646  // std::copy(&audioBuffer[2*remainder], &audioBuffer[2*frame_count], &m_audioFifoBuffer[0]);
647  // m_audioFifoBufferIndex = frame_count - remainder;
648  // }
649 
650  // Apply volume:
651  for (int i = 0; i < frame_count; i++)
652  {
654  m_audioFifoBuffer[2*m_audioFifoBufferIndex+1] = m_audioVolume * audioBuffer[2*i+1];
656 
658  {
661  }
662  }
663  }
664  }
665  else
666  {
667  m_audioDecodeOK = false;
668  // qDebug("DATVideoRender::RenderStream: audio decode error");
669  }
670  }
671 
672  av_packet_unref(&packet);
673 
674  //********** Rendering **********
675 
676  m_running = false;
677  return true;
678 }
short int16_t
Definition: rtptypes_win.h:43
void resetImage()
Definition: tvscreen.cpp:76
static const int m_audioFifoBufferSize
SwsContext * m_swsCtx
void onMetaDataChanged(DataTSMetaData2 *metaData)
struct DataTSMetaData2 MetaData
void renderImage(unsigned char *objData)
Definition: tvscreen.cpp:70
AudioFifo * m_audioFifo
AVCodecContext * m_videoDecoderCtx
bool m_updateAudioResampler
void resizeTVScreen(int intCols, int intRows)
Definition: tvscreen.cpp:86
int new_decode(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *pkt)
unsigned char uint8_t
Definition: rtptypes_win.h:42
AVCodecContext * m_audioDecoderCtx
int16_t m_audioFifoBuffer[m_audioFifoBufferSize *2]
int32_t i
Definition: decimators.h:244
uint8_t * m_pbytDecodedData[4]
int m_pintDecodedLineSize[4]
AVFrame * m_frame
AVFormatContext * m_formatCtx
struct SwrContext * m_audioSWR
uint32_t write(const quint8 *data, uint32_t numSamples)
Definition: audiofifo.cpp:66
+ Here is the call graph for this function:

◆ ResetMetaData()

void DATVideoRender::ResetMetaData ( )
private

Definition at line 158 of file datvideorender.cpp.

References DataTSMetaData2::BitRate, DataTSMetaData2::Channels, DataTSMetaData2::CodecDescription, DataTSMetaData2::CodecID, DataTSMetaData2::Height, MetaData, DataTSMetaData2::OK_Decoding, DataTSMetaData2::OK_TransportStream, DataTSMetaData2::OK_VideoStream, onMetaDataChanged(), DataTSMetaData2::PID, DataTSMetaData2::Program, DataTSMetaData2::Stream, and DataTSMetaData2::Width.

Referenced by CloseStream(), and InitializeFFMPEG().

159 {
160  MetaData.CodecID = -1;
161  MetaData.PID = -1;
162  MetaData.Program = "";
163  MetaData.Stream = "";
164  MetaData.Width = -1;
165  MetaData.Height = -1;
166  MetaData.BitRate = -1;
167  MetaData.Channels = -1;
169 
170  MetaData.OK_Decoding = false;
172  MetaData.OK_VideoStream = false;
173 
175 }
void onMetaDataChanged(DataTSMetaData2 *metaData)
struct DataTSMetaData2 MetaData
QString CodecDescription
+ Here is the caller graph for this function:

◆ setAudioFIFO()

void DATVideoRender::setAudioFIFO ( AudioFifo fifo)
inline

Definition at line 99 of file datvideorender.h.

Referenced by DATVDemod::SetVideoRender().

99 { m_audioFifo = fifo; }
AudioFifo * m_audioFifo
+ Here is the caller graph for this function:

◆ setAudioMute()

void DATVideoRender::setAudioMute ( bool  audioMute)
inline

Definition at line 103 of file datvideorender.h.

Referenced by DATVDemod::applySettings().

103 { m_audioMute = audioMute; }
+ Here is the caller graph for this function:

◆ setAudioVolume()

void DATVideoRender::setAudioVolume ( int  audioVolume)

Definition at line 680 of file datvideorender.cpp.

References m_audioVolume.

Referenced by DATVDemod::applySettings().

681 {
682  int audioVolumeConstrained = audioVolume < 0 ? 0 : audioVolume > 100 ? 100 : audioVolume;
683  m_audioVolume = pow(10.0, audioVolumeConstrained*0.02 - 2.0); // .01 -> 1 log
684 }
+ Here is the caller graph for this function:

◆ SetFullScreen()

void DATVideoRender::SetFullScreen ( bool  blnFullScreen)

Definition at line 92 of file datvideorender.cpp.

References m_isFullScreen.

Referenced by eventFilter().

93 {
94  if (m_isFullScreen == fullScreen)
95  {
96  return;
97  }
98 
99  if (fullScreen == true)
100  {
101  qDebug("DATVideoRender::SetFullScreen: go to fullscreen");
102  // m_originalWindowFlags = this->windowFlags();
103  // m_originalSize = this->size();
104  // m_parentWidget->layout()->removeWidget(this);
105  // //this->setParent(0);
106  // this->setWindowFlags( Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint);
107  // m_parentWidget->show();
108  setWindowFlags(Qt::Window);
109  setWindowState(Qt::WindowFullScreen);
110  show();
111  m_isFullScreen = true;
112  }
113  else
114  {
115  qDebug("DATVideoRender::SetFullScreen: come back from fullscreen");
116  // //this->setParent(m_parentWidget);
117  // this->resize(m_originalSize);
118  // this->overrideWindowFlags(m_originalWindowFlags);
119  // setWindowState(Qt::WindowNoState);
120  // m_parentWidget->layout()->addWidget(this);
121  // m_parentWidget->show();
122  setWindowFlags(Qt::Widget);
123  setWindowState(Qt::WindowNoState);
124  show();
125  m_isFullScreen = false;
126  }
127 }
+ Here is the caller graph for this function:

◆ setResampler()

void DATVideoRender::setResampler ( )
private

Definition at line 686 of file datvideorender.cpp.

References m_audioDecoderCtx, m_audioSampleRate, and m_audioSWR.

Referenced by PreprocessStream(), and RenderStream().

687 {
688  if (m_audioSWR) {
689  swr_free(&m_audioSWR);
690  }
691 
692  m_audioSWR = swr_alloc();
693  av_opt_set_int(m_audioSWR, "in_channel_count", m_audioDecoderCtx->channels, 0);
694  av_opt_set_int(m_audioSWR, "out_channel_count", 2, 0);
695  av_opt_set_int(m_audioSWR, "in_channel_layout", m_audioDecoderCtx->channel_layout, 0);
696  av_opt_set_int(m_audioSWR, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0);
697  av_opt_set_int(m_audioSWR, "in_sample_rate", m_audioDecoderCtx->sample_rate, 0);
698  av_opt_set_int(m_audioSWR, "out_sample_rate", m_audioSampleRate, 0);
699  av_opt_set_sample_fmt(m_audioSWR, "in_sample_fmt", m_audioDecoderCtx->sample_fmt, 0);
700  av_opt_set_sample_fmt(m_audioSWR, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
701 
702  swr_init(m_audioSWR);
703 
704  qDebug() << "DATVideoRender::setResampler: "
705  << " in_channel_count: " << m_audioDecoderCtx->channels
706  << " out_channel_count: " << 2
707  << " in_channel_layout: " << m_audioDecoderCtx->channel_layout
708  << " out_channel_layout: " << AV_CH_LAYOUT_STEREO
709  << " in_sample_rate: " << m_audioDecoderCtx->sample_rate
710  << " out_sample_rate: " << m_audioSampleRate
711  << " in_sample_fmt: " << m_audioDecoderCtx->sample_fmt
712  << " out_sample_fmt: " << AV_SAMPLE_FMT_S16;
713 }
AVCodecContext * m_audioDecoderCtx
struct SwrContext * m_audioSWR
+ Here is the caller graph for this function:

◆ setVideoMute()

void DATVideoRender::setVideoMute ( bool  videoMute)
inline

Definition at line 104 of file datvideorender.h.

Referenced by DATVDemod::applySettings().

104 { m_videoMute = videoMute; }
+ Here is the caller graph for this function:

Member Data Documentation

◆ m_audioDecodeOK

bool DATVideoRender::m_audioDecodeOK
private

Definition at line 149 of file datvideorender.h.

Referenced by DATVideoRender(), and RenderStream().

◆ m_audioDecoderCtx

AVCodecContext* DATVideoRender::m_audioDecoderCtx
private

Definition at line 126 of file datvideorender.h.

Referenced by DATVideoRender(), PreprocessStream(), RenderStream(), and setResampler().

◆ m_audioFifo

AudioFifo* DATVideoRender::m_audioFifo
private

Definition at line 128 of file datvideorender.h.

Referenced by DATVideoRender(), and RenderStream().

◆ m_audioFifoBuffer

int16_t DATVideoRender::m_audioFifoBuffer[m_audioFifoBufferSize *2]
private

Definition at line 132 of file datvideorender.h.

Referenced by RenderStream().

◆ m_audioFifoBufferIndex

int DATVideoRender::m_audioFifoBufferIndex
private

Definition at line 133 of file datvideorender.h.

Referenced by DATVideoRender(), and RenderStream().

◆ m_audioFifoBufferSize

const int DATVideoRender::m_audioFifoBufferSize = 16000
staticprivate

Definition at line 131 of file datvideorender.h.

Referenced by RenderStream().

◆ m_audioMute

bool DATVideoRender::m_audioMute
private

Definition at line 134 of file datvideorender.h.

Referenced by DATVideoRender(), and RenderStream().

◆ m_audioSampleRate

int DATVideoRender::m_audioSampleRate
private

Definition at line 130 of file datvideorender.h.

Referenced by DATVideoRender(), and setResampler().

◆ m_audioStreamIndex

int DATVideoRender::m_audioStreamIndex
private

Definition at line 144 of file datvideorender.h.

Referenced by DATVideoRender(), PreprocessStream(), and RenderStream().

◆ m_audioSWR

struct SwrContext* DATVideoRender::m_audioSWR
private

Definition at line 129 of file datvideorender.h.

Referenced by DATVideoRender(), RenderStream(), setResampler(), and ~DATVideoRender().

◆ m_audioVolume

float DATVideoRender::m_audioVolume
private

Definition at line 136 of file datvideorender.h.

Referenced by DATVideoRender(), RenderStream(), and setAudioVolume().

◆ m_currentRenderHeight

int DATVideoRender::m_currentRenderHeight
private

Definition at line 147 of file datvideorender.h.

Referenced by CloseStream(), DATVideoRender(), and RenderStream().

◆ m_currentRenderWidth

int DATVideoRender::m_currentRenderWidth
private

Definition at line 146 of file datvideorender.h.

Referenced by CloseStream(), DATVideoRender(), and RenderStream().

◆ m_formatCtx

AVFormatContext* DATVideoRender::m_formatCtx
private

◆ m_frame

AVFrame* DATVideoRender::m_frame
private

Definition at line 127 of file datvideorender.h.

Referenced by CloseStream(), DATVideoRender(), PreprocessStream(), and RenderStream().

◆ m_frameCount

int DATVideoRender::m_frameCount
private

Definition at line 142 of file datvideorender.h.

Referenced by DATVideoRender(), PreprocessStream(), and RenderStream().

◆ m_isFFMPEGInitialized

bool DATVideoRender::m_isFFMPEGInitialized
private

Definition at line 120 of file datvideorender.h.

Referenced by DATVideoRender(), InitializeFFMPEG(), and OpenStream().

◆ m_isFullScreen

bool DATVideoRender::m_isFullScreen
private

Definition at line 118 of file datvideorender.h.

Referenced by DATVideoRender(), and SetFullScreen().

◆ m_isOpen

bool DATVideoRender::m_isOpen
private

Definition at line 121 of file datvideorender.h.

Referenced by CloseStream(), DATVideoRender(), OpenStream(), and RenderStream().

◆ m_originalSize

QSize DATVideoRender::m_originalSize
private

Definition at line 115 of file datvideorender.h.

◆ m_originalWindowFlags

Qt::WindowFlags DATVideoRender::m_originalWindowFlags
private

Definition at line 114 of file datvideorender.h.

◆ m_parentWidget

QWidget* DATVideoRender::m_parentWidget
private

Definition at line 113 of file datvideorender.h.

◆ m_pbytDecodedData

uint8_t* DATVideoRender::m_pbytDecodedData[4]
private

Definition at line 139 of file datvideorender.h.

Referenced by RenderStream().

◆ m_pintDecodedLineSize

int DATVideoRender::m_pintDecodedLineSize[4]
private

Definition at line 140 of file datvideorender.h.

Referenced by RenderStream().

◆ m_running

bool DATVideoRender::m_running
private

Definition at line 117 of file datvideorender.h.

Referenced by CloseStream(), DATVideoRender(), OpenStream(), and RenderStream().

◆ m_swsCtx

SwsContext* DATVideoRender::m_swsCtx
private

Definition at line 123 of file datvideorender.h.

Referenced by CloseStream(), DATVideoRender(), and RenderStream().

◆ m_updateAudioResampler

bool DATVideoRender::m_updateAudioResampler
private

Definition at line 137 of file datvideorender.h.

Referenced by DATVideoRender(), and RenderStream().

◆ m_videoDecodeOK

bool DATVideoRender::m_videoDecodeOK
private

Definition at line 150 of file datvideorender.h.

Referenced by DATVideoRender(), and RenderStream().

◆ m_videoDecoderCtx

AVCodecContext* DATVideoRender::m_videoDecoderCtx
private

Definition at line 125 of file datvideorender.h.

Referenced by CloseStream(), DATVideoRender(), PreprocessStream(), and RenderStream().

◆ m_videoMute

bool DATVideoRender::m_videoMute
private

Definition at line 135 of file datvideorender.h.

Referenced by DATVideoRender(), and RenderStream().

◆ m_videoStreamIndex

int DATVideoRender::m_videoStreamIndex
private

Definition at line 143 of file datvideorender.h.

Referenced by DATVideoRender(), PreprocessStream(), and RenderStream().

◆ MetaData

struct DataTSMetaData2 DATVideoRender::MetaData

The documentation for this class was generated from the following files: