4.9. MultiDecoder

多路解码接口,支持同时解码多路视频。

4.9.1. 构造函数

接口形式:
MultiDecoder(
    int queue_size=10,
    int tpu_id=0,
    int discard_mode=0);

参数说明:

  • queue_size: int

输入参数。每路视频,解码缓存图像队列的长度。

  • tpu_id: int

输入参数。使用的智能视觉深度学习处理器 id,默认为0。

  • discard_mode: int

输入参数。缓存达到最大值之后,数据的丢弃策略。0表示不再放数据进缓存;1表示先从队列中取出队列头的图片,丢弃之后再讲解码出来的图片缓存进去。默认为0。

4.9.2. set_read_timeout

设置读取图片的超时时间,对read和read_接口生效,超时之后仍然没有获取到图像,结果就会返回。

接口形式:
void set_read_timeout(int time_second);

参数说明:

  • timeout: int

输入参数。超时时间,单位是秒。

示例代码:
#include <sail/cvwrapper.h>
#include <sail/decoder_multi.h>

using namespace std;

int main() {
    int queue_size = 16;
    int dev_id = 0;
    int discard_mode = 0;
    sail::MultiDecoder multiDecoder(queue_size, dev_id, discard_mode);
    multiDecoder.set_read_timeout(100);
    return 0;
}

4.9.3. add_channel

添加一个通道。

接口形式1:

通过该接口添加的通道,不会自动停止解码,会自动循环,直到该MultiDecoder析构,或者调用del_channel。

int add_channel(
    const std::string&  file_path,
    int                 frame_skip_num=0);

参数说明1:

  • file_path: string

输入参数。视频的路径或者链接。

  • frame_skip_num: int

输入参数。解码缓存的主动丢帧数,默认是0,不主动丢帧。

返回值说明1

返回视频对应的唯一的通道号。类型为整形。

示例代码1:
#include <sail/cvwrapper.h>
#include <sail/decoder_multi.h>

using namespace std;

int main() {
    int queue_size = 16;
    int dev_id = 0;
    int discard_mode = 0;
    sail::MultiDecoder multiDecoder(queue_size, dev_id, discard_mode);
    vector<int> channel_list;
    for (int i = 0; i < 4; i++) {
        int idx = multiDecoder.add_channel("your_video_path");
        if(idx<0) return -1;
        channel_list.push_back(idx);
    }
    return 0;
}

接口形式2:

该接口添加通道时,支持设置循环次数。仅适用于解码本地视频文件的场景。

int add_channel(
    const std::string&  file_path,
    int                 frame_skip_num
    int                 loopnum);

参数说明2:

  • file_path: string

输入参数。视频的路径或者链接。

  • frame_skip_num: int

输入参数。解码缓存的主动丢帧数。设置为0表示不主动丢帧。

  • loopnum: int

输入参数。解码循环次数。设置为0表示不循环,解码一遍后停止。

返回值说明

返回视频对应的唯一的通道号。类型为整形。

示例代码:
#include <sail/cvwrapper.h>
#include <sail/decoder_multi.h>

using namespace std;

int main() {
    int queue_size = 16;
    int dev_id = 0;
    int discard_mode = 0;
    sail::MultiDecoder multiDecoder(queue_size, dev_id, discard_mode);
    vector<int> channel_list;
    std::string file_path = "your_video_path";
    int frame_skip_num = 0;
    int loopnum = 0;
    for (int i = 0; i < 4; i++) {
        int idx = multiDecoder.add_channel(file_path, frame_skip_num, loopnum);
        if(idx<0) return -1;
        channel_list.push_back(idx);
    }
    return 0;
}

4.9.4. del_channel

删除一个已经添加的视频通道。

接口形式:
int del_channel(int channel_idx);

参数说明:

  • channel_idx: int

输入参数。将要删除视频的通道号。

返回值说明

成功返回0,其他值时表示失败。

示例代码:
#include <sail/cvwrapper.h>
#include <sail/decoder_multi.h>

using namespace std;

int main() {
    int queue_size = 16;
    int dev_id = 0;
    int discard_mode = 0;
    sail::MultiDecoder multiDecoder(queue_size, dev_id, discard_mode);
    vector<int> channel_list;
    for (int i = 0; i < 4; i++) {
        int idx = multiDecoder.add_channel("your_video_path");
        if(idx<0) return -1;
        channel_list.push_back(idx);
    }
    int ret = multiDecoder.del_channel(0);
    if (ret!=0) {
        cout << "Failed!" << endl;
        return -1;
    }
    return 0;
}

