blob: bfa58edcc4bec89b88451e6359e59521cbe8525e (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/video/capture/win/capability_list_win.h"
#include <algorithm>
#include "base/logging.h"
namespace media {
namespace {
// Help structure used for comparing video capture capabilities.
struct ResolutionDiff {
const VideoCaptureCapabilityWin* capability;
int diff_height;
int diff_width;
int diff_frame_rate;
};
bool CompareHeight(const ResolutionDiff& item1, const ResolutionDiff& item2) {
return abs(item1.diff_height) < abs(item2.diff_height);
}
bool CompareWidth(const ResolutionDiff& item1, const ResolutionDiff& item2) {
return abs(item1.diff_width) < abs(item2.diff_width);
}
bool CompareFrameRate(const ResolutionDiff& item1,
const ResolutionDiff& item2) {
return abs(item1.diff_frame_rate) < abs(item2.diff_frame_rate);
}
bool CompareColor(const ResolutionDiff& item1, const ResolutionDiff& item2) {
return item1.capability->supported_format.pixel_format <
item2.capability->supported_format.pixel_format;
}
} // namespace.
CapabilityList::CapabilityList() {
DetachFromThread();
}
CapabilityList::~CapabilityList() {}
// Appends an entry to the list.
void CapabilityList::Add(const VideoCaptureCapabilityWin& capability) {
DCHECK(CalledOnValidThread());
capabilities_.push_back(capability);
}
const VideoCaptureCapabilityWin& CapabilityList::GetBestMatchedFormat(
int requested_width,
int requested_height,
int requested_frame_rate) const {
DCHECK(CalledOnValidThread());
DCHECK(!capabilities_.empty());
std::list<ResolutionDiff> diff_list;
// Loop through the candidates to create a list of differentials between the
// requested resolution and the camera capability.
for (Capabilities::const_iterator it = capabilities_.begin();
it != capabilities_.end(); ++it) {
ResolutionDiff diff;
diff.capability = &(*it);
diff.diff_width = it->supported_format.frame_size.width() - requested_width;
diff.diff_height =
it->supported_format.frame_size.height() - requested_height;
// The 1000 allows using integer arithmetic for f.i. 29.971 fps.
diff.diff_frame_rate =
1000 * ((static_cast<float>(it->frame_rate_numerator) /
it->frame_rate_denominator) -
requested_frame_rate);
diff_list.push_back(diff);
}
// Sort the best height candidates.
diff_list.sort(&CompareHeight);
int best_diff = diff_list.front().diff_height;
for (std::list<ResolutionDiff>::iterator it = diff_list.begin();
it != diff_list.end(); ++it) {
if (it->diff_height != best_diff) {
// Remove all candidates but the best.
diff_list.erase(it, diff_list.end());
break;
}
}
// Sort the best width candidates.
diff_list.sort(&CompareWidth);
best_diff = diff_list.front().diff_width;
for (std::list<ResolutionDiff>::iterator it = diff_list.begin();
it != diff_list.end(); ++it) {
if (it->diff_width != best_diff) {
// Remove all candidates but the best.
diff_list.erase(it, diff_list.end());
break;
}
}
// Sort the best frame rate candidates.
diff_list.sort(&CompareFrameRate);
best_diff = diff_list.front().diff_frame_rate;
for (std::list<ResolutionDiff>::iterator it = diff_list.begin();
it != diff_list.end(); ++it) {
if (it->diff_frame_rate != best_diff) {
diff_list.erase(it, diff_list.end());
break;
}
}
// Decide the best color format.
diff_list.sort(&CompareColor);
return *diff_list.front().capability;
}
} // namespace media
|