Browse Source

Get codec info from PMS info if possible

startCodecsLoading() is now called twice:
1. Before the stream is even opened. getPlaybackInfo() is made to use
the PMS metadata in this case.
2. After the stream has been opened and before a dedoder starts.
getPlaybackInfo() will use the player-analyzed metadata.

I'm hoping this makes all combinations of possible fuckups work. One
case this should certainly fix is playing raw DTS. If no DTS codec was
present yet, opening would fail in libavformat. Downloading the codec
before opening the file should take care of it.

This is chained with display mode switching. Not bothering with making
it run in parallel with mode switching, because I'm not even sure the
simpler current implementation is always correct.
Vincent Lang 8 years ago
parent
commit
28156134c3
3 changed files with 33 additions and 5 deletions
  1. 2 2
      src/player/CodecsComponent.cpp
  2. 2 0
      src/player/CodecsComponent.h
  3. 29 3
      src/player/PlayerComponent.cpp

+ 2 - 2
src/player/CodecsComponent.cpp

@@ -92,7 +92,7 @@ static QString getBuildType()
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-static QString plexNameToFF(QString plex)
+QString Codecs::plexNameToFF(QString plex)
 {
   if (plex == "dca")
     return "dts";
@@ -136,7 +136,7 @@ void Codecs::updateCachedCodecList()
     {
       CodecDriver codec = {};
       codec.type = type;
-      codec.format = plexNameToFF(list[i].codecName);
+      codec.format = Codecs::plexNameToFF(list[i].codecName);
       codec.driver = list[i].name;
       codec.external = list[i].external;
       if (!codec.isSystemCodec())

+ 2 - 0
src/player/CodecsComponent.h

@@ -117,6 +117,8 @@ class Codecs
 public:
   static void preinitCodecs();
 
+  static QString plexNameToFF(QString plex);
+
   static inline bool sameCodec(const CodecDriver& a, const CodecDriver& b)
   {
     return a.type == b.type && a.format == b.format && a.driver == b.driver;

+ 29 - 3
src/player/PlayerComponent.cpp

@@ -480,8 +480,11 @@ void PlayerComponent::handleMpvEvent(mpv_event *event)
       {
         // Calling this lambda will instruct mpv to continue loading the file.
         auto resume = [=] {
-          QLOG_INFO() << "resuming loading";
-          mpv::qt::command_variant(m_mpv, QStringList() << "hook-ack" << resumeId);
+          QLOG_INFO() << "checking codecs";
+          startCodecsLoading([=] {
+            QLOG_INFO() << "resuming loading";
+            mpv::qt::command_variant(m_mpv, QStringList() << "hook-ack" << resumeId);
+          });
         };
         if (switchDisplayFrameRate())
         {
@@ -952,7 +955,7 @@ PlaybackInfo PlayerComponent::getPlaybackInfo()
   info.enableAC3Transcoding = m_doAc3Transcoding;
 
   auto tracks = mpv::qt::get_property_variant(m_mpv, "track-list");
-  foreach (const QVariant& track, tracks.toList())
+  for (auto track : tracks.toList())
   {
     QVariantMap map = track.toMap();
     QString type = map["type"].toString();
@@ -974,6 +977,29 @@ PlaybackInfo PlayerComponent::getPlaybackInfo()
     info.streams.append(stream);
   }
 
+  // If we're in an early stage where we don't have streams yet, try to get the
+  // info from the PMS metadata.
+  if (!info.streams.size())
+  {
+    for (auto partInfo : m_serverMediaInfo["Part"].toList())
+    {
+      for (auto streamInfo : partInfo.toMap()["Stream"].toList())
+      {
+        auto streamInfoMap = streamInfo.toMap();
+
+        StreamInfo stream = {};
+        stream.isVideo = streamInfoMap["width"].isValid();
+        stream.isAudio = streamInfoMap["channels"].isValid();
+        stream.codec = Codecs::plexNameToFF(streamInfoMap["codec"].toString());
+        stream.audioChannels = streamInfoMap["channels"].toInt();
+        stream.videoResolution = QSize(streamInfoMap["width"].toInt(), streamInfoMap["height"].toInt());
+        stream.profile = streamInfoMap["profile"].toString();
+
+        info.streams.append(stream);
+      }
+    }
+  }
+
   return info;
 }