Stream管理

原理介绍

在LXHPL中,Stream是一个异步任务队列,用户应用通过Stream来管理任务的并行,单个Stream内部的异步任务保序执行,即Stream根据用户推送的异步任务一次执行;不同Stream中的异步任务可以并行。用户在应用中,如果需要调用LXHPL提供的异步接口,那么必须在特定Context下显式创建Stream,然后在对应的Stream中进行异步任务下发。

单线程单Stream

用户可以从LynSDK提供的示例代码中查看完整样例,在示例代码中,调用各接口后都添加了异常判断和处理,以下是关键步骤代码示例,仅供参考,不可以直接拷贝编译。

lynModel_t model = LYN_FAKE_MODEL_HANDLE;
int32_t devID = 0;
lynContext_t context = nullptr;
lynStream_t stream = nullptr;

lynModelDesc_t *modelDesc = nullptr;
uint8_t* hostIn = nullptr;
void * devinptr = nullptr;
uint8_t *hostOut= nullptr;
void * devoutptr = nullptr;

//创建Context和Stream
lynCreateContext(&context, devID);
lynCreateStream(&stream);

//加载模型
lynLoadModel(modelPath,&model);
lynModelGetDesc(model,&modelDesc));

//执行异步推理
lynExecuteModelAsync(stream, model, devinptr, devoutptr, modelDesc->inputTensorAttrArray[0].batchSize));

//同步等待Stream计算任务结束
lynSynchronizeStream(stream);

//销毁资源
lynDestroyStream(stream);
lynDestroyContext(context);

单线程多Stream

单线程多Stream场景多用于多路并行下发异步任务的场景,例如多路视频解码等。此外,上文中 视频解码视频编码 中提及的视频解码和视频编码部分,由于硬件平台工作原理的限制,也需要为发送和接收分别创建Stream。用户可以从LynSDK提供的示例代码中查看完整样例,在示例代码中,调用各接口后都添加了异常判断和处理,以下是关键步骤代码示例,仅供参考,不可以直接拷贝编译。

lynError_t ret = 0;
lynContext_t context = nullptr;

//创建Context
ret = lynCreateContext(&context, 0);

//初始化解封装
lynDemuxHandle_t demuxHdl;
ret = lynDemuxOpen(&demuxHdl, url, nullptr);

//获取解码相关参数
lynCodecPara_t codecPara;
ret = lynDemuxGetCodecPara(demuxHdl, &codecPara);

//初始化解码器
lynVdecAttr_t attr;
attr.codecId = codecPara.codecId;
lynVdecHandle_t vdecHdl;
ret = lynVdecOpen(&vdecHdl, &attr);

//创建发送Stream和接收Stream
lynStream_t sendStream = nullptr;
ret = lynCreateStream(&sendStream);

lynStream_t recvStream = nullptr;
ret = lynCreateStream(&recvStream);

// 在发送Stream里发送待解码数据
lynVdecSendPacketAsync(sendStream, vdecHdl, &pkt);

// 同步等待(可选)
lynSynchronizeStream(sendStream);
lynDemuxFreePacket(&pkt);

//在接收Stream里接收解码后的图像
lynFrame_t frame = {0};
frame.data = (uint8_t *)recvBufManager.GetNewBuf();
frame.size = g_bufSize;
lynVdecRecvFrameAsync(recvStream, g_vdecHdl, &frame);

// 同步等待(可选)
lynSynchronizeStream(recvStream);

//销毁资源
lynDestroyStream(sendStream);
lynDestroyStream(recvStream);
lynDestroyContext(context);

多线程多Stream

用户可以从LynSDK提供的示例代码中查看完整样例,在示例代码中,调用各接口后都添加了异常判断和处理,以下是关键步骤代码示例,仅供参考,不可以直接拷贝编译。

void threadFunc(lynStream_t stream) {
    int32_t deviceId = 0;
    lynContext_t context;

    //如果只创建了一个Context,线程默认将这个Context作为线程当前的Context;
    //如果是多个Context,则以最后一次创建的Context为当前线程Context
    lynCreateContext(&context, deviceId);
    lynCreateStream(&stream);

    //下发异步任务
    //.....

    //释放资源
    lynDestroyStream(stream);
    lynDestroyContext(context);
}

lynStream_t stream1;
lynStream_t stream2;

//创建2个线程,每个线程对应一个Stream
std::thread t1(threadFunc, stream1);
std::thread t2(threadFunc, stream2);

t1.join();
t2.join();