Skip to content

Commit 338de54

Browse files
committed
v4.5.0
1 parent c00a230 commit 338de54

5 files changed

Lines changed: 97 additions & 32 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# Son Feb 26 2023 Maxime Dirksen - 4.5.0
2+
- Improvement of driver generation
13
# Fri Feb 24 2023 Maxime Dirksen - 4.4.2
24
- Fix command not found
35
- Smaller size

sources/driver/camera.cpp

Lines changed: 89 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <cstring>
66
#include <errno.h>
77
#include <vector>
8+
#include <numeric>
89
#include <sys/ioctl.h>
910
#include <linux/usb/video.h>
1011
#include <linux/uvcvideo.h>
@@ -21,6 +22,18 @@ using namespace std;
2122
#include "logger.hpp"
2223
#include "camera.hpp"
2324

25+
int array_gcd(const uint8_t *arr, uint16_t size)
26+
{
27+
int result = arr[0];
28+
for (int i = 1; i < size; ++i)
29+
{
30+
result = gcd(arr[i], result);
31+
if (result == 1)
32+
return 1;
33+
}
34+
return result;
35+
}
36+
2437
/**
2538
* @brief Obtain the id of any device path
2639
*
@@ -264,21 +277,51 @@ void CameraInstruction::logDebugCtrl(string prefixMsg, const uint8_t *control, c
264277
}
265278

266279
/**
267-
* @brief We remarked that sometimes the min instruction provided by the camera is not consistent
268-
* i.e. its patern does not look right when compared to the current or max control.
280+
* @brief Compute the resolution control instruction composed of 0 or 1
281+
* by comparing two controls instruction
282+
* we assume isReachable(first, res, second, size) is true
269283
*
270-
* @return false if minCtrl is nullptr or not coherent, otherwise true
284+
* @param first the first instruction
285+
* @param second the second instruction
286+
* @param res the resolution instruction will be stored in it
287+
* @param size of the instructions
271288
*/
272-
bool CameraInstruction::isMinConsistent() noexcept
289+
void CameraInstruction::computeResCtrl(const uint8_t *first, const uint8_t *second, uint8_t *res, const uint16_t size) noexcept
273290
{
274-
if (minCtrl == nullptr)
275-
return false;
291+
int secondGcd = array_gcd(second, size);
276292

277-
for (unsigned i = 0; i < ctrlSize; ++i)
278-
if (minCtrl[i] > curCtrl[i] || minCtrl[i] > maxCtrl[i])
279-
return false;
293+
if (secondGcd > 1)
294+
for (unsigned i = 0; i < size; ++i)
295+
res[i] = (second[i] - first[i]) / secondGcd;
296+
else
297+
for (unsigned i = 0; i < size; ++i)
298+
res[i] = (uint8_t)second[i] != first[i];
299+
}
280300

281-
return true;
301+
/**
302+
* @brief Check if a resolution control allow to reach a control from another
303+
*
304+
* @param base instruction from which the resolution must be added
305+
* @param res the resolution control
306+
* @param toReach the instruction to reach
307+
* @param size of the instructions
308+
* @return true if reacheable, otherwise false
309+
*/
310+
bool CameraInstruction::isReachable(const uint8_t *base, const uint8_t *res, const uint8_t *toReach, const uint16_t size) noexcept
311+
{
312+
int it = 256;
313+
for (unsigned i = 0; i < size; ++i)
314+
{
315+
if (res[i] != 0)
316+
{
317+
int newit = (toReach[i] - base[i]) / res[i]; // # iterations required for that value
318+
if (newit < 0 || (newit != it && it != 256)) // negative iteration or not all value have the same # iterations
319+
return false;
320+
it = newit;
321+
}
322+
}
323+
324+
return it != 256;
282325
}
283326

