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.
datvideorender.cpp
Go to the documentation of this file.
1 // Copyright (C) 2018 F4HKW //
3 // for F4EXB / SDRAngel //
4 // //
5 // This program is free software; you can redistribute it and/or modify //
6 // it under the terms of the GNU General Public License as published by //
7 // the Free Software Foundation as version 3 of the License, or //
8 // (at your option) any later version. //
9 // //
10 // This program is distributed in the hope that it will be useful, //
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of //
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
13 // GNU General Public License V3 for more details. //
14 // //
15 // You should have received a copy of the GNU General Public License //
16 // along with this program. If not, see <http://www.gnu.org/licenses/>. //
18 
19 #include <math.h>
20 #include <algorithm>
21 
22 #include <QLayout>
23 
24 extern "C"
25 {
26 #include <libswresample/swresample.h>
27 }
28 
29 #include "audio/audiofifo.h"
30 #include "datvideorender.h"
31 
32 DATVideoRender::DATVideoRender(QWidget *parent) : 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 }
70 
72 {
73  if (m_audioSWR) {
74  swr_free(&m_audioSWR);
75  }
76 }
77 
78 bool DATVideoRender::eventFilter(QObject *obj, QEvent *event)
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 }
91 
92 void DATVideoRender::SetFullScreen(bool fullScreen)
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 }
128 
129 static int ReadFunction(void *opaque, uint8_t *buf, int buf_size)
130 {
131  QIODevice *stream = reinterpret_cast<QIODevice *>(opaque);
132  int nbBytes = stream->read((char *)buf, buf_size);
133  return nbBytes;
134 }
135 
136 static int64_t SeekFunction(void *opaque, int64_t offset, int whence)
137 {
138  QIODevice *stream = reinterpret_cast<QIODevice *>(opaque);
139 
140  if (whence == AVSEEK_SIZE)
141  {
142  return -1;
143  }
144 
145  if (stream->isSequential())
146  {
147  return -1;
148  }
149 
150  if (stream->seek(offset) == false)
151  {
152  return -1;
153  }
154 
155  return stream->pos();
156 }
157 
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 }
176 
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 }
195 
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 }
377 
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 }
473 
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 }
679 
680 void DATVideoRender::setAudioVolume(int audioVolume)
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 }
685 
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 }
714 
715 bool DATVideoRender::CloseStream(QIODevice *device)
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 }
777 
782 int DATVideoRender::new_decode(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *pkt)
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 }
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
bool OpenStream(DATVideostream *objDevice)
bool m_isFFMPEGInitialized
QString CodecDescription
AVCodecContext * m_videoDecoderCtx
bool m_updateAudioResampler
__int64 int64_t
Definition: rtptypes_win.h:47
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
virtual bool eventFilter(QObject *obj, QEvent *event)
AVCodecContext * m_audioDecoderCtx
int16_t m_audioFifoBuffer[m_audioFifoBufferSize *2]
DATVideoRender(QWidget *parent)
int32_t i
Definition: decimators.h:244
bool CloseStream(QIODevice *objDevice)
uint8_t * m_pbytDecodedData[4]
int m_pintDecodedLineSize[4]
void setAudioVolume(int audioVolume)
virtual qint64 bytesAvailable() const
void SetFullScreen(bool blnFullScreen)
virtual bool open(OpenMode mode)
AVFrame * m_frame
AVFormatContext * m_formatCtx
struct SwrContext * m_audioSWR
uint32_t write(const quint8 *data, uint32_t numSamples)
Definition: audiofifo.cpp:66