4.9.5. clear_queue

清除指定通道的图片缓存。

接口形式:
int clear_queue(int channel_idx);

参数说明:

  • channel_idx: int

输入参数。将要删除视频的通道号。

返回值说明:

成功返回0,其他值时表示失败。

示例代码:
#include <sail/cvwrapper.h>
#include <sail/decoder_multi.h>

using namespace std;

int main() {
    int queue_size = 16;
    int dev_id = 0;
    int discard_mode = 0;
    sail::MultiDecoder multiDecoder(queue_size, dev_id, discard_mode);
    vector<int> channel_list;
    for (int i = 0; i < 4; i++) {
        int idx = multiDecoder.add_channel("your_video_path");
        if(idx<0) return -1;
        channel_list.push_back(idx);
    }
    int ret = multiDecoder.clear_queue(0);
    if (ret!=0) {
        cout << "Failed!" << endl;
        return -1;
    }
    return 0;
}

4.9.6. read

从指定的视频通道中获取一张图片。

接口形式1:
int read(
    int         channel_idx,
    BMImage&    image,
    int         read_mode=0);

参数说明1:

  • channel_idx: int

输入参数。指定的视频通道号。

  • image: BMImage

输出参数。解码出来的图片。

  • read_mode: int

输入参数。获取图片的模式,0表示不等待,直接从缓存中读取一张,无论有没有读取到都会返回。其他的表示等到获取到图片之后或等待时间超时再返回。

返回值说明1:

成功返回0,其他值时表示失败。

示例代码:
#include <sail/cvwrapper.h>
#include <sail/decoder_multi.h>

using namespace std;

int main() {
    int queue_size = 16;
    int dev_id = 0;
    int discard_mode = 0;
    sail::MultiDecoder multiDecoder(queue_size, dev_id, discard_mode);
    vector<int> channel_list;
    for (int i = 0; i < 4; i++) {
        int idx = multiDecoder.add_channel("your_video_path");
        if(idx<0) return -1;
        channel_list.push_back(idx);
    }

    int count = 0;
    while (true) {
        count++;
        for (int idx : channel_list) {
            sail::BMImage bmimg;
            int ret = multiDecoder.read(idx, bmimg, 1);
        }
        if (count == 20) {
            break;
        }
    }
    return 0;
}
接口形式2:
BMImage read(int channel_idx);

参数说明2:

  • channel_idx: int

输入参数。指定的视频通道号。

返回值说明2:

返回解码出来的图片,类型为BMImage。

示例代码:
#include <sail/cvwrapper.h>
#include <sail/decoder_multi.h>

using namespace std;

int main() {
    int queue_size = 16;
    int dev_id = 0;
    int discard_mode = 0;
    sail::MultiDecoder multiDecoder(queue_size, dev_id, discard_mode);
    vector<int> channel_list;
    for (int i = 0; i < 4; i++) {
        int idx = multiDecoder.add_channel("your_video_path");
        if(idx<0) return -1;
        channel_list.push_back(idx);
    }

    int count = 0;
    while (true) {
        count++;
        for (int idx : channel_list) {
            sail::BMImage bmimg = multiDecoder.read(idx);
        }
        if (count == 20) {
            break;
        }
    }
    return 0;
}

4.9.7. read_

从指定的视频通道中获取一张图片,通常是要和BMImageArray一起使用。

接口形式1:
int read_(
    int         channel_idx,
    bm_image&   image,
    int         read_mode=0);

参数说明1:

  • channel_idx: int

输入参数。指定的视频通道号。

  • image: bm_image

输出参数。解码出来的图片。

  • read_mode: int

输入参数。获取图片的模式,0表示不等待,直接从缓存中读取一张,无论有没有读取到都会返回。其他的表示等到获取到图片之后或等待时间超时再返回。

返回值说明1:

成功返回0,其他值时表示失败。

示例代码:
#include <sail/cvwrapper.h>
#include <sail/decoder_multi.h>

using namespace std;

int main() {
    int queue_size = 16;
    int dev_id = 0;
    int discard_mode = 0;
    sail::MultiDecoder multiDecoder(queue_size, dev_id, discard_mode);
    vector<int> channel_list;
    for (int i = 0; i < 4; i++) {
        int idx = multiDecoder.add_channel("your_video_path");
        if(idx<0) return -1;
        channel_list.push_back(idx);
    }

    int count = 0;
    while (true) {
        count++;
        for (int idx : channel_list) {
            sail::BMImage image;
            bm_image bmimg = image.data()
            int ret = multiDecoder.read_(idx,bmimg,1);
        }
        if (count == 20) {
            break;
        }
    }
    return 0;
}
接口形式2:
bm_image read_(int channel_idx);