284327
/**
@@ -301,35 +344,55 @@ CameraInstruction::CameraInstruction(Camera &camera, uint8_t unit, uint8_t selec
301344

302345
// get the current control value
303346
curCtrl = new uint8_t[ctrlSize];
304-
if (camera.getUvcQuery(UVC_GET_CUR, unit, selector, ctrlSize, curCtrl))
347+
if (camera.getUvcQuery(UVC_GET_CUR, unit, selector, ctrlSize, curCtrl) == 1)
348+
throw CameraInstructionException(camera.device, unit, selector);
349+
350+
// ensure the control can be modified
351+
if (camera.setUvcQuery(unit, selector, ctrlSize, curCtrl) == 1)
305352
throw CameraInstructionException(camera.device, unit, selector);
306-
logDebugCtrl("current:", curCtrl, ctrlSize);
307353

308354
// try to get the maximum control value (it does not necessary exists)
309355
maxCtrl = new uint8_t[ctrlSize];
310-
if (camera.getUvcQuery(UVC_GET_MAX, unit, selector, ctrlSize, maxCtrl))
311-
memset(maxCtrl, 255, ctrlSize * sizeof(uint8_t)); // use the 255 array
312-
logDebugCtrl("maximum:", maxCtrl, ctrlSize);
356+
if (camera.getUvcQuery(UVC_GET_MAX, unit, selector, ctrlSize, maxCtrl) == 1)
357+
throw CameraInstructionException(camera.device, unit, selector);
313358

314359
// try get the minimum control value (it does not necessary exists)
315360
minCtrl = new uint8_t[ctrlSize];
316-
if (camera.getUvcQuery(UVC_GET_MIN, unit, selector, ctrlSize, minCtrl))
317-
logDebugCtrl("minimum:", minCtrl, ctrlSize);
318-
else
361+
if (camera.getUvcQuery(UVC_GET_MIN, unit, selector, ctrlSize, minCtrl) == 1)
319362
{
320363
delete[] minCtrl;
321364
minCtrl = nullptr;
322365
}
323366

324367
// try to get the resolution control value (it does not necessary exists)
368+
// and check if it is consistent
325369
resCtrl = new uint8_t[ctrlSize];
326-
if (camera.getUvcQuery(UVC_GET_RES, unit, selector, ctrlSize, resCtrl))
370+
if (camera.getUvcQuery(UVC_GET_RES, unit, selector, ctrlSize, resCtrl) == 1 ||
371+
!isReachable(curCtrl, resCtrl, maxCtrl, ctrlSize))
327372
{
328373
Logger::debug("Computing the resolution control.");
329-
for (unsigned i = 0; i < ctrlSize; ++i)
330-
resCtrl[i] = (uint8_t)curCtrl[i] != maxCtrl[i]; // step of 0 or 1
374+
375+
if (minCtrl != nullptr)
376+
{
377+
computeResCtrl(minCtrl, curCtrl, resCtrl, ctrlSize);
378+
if (!isReachable(minCtrl, resCtrl, curCtrl, ctrlSize))
379+
{
380+
Logger::debug("Minimum not consistent, it will be ignored.");
381+
delete[] minCtrl;
382+
minCtrl = nullptr;
383+
computeResCtrl(curCtrl, maxCtrl, resCtrl, ctrlSize);
384+
}
385+
}
386+
else
387+
computeResCtrl(curCtrl, maxCtrl, resCtrl, ctrlSize);
331388
}
389+
390+
logDebugCtrl("current:", curCtrl, ctrlSize);
391+
logDebugCtrl("maximum:", maxCtrl, ctrlSize);
392+
if (minCtrl != nullptr)
393+
logDebugCtrl("minimum:", minCtrl, ctrlSize);
332394
logDebugCtrl("resolution:", resCtrl, ctrlSize);
395+
Logger::debug(("unit: " + to_string((int)unit) + " selector: " + to_string((int)selector)).c_str());
333396
}
334397

335398
/**
@@ -465,14 +528,15 @@ uint8_t CameraInstruction::getSelector() const noexcept
465528
}
466529

467530
/**
468-
* @brief If a minimun control instruction exists and is consistent,
531+
* @brief If a minimun control instruction exists
532+
* and is not already the current,
469533
* set the current control instruction with that value
470534
*
471535
* @return true if success, otherwise false
472536
*/
473537
bool CameraInstruction::trySetMinAsCur() noexcept
474538
{
475-
if (!isMinConsistent())
539+
if (minCtrl == nullptr || memcmp(curCtrl, minCtrl, ctrlSize * sizeof(uint8_t)) == 0)
476540
return false;
477541

478542
memcpy(curCtrl, minCtrl, ctrlSize * sizeof(uint8_t));
@@ -488,7 +552,8 @@ const char *CameraException::what()
488552
return message.c_str();
489553
}
490554

491-
CameraInstructionException::CameraInstructionException(string device, uint8_t unit, uint8_t selector) : message("ERROR: Impossible to obtain the instruction on " + device + " for unit: " + to_string((int)unit) + " selector:" + to_string((int)selector)) {}
555+
CameraInstructionException::CameraInstructionException(string device, uint8_t unit, uint8_t selector)
556+
: message("ERROR: Impossible to obtain the instruction on " + device + " for unit: " + to_string((int)unit) + " selector:" + to_string((int)selector)) {}
492557

493558
const char *CameraInstructionException::what()
494559
{

sources/driver/camera.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@ class CameraInstruction
5757

5858
static void logDebugCtrl(string prefixMsg, const uint8_t *control, const uint16_t len) noexcept;
5959

60-
bool isMinConsistent() noexcept;
60+
static void computeResCtrl(const uint8_t *first, const uint8_t *second, uint8_t *res, const uint16_t size) noexcept;
61+
62+
static bool isReachable(const uint8_t *base, const uint8_t *res, const uint8_t *toReach, const uint16_t size) noexcept;
6163

6264
public:
6365
CameraInstruction(Camera &camera, uint8_t unit, uint8_t selector);

sources/driver/finder.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -170,10 +170,8 @@ Driver **Finder::find()
170170
if (isExcluded(unit, selector))
171171
continue;
172172
try
173-
{
173+
{
174174
CameraInstruction instruction(camera, unit, selector);
175-
// if (!camera.apply(instruction)) // ensure the instruction can be modified
176-
// continue;
177175
CameraInstruction initInstruction = instruction; // copy for reset later
178176

179177
if (!instruction.trySetMinAsCur()) // if no min instruction exists
@@ -183,9 +181,7 @@ Driver **Finder::find()
183181
else
184182
continue;
185183
}
186-
187-
Logger::debug(("unit: " + to_string((int)unit) + " selector: " + to_string((int)selector)).c_str());
188-
184+
189185
unsigned negAnswerCounter = 0;
190186
do
191187
{

sources/linux-enable-ir-emitter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
parser.add_argument(
2626
"-V", "--version",
2727
action="version",
28-
version="%(prog)s 4.4.0\nDevelopped by Maxime Dirksen - EmixamPP\nMIT License",
28+
version="%(prog)s 4.5.0\nDevelopped by Maxime Dirksen - EmixamPP\nMIT License",
2929
help="show version information and exit"
3030
)
3131
parser.add_argument(

0 commit comments

Comments
 (0)