打印私钥,主要使用这个函数:
mbedtls_mpi_write_file

int mbedtls_mpi_write_file( const char p, const mbedtls_mpi X, int radix, FILE *fout );

当fout为NULL,就输出到标准输出了。

When reading from files with mbedtls_mpi_read_file() and writing to files with
mbedtls_mpi_write_file() the buffer should have space
for a (short) label, the MPI (in the provided radix), the newline
characters and the '0'.

int main( int argc, char *argv[] )
{
    int ret = 1;
    int exit_code = MBEDTLS_EXIT_FAILURE;
    mbedtls_ecdsa_context ctx_sign, ctx_verify;
    mbedtls_entropy_context entropy;
    mbedtls_ctr_drbg_context ctr_drbg;
    unsigned char message[100];
    unsigned char hash[32];
    unsigned char sig[MBEDTLS_ECDSA_MAX_LEN];
    size_t sig_len;
    const char *pers = "ecdsa";
    ((void) argv);

    mbedtls_ecdsa_init( &ctx_sign );
    mbedtls_ecdsa_init( &ctx_verify );
    mbedtls_ctr_drbg_init( &ctr_drbg );

    memset( sig, 0, sizeof( sig ) );
    memset( message, 0x25, sizeof( message ) );

    if( argc != 1 )
    {
        mbedtls_printf( "usage: ecdsa\n" );

#if defined(_WIN32)
        mbedtls_printf( "\n" );
#endif

        goto exit;
    }

    /*
     * Generate a key pair for signing
     */
    mbedtls_printf( "\n  . Seeding the random number generator..." );
    fflush( stdout );

    mbedtls_entropy_init( &entropy );
    if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
                               (const unsigned char *) pers,
                               strlen( pers ) ) ) != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned %d\n", ret );
        goto exit;
    }

    mbedtls_printf( " ok\n  . Generating key pair..." );
    fflush( stdout );

    if( ( ret = mbedtls_ecdsa_genkey( &ctx_sign, ECPARAMS,
                              mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_ecdsa_genkey returned %d\n", ret );
        goto exit;
    }

    mbedtls_printf( " ok (key size: %d bits)\n", (int) ctx_sign.MBEDTLS_PRIVATE(grp).pbits );

    dump_pubkey( "  + Public key: ", &ctx_sign );
    mbedtls_mpi_write_file( "D   : ", &ctx_sign.MBEDTLS_PRIVATE(d)  , 16, NULL );
exit:

#if defined(_WIN32)
    mbedtls_printf( "  + Press Enter to exit this program.\n" );
    fflush( stdout ); getchar();
#endif

    mbedtls_ecdsa_free( &ctx_verify );
    mbedtls_ecdsa_free( &ctx_sign );
    mbedtls_ctr_drbg_free( &ctr_drbg );
    mbedtls_entropy_free( &entropy );

    mbedtls_exit( exit_code );
}

视频编解码分为硬件加速以及非硬件加速。硬件加速是指通过显卡,FPGA等硬件进行视频编解码,由于硬件有专门优化,所以性能高,能耗低,非硬件加速编解码是指通过CPU进行视频编解码,性能就没那么高(虽然有相关CPU指令优化),由于视频编解码计算量很大,所以能耗也很高。在PC平台上主流的硬件加速编解码有Intel集成显卡,Nvidia显卡。

Quick Sync Video
Intel Quick Sync Video(QSV)是Intel GPU上跟视频处理有关的一系列硬件特性的称呼。

英特尔® Quick Sync Video 技术可以快速转换便携式多媒体播放器的视频,还能提供在线共享、视频编辑及视频制作功能。

看到CPU带的集成显卡支持Quick Sync Video就表示支持硬件加速的视频编解码。

比如查看Intel J1900是否支持QSV.如下
https://ark.intel.com/content/www/cn/zh/ark/products/78867/intel-celeron-processor-j1900-2m-cache-up-to-2-42-ghz.html

在不同平台上可通过不同API使用Intel GPU的硬件加速能力。目前主要由两套API:VAAPI以及libmfx。

VAAPI (视频加速API,Video Acceleration API)包含一套开源的库(LibVA) 以及API规范, 用于硬件加速下的视频编解码以及处理,只有Linux上的驱动提供支持。
libmfx。Intel Media SDK中的API规范,支持视频编解码以及媒体处理。支持Windows以及Linux。

所以,回到标题所在的问题,就知道了vaapi应该只是qsv的一种包含关系。

VAAPI驱动
VAAPI驱动属于用户态驱动,用于支持LibVA,底层是i965/1915驱动。Intel提供了两种开源的VAAPI驱动:intel-vaapi-driver以及intel-media-driver,intel-media-driver较intel-vaapi-driver新,维护更积极,所以目前更推荐使用intel-media-driver。

FFmpeg VAAPI/QSV开发环境搭建
对于VAAPI以及Intel Media SDK,如果使用原生API开发的话比较麻烦,好在FFmpeg提供了对应的插件。我们可以通过FFmpeg间接使用这两套API。在FFmpeg中VAAPI还是叫做VAAPI,但是Intel Media SDK却叫做QSV(一脸懵逼)。

FFmpeg-vaapi插件:基于VAAPI接口
FFmpeg-qsv插件:基于Intel Media SDK

FFmpeg VAAPI/QSV开发环境搭建我就不做搬运工了,大家可参考官网教程。

Linux FFmpeg VAAPI/QSV Installation Environment:https://01.org/linuxmedia/quickstart/ffmpeg-vaapi-qsv-installation-environment

查看支持的编解码功能
apt install vainfo

vainfo
libva info: VA-API version 1.7.0
libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/iHD_drv_video.so
libva info: Found init function __vaDriverInit_1_7
libva info: va_openDriver() returns 0
vainfo: VA-API version: 1.7 (libva 2.6.0)
vainfo: Driver version: Intel iHD driver for Intel(R) Gen Graphics - 20.1.1 ()
vainfo: Supported profile and entrypoints

  VAProfileMPEG2Simple            :    VAEntrypointVLD
  VAProfileMPEG2Main              :    VAEntrypointVLD
  VAProfileH264Main               :    VAEntrypointVLD
  VAProfileH264Main               :    VAEntrypointEncSliceLP
  VAProfileH264High               :    VAEntrypointVLD
  VAProfileH264High               :    VAEntrypointEncSliceLP
  VAProfileJPEGBaseline           :    VAEntrypointVLD
  VAProfileJPEGBaseline           :    VAEntrypointEncPicture
  VAProfileH264ConstrainedBaseline:    VAEntrypointVLD
  VAProfileH264ConstrainedBaseline:    VAEntrypointEncSliceLP
  VAProfileVP8Version0_3          :    VAEntrypointVLD
  VAProfileHEVCMain               :    VAEntrypointVLD
  VAProfileHEVCMain10             :    VAEntrypointVLD
  VAProfileVP9Profile0            :    VAEntrypointVLD
  VAProfileVP9Profile2            :    VAEntrypointVLD

VAEntrypointVLD 指的是显卡能够解码这个格式,VAEntrypointEncSlice 指的是显卡可以编码这个格式。

form:https://blog.jianchihu.net/intel-gpu-hw-video-codec-develop.html

1. 查看现有的cmake版本

cmake --version
  1. 卸载现有版本的cmake,也有人建议不用删除,之后更新软链接即可。

    sudo apt remove cmake

  2. 下载目标版本的CMake,官网链接 https://cmake.org/download/,找到目标版本的 “.sh” 文件。下载后拷贝到/opt/文件夹下。

    wget https://github.com/Kitware/CMake/releases/download/v3.21.3/cmake-3.21.3-linux-x86_64.sh
    cp cmake-3.21.3-linux-x86_64.sh /opt/

  3. 修改 “.sh” 文件权限。

    chmod +x /opt/cmake-3.21.3-linux-x86_64.sh

  4. 安装cmake。

    sudo bash /opt/cmake-3.21.3-linux-x86_64.sh

过程中需要多次点击回车,然后输入两次Y。

  1. 将cmake文件软连接到bin。

    sudo ln -s /opt/cmake-3.21.3-linux-x86_64/bin/* /usr/local/bin

我的情况是软连接到 /usr/bin 才能找到cmake指令。

sudo ln -s /opt/cmake-3.21.3-linux-x86_64/bin/* /usr/bin
  1. 安装成功后,输入以下指令查看cmake版本。

    cmake --version

Referenced from:https://blog.csdn.net/iLOVEJohnny/article/details/103681032

编译的解决方法:

sudo apt remove cmake 
sudo apt-get install build-essential libssl-dev
wget https://github.com/Kitware/CMake/releases/download/v3.20.0/cmake-3.20.0.tar.gz

tar -zxvf cmake-3.20.0.tar.gz
cd cmake-3.20.0
./bootstrap
make
sudo make install
cmake --version 

编译OpenCV 4.5.3出现这个错误
In file included from /opt/opencv-4.5.3/modules/videoio/src/cap_ffmpeg.cpp:50:0:
/opt/opencv-4.5.3/modules/videoio/src/cap_ffmpeg_impl.hpp:535:5: error: ‘AVBSFContext’ does not name a type

 AVBSFContext* bsfc;
 ^

/opt/opencv-4.5.3/modules/videoio/src/cap_ffmpeg_impl.hpp: In member function ‘void CvCapture_FFMPEG::init()’:
/opt/opencv-4.5.3/modules/videoio/src/cap_ffmpeg_impl.hpp:576:5: error: ‘bsfc’ was not declared in this scope

 bsfc = NULL;

add support for HW accelerated decode/encode in FFMPEG backend of VideoCapture and VideoWriter APIs under #ifdef check for FFMPEG version >= 4.0
introduce new properties CAP_PROP_HW_ACCELERATION, CAP_PROP_HW_DEVICE, VIDEOWRITER_PROP_HW_ACCELERATION, VIDEOWRITER_PROP_HW_DEVICE and enum VideoAccelerationType.
new properties supported in three HW-capable backends: ffmpeg, gstreamer, msmf
setting new properties supported only via params parameter in VideoCapture/VideoWriter constructor or open() function, not supported in setProperty() call after open() call
by default (if property not set) HW acceleration enabled in HW-capable backends for both VideoCapture and VideoWriter
if HW accelerated decoder/encoder not found or failed to initilize, VideoCapture/VideoWriter gracefully falls back to SW decoder/encoder. Video acceleration status (HW or SW codec) could be queried via getProperty(CAP_PROP_HW_ACCELERATION) / getProperty(VIDEOWRITER_PROP_HW_ACCELERATION)
new sample video_acceleration
test iterating three backends and acceleration types
HW acceleration types support matrix, in priority order:

OS Backend VideoCapture VideoWriter
Linux FFMPEG VAAPI, MFX MFX, VAAPI

 GStreamer    VAAPI (and others HW plugins)    VAAPI (and others HW plugins)

Windows FFMPEG D3D11, MFX MFX

 MSMF    D3D11

示例代码:
video_acceleration
samples/tapi/video_acceleration.cpp

#include <iostream>
#include <chrono>
#include "opencv2/core.hpp"
#include "opencv2/core/ocl.hpp"
#include "opencv2/core/utility.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/videoio.hpp"
#include "opencv2/highgui.hpp"

using namespace cv;
using namespace std;

const char* keys =
"{ i input    |        | input video file }"
"{ o output   |        | output video file, or specify 'null' to measure decoding without rendering to screen}"
"{ backend    | any    | VideoCapture and VideoWriter backend, valid values: 'any', 'ffmpeg', 'msmf', 'gstreamer' }"
"{ accel      | any    | GPU Video Acceleration, valid values: 'none', 'any', 'd3d11', 'vaapi', 'mfx' }"
"{ device     | -1     | Video Acceleration device (GPU) index (-1 means default device) }"
"{ out_w      |        | output width (resize by calling cv::resize) }"
"{ out_h      |        | output height (resize by calling cv::resize) }"
"{ bitwise_not| false  | apply simple image processing - bitwise_not pixels by calling cv::bitwise_not }"
"{ opencl     | true   | use OpenCL (inside VideoCapture/VideoWriter and for image processing) }"
"{ codec      | H264   | codec id (four characters string) of output file encoder }"
"{ h help     |        | print help message }";

struct {
    cv::VideoCaptureAPIs backend;
    const char* str;
} backend_strings[] = {
    { cv::CAP_ANY, "any" },
    { cv::CAP_FFMPEG, "ffmpeg" },
    { cv::CAP_MSMF, "msmf" },
    { cv::CAP_GSTREAMER, "gstreamer" },
};

struct {
    VideoAccelerationType acceleration;
    const char* str;
} acceleration_strings[] = {
    { VIDEO_ACCELERATION_NONE, "none" },
    { VIDEO_ACCELERATION_ANY, "any" },
    { VIDEO_ACCELERATION_D3D11, "d3d11" },
    { VIDEO_ACCELERATION_VAAPI, "vaapi" },
    { VIDEO_ACCELERATION_MFX, "mfx" },
};

class FPSCounter {
public:
    FPSCounter(double _interval) : interval(_interval) {
    }

    ~FPSCounter() {
        NewFrame(true);
    }

    void NewFrame(bool last_frame = false) {
        num_frames++;
        auto now = std::chrono::high_resolution_clock::now();
        if (!last_time.time_since_epoch().count()) {
            last_time = now;
        }

        double sec = std::chrono::duration_cast<std::chrono::duration<double>>(now - last_time).count();
        if (sec >= interval || last_frame) {
            printf("FPS(last %.2f sec) = %.2f\n", sec, num_frames / sec);
            fflush(stdout);
            num_frames = 0;
            last_time = now;
        }
    }

private:
    double interval = 1;
    std::chrono::time_point<std::chrono::high_resolution_clock> last_time;
    int num_frames = 0;
};

int main(int argc, char** argv)
{
    cv::CommandLineParser cmd(argc, argv, keys);
    if (cmd.has("help"))
    {
        cout << "Usage : video_acceleration [options]" << endl;
        cout << "Available options:" << endl;
        cmd.printMessage();
        return EXIT_SUCCESS;
    }

    string infile = cmd.get<string>("i");
    string outfile = cmd.get<string>("o");
    string codec = cmd.get<string>("codec");
    int device = cmd.get<int>("device");
    int out_w = cmd.get<int>("out_w");
    int out_h = cmd.get<int>("out_h");
    bool use_opencl = cmd.get<bool>("opencl");
    bool bitwise_not = cmd.get<bool>("bitwise_not");

    cv::VideoCaptureAPIs backend = cv::CAP_ANY;
    string backend_str = cmd.get<string>("backend");
    for (size_t i = 0; i < sizeof(backend_strings)/sizeof(backend_strings[0]); i++) {
        if (backend_str == backend_strings[i].str) {
            backend = backend_strings[i].backend;
            break;
        }
    }

    VideoAccelerationType accel = VIDEO_ACCELERATION_ANY;
    string accel_str = cmd.get<string>("accel");
    for (size_t i = 0; i < sizeof(acceleration_strings) / sizeof(acceleration_strings[0]); i++) {
        if (accel_str == acceleration_strings[i].str) {
            accel = acceleration_strings[i].acceleration;
            break;
        }
    }

    ocl::setUseOpenCL(use_opencl);

    VideoCapture capture(infile, backend, {
            CAP_PROP_HW_ACCELERATION, (int)accel,
            CAP_PROP_HW_DEVICE, device
    });
    if (!capture.isOpened()) {
        cerr << "Failed to open VideoCapture" << endl;
        return 1;
    }
    cout << "VideoCapture backend = " << capture.getBackendName() << endl;
    VideoAccelerationType actual_accel = static_cast<VideoAccelerationType>(static_cast<int>(capture.get(CAP_PROP_HW_ACCELERATION)));
    for (size_t i = 0; i < sizeof(acceleration_strings) / sizeof(acceleration_strings[0]); i++) {
        if (actual_accel == acceleration_strings[i].acceleration) {
            cout << "VideoCapture acceleration = " << acceleration_strings[i].str << endl;
            cout << "VideoCapture acceleration device = " << (int)capture.get(CAP_PROP_HW_DEVICE) << endl;
            break;
        }
    }

    VideoWriter writer;
    if (!outfile.empty() && outfile != "null") {
        const char* codec_str = codec.c_str();
        int fourcc = VideoWriter::fourcc(codec_str[0], codec_str[1], codec_str[2], codec_str[3]);
        double fps = capture.get(CAP_PROP_FPS);
        Size frameSize = { out_w, out_h };
        if (!out_w || !out_h) {
            frameSize = { (int)capture.get(CAP_PROP_FRAME_WIDTH), (int)capture.get(CAP_PROP_FRAME_HEIGHT) };
        }
        writer = VideoWriter(outfile, backend, fourcc, fps, frameSize, {
                VIDEOWRITER_PROP_HW_ACCELERATION, (int)accel,
                VIDEOWRITER_PROP_HW_DEVICE, device
        });
        if (!writer.isOpened()) {
            cerr << "Failed to open VideoWriter" << endl;
            return 1;
        }
        cout << "VideoWriter backend = " << writer.getBackendName() << endl;
        actual_accel = static_cast<VideoAccelerationType>(static_cast<int>(writer.get(VIDEOWRITER_PROP_HW_ACCELERATION)));
        for (size_t i = 0; i < sizeof(acceleration_strings) / sizeof(acceleration_strings[0]); i++) {
            if (actual_accel == acceleration_strings[i].acceleration) {
                cout << "VideoWriter acceleration = " << acceleration_strings[i].str << endl;
                cout << "VideoWriter acceleration device = " << (int)writer.get(VIDEOWRITER_PROP_HW_DEVICE) << endl;
                break;
            }
        }
    }

    cout << "\nStarting frame loop. Press ESC to exit\n";

    FPSCounter fps_counter(0.5); // print FPS every 0.5 seconds

    UMat frame, frame2, frame3;

    for (;;)
    {
        capture.read(frame);
        if (frame.empty()) {
            cout << "End of stream" << endl;
            break;
        }

        if (out_w && out_h) {
            cv::resize(frame, frame2, cv::Size(out_w, out_h));
            //cv::cvtColor(frame, outframe, COLOR_BGRA2RGBA);
        }
        else {
            frame2 = frame;
        }

        if (bitwise_not) {
            cv::bitwise_not(frame2, frame3);
        }
        else {
            frame3 = frame2;
        }

        if (writer.isOpened()) {
            writer.write(frame3);
        }

        if (outfile.empty()) {
            imshow("output", frame3);
            char key = (char) waitKey(1);
            if (key == 27)
                break;
            else if (key == 'm') {
                ocl::setUseOpenCL(!cv::ocl::useOpenCL());
                cout << "Switched to " << (ocl::useOpenCL() ? "OpenCL enabled" : "CPU") << " mode\n";
            }
        }
        fps_counter.NewFrame();
    }

    return EXIT_SUCCESS;
}