26 #include <libswresample/swresample.h> 34 installEventFilter(
this);
80 if (event->type() == QEvent::MouseButtonRelease)
88 return QObject::eventFilter(obj, event);
99 if (fullScreen ==
true)
101 qDebug(
"DATVideoRender::SetFullScreen: go to fullscreen");
108 setWindowFlags(Qt::Window);
109 setWindowState(Qt::WindowFullScreen);
115 qDebug(
"DATVideoRender::SetFullScreen: come back from fullscreen");
122 setWindowFlags(Qt::Widget);
123 setWindowState(Qt::WindowNoState);
129 static int ReadFunction(
void *opaque,
uint8_t *buf,
int buf_size)
131 QIODevice *stream =
reinterpret_cast<QIODevice *
>(opaque);
132 int nbBytes = stream->read((
char *)buf, buf_size);
136 static int64_t SeekFunction(
void *opaque,
int64_t offset,
int whence)
138 QIODevice *stream =
reinterpret_cast<QIODevice *
>(opaque);
140 if (whence == AVSEEK_SIZE)
145 if (stream->isSequential())
150 if (stream->seek(offset) ==
false)
155 return stream->pos();
186 avcodec_register_all();
188 av_log_set_level(AV_LOG_FATAL);
198 AVDictionary *opts =
nullptr;
199 AVCodec *videoCodec =
nullptr;
200 AVCodec *audioCodec =
nullptr;
203 char *buffer =
nullptr;
207 if (avformat_find_stream_info(
m_formatCtx,
nullptr) < 0)
211 qDebug() <<
"DATVideoRender::PreprocessStream cannot find stream info";
216 intRet = av_find_best_stream(
m_formatCtx, AVMEDIA_TYPE_VIDEO, -1, -1,
nullptr, 0);
221 qDebug() <<
"DATVideoRender::PreprocessStream cannot find video stream";
228 intRet = av_find_best_stream(
m_formatCtx, AVMEDIA_TYPE_AUDIO, -1, -1,
nullptr, 0);
232 qDebug() <<
"DATVideoRender::PreprocessStream cannot find audio stream";
263 if (buffer !=
nullptr)
273 if (buffer !=
nullptr)
283 if (videoCodec ==
nullptr)
288 qDebug() <<
"DATVideoRender::PreprocessStream cannot find associated video CODEC";
293 qDebug() <<
"DATVideoRender::PreprocessStream: video CODEC found: " << videoCodec->name;
296 av_dict_set(&opts,
"refcounted_frames",
"1", 0);
303 qDebug() <<
"DATVideoRender::PreprocessStream cannot open associated video CODEC";
315 qDebug() <<
"DATVideoRender::PreprocessStream cannot allocate frame";
344 qDebug() <<
"DATVideoRender::PreprocessStream: audio: " 353 if (audioCodec ==
nullptr)
355 qDebug() <<
"DATVideoRender::PreprocessStream cannot find associated audio CODEC";
360 qDebug() <<
"DATVideoRender::PreprocessStream: audio CODEC found: " << audioCodec->name;
364 qDebug() <<
"DATVideoRender::PreprocessStream cannot open associated audio CODEC";
380 int ioBufferSize = 32768;
381 unsigned char *ptrIOBuffer =
nullptr;
382 AVIOContext *ioCtx =
nullptr;
389 if (device ==
nullptr)
391 qDebug() <<
"DATVideoRender::OpenStream QIODevice is nullptr";
397 qDebug() <<
"DATVideoRender::OpenStream already open";
403 qDebug() <<
"DATVideoRender::OpenStream no data available";
419 qDebug() <<
"DATVideoRender::OpenStream FFMPEG not initialized";
424 if (!device->
open(QIODevice::ReadOnly))
426 qDebug() <<
"DATVideoRender::OpenStream cannot open QIODevice";
437 qDebug() <<
"DATVideoRender::OpenStream cannot alloc format FFMPEG context";
442 ptrIOBuffer = (
unsigned char *)av_malloc(ioBufferSize + AV_INPUT_BUFFER_PADDING_SIZE);
444 ioCtx = avio_alloc_context(ptrIOBuffer,
447 reinterpret_cast<void *>(device),
455 if (avformat_open_input(&
m_formatCtx,
nullptr,
nullptr,
nullptr) < 0)
457 qDebug() <<
"DATVideoRender::OpenStream cannot open stream";
478 bool needRenderingSetup;
482 qDebug() <<
"DATVideoRender::RenderStream Stream not open";
498 qDebug() <<
"DATVideoRender::RenderStream reading packet error";
506 memset(
m_frame, 0,
sizeof(AVFrame));
519 needRenderingSetup |= (
m_swsCtx ==
nullptr);
523 needRenderingSetup =
true;
526 if (needRenderingSetup)
543 av_opt_set_int(
m_swsCtx,
"dst_format", AV_PIX_FMT_RGB24, 0);
545 av_opt_set_int(
m_swsCtx,
"sws_flag", SWS_FAST_BILINEAR , 0);
547 if (sws_init_context(
m_swsCtx,
nullptr,
nullptr) < 0)
549 qDebug() <<
"DATVideoRender::RenderStream cannont init video data converter";
563 qDebug() <<
"DATVideoRender::RenderStream cannont init video image buffer";
589 qDebug() <<
"DATVideoRender::RenderStream error converting video frame to RGB";
614 memset(
m_frame, 0,
sizeof(AVFrame));
625 av_samples_alloc((
uint8_t**) &audioBuffer,
nullptr, 2,
m_frame->nb_samples, AV_SAMPLE_FMT_S16, 0);
651 for (
int i = 0;
i < frame_count;
i++)
672 av_packet_unref(&packet);
682 int audioVolumeConstrained = audioVolume < 0 ? 0 : audioVolume > 100 ? 100 : audioVolume;
683 m_audioVolume = pow(10.0, audioVolumeConstrained*0.02 - 2.0);
694 av_opt_set_int(
m_audioSWR,
"out_channel_count", 2, 0);
696 av_opt_set_int(
m_audioSWR,
"out_channel_layout", AV_CH_LAYOUT_STEREO, 0);
700 av_opt_set_sample_fmt(
m_audioSWR,
"out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
704 qDebug() <<
"DATVideoRender::setResampler: " 706 <<
" out_channel_count: " << 2
708 <<
" out_channel_layout: " << AV_CH_LAYOUT_STEREO
712 <<
" out_sample_fmt: " << AV_SAMPLE_FMT_S16;
725 qDebug() <<
"DATVideoRender::CloseStream QIODevice is nullptr";
731 qDebug() <<
"DATVideoRender::CloseStream Stream not open";
737 qDebug() <<
"DATVideoRender::CloseStream FFMEG Context is not initialized";
790 ret = avcodec_send_packet(avctx, pkt);
795 return ret == AVERROR_EOF ? 0 : ret;
799 ret = avcodec_receive_frame(avctx, frame);
801 if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
static const int m_audioFifoBufferSize
void onMetaDataChanged(DataTSMetaData2 *metaData)
struct DataTSMetaData2 MetaData
void renderImage(unsigned char *objData)
bool OpenStream(DATVideostream *objDevice)
bool m_isFFMPEGInitialized
int m_currentRenderHeight
AVCodecContext * m_videoDecoderCtx
bool m_updateAudioResampler
void resizeTVScreen(int intCols, int intRows)
int new_decode(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *pkt)
virtual bool eventFilter(QObject *obj, QEvent *event)
AVCodecContext * m_audioDecoderCtx
int16_t m_audioFifoBuffer[m_audioFifoBufferSize *2]
DATVideoRender(QWidget *parent)
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)
int m_audioFifoBufferIndex
virtual bool open(OpenMode mode)
AVFormatContext * m_formatCtx
struct SwrContext * m_audioSWR
uint32_t write(const quint8 *data, uint32_t numSamples)