参数说明2:

  • channel_idx: int

输入参数。指定的视频通道号。

返回值说明2:

返回解码出来的图片,类型为bm_image。

示例代码:
#include <sail/cvwrapper.h>
#include <sail/decoder_multi.h>

using namespace std;

int main() {
    int queue_size = 16;
    int dev_id = 0;
    int discard_mode = 0;
    sail::MultiDecoder multiDecoder(queue_size, dev_id, discard_mode);
    vector<int> channel_list;
    for (int i = 0; i < 4; i++) {
        int idx = multiDecoder.add_channel("your_video_path");
        if(idx<0) return -1;
        channel_list.push_back(idx);
    }
    int count = 0;
    while (true) {
        count++;
        for (int idx : channel_list) {
            bm_image bmimg =  multiDecoder.read_(idx);
        }
        if (count == 20) {
            break;
        }
    }
    return 0;
}

4.9.8. reconnect

重连相应的通道的视频。

接口形式:
int reconnect(int channel_idx);

参数说明:

  • channel_idx: int

输入参数。输入图像的通道号。

返回值说明

成功返回0,其他值时表示失败。

示例代码:
#include <sail/cvwrapper.h>
#include <sail/decoder_multi.h>
using namespace std;

int main() {
    int queue_size = 16;
    int dev_id = 0;
    int discard_mode = 0;
    sail::MultiDecoder multiDecoder(queue_size, dev_id, discard_mode);
    vector<int> channel_list;
    for (int i = 0; i < 4; i++) {
        int idx = multiDecoder.add_channel("your_video_path");
        if(idx<0) return -1;
        channel_list.push_back(idx);
    }
    int ret = multiDecoder.reconnect(0);
    if (ret!=0) {
        cout << "Failed!" << endl;
        return -1;
    }
    return 0;
}

4.9.9. get_frame_shape

获取相应通道的图像shape。

接口形式:
std::vector<int> get_frame_shape(int channel_idx);

参数说明:

输入参数。输入图像的通道号。

返回值说明

返回一个由1,通道数,图像高度,图像宽度组成的list。

示例代码:
#include <sail/cvwrapper.h>
#include <sail/decoder_multi.h>

using namespace std;

int main() {
    int queue_size = 16;
    int dev_id = 0;
    int discard_mode = 0;
    sail::MultiDecoder multiDecoder(queue_size, dev_id, discard_mode);
    vector<int> channel_list;
    for (int i = 0; i < 4; i++) {
        int idx = multiDecoder.add_channel("your_video_path");
        if(idx<0) return -1;
        channel_list.push_back(idx);
        vector<int> shape = multiDecoder.get_frame_shape(idx);
    }
    return 0;
}

4.9.10. set_local_flag

设置视频是否为本地视频。如果不调用则表示为视频为网络视频流。

接口形式:
void set_local_flag(bool flag);

参数说明:

  • flag: bool

标准位,如果为True,每路视频每秒固定解码25帧

示例代码:
#include <sail/cvwrapper.h>
#include <sail/decoder_multi.h>
using namespace std;

int main() {
    int queue_size = 16;
    int dev_id = 0;
    int discard_mode = 0;
    sail::MultiDecoder multiDecoder(queue_size, dev_id, discard_mode);
    multiDecoder.set_local_flag(true);
    return 0;
}

4.9.11. get_channel_fps

Get the video fps of the specified channel

接口形式:
float get_channel_fps(int channel_idx):

参数说明:

  • channel_idx: int

指定需要获取视频帧数的视频通道号

返回值说明

返回指定视频通道的视频帧数

示例代码:
#include <sail/cvwrapper.h>
#include <sail/decoder_multi.h>

using namespace std;

int main() {
    int queue_size = 16;
    int dev_id = 0;
    int discard_mode = 0;
    sail::MultiDecoder  multiDecoder(queue_size, dev_id, discard_mode);
    vector<int> channel_list;
    for (int i = 0; i < 4; i++) {
        int idx = multiDecoder.add_channel("your_video_path");
        if(idx<0) return -1;
        channel_list.push_back(idx);
        float fps = multiDecoder.get_channel_fps(idx);
    }
    return 0;
}

get_drop_num

获取丢帧数。

接口形式:
size_t get_drop_num(int channel_idx);

参数说明:

输入参数。输入图像的通道号。

