when automatically determining FPS/resolution for devices, prioritize FPS rather than resolution

This commit is contained in:
jp9000 2013-07-07 16:11:15 -07:00
parent a666ebddaa
commit c0438dacb4
3 changed files with 37 additions and 11 deletions

View File

@ -499,7 +499,18 @@ struct FPSInfo
List<FPSInterval> supportedIntervals; List<FPSInterval> supportedIntervals;
}; };
bool GetClosestResolution(List<MediaOutputInfo> &outputList, SIZE &resolution, UINT64 &frameInterval) static inline UINT64 GetFrameIntervalDist(UINT64 minInterval, UINT64 maxInterval, UINT64 desiredInterval)
{
INT64 minDist = INT64(minInterval)-INT64(desiredInterval);
INT64 maxDist = INT64(desiredInterval)-INT64(maxInterval);
if (minDist < 0) minDist = 0;
if (maxDist < 0) maxDist = 0;
return UINT64(MAX(minDist, maxDist));
}
bool GetClosestResolutionFPS(List<MediaOutputInfo> &outputList, SIZE &resolution, UINT64 &frameInterval, bool bPrioritizeFPS)
{ {
LONG width, height; LONG width, height;
UINT64 internalFrameInterval = 10000000/UINT64(API->GetMaxFPS()); UINT64 internalFrameInterval = 10000000/UINT64(API->GetMaxFPS());
@ -508,7 +519,8 @@ bool GetClosestResolution(List<MediaOutputInfo> &outputList, SIZE &resolution, U
LONG bestDistance = 0x7FFFFFFF; LONG bestDistance = 0x7FFFFFFF;
SIZE bestSize; SIZE bestSize;
UINT64 maxFrameInterval = 0; UINT64 maxFrameInterval = 0;
UINT64 bestFrameInterval = 0xFFFFFFFFFFFFFFFFLL; UINT64 minFrameInterval = 0;
UINT64 bestFrameIntervalDist = 0xFFFFFFFFFFFFFFFFLL;
for(UINT i=0; i<outputList.Num(); i++) for(UINT i=0; i<outputList.Num(); i++)
{ {
@ -523,7 +535,7 @@ bool GetClosestResolution(List<MediaOutputInfo> &outputList, SIZE &resolution, U
if(distWidth > bestDistance) if(distWidth > bestDistance)
{ {
outputWidth += outputInfo.xGranularity; outputWidth += outputInfo.xGranularity;
continue; continue;
} }
@ -535,13 +547,27 @@ bool GetClosestResolution(List<MediaOutputInfo> &outputList, SIZE &resolution, U
break; break;
LONG totalDist = distHeight+distWidth; LONG totalDist = distHeight+distWidth;
if((totalDist <= bestDistance) || (totalDist == bestDistance && outputInfo.minFrameInterval < bestFrameInterval))
{ UINT64 frameIntervalDist = GetFrameIntervalDist(outputInfo.minFrameInterval,
outputInfo.maxFrameInterval, internalFrameInterval);
bool bBetter;
if (bPrioritizeFPS)
bBetter = (frameIntervalDist != bestFrameIntervalDist) ?
(frameIntervalDist < bestFrameIntervalDist) :
(totalDist < bestDistance);
else
bBetter = (totalDist != bestDistance) ?
(totalDist < bestDistance) :
(frameIntervalDist < bestFrameIntervalDist);
if (bBetter) {
bestDistance = totalDist; bestDistance = totalDist;
bestSize.cx = outputWidth; bestSize.cx = outputWidth;
bestSize.cy = outputHeight; bestSize.cy = outputHeight;
maxFrameInterval = outputInfo.maxFrameInterval; maxFrameInterval = outputInfo.maxFrameInterval;
bestFrameInterval = outputInfo.minFrameInterval; minFrameInterval = outputInfo.minFrameInterval;
bestFrameIntervalDist = frameIntervalDist;
} }
outputHeight += outputInfo.yGranularity; outputHeight += outputInfo.yGranularity;
@ -558,8 +584,8 @@ bool GetClosestResolution(List<MediaOutputInfo> &outputList, SIZE &resolution, U
if(internalFrameInterval > maxFrameInterval) if(internalFrameInterval > maxFrameInterval)
frameInterval = maxFrameInterval; frameInterval = maxFrameInterval;
else if(internalFrameInterval < bestFrameInterval) else if(internalFrameInterval < minFrameInterval)
frameInterval = bestFrameInterval; frameInterval = minFrameInterval;
else else
frameInterval = internalFrameInterval; frameInterval = internalFrameInterval;
return true; return true;
@ -1499,7 +1525,7 @@ INT_PTR CALLBACK ConfigureDialogProc(HWND hwnd, UINT message, WPARAM wParam, LPA
SIZE size; SIZE size;
UINT64 frameInterval; UINT64 frameInterval;
if(GetClosestResolution(configData->outputList, size, frameInterval)) if(GetClosestResolutionFPS(configData->outputList, size, frameInterval, true))
{ {
String strResolution; String strResolution;
strResolution << UIntString(size.cx) << TEXT("x") << UIntString(size.cy); strResolution << UIntString(size.cx) << TEXT("x") << UIntString(size.cy);

View File

@ -37,7 +37,7 @@ extern HINSTANCE hinstMain;
IBaseFilter* GetDeviceByValue(const IID &enumType, WSTR lpType, CTSTR lpName, WSTR lpType2=NULL, CTSTR lpName2=NULL); IBaseFilter* GetDeviceByValue(const IID &enumType, WSTR lpType, CTSTR lpName, WSTR lpType2=NULL, CTSTR lpName2=NULL);
IPin* GetOutputPin(IBaseFilter *filter, const GUID *majorType); IPin* GetOutputPin(IBaseFilter *filter, const GUID *majorType);
void GetOutputList(IPin *curPin, List<MediaOutputInfo> &outputInfoList); void GetOutputList(IPin *curPin, List<MediaOutputInfo> &outputInfoList);
bool GetClosestResolution(List<MediaOutputInfo> &outputList, SIZE &resolution, UINT64 &frameInterval); bool GetClosestResolutionFPS(List<MediaOutputInfo> &outputList, SIZE &resolution, UINT64 &frameInterval, bool bPrioritizeFPS);
extern LocaleStringLookup *pluginLocale; extern LocaleStringLookup *pluginLocale;
#define PluginStr(text) pluginLocale->LookupString(TEXT2(text)) #define PluginStr(text) pluginLocale->LookupString(TEXT2(text))

View File

@ -311,7 +311,7 @@ bool DeviceSource::LoadFilters()
else else
{ {
SIZE size; SIZE size;
if (!GetClosestResolution(outputList, size, frameInterval)) if (!GetClosestResolutionFPS(outputList, size, frameInterval, true))
{ {
AppWarning(TEXT("DShowPlugin: Unable to find appropriate resolution")); AppWarning(TEXT("DShowPlugin: Unable to find appropriate resolution"));
renderCX = renderCY = 64; renderCX = renderCY = 64;