CodecsComponent.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. #ifndef CODECS_H
  2. #define CODECS_H
  3. #include <QObject>
  4. #include <QtCore/qglobal.h>
  5. #include <QList>
  6. #include <QSize>
  7. #include <QNetworkAccessManager>
  8. #include <QNetworkReply>
  9. #include <QQueue>
  10. #include <QUrl>
  11. #include <QVariant>
  12. #include <QElapsedTimer>
  13. #include <QSet>
  14. ///////////////////////////////////////////////////////////////////////////////////////////////////
  15. enum class CodecType {
  16. Decoder,
  17. Encoder,
  18. };
  19. ///////////////////////////////////////////////////////////////////////////////////////////////////
  20. struct CodecDriver {
  21. CodecType type; // encoder/decoder
  22. QString format; // e.g. "h264", the canonical FFmpeg name of the codec
  23. QString driver; // specific implementation, e.g. "h264" (native) or "h264_mf" (MediaFoundation)
  24. bool present; // if false, it's a not-installed installable codec
  25. bool external; // marked as external in CodecManifest.h
  26. // Driver name decorated with additional attributes, e.g. "h264_mf_decoder".
  27. QString getMangledName() const;
  28. // Filename of the DLL/SO including build version/type, without path.
  29. // Only applies to external drivers.
  30. QString getFileName() const;
  31. // Like getFileName(), but includes full path.
  32. // Only applies to external drivers.
  33. QString getPath() const;
  34. // Return whether the codec is provided by the OS or the hardware. They are
  35. // distinct from FFmpeg-native codecs and usually have weaker capabilities.
  36. // While they are also always available, they might fail in various ways
  37. // depending on input media and OS version.
  38. bool isSystemCodec() const;
  39. // Return "mf" for Windows codecs, "at" for OSX audio, "mmal" for RPI video, "eae" for EAE, "" otherwise
  40. QString getSystemCodecType() const;
  41. bool isWhitelistedSystemAudioCodec() const;
  42. bool isWhitelistedSystemVideoCodec() const;
  43. bool valid() { return format.size() > 0; }
  44. };
  45. struct StreamInfo {
  46. bool isVideo, isAudio;
  47. QString codec;
  48. QString profile;
  49. int audioChannels;
  50. int audioSampleRate;
  51. QSize videoResolution;
  52. };
  53. struct PlaybackInfo {
  54. QList<StreamInfo> streams; // information for _all_ streams the file has
  55. // (even if not selected)
  56. QSet<QString> audioPassthroughCodecs; // list of audio formats to pass through
  57. bool enableAC3Transcoding; // encode non-stereo to AC3
  58. };
  59. ///////////////////////////////////////////////////////////////////////////////////////////////////
  60. class Downloader : public QObject
  61. {
  62. Q_OBJECT
  63. public:
  64. typedef QPair<QString, QString> Header;
  65. typedef QList<Header> HeaderList;
  66. explicit Downloader(QVariant userData, const QUrl& url, const HeaderList& headers, QObject* parent);
  67. Q_SIGNALS:
  68. void done(QVariant userData, bool success, const QByteArray& data);
  69. private Q_SLOTS:
  70. void networkFinished(QNetworkReply* pReply);
  71. void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
  72. private:
  73. QNetworkAccessManager m_WebCtrl;
  74. QByteArray m_DownloadedData;
  75. QVariant m_userData;
  76. QElapsedTimer m_currentStartTime;
  77. int m_lastProgress;
  78. };
  79. ///////////////////////////////////////////////////////////////////////////////////////////////////
  80. class CodecsFetcher : public QObject
  81. {
  82. Q_OBJECT
  83. public:
  84. CodecsFetcher()
  85. : startCodecs(true), m_eaeNeeded(false), m_fetchEAE(false)
  86. {
  87. }
  88. // Download the given list of codecs (skip download for codecs already
  89. // installed). Then call done(userData), regardless of success.
  90. void installCodecs(const QList<CodecDriver>& codecs);
  91. // For free use by the user of this object.
  92. QVariant userData;
  93. bool startCodecs;
  94. Q_SIGNALS:
  95. void done(CodecsFetcher* sender);
  96. private Q_SLOTS:
  97. void codecInfoDownloadDone(QVariant userData, bool success, const QByteArray& data);
  98. void codecDownloadDone(QVariant userData, bool success, const QByteArray& data);
  99. private:
  100. bool codecNeedsDownload(const CodecDriver& codec);
  101. bool processCodecInfoReply(const QVariant& context, const QByteArray& data);
  102. void processCodecDownloadDone(const QVariant& context, const QByteArray& data);
  103. void startNext();
  104. void startEAE();
  105. QQueue<CodecDriver> m_Codecs;
  106. QByteArray m_currentHash;
  107. bool m_eaeNeeded;
  108. bool m_fetchEAE;
  109. };
  110. class Codecs
  111. {
  112. public:
  113. static void preinitCodecs();
  114. static void initCodecs();
  115. static QString plexNameToFF(QString plex);
  116. static QString plexNameFromFF(QString ffname);
  117. static inline bool sameCodec(const CodecDriver& a, const CodecDriver& b)
  118. {
  119. return a.type == b.type && a.format == b.format && a.driver == b.driver;
  120. }
  121. static void updateCachedCodecList();
  122. static void Uninit();
  123. static const QList<CodecDriver>& getCachedCodecList();
  124. static QList<CodecDriver> findCodecsByFormat(const QList<CodecDriver>& list, CodecType type, const QString& format);
  125. static QList<CodecDriver> determineRequiredCodecs(const PlaybackInfo& info);
  126. };
  127. #endif // CODECS_H