返回值说明

返回一个数代表丢帧数

示例代码:
#include <sail/cvwrapper.h>
#include <sail/decoder_multi.h>

using namespace std;

int main() {
    int queue_size = 16;
    int dev_id = 0;
    int discard_mode = 0;
    sail::MultiDecoder multiDecoder(queue_size, dev_id, discard_mode);
    vector<int> channel_list;
    for (int i = 0; i < 4; i++) {
        int idx = multiDecoder.add_channel("your_video_path");
        if(idx<0) return -1;
        channel_list.push_back(idx);
        size_t ret = multiDecoder.get_drop_num(idx);
    }
    return 0;
}

4.9.12. reset_drop_num

设置丢帧数为0。

接口形式:
void reset_drop_num(int channel_idx);

参数说明:

输入参数。输入图像的通道号。

示例代码:
#include <sail/cvwrapper.h>
#include <sail/decoder_multi.h>
using namespace std;

int main() {
    int queue_size = 16;
    int dev_id = 0;
    int discard_mode = 0;
    sail::MultiDecoder multiDecoder(queue_size, dev_id, discard_mode);
    vector<int> channel_list;
    for (int i = 0; i < 4; i++) {
        int idx = multiDecoder.add_channel("your_video_path");
        if(idx<0) return -1;
        channel_list.push_back(idx);
        multiDecoder.reset_drop_num(idx);
    }
    return 0;
}

4.9.13. get_channel_status

获取指定通道的解码器状态。

接口形式:
sail::DecoderStatus get_channel_status(int channel_idx) const

参数说明:

  • channel_idx (int): 要查询状态的通道索引。

返回值说明:

返回一个 sail::DecoderStatus 枚举值,表示指定通道的解码器状态。 比如 sail::DecoderStatus::OPENEDsail::DecoderStatus::CLOSED

示例代码:
#include <sail/cvwrapper.h>
#include <sail/decoder_multi.h>

int main() {
    int queue_size = 10;
    int dev_id = 0;
    int discard_mode = 0;
    sail::MultiDecoder multiDecoder(queue_size, dev_id, discard_mode);
    std::vector<int> channel_list;
    std::vector<std::string> file_path_list(4, "your_video_path");

    for (int i = 0; i < 4; ++i) {
        int idx = multiDecoder.add_channel(file_path_list.at(i));
        if (idx < 0) {
            std::cout << "Failed to add channel " << i << ". Error: " << idx << std::endl;
            continue;
        }

        channel_list.push_back(idx);
        sail::DecoderStatus status = multiDecoder.get_channel_status(idx);
        std::cout << "Channel " << i << " status: " << status << std::endl;
    }

    return 0;
}

4.9.14. is_channel_eof

查询某个通道的解码器是否已经到达文件结尾。

接口形式:
bool is_channel_eof(int channel_idx) const

参数说明:

  • channel_idx : 要查询状态的通道索引。

返回值说明:

如果该通道已经到达文件结尾(EOF, end of file),则返回True,否则返回False。 如果不存在索引对应的通道,则抛出异常。

示例代码:
#include <sail/cvwrapper.h>
#include <sail/decoder_multi.h>

int main() {
    std::string filepath{"./jellyfish_200frames.mkv"};
    sail::MultiDecoder md;
    md.set_local_flag(true);
    int frame_skip_num = 0;
    int loopnum = 0;  // no loop
    auto idx = md.add_channel(filepath, frame_skip_num, loopnum);
    if (idx != 0) {
        std::cerr << "add_channel fail, ret: " << idx << std::endl;
        return 1;
    }
    auto cnt = 0;
    while (true) {
        sail::BMImage img;
        int read_mode = 1;  // wait block
        auto ret = md.read(idx, img, read_mode);
        if (ret != 0) {
            std::cout << "===================="
                    << "channel status: "
                    << static_cast<int>(md.get_channel_status(idx))
                    << ", channel eof: " << md.is_channel_eof(idx)
                    << std::endl;
            if (md.get_channel_status(idx) == sail::DecoderStatus::CLOSED &&
                md.is_channel_eof(idx)) {
                std::cout << "channel " << idx << " reached EOF, total read "
                        << cnt << " images, decode thread will stop"
                        << std::endl;
                break;
            } else {
                std::cout << "channel " << idx << " meet an error, total" << cnt
                        << " images, ret = " << ret << std::endl;
            }
        } else {
            cnt += 1;
            std::cout << "channel " << idx << " read " << cnt << " images"
                    << std::endl;
        }
    }
    return 0;
}