2016-11-24, 19:20
I recently got a 4k monitor, but don't have much 4k content so I created a 4k smart playlist.
Here's the XML definition:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<smartplaylist type="movies">
<name>4k</name>
<match>all</match>
<rule field="videoresolution" operator="greaterthan">
<value>2159</value>
</rule>
<order direction="ascending">sorttitle</order>
</smartplaylist>
To my surprise, this returned 0 results.
I went and verified that I most definitely had 4k content in Kodi and that it was showing as such.
And this point I didn't know if it was a db issue, a smart playlist issue, or a general Kodi issue, so I turned on debug logging and ran the play list. Result:
08:27:59 T:13900 DEBUG: CGUIMediaWindow::GetDirectory (special://profile/playlists/video/4K.xsp)
08:27:59 T:13900 DEBUG: ParentPath = [special://videoplaylists/]
08:27:59 T:13900 DEBUG: CVideoDatabase::RunQuery took 1 ms for 0 items query: select * from movie_view WHERE ((movie_view.idFile IN (SELECT DISTINCT idFile FROM streamdetails WHERE iVideoWidth > 2147483647)))
Well that would be why I get no results. A quick Google search for 2147483647 shows this is the max value of a 32bit int. Ok. At least I know it's just not some random number.
Now I'm wondering if maybe filtering on video resolution is just completely broken, so I change the filter value from 2159 to 1079. And low and behold, I get results back.Here's the query in the log for that:
10:58:13 T:12864 DEBUG: CVideoDatabase::RunQuery took 56 ms for 1742 items query: select * from movie_view WHERE ((movie_view.idFile IN (SELECT DISTINCT idFile FROM streamdetails WHERE iVideoWidth > 1280)
1280? Why is it using the vertical resolution for 720p content
Time to look up the source code. I searched for iVideoWidth in the repro and found the smartplaylist code at https://github.com/xbmc/xbmc/blob/5c2002...ayList.cpp
Here's the bit we're interested in:
What's the point of letting you put any number you want into the filter if you're just going to throw it into 1 of 4 buckets anyway? Especially if it's not future proof at all.
Here's my "fix" below:
This brings it back to what I think should be the expected functionality. Can anyone see why this might not work well before I go make a trac bug and pull request?
If this isn't a good idea, I think the second best option would be to add new "buckets" for 4k and 8k content.
Here's the XML definition:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<smartplaylist type="movies">
<name>4k</name>
<match>all</match>
<rule field="videoresolution" operator="greaterthan">
<value>2159</value>
</rule>
<order direction="ascending">sorttitle</order>
</smartplaylist>
To my surprise, this returned 0 results.
I went and verified that I most definitely had 4k content in Kodi and that it was showing as such.
And this point I didn't know if it was a db issue, a smart playlist issue, or a general Kodi issue, so I turned on debug logging and ran the play list. Result:
08:27:59 T:13900 DEBUG: CGUIMediaWindow::GetDirectory (special://profile/playlists/video/4K.xsp)
08:27:59 T:13900 DEBUG: ParentPath = [special://videoplaylists/]
08:27:59 T:13900 DEBUG: CVideoDatabase::RunQuery took 1 ms for 0 items query: select * from movie_view WHERE ((movie_view.idFile IN (SELECT DISTINCT idFile FROM streamdetails WHERE iVideoWidth > 2147483647)))
Well that would be why I get no results. A quick Google search for 2147483647 shows this is the max value of a 32bit int. Ok. At least I know it's just not some random number.
Now I'm wondering if maybe filtering on video resolution is just completely broken, so I change the filter value from 2159 to 1079. And low and behold, I get results back.Here's the query in the log for that:
10:58:13 T:12864 DEBUG: CVideoDatabase::RunQuery took 56 ms for 1742 items query: select * from movie_view WHERE ((movie_view.idFile IN (SELECT DISTINCT idFile FROM streamdetails WHERE iVideoWidth > 1280)
1280? Why is it using the vertical resolution for 720p content
Time to look up the source code. I searched for iVideoWidth in the repro and found the smartplaylist code at https://github.com/xbmc/xbmc/blob/5c2002...ayList.cpp
Here's the bit we're interested in:
Code:
std::string CSmartPlaylistRule::GetVideoResolutionQuery(const std::string ¶meter) const
{
std::string retVal(" IN (SELECT DISTINCT idFile FROM streamdetails WHERE iVideoWidth ");
int iRes = (int)std::strtol(parameter.c_str(), NULL, 10);
int min, max;
if (iRes >= 1080) { min = 1281; max = INT_MAX; }
else if (iRes >= 720) { min = 961; max = 1280; }
else if (iRes >= 540) { min = 721; max = 960; }
else { min = 0; max = 720; }
switch (m_operator)
{
case OPERATOR_EQUALS:
retVal += StringUtils::Format(">= %i AND iVideoWidth <= %i", min, max);
break;
case OPERATOR_DOES_NOT_EQUAL:
retVal += StringUtils::Format("< %i OR iVideoWidth > %i", min, max);
break;
case OPERATOR_LESS_THAN:
retVal += StringUtils::Format("< %i", min);
break;
case OPERATOR_GREATER_THAN:
retVal += StringUtils::Format("> %i", max);
break;
default:
break;
}
retVal += ")";
return retVal;
}
What's the point of letting you put any number you want into the filter if you're just going to throw it into 1 of 4 buckets anyway? Especially if it's not future proof at all.
Here's my "fix" below:
Code:
std::string CSmartPlaylistRule::GetVideoResolutionQuery(const std::string ¶meter) const
{
std::string retVal(" IN (SELECT DISTINCT idFile FROM streamdetails WHERE iVideoWidth ");
int iRes = (int)std::strtol(parameter.c_str(), NULL, 10);
switch (m_operator)
{
case OPERATOR_EQUALS:
retVal += StringUtils::Format("= %i", iRes);
break;
case OPERATOR_DOES_NOT_EQUAL:
retVal += StringUtils::Format("!= %i", iRes);
break;
case OPERATOR_LESS_THAN:
retVal += StringUtils::Format("< %i", iRes);
break;
case OPERATOR_GREATER_THAN:
retVal += StringUtils::Format("> %i", iRes);
break;
default:
break;
}
retVal += ")";
return retVal;
}
This brings it back to what I think should be the expected functionality. Can anyone see why this might not work well before I go make a trac bug and pull request?
If this isn't a good idea, I think the second best option would be to add new "buckets" for 4k and 8k content.