diff --git a/.gitignore b/.gitignore index 8a9d35c887947b2618399e6cd64808e7df019e67..094516a04b71ff017e46ebfa9499aae002509a61 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ *.user +build-qt59 diff --git a/AVQt/AVQt b/AVQt/AVQt index c554c7d4ce0ce513832a76995db98a626ba97981..aafb3e7a7166e85dfd73f8042d767cd50316418c 100644 --- a/AVQt/AVQt +++ b/AVQt/AVQt @@ -7,10 +7,11 @@ #include "filter/DecoderQSV.h" #include "filter/DecoderDXVA2.h" #include "filter/AudioDecoder.h" +#include "filter/EncoderVAAPI.h" #include "output/IPacketSink.h" #include "output/IFrameSink.h" #include "output/IAudioSink.h" #include "output/OpenGLRenderer.h" #include "output/OpenALAudioOutput.h" -#include "filter/EncoderVAAPI.h" +#include "output/Muxer.h" //#include "output/FrameFileSaver.h" \ No newline at end of file diff --git a/AVQt/CMakeLists.txt b/AVQt/CMakeLists.txt index e25acb2bbccaae27fe138b8c508326c4aa8a055c..27438a38c7a0de4e7b5090cf1e060715df7cdccd 100644 --- a/AVQt/CMakeLists.txt +++ b/AVQt/CMakeLists.txt @@ -9,8 +9,8 @@ set(CMAKE_AUTOUIC on) set(CMAKE_INCLUDE_CURRENT_DIR on) -find_package(Qt6 COMPONENTS Core Gui Concurrent Widgets OpenGL OpenGLWidgets) -#find_package(Qt5 COMPONENTS Core Gui Concurrent Widgets OpenGL) +#find_package(Qt6 COMPONENTS Core Gui Concurrent Widgets OpenGL OpenGLWidgets) +find_package(Qt5 COMPONENTS Core Gui Concurrent Widgets OpenGL) if (WIN32) set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS on) @@ -172,6 +172,7 @@ target_compile_options(AVQtStatic PRIVATE -Wdouble-promotion ) -target_link_libraries(AVQt Qt6::Core Qt6::Gui Qt6::Concurrent Qt6::Widgets Qt6::OpenGL Qt6::OpenGLWidgets avformat avfilter avutil avcodec avdevice swscale swresample GL openal) -target_link_libraries(AVQtStatic Qt6::Core Qt6::Gui Qt6::Concurrent Qt6::Widgets Qt6::OpenGL Qt6::OpenGLWidgets avformat avfilter avutil avcodec avdevice swscale swresample GL openal) -#target_link_libraries(AVQt Qt5::Core Qt5::Gui Qt5::Concurrent Qt5::Widgets Qt5::OpenGL avformat avfilter avutil avcodec avdevice swscale swresample GL openal) \ No newline at end of file +#target_link_libraries(AVQt Qt6::Core Qt6::Gui Qt6::Concurrent Qt6::Widgets Qt6::OpenGL Qt6::OpenGLWidgets avformat avfilter avutil avcodec avdevice swscale swresample GL openal) +#target_link_libraries(AVQtStatic Qt6::Core Qt6::Gui Qt6::Concurrent Qt6::Widgets Qt6::OpenGL Qt6::OpenGLWidgets avformat avfilter avutil avcodec avdevice swscale swresample GL openal) +target_link_libraries(AVQt Qt5::Core Qt5::Gui Qt5::Concurrent Qt5::Widgets Qt5::OpenGL avformat avfilter avutil avcodec avdevice swscale swresample GL openal) +target_link_libraries(AVQtStatic Qt5::Core Qt5::Gui Qt5::Concurrent Qt5::Widgets Qt5::OpenGL avformat avfilter avutil avcodec avdevice swscale swresample GL openal) diff --git a/AVQt/filter/AudioDecoder.cpp b/AVQt/filter/AudioDecoder.cpp index f591355a9f1d1a7714f592948ea102b2732cc874..89fb56619dfa978e62a9d148d517ec5f1133ff44 100644 --- a/AVQt/filter/AudioDecoder.cpp +++ b/AVQt/filter/AudioDecoder.cpp @@ -129,7 +129,7 @@ namespace AVQt { return d->m_paused.load(); } - qsizetype AudioDecoder::registerCallback(IAudioSink *callback) { + qint64 AudioDecoder::registerCallback(IAudioSink *callback) { Q_D(AVQt::AudioDecoder); QMutexLocker lock(&d->m_cbListMutex); @@ -149,7 +149,7 @@ namespace AVQt { return -1; } - qsizetype AudioDecoder::unregisterCallback(IAudioSink *callback) { + qint64 AudioDecoder::unregisterCallback(IAudioSink *callback) { Q_D(AVQt::AudioDecoder); QMutexLocker lock(&d->m_cbListMutex); @@ -225,7 +225,7 @@ namespace AVQt { while (d->m_running.load()) { if (!d->m_paused.load() && !d->m_inputQueue.isEmpty()) { QTime time1 = QTime::currentTime(); - qDebug("Audio packet queue size: %lld", d->m_inputQueue.size()); + qDebug("Audio packet queue size: %d", d->m_inputQueue.size()); int ret; constexpr size_t strBufSize = 64; @@ -260,7 +260,7 @@ namespace AVQt { AVPacket *packet = d->m_inputQueue.dequeue(); lock.unlock(); - qDebug("Audio packet queue size: %lld", d->m_inputQueue.size()); + qDebug("Audio packet queue size: %d", d->m_inputQueue.size()); ret = avcodec_send_packet(d->m_pCodecCtx, packet); if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN)) { @@ -311,4 +311,4 @@ namespace AVQt { } } -} \ No newline at end of file +} diff --git a/AVQt/filter/AudioDecoder.h b/AVQt/filter/AudioDecoder.h index 6b198c176cb685a2796619e19308ec1543ee16b6..d0dba7fdc3fa2e281019d5781b8b38a2ec451a10 100644 --- a/AVQt/filter/AudioDecoder.h +++ b/AVQt/filter/AudioDecoder.h @@ -34,9 +34,9 @@ namespace AVQt { bool isPaused() Q_DECL_OVERRIDE; - qsizetype registerCallback(IAudioSink *callback) Q_DECL_OVERRIDE; + qint64 registerCallback(IAudioSink *callback) Q_DECL_OVERRIDE; - qsizetype unregisterCallback(IAudioSink *callback) Q_DECL_OVERRIDE; + qint64 unregisterCallback(IAudioSink *callback) Q_DECL_OVERRIDE; void run() Q_DECL_OVERRIDE; diff --git a/AVQt/filter/DecoderDXVA2.cpp b/AVQt/filter/DecoderDXVA2.cpp index 151668d4b02fdcdd3f3ec9aa986422f174b6c9f9..903ff3fc3151dd6f092ca6a05ffb24c14dd885c2 100644 --- a/AVQt/filter/DecoderDXVA2.cpp +++ b/AVQt/filter/DecoderDXVA2.cpp @@ -160,7 +160,7 @@ namespace AVQt { return d->m_paused.load(); } - qsizetype DecoderDXVA2::registerCallback(IFrameSink *frameSink) { + qint64 DecoderDXVA2::registerCallback(IFrameSink *frameSink) { Q_D(AVQt::DecoderDXVA2); QMutexLocker lock(&d->m_cbListMutex); @@ -175,7 +175,7 @@ namespace AVQt { return -1; } - qsizetype DecoderDXVA2::unregisterCallback(IFrameSink *frameSink) { + qint64 DecoderDXVA2::unregisterCallback(IFrameSink *frameSink) { Q_D(AVQt::DecoderDXVA2); QMutexLocker lock(&d->m_cbListMutex); if (d->m_cbList.contains(frameSink)) { @@ -246,7 +246,7 @@ namespace AVQt { AVPacket *packet = d->m_inputQueue.dequeue(); lock.unlock(); - qDebug("Video packet queue size: %lld", d->m_inputQueue.size()); + qDebug("Video packet queue size: %d", d->m_inputQueue.size()); ret = avcodec_send_packet(d->m_pCodecCtx, packet); if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN)) { @@ -318,4 +318,4 @@ namespace AVQt { } } } -} \ No newline at end of file +} diff --git a/AVQt/filter/DecoderDXVA2.h b/AVQt/filter/DecoderDXVA2.h index 501b565bfb5c70b0c20df2b5edaf1555c8bb4a8d..7c4eee29f656c4831c24ce98af6a9609b5632a9f 100644 --- a/AVQt/filter/DecoderDXVA2.h +++ b/AVQt/filter/DecoderDXVA2.h @@ -81,14 +81,14 @@ namespace AVQt { * @param type One element or some bitwise or combination of elements of IFrameSource::CB_TYPE * @return Current position in callback list */ - Q_INVOKABLE qsizetype registerCallback(IFrameSink *frameSink) Q_DECL_OVERRIDE; + Q_INVOKABLE qint64 registerCallback(IFrameSink *frameSink) Q_DECL_OVERRIDE; /*! * \brief Removes frame sink/filter from registry * @param frameSink Frame sink/filter to be removed * @return Last position in callback list, -1 when not found */ - Q_INVOKABLE qsizetype unregisterCallback(IFrameSink *frameSink) Q_DECL_OVERRIDE; + Q_INVOKABLE qint64 unregisterCallback(IFrameSink *frameSink) Q_DECL_OVERRIDE; public slots: /*! diff --git a/AVQt/filter/DecoderQSV.cpp b/AVQt/filter/DecoderQSV.cpp index f8162528edd595a8db074f2fd399e65092f3331c..12c4085734fd56eff6b6acd2afb9bfc806ddd4bb 100644 --- a/AVQt/filter/DecoderQSV.cpp +++ b/AVQt/filter/DecoderQSV.cpp @@ -160,7 +160,7 @@ namespace AVQt { return d->m_paused.load(); } - qsizetype DecoderQSV::registerCallback(IFrameSink *frameSink) { + qint64 DecoderQSV::registerCallback(IFrameSink *frameSink) { Q_D(AVQt::DecoderQSV); QMutexLocker lock(&d->m_cbListMutex); @@ -175,7 +175,7 @@ namespace AVQt { return -1; } - qsizetype DecoderQSV::unregisterCallback(IFrameSink *frameSink) { + qint64 DecoderQSV::unregisterCallback(IFrameSink *frameSink) { Q_D(AVQt::DecoderQSV); QMutexLocker lock(&d->m_cbListMutex); if (d->m_cbList.contains(frameSink)) { @@ -246,7 +246,7 @@ namespace AVQt { AVPacket *packet = d->m_inputQueue.dequeue(); lock.unlock(); - qDebug("Video packet queue size: %lld", d->m_inputQueue.size()); + qDebug("Video packet queue size: %d", d->m_inputQueue.size()); ret = avcodec_send_packet(d->m_pCodecCtx, packet); if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN)) { @@ -317,4 +317,4 @@ namespace AVQt { } } } -} \ No newline at end of file +} diff --git a/AVQt/filter/DecoderQSV.h b/AVQt/filter/DecoderQSV.h index b23e824d3d77c272cbfa379ea581c391dcc6a6f8..3d740cf8066c269aef0c21ebf3a2a036359ddd4a 100644 --- a/AVQt/filter/DecoderQSV.h +++ b/AVQt/filter/DecoderQSV.h @@ -81,14 +81,14 @@ namespace AVQt { * @param type One element or some bitwise or combination of elements of IFrameSource::CB_TYPE * @return Current position in callback list */ - Q_INVOKABLE qsizetype registerCallback(IFrameSink *frameSink) Q_DECL_OVERRIDE; + Q_INVOKABLE qint64 registerCallback(IFrameSink *frameSink) Q_DECL_OVERRIDE; /*! * \brief Removes frame sink/filter from registry * @param frameSink Frame sink/filter to be removed * @return Last position in callback list, -1 when not found */ - Q_INVOKABLE qsizetype unregisterCallback(IFrameSink *frameSink) Q_DECL_OVERRIDE; + Q_INVOKABLE qint64 unregisterCallback(IFrameSink *frameSink) Q_DECL_OVERRIDE; public slots: /*! diff --git a/AVQt/filter/DecoderVAAPI.cpp b/AVQt/filter/DecoderVAAPI.cpp index 9ab4713cc62e6b5515ede7cf17d882e56f1e4b7f..43a5528e39d6cf29d90714b7a6af0cc1772a73a1 100644 --- a/AVQt/filter/DecoderVAAPI.cpp +++ b/AVQt/filter/DecoderVAAPI.cpp @@ -160,7 +160,7 @@ namespace AVQt { return d->m_paused.load(); } - qsizetype DecoderVAAPI::registerCallback(IFrameSink *frameSink) { + qint64 DecoderVAAPI::registerCallback(IFrameSink *frameSink) { Q_D(AVQt::DecoderVAAPI); QMutexLocker lock(&d->m_cbListMutex); @@ -175,7 +175,7 @@ namespace AVQt { return -1; } - qsizetype DecoderVAAPI::unregisterCallback(IFrameSink *frameSink) { + qint64 DecoderVAAPI::unregisterCallback(IFrameSink *frameSink) { Q_D(AVQt::DecoderVAAPI); QMutexLocker lock(&d->m_cbListMutex); if (d->m_cbList.contains(frameSink)) { @@ -246,7 +246,7 @@ namespace AVQt { AVPacket *packet = d->m_inputQueue.dequeue(); lock.unlock(); - qDebug("Video packet queue size: %lld", d->m_inputQueue.size()); + qDebug("Video packet queue size: %d", d->m_inputQueue.size()); ret = avcodec_send_packet(d->m_pCodecCtx, packet); if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN)) { @@ -317,4 +317,4 @@ namespace AVQt { } } } -} \ No newline at end of file +} diff --git a/AVQt/filter/DecoderVAAPI.h b/AVQt/filter/DecoderVAAPI.h index bab451b6ac12b6dabd6f4881d85b27169e2d1340..f9170617791c82edd17f5cbaa0210b101ce30150 100644 --- a/AVQt/filter/DecoderVAAPI.h +++ b/AVQt/filter/DecoderVAAPI.h @@ -81,14 +81,14 @@ namespace AVQt { * @param type One element or some bitwise or combination of elements of IFrameSource::CB_TYPE * @return Current position in callback list */ - Q_INVOKABLE qsizetype registerCallback(IFrameSink *frameSink) Q_DECL_OVERRIDE; + Q_INVOKABLE qint64 registerCallback(IFrameSink *frameSink) Q_DECL_OVERRIDE; /*! * \brief Removes frame sink/filter from registry * @param frameSink Frame sink/filter to be removed * @return Last position in callback list, -1 when not found */ - Q_INVOKABLE qsizetype unregisterCallback(IFrameSink *frameSink) Q_DECL_OVERRIDE; + Q_INVOKABLE qint64 unregisterCallback(IFrameSink *frameSink) Q_DECL_OVERRIDE; public slots: /*! diff --git a/AVQt/filter/EncoderVAAPI.cpp b/AVQt/filter/EncoderVAAPI.cpp index 14acd26f196e12b838758759de4cf57ce9dc5c9d..657a61be7792f3250409124626038940b4bac9e3 100644 --- a/AVQt/filter/EncoderVAAPI.cpp +++ b/AVQt/filter/EncoderVAAPI.cpp @@ -45,6 +45,13 @@ namespace AVQt { int EncoderVAAPI::deinit() { Q_D(AVQt::EncoderVAAPI); + { + QMutexLocker lock(&d->m_cbListMutex); + for (const auto &cb: d->m_cbList) { + cb->deinit(this); + } + } + if (d->m_pDeviceCtx) { av_buffer_unref(&d->m_pDeviceCtx); } @@ -71,6 +78,7 @@ namespace AVQt { bool shouldBe = false; if (d->m_running.compare_exchange_strong(shouldBe, true)) { d->m_paused.store(false); + QThread::start(); started(); @@ -83,7 +91,7 @@ namespace AVQt { Q_D(AVQt::EncoderVAAPI); bool shouldBe = true; - if (d->m_running.compare_exchange_strong(shouldBe, true)) { + if (d->m_running.compare_exchange_strong(shouldBe, false)) { d->m_paused.store(false); { @@ -159,7 +167,7 @@ namespace AVQt { this->pause(paused); } - qsizetype EncoderVAAPI::registerCallback(IPacketSink *packetSink, int8_t type) { + qint64 EncoderVAAPI::registerCallback(IPacketSink *packetSink, int8_t type) { Q_D(AVQt::EncoderVAAPI); if (type != IPacketSource::CB_VIDEO) { @@ -177,7 +185,7 @@ namespace AVQt { } } - qsizetype EncoderVAAPI::unregisterCallback(IPacketSink *packetSink) { + qint64 EncoderVAAPI::unregisterCallback(IPacketSink *packetSink) { Q_D(AVQt::EncoderVAAPI); { @@ -198,6 +206,7 @@ namespace AVQt { case AV_PIX_FMT_DXVA2_VLD: qDebug("Transferring frame from GPU to CPU"); av_hwframe_transfer_data(queueFrame.first, frame, 0); + queueFrame.first->pts = frame->pts; break; default: qDebug("Referencing frame"); @@ -288,17 +297,26 @@ namespace AVQt { // } // d->m_pCodecCtx->pix_fmt = AV_PIX_FMT_VAAPI; - d->m_pCodecCtx->time_base = av_inv_q(d->m_framerate); + d->m_pCodecCtx->time_base = av_make_q(1, 1000000); ret = avcodec_open2(d->m_pCodecCtx, d->m_pCodec, nullptr); if (ret < 0) { qFatal("%i: Unable to open VAAPI encoder: %s", ret, av_make_error_string(strBuf, strBufSize, ret)); } + qDebug("[AVQt::EncoderVAAPI] Encoder timebase: %d/%d", d->m_pCodecCtx->time_base.num, d->m_pCodecCtx->time_base.den); d->m_pHWFrame = av_frame_alloc(); ret = av_hwframe_get_buffer(d->m_pFramesCtx, d->m_pHWFrame, 0); if (ret != 0) { qFatal("%i: Could not allocate HW frame in encoder context: %s", ret, av_make_error_string(strBuf, strBufSize, ret)); } + + QMutexLocker lock(&d->m_cbListMutex); + for (const auto &cb: d->m_cbList) { + AVCodecParameters *parameters = avcodec_parameters_alloc(); + avcodec_parameters_from_context(parameters, d->m_pCodecCtx); + cb->init(this, d->m_framerate, d->m_pCodecCtx->time_base, 0, parameters, nullptr, nullptr); + cb->start(this); + } } while (!d->m_inputQueue.isEmpty()) { QPair<AVFrame *, int64_t> frame; @@ -311,6 +329,7 @@ namespace AVQt { } else { av_hwframe_transfer_data(d->m_pHWFrame, frame.first, 0); } + d->m_pHWFrame->pts = av_rescale_q(frame.first->pts, av_make_q(1, 1000000), d->m_pCodecCtx->time_base); av_frame_free(&frame.first); ret = avcodec_send_frame(d->m_pCodecCtx, d->m_pHWFrame); if (ret != 0) { diff --git a/AVQt/filter/EncoderVAAPI.h b/AVQt/filter/EncoderVAAPI.h index dec1e74bf15450cd259f36a222e3e18d007b7ae9..617160defbe3ee073a00125e38b0b4cc4d8088e2 100644 --- a/AVQt/filter/EncoderVAAPI.h +++ b/AVQt/filter/EncoderVAAPI.h @@ -42,9 +42,9 @@ namespace AVQt { bool isPaused() Q_DECL_OVERRIDE; - qsizetype registerCallback(IPacketSink *packetSink, int8_t type) Q_DECL_OVERRIDE; + qint64 registerCallback(IPacketSink *packetSink, int8_t type) Q_DECL_OVERRIDE; - qsizetype unregisterCallback(IPacketSink *packetSink) Q_DECL_OVERRIDE; + qint64 unregisterCallback(IPacketSink *packetSink) Q_DECL_OVERRIDE; void run() Q_DECL_OVERRIDE; diff --git a/AVQt/filter/IDecoder.h b/AVQt/filter/IDecoder.h index a55e45983721ccaf7e04bbe724c4805027cef8a4..f0dfb84aa4c3d619955c3520ac73a3627656aa28 100644 --- a/AVQt/filter/IDecoder.h +++ b/AVQt/filter/IDecoder.h @@ -39,9 +39,9 @@ namespace AVQt { // IFrameSource interface public: - virtual qsizetype registerCallback(IFrameSink *frameSink) Q_DECL_OVERRIDE = 0; + virtual qint64 registerCallback(IFrameSink *frameSink) Q_DECL_OVERRIDE = 0; - virtual qsizetype unregisterCallback(IFrameSink *frameSink) Q_DECL_OVERRIDE = 0; + virtual qint64 unregisterCallback(IFrameSink *frameSink) Q_DECL_OVERRIDE = 0; virtual int init() Q_DECL_OVERRIDE = 0; diff --git a/AVQt/filter/IEncoder.h b/AVQt/filter/IEncoder.h index d3e1adafbb504db9aaa27bcb5f7346de2d8b6cbc..0554f17f0783899c26f1420fff0cae824e2b1e66 100644 --- a/AVQt/filter/IEncoder.h +++ b/AVQt/filter/IEncoder.h @@ -46,9 +46,9 @@ namespace AVQt { Q_INVOKABLE virtual void pause(bool pause) = 0; - Q_INVOKABLE virtual qsizetype registerCallback(IPacketSink *packetSink, int8_t type) = 0; + Q_INVOKABLE virtual qint64 registerCallback(IPacketSink *packetSink, int8_t type) = 0; - Q_INVOKABLE virtual qsizetype unregisterCallback(IPacketSink *packetSink) = 0; + Q_INVOKABLE virtual qint64 unregisterCallback(IPacketSink *packetSink) = 0; signals: diff --git a/AVQt/input/Demuxer.cpp b/AVQt/input/Demuxer.cpp index 881e8063644e53536e332749a123499cd84af6dd..df65c4ad4ee777168db4c397f9e8383f838013c9 100644 --- a/AVQt/input/Demuxer.cpp +++ b/AVQt/input/Demuxer.cpp @@ -34,7 +34,7 @@ namespace AVQt { return d->m_paused.load(); } - qsizetype Demuxer::registerCallback(IPacketSink *packetSink, int8_t type) { + qint64 Demuxer::registerCallback(IPacketSink *packetSink, int8_t type) { Q_D(AVQt::Demuxer); QMutexLocker lock(&d->m_cbMutex); @@ -79,7 +79,7 @@ namespace AVQt { return 0; } - qsizetype Demuxer::unregisterCallback(IPacketSink *packetSink) { + qint64 Demuxer::unregisterCallback(IPacketSink *packetSink) { Q_D(AVQt::Demuxer); QMutexLocker lock(&d->m_cbMutex); @@ -204,7 +204,6 @@ namespace AVQt { // avio_closep(&d->m_pIOCtx); avformat_close_input(&d->m_pFormatCtx); - delete[] d->m_pBuffer; d->m_videoStreams.clear(); d->m_audioStreams.clear(); diff --git a/AVQt/input/Demuxer.h b/AVQt/input/Demuxer.h index 2c66a39f53239c90cde299b4e7d3c6f854eb06b8..295e167898f305d812d5cd7f9c0303b43ab0c4d2 100644 --- a/AVQt/input/Demuxer.h +++ b/AVQt/input/Demuxer.h @@ -45,14 +45,14 @@ namespace AVQt { * @param type Callback type, can be linked with bitwise or to set multiple options * @return */ - Q_INVOKABLE qsizetype registerCallback(IPacketSink *packetSink, int8_t type) Q_DECL_OVERRIDE; + Q_INVOKABLE qint64 registerCallback(IPacketSink *packetSink, int8_t type) Q_DECL_OVERRIDE; /*! * \brief Removes packet callback \c packetSink from registry * @param packetSink Packet sink/filter to be removed * @return Previous position of the item, is -1 when not in registry */ - Q_INVOKABLE qsizetype unregisterCallback(IPacketSink *packetSink) Q_DECL_OVERRIDE; + Q_INVOKABLE qint64 unregisterCallback(IPacketSink *packetSink) Q_DECL_OVERRIDE; public slots: /*! diff --git a/AVQt/input/IAudioSource.h b/AVQt/input/IAudioSource.h index 6c2137e700e3c232fbcfd8f1a7ff7cb3258b742b..9d563e134a105deaf3531e306bad3f71ec8989eb 100644 --- a/AVQt/input/IAudioSource.h +++ b/AVQt/input/IAudioSource.h @@ -18,9 +18,9 @@ namespace AVQt { virtual bool isPaused() = 0; - Q_INVOKABLE virtual qsizetype registerCallback(IAudioSink *callback) = 0; + Q_INVOKABLE virtual qint64 registerCallback(IAudioSink *callback) = 0; - Q_INVOKABLE virtual qsizetype unregisterCallback(IAudioSink *callback) = 0; + Q_INVOKABLE virtual qint64 unregisterCallback(IAudioSink *callback) = 0; public slots: Q_INVOKABLE virtual int init() = 0; diff --git a/AVQt/input/IFrameSource.h b/AVQt/input/IFrameSource.h index 740bb0a45260fe1afbba9a6b8f86cb3184b4c0f9..2e3c88a44dfe3b0534b003ec3df72cbb972dac7f 100644 --- a/AVQt/input/IFrameSource.h +++ b/AVQt/input/IFrameSource.h @@ -63,14 +63,14 @@ namespace AVQt { * @param type Callback type, can be linked with bitwise or to set multiple options * @return */ - Q_INVOKABLE virtual qsizetype registerCallback(IFrameSink *frameSink) = 0; + Q_INVOKABLE virtual qint64 registerCallback(IFrameSink *frameSink) = 0; /*! * \brief Removes frame callback \c frameSink from registry * @param frameSink Frame sink/filter to be removed * @return Previous position of the item, is -1 when not in registry */ - Q_INVOKABLE virtual qsizetype unregisterCallback(IFrameSink *frameSink) = 0; + Q_INVOKABLE virtual qint64 unregisterCallback(IFrameSink *frameSink) = 0; public slots: /*! diff --git a/AVQt/input/IPacketSource.h b/AVQt/input/IPacketSource.h index d40ff21fd854846f69cfd6f1ff5d2c7302e71260..e092baf597c99fa3b7252798103921b379a3ca66 100644 --- a/AVQt/input/IPacketSource.h +++ b/AVQt/input/IPacketSource.h @@ -57,14 +57,14 @@ namespace AVQt { * @param type Callback type, can be linked with bitwise or to set multiple options * @return */ - Q_INVOKABLE virtual qsizetype registerCallback(IPacketSink *packetSink, int8_t type) = 0; + Q_INVOKABLE virtual qint64 registerCallback(IPacketSink *packetSink, int8_t type) = 0; /*! * \brief Removes packet callback \c packetSink from registry * @param packetSink Packet sink/filter to be removed * @return Previous position of the item, is -1 when not in registry */ - Q_INVOKABLE virtual qsizetype unregisterCallback(IPacketSink *packetSink) = 0; + Q_INVOKABLE virtual qint64 unregisterCallback(IPacketSink *packetSink) = 0; public slots: /*! diff --git a/AVQt/output/Muxer.cpp b/AVQt/output/Muxer.cpp index cff343960136270af5688c019d4660553c55c588..35c7253b3a831ea623b5434fd3e9fa3d40a02221 100644 --- a/AVQt/output/Muxer.cpp +++ b/AVQt/output/Muxer.cpp @@ -38,7 +38,7 @@ namespace AVQt { if (d->m_sourceStreamMap.contains(source)) { bool alreadyCalled = false; - for (const auto &stream: d->m_sourceStreamMap[source]) { + for (const auto &stream: d->m_sourceStreamMap[source].keys()) { if ((vParams && stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) || (aParams && stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) || (sParams && stream->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)) { @@ -61,6 +61,7 @@ namespace AVQt { qFatal("[AVQt::Muxer] Output device is not writable"); } d->m_pFormatContext = avformat_alloc_context(); + d->m_pFormatContext->oformat = av_guess_format("mpegts", "", nullptr); d->m_pIOBuffer = static_cast<uint8_t *>(av_malloc(MuxerPrivate::IOBUF_SIZE)); d->m_pIOContext = avio_alloc_context(d->m_pIOBuffer, MuxerPrivate::IOBUF_SIZE, 1, d->m_outputDevice, nullptr, &MuxerPrivate::writeToIO, &MuxerPrivate::seekIO); @@ -70,32 +71,40 @@ namespace AVQt { } if (!d->m_sourceStreamMap.contains(source)) { - d->m_sourceStreamMap[source] = QList<AVStream *>(); + d->m_sourceStreamMap[source] = QMap<AVStream *, AVRational>(); } if (vParams) { AVStream *videoStream = avformat_new_stream(d->m_pFormatContext, avcodec_find_encoder(vParams->codec_id)); videoStream->codecpar = avcodec_parameters_alloc(); avcodec_parameters_copy(videoStream->codecpar, vParams); videoStream->time_base = timebase; - d->m_sourceStreamMap[source].append(videoStream); + d->m_sourceStreamMap[source].insert(videoStream, timebase); } else if (aParams) { AVStream *audioStream = avformat_new_stream(d->m_pFormatContext, avcodec_find_encoder(aParams->codec_id)); audioStream->codecpar = avcodec_parameters_alloc(); avcodec_parameters_copy(audioStream->codecpar, aParams); audioStream->time_base = timebase; - d->m_sourceStreamMap[source].append(audioStream); + d->m_sourceStreamMap[source].insert(audioStream, timebase); } else if (sParams) { AVStream *subtitleStream = avformat_new_stream(d->m_pFormatContext, avcodec_find_encoder(sParams->codec_id)); subtitleStream->codecpar = avcodec_parameters_alloc(); avcodec_parameters_copy(subtitleStream->codecpar, sParams); subtitleStream->time_base = timebase; - d->m_sourceStreamMap[source].append(subtitleStream); + d->m_sourceStreamMap[source].insert(subtitleStream, timebase); + } + int ret = avformat_init_output(d->m_pFormatContext, nullptr); + if (ret <= 0) { + constexpr auto strBufSize = 32; + char strBuf[strBufSize]; + qWarning("[AVQt::Muxer] %d: Couldn't init AVFormatContext: %s", ret, av_make_error_string(strBuf, strBufSize, ret)); } } void Muxer::deinit(IPacketSource *source) { Q_D(AVQt::Muxer); + stop(nullptr); + if (d->m_sourceStreamMap.contains(source)) { d->m_sourceStreamMap.remove(source); } else { @@ -130,14 +139,9 @@ namespace AVQt { bool shouldBe = false; if (d->m_running.compare_exchange_strong(shouldBe, true)) { shouldBe = false; - if (d->m_headerWritten.compare_exchange_strong(shouldBe, true)) { - int ret = avformat_write_header(d->m_pFormatContext, nullptr); - if (ret != 0) { - constexpr auto strBufSize = 32; - char strBuf[strBufSize]; - qWarning("[AVQt::Muxer] %d: Couldn't init AVFormatContext: %s", ret, av_make_error_string(strBuf, strBufSize, ret)); - } - } +// if (d->m_headerWritten.compare_exchange_strong(shouldBe, true)) { +// +// } d->m_paused.store(false); QThread::start(); started(); @@ -151,7 +155,14 @@ namespace AVQt { bool shouldBe = true; if (d->m_running.compare_exchange_strong(shouldBe, false)) { d->m_paused.store(false); - QThread::wait(); + wait(); + { + QMutexLocker lock{&d->m_inputQueueMutex}; + while (!d->m_inputQueue.isEmpty()) { + auto packet = d->m_inputQueue.dequeue(); + av_packet_free(&packet.first); + } + } stopped(); } } @@ -172,7 +183,7 @@ namespace AVQt { bool initStream = false; AVStream *addStream; if (!unknownSource) { - for (const auto &stream : d->m_sourceStreamMap[source]) { + for (const auto &stream : d->m_sourceStreamMap[source].keys()) { if ((packetType == IPacketSource::CB_VIDEO && stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) || (packetType == IPacketSource::CB_AUDIO && stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) || (packetType == IPacketSource::CB_SUBTITLE && stream->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)) { @@ -189,6 +200,8 @@ namespace AVQt { QPair<AVPacket *, AVStream *> queuePacket{av_packet_clone(packet), addStream}; queuePacket.first->stream_index = addStream->index; + qDebug("[AVQt::Muxer] Getting packet with PTS: %ld", packet->pts); + av_packet_rescale_ts(queuePacket.first, d->m_sourceStreamMap[source][addStream], addStream->time_base); QMutexLocker lock(&d->m_inputQueueMutex); d->m_inputQueue.enqueue(queuePacket); @@ -198,13 +211,15 @@ namespace AVQt { Q_D(AVQt::Muxer); while (d->m_running.load()) { - if (!d->m_paused.load()) { + if (!d->m_paused.load() && !d->m_inputQueue.isEmpty()) { QPair<AVPacket *, AVStream *> packet; { QMutexLocker lock(&d->m_inputQueueMutex); packet = d->m_inputQueue.dequeue(); } +// av_packet_rescale_ts(packet.first, packet.second->time_base, av_make_q(1, AV_TIME_BASE)); int ret = av_interleaved_write_frame(d->m_pFormatContext, packet.first); + qDebug("Written packet"); if (ret != 0) { constexpr auto strBufSize = 32; char strBuf[strBufSize]; diff --git a/AVQt/output/Muxer.h b/AVQt/output/Muxer.h index f774631aa3505a4c3017aa18bc23af03b1cc6256..a0ddeeda02cdf1b994ed35483680c2924d0fb902 100644 --- a/AVQt/output/Muxer.h +++ b/AVQt/output/Muxer.h @@ -5,6 +5,7 @@ #include "IPacketSink.h" #include <QThread> +#include <QIODevice> #ifndef LIBAVQT_MUXER_H #define LIBAVQT_MUXER_H @@ -60,4 +61,4 @@ namespace AVQt { }; } -#endif //LIBAVQT_MUXER_H \ No newline at end of file +#endif //LIBAVQT_MUXER_H diff --git a/AVQt/output/OpenALAudioOutput.cpp b/AVQt/output/OpenALAudioOutput.cpp index 66306e41a0b7c26ca88e4526b922b5546be02f13..08dc94f2588d4c2eb1b19a58c4043fd03e7cbfb5 100644 --- a/AVQt/output/OpenALAudioOutput.cpp +++ b/AVQt/output/OpenALAudioOutput.cpp @@ -114,7 +114,7 @@ namespace AVQt { alCall(alDeleteSources, 1, &d->m_ALSource); alCall(alDeleteBuffers, d->m_ALBufferCount, d->m_ALBuffers.data()); d->m_ALBuffers.clear(); - d->m_ALBuffers.shrink_to_fit(); + d->m_ALBuffers.squeeze(); alcCall(alcMakeContextCurrent, contextCurrent, d->m_ALCDevice, nullptr); alcCall(alcDestroyContext, d->m_ALCDevice, d->m_ALCContext); @@ -374,8 +374,7 @@ namespace AVQt { QMutexLocker lock3(&d->m_ALBufferQueueMutex); alCall(alSourceQueueBuffers, d->m_ALSource, static_cast<int>(qMin(d->m_ALBufferQueue.size(), 4)), d->m_ALBufferQueue.toVector().data()); - for (const auto &buf: QList(d->m_ALBufferQueue.end() - static_cast<int>(qMin(d->m_ALBufferQueue.size(), 4)), - d->m_ALBufferQueue.end())) { + for (const auto &buf: d->m_ALBufferQueue.mid(d->m_ALBufferQueue.size() - static_cast<int>(qMin(d->m_ALBufferQueue.size(), 4)))) { d->m_queuedSamples += d->m_ALBufferSampleMap[buf]; } if (d->m_ALBufferQueue.size() < 4) { @@ -440,7 +439,7 @@ namespace AVQt { if (d->m_inputQueue.isEmpty() || d->m_paused.load()) { return; } - qDebug("Size of output queue: %lld", d->m_inputQueue.size()); + qDebug("Size of output queue: %d", d->m_inputQueue.size()); QMutexLocker lock(&d->m_ALBufferQueueMutex); if (!d->m_ALBufferQueue.isEmpty()) { lock.unlock(); @@ -523,4 +522,4 @@ namespace AVQt { alcCall(alcMakeContextCurrent, contextCurrent, d->m_ALCDevice, nullptr); } -} \ No newline at end of file +} diff --git a/AVQt/output/private/Muxer_p.h b/AVQt/output/private/Muxer_p.h index 8b0fa50e776d45afcf836ab1f1f58fb10414b188..4f78ee9281b795acb099b626a489694ff16284fa 100644 --- a/AVQt/output/private/Muxer_p.h +++ b/AVQt/output/private/Muxer_p.h @@ -33,7 +33,7 @@ namespace AVQt { uint8_t *m_pIOBuffer{nullptr}; AVIOContext *m_pIOContext{nullptr}; AVFormatContext *m_pFormatContext{nullptr}; - QMap<IPacketSource *, QList<AVStream *>> m_sourceStreamMap{}; + QMap<IPacketSource *, QMap<AVStream *, AVRational>> m_sourceStreamMap{}; QMutex m_inputQueueMutex{}; QQueue<QPair<AVPacket *, AVStream *>> m_inputQueue{}; diff --git a/AVQt/output/private/OpenALAudioOutput_p.h b/AVQt/output/private/OpenALAudioOutput_p.h index c9330cc3f612f87cec1604f446b2f19db0c5cd70..5ebc8169d9ee4f149f6063b12e10ec986828cc4e 100644 --- a/AVQt/output/private/OpenALAudioOutput_p.h +++ b/AVQt/output/private/OpenALAudioOutput_p.h @@ -49,9 +49,9 @@ namespace AVQt { int m_ALBufferCount{5}; std::atomic_int64_t m_playingBuffers{0}; QVector<ALuint> m_ALBuffers{}; - QRecursiveMutex m_ALBufferQueueMutex{}; + QMutex m_ALBufferQueueMutex{}; QQueue<ALuint> m_ALBufferQueue{}; - QRecursiveMutex m_ALBufferSampleMapMutex{}; + QMutex m_ALBufferSampleMapMutex{}; QMap<ALuint, int64_t> m_ALBufferSampleMap{}; int64_t m_queuedSamples{0}; ALCdevice *m_ALCDevice{nullptr}; @@ -70,4 +70,4 @@ namespace AVQt { }; } -#endif //LIBAVQT_OPENALAUDIOOUTPUT_P_H \ No newline at end of file +#endif //LIBAVQT_OPENALAUDIOOUTPUT_P_H diff --git a/Player.pro.user b/Player.pro.user index be6e13f22ce1231dee0e3945ef97de4c1140f736..f83227fa715eaf8098ae427188c8cc4f03cc6810 100644 --- a/Player.pro.user +++ b/Player.pro.user @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE QtCreatorProject> -<!-- Written by QtCreator 4.14.1, 2021-05-08T11:26:40. --> +<!-- Written by QtCreator 4.14.1, 2021-05-28T17:40:00. --> <qtcreator> <data> <variable>EnvironmentId</variable> @@ -8,7 +8,7 @@ </data> <data> <variable>ProjectExplorer.Project.ActiveTarget</variable> - <value type="int">0</value> + <value type="int">1</value> </data> <data> <variable>ProjectExplorer.Project.EditorSettings</variable> @@ -109,8 +109,8 @@ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> </valuemap> <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Erstellen</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Erstellen</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value> </valuemap> <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1"> @@ -120,8 +120,8 @@ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value> </valuemap> <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Bereinigen</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Bereinigen</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value> </valuemap> <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> @@ -151,8 +151,8 @@ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> </valuemap> <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Erstellen</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Erstellen</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value> </valuemap> <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1"> @@ -162,8 +162,8 @@ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value> </valuemap> <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Bereinigen</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Bereinigen</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value> </valuemap> <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> @@ -193,8 +193,8 @@ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> </valuemap> <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Erstellen</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Erstellen</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value> </valuemap> <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1"> @@ -204,8 +204,8 @@ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value> </valuemap> <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Bereinigen</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Bereinigen</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value> </valuemap> <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> @@ -223,8 +223,8 @@ <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0"> <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deployment</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deployment</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value> </valuemap> <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value> @@ -311,15 +311,16 @@ <variable>ProjectExplorer.Project.Target.1</variable> <valuemap type="QVariantMap"> <value type="QString" key="DeviceType">Desktop</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">MinGW x86_64</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">MinGW x86_64</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{d1a101cb-333a-40d5-afd0-8c544cd86c51}</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{ff2c954c-33d9-44cd-91b8-591dd542e6e9}</value> <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value> <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value> <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value> <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0"> - <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/silas/CLionProjects/build-Player-MinGW_x86_64-Debug</value> - <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/silas/CLionProjects/build-Player-MinGW_x86_64-Debug</value> + <value type="int" key="EnableQmlDebugging">0</value> + <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/silas/CLionProjects/build-Player-Desktop-Debug</value> + <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/silas/CLionProjects/build-Player-Desktop-Debug</value> <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> @@ -333,8 +334,8 @@ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> </valuemap> <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Erstellen</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Erstellen</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value> </valuemap> <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1"> @@ -344,8 +345,8 @@ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value> </valuemap> <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Bereinigen</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Bereinigen</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value> </valuemap> <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> @@ -355,12 +356,12 @@ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value> <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value> - <value type="int" key="QtQuickCompiler">0</value> + <value type="int" key="RunSystemFunction">0</value> </valuemap> <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1"> <value type="int" key="EnableQmlDebugging">0</value> - <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/silas/CLionProjects/build-Player-MinGW_x86_64-Release</value> - <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/silas/CLionProjects/build-Player-MinGW_x86_64-Release</value> + <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/silas/CLionProjects/build-Player-Desktop-Release</value> + <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/silas/CLionProjects/build-Player-Desktop-Release</value> <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> @@ -374,8 +375,8 @@ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> </valuemap> <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Erstellen</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Erstellen</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value> </valuemap> <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1"> @@ -385,8 +386,8 @@ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value> </valuemap> <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Bereinigen</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Bereinigen</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value> </valuemap> <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> @@ -401,8 +402,8 @@ </valuemap> <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2"> <value type="int" key="EnableQmlDebugging">0</value> - <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/silas/CLionProjects/build-Player-MinGW_x86_64-Profile</value> - <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/silas/CLionProjects/build-Player-MinGW_x86_64-Profile</value> + <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/silas/CLionProjects/build-Player-Desktop-Profile</value> + <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/silas/CLionProjects/build-Player-Desktop-Profile</value> <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> @@ -416,8 +417,8 @@ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> </valuemap> <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Erstellen</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Erstellen</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value> </valuemap> <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1"> @@ -427,8 +428,8 @@ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value> </valuemap> <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Bereinigen</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Bereinigen</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value> </valuemap> <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> @@ -446,8 +447,8 @@ <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0"> <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deployment</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deployment</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value> </valuemap> <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value> @@ -524,7 +525,7 @@ <value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value> <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value> <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value> - <value type="bool" key="RunConfiguration.UseTerminal">true</value> + <value type="QString" key="RunConfiguration.WorkingDirectory.default">/home/silas/CLionProjects/build-Player-Desktop-Debug/Player</value> </valuemap> <value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value> </valuemap> diff --git a/Player/CMakeLists.txt b/Player/CMakeLists.txt index 684765b0169160633af05a4c1670e2cfd912d249..7b5e0e2d7235b717ebc42b1edd318b4aa02de322 100644 --- a/Player/CMakeLists.txt +++ b/Player/CMakeLists.txt @@ -1,19 +1,22 @@ #SET(CMAKE_INSTALL_RPATH "$ORIGIN/../AVQt") #SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH on) -find_package(Qt6 COMPONENTS Core Gui Widgets OpenGL OpenGLWidgets Concurrent) -#find_package(Qt5 COMPONENTS Core Gui Widgets OpenGL Concurrent) +#find_package(Qt6 COMPONENTS Core Gui Widgets OpenGL OpenGLWidgets Concurrent) + +set(CMAKE_CXX_STANDARD 20) + +find_package(Qt5 COMPONENTS Core Gui Widgets OpenGL Concurrent) find_package(OpenAL) #add_compile_options(-O4) add_executable(Player main.cpp) -target_link_libraries(Player Qt6::Core Qt6::Gui Qt6::Concurrent Qt6::Widgets Qt6::OpenGLWidgets Qt6::OpenGL avformat avfilter avutil avcodec avdevice swscale swresample AVQt) -#target_link_libraries(Player Qt5::Core Qt5::Gui Qt5::Concurrent Qt5::Widgets Qt5::OpenGL avformat avfilter avutil avcodec avdevice swscale swresample AVQt) +#target_link_libraries(Player Qt6::Core Qt6::Gui Qt6::Concurrent Qt6::Widgets Qt6::OpenGLWidgets Qt6::OpenGL avformat avfilter avutil avcodec avdevice swscale swresample AVQt) +target_link_libraries(Player Qt5::Core Qt5::Gui Qt5::Concurrent Qt5::Widgets Qt5::OpenGL avformat avfilter avutil avcodec avdevice swscale swresample AVQt) if (LINUX) target_link_libraries(Player openal GL) elseif (WIN32) target_link_libraries(Player OpenAL32 opengl32) -endif () \ No newline at end of file +endif () diff --git a/Player/main.cpp b/Player/main.cpp index 5d6937800afc33a297a0c6beef2e75ceb0a0cc18..6e102c739a3ccc290e7d425ccd17bf5226d697d3 100644 --- a/Player/main.cpp +++ b/Player/main.cpp @@ -28,7 +28,7 @@ void messageHandler(QtMsgType type, const QMessageLogContext &context, const QSt auto now = QDateTime::currentDateTime(); os << now.toString(Qt::ISODateWithMs) << ": "; - os << qPrintable(qFormatLogMessage(type, context, message)) << Qt::endl; + os << qPrintable(qFormatLogMessage(type, context, message)) << "\n"; std::cerr << output.toStdString(); @@ -67,7 +67,7 @@ int main(int argc, char *argv[]) { AVQt::IDecoder *videoDecoder; #ifdef Q_OS_LINUX - videoDecoder = new AVQt::DecoderQSV; + videoDecoder = new AVQt::DecoderVAAPI; #elif defined(Q_OS_WINDOWS) videoDecoder = new AVQt::DecoderDXVA2(); #else @@ -79,6 +79,12 @@ int main(int argc, char *argv[]) { demuxer.registerCallback(videoDecoder, AVQt::IPacketSource::CB_VIDEO); // videoDecoder->registerCallback(encoder); + + QFile outputFile("output.ts"); + outputFile.open(QIODevice::ReadWrite | QIODevice::Truncate); + AVQt::Muxer muxer(&outputFile); + +// encoder->registerCallback(&muxer, AVQt::IPacketSource::CB_VIDEO); videoDecoder->registerCallback(&renderer); renderer.setMinimumSize(QSize(360, 240)); @@ -103,4 +109,4 @@ int main(int argc, char *argv[]) { }); return QApplication::exec(); -} \ No newline at end of file +}