/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * Copyright (C) 2020, Google Inc. * * A provider of external buffers, suitable for use in tests. */ #include "buffer_source.h" #include #include #include "libcamera/internal/device_enumerator.h" #include "test.h" BufferSource::BufferSource() { } BufferSource::~BufferSource() { if (media_) media_->release(); } int BufferSource::allocate(const StreamConfiguration &config) { /* Locate and open the video device. */ std::string videoDeviceName = "vivid-000-vid-out"; std::unique_ptr enumerator = DeviceEnumerator::create(); if (!enumerator) { std::cout << "Failed to create device enumerator" << std::endl; return TestFail; } if (enumerator->enumerate()) { std::cout << "Failed to enumerate media devices" << std::endl; return TestFail; } DeviceMatch dm("vivid"); dm.add(videoDeviceName); media_ = enumerator->search(dm); if (!media_) { std::cout << "No vivid output device available" << std::endl; return TestSkip; } std::unique_ptr video{ V4L2VideoDevice::fromEntityName(media_.get(), videoDeviceName) }; if (!video) { std::cout << "Failed to get video device from entity " << videoDeviceName << std::endl; return TestFail; } if (video->open()) { std::cout << "Unable to open " << videoDeviceName << std::endl; return TestFail; } /* Configure the format. */ V4L2DeviceFormat format; if (video->getFormat(&format)) { std::cout << "Failed to get format on output device" << std::endl; return TestFail; } format.size = config.size; format.fourcc = V4L2PixelFormat::fromPixelFormat(config.pixelFormat, false); if (video->setFormat(&format)) { std::cout << "Failed to set format on output device" << std::endl; return TestFail; } if (video->allocateBuffers(config.bufferCount, &buffers_) < 0) { std::cout << "Failed to allocate buffers" << std::endl; return TestFail; } video->close(); return TestPass; } const std::vector> &BufferSource::buffers() { return buffers_; } /tracepoints/analyze-ipa-trace.py?id=f0a427d4b74612e1583ea300d758bd00fe281d42'>diff
blob: 50fbbf4299705dfc9b0ee774e0a03e1f5b754dee (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
#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2020, Google Inc.
#
# Author: Paul Elder <paul.elder@ideasonboard.com>
#
# analyze-ipa-trace.py - Example of how to extract information from libcamera lttng traces

import argparse
import bt2
import statistics as stats
import sys

# pipeline -> {function -> stack(timestamps)}
timestamps = {}

# pipeline:function -> samples[]
samples = {}

def main(argv):
    parser = argparse.ArgumentParser(
            description='A simple analysis script to get statistics on time taken for IPA calls')
    parser.add_argument('-p', '--pipeline', type=str,
                        help='Name of pipeline to filter for')
    parser.add_argument('trace_path', type=str,
                        help='Path to lttng trace (eg. ~/lttng-traces/demo-20201029-184003)')
    args = parser.parse_args(argv[1:])

    traces = bt2.TraceCollectionMessageIterator(args.trace_path)
    for msg in traces:
        if type(msg) is not bt2._EventMessageConst or \
           'pipeline_name' not in msg.event.payload_field or \
           (args.pipeline is not None and \
            msg.event.payload_field['pipeline_name'] != args.pipeline):
            continue

        pipeline = msg.event.payload_field['pipeline_name']
        event = msg.event.name
        func = msg.event.payload_field['function_name']
        timestamp_ns = msg.default_clock_snapshot.ns_from_origin

        if event == 'libcamera:ipa_call_begin':
            if pipeline not in timestamps:
                timestamps[pipeline] = {}
            if func not in timestamps[pipeline]:
                timestamps[pipeline][func] = []
            timestamps[pipeline][func].append(timestamp_ns)

        if event == 'libcamera:ipa_call_end':
            ts = timestamps[pipeline][func].pop()
            key = f'{pipeline}:{func}'
            if key not in samples:
                samples[key] = []
            samples[key].append(timestamp_ns - ts)

    # Compute stats
    rows = []
    rows.append(['pipeline:function', 'min', 'max', 'mean', 'stddev'])
    for k, v in samples.items():
        mean = int(stats.mean(v))
        stddev = int(stats.stdev(v))
        minv = min(v)
        maxv = max(v)
        rows.append([k, str(minv), str(maxv), str(mean), str(stddev)])

    # Get maximum string width for every column
    widths = []
    for i in range(len(rows[0])):
        widths.append(max([len(row[i]) for row in rows]))