视频解码问题
收藏回复举报
视频解码问题
t('forum.solved') 已解决
发表于2026-04-08 16:09:42
0 查看

Screenshot_2026-04-08_15-52-08.jpg

我现在想直接将RTSP/h264 文件解码出 RGB或BGR格式填充对opencv cv::Mat 中, 视频尺寸为1920*1080
得到的图像是如上图:

现在部分代码如下:

一 初始化:

TNVErrorCode TAclVideoDecoder::init(decoder_t *hwd)
{
running=true;
if(acl_init)
{
return No_Error;
}
switch(hwd->image_format_)
{
case  PIXEL_FORMAT_BGR_888:
case PIXEL_FORMAT_RGB_888:
hwd->image_bufsize=RGBU8_IMAGE_SIZE(hwd->width,hwd->height);
break;
case PIXEL_FORMAT_YUV_SEMIPLANAR_420:
case PIXEL_FORMAT_YVU_SEMIPLANAR_420:
hwd->image_bufsize=YUV420SP_SIZE(hwd->width,hwd->height);//t*1.5;
break;
case PIXEL_FORMAT_ARGB_8888:
case PIXEL_FORMAT_ABGR_8888:
case PIXEL_FORMAT_RGBA_8888:
case PIXEL_FORMAT_BGRA_8888:
hwd->image_bufsize=hwd->width*hwd->height*4;
break;
default:
hwd->image_bufsize=hwd->width*hwd->height;
break;
}
hwd->alignWidth= ALIGN_UP16(hwd->width);
hwd->alignHeight= ALIGN_UP2(hwd->height);
/* 1.ACL initialization */
//const char *aclConfigPath = nullptr;
aclError ret =aclInit(nullptr);
// int channelId = 10;
if(ACL_SUCCESS!=aclrtSetDevice(hwd->deviceId))
{
return ERROR_SET_DEVICE;
}
/* 2.Run the management resource application, including Device, Context, Stream */
if(ACL_SUCCESS!=aclrtCreateContext(&context_, hwd->deviceId))
{
return ERROR_CREATE_CONTEXT;
}
if(ACL_SUCCESS!=aclrtCreateStream(&stream_))
{
return ERROR_SET_DEVICE;
}
if(ACL_SUCCESS!=aclrtGetRunMode(&runMode_))
{
return ERROR_GET_MODE;
}
/* 3.Vdec init */
// create threadId
threadId_=create_pthread_attr((void*)ThreadContext, this);
//    int createThreadErr=pthread_create(&threadId_, nullptr, ThreadFunc, this);
if (threadId_ == 0)
{
//ERROR_LOG("create thread failed, err = %d", createThreadErr);
return ERROR_CREATE_THREAD;
}
/* 4.Set the properties of the channel description information when creating the video code stream
processing channel, in which the callback callback function needs to be created in advance by the
user. */
//vdecChannelDesc_ is aclvdecChannelDesc
vdecChannelDesc_ = aclvdecCreateChannelDesc();
if(vdecChannelDesc_==nullptr)
{
return ERROR_CREATE_DESC;
}
ret |= aclvdecSetChannelDescChannelId(vdecChannelDesc_, hwd->channelId);
ret |= aclvdecSetChannelDescThreadId(vdecChannelDesc_, threadId_);
/* Sets the callback function */
ret |= aclvdecSetChannelDescCallback(vdecChannelDesc_, callback);
// The H265_MAIN_LEVEL video encoding protocol is used in the example
ret |= aclvdecSetChannelDescEnType(vdecChannelDesc_, static_cast<acldvppStreamFormat>(hwd->video_format_));
// PIXEL_FORMAT_YVU_SEMIPLANAR_420
ret |= aclvdecSetChannelDescOutPicFormat(vdecChannelDesc_,PIXEL_FORMAT_YUV_SEMIPLANAR_420);// static_cast<acldvppPixelFormat>(format_));
if(ret!=ACL_SUCCESS)
{
//return ERROR_SET_PARAM;
}
/* 5.Create video stream processing channel */
if(ACL_SUCCESS!=aclvdecCreateChannel(vdecChannelDesc_))
{
return ERROR_CREATE_CHANNEL;
}

二 .解码部分:

TNVErrorCode TAclVideoDecoder::CreatePicDesc(decoder_t *hwd)
{
picOutputDesc_ = acldvppCreatePicDesc();
if(picOutputDesc_==nullptr)
{
return ERROR_CREATE_PICTRUE;
}
if(ACL_SUCCESS!=acldvppMalloc(&picOutBufferDev_, hwd->image_bufsize))
{
return ERROR_ACL_MALLOC;
}
if(ACL_SUCCESS!=acldvppSetPicDescData(picOutputDesc_, picOutBufferDev_))
{
return ERROR_SET_PARAM;
}
if(ACL_SUCCESS!=acldvppSetPicDescSize(picOutputDesc_, hwd->image_bufsize))
{
return ERROR_SET_PARAM;
}
//例子是设置为PIXEL_FORMAT_YUV_SEMIPLANAR_420,我现在改为:PIXEL_FORMAT_BGR_888
if(ACL_SUCCESS!=acldvppSetPicDescFormat(picOutputDesc_, static_cast<acldvppPixelFormat>(hwd->image_format_)))
{
return ERROR_SET_PARAM;
}
if(ACL_SUCCESS!=acldvppSetPicDescWidth(picOutputDesc_, hwd->width))
{
return ERROR_SET_PARAM;
}
if(ACL_SUCCESS!=acldvppSetPicDescHeight(picOutputDesc_, hwd->height))
{
return ERROR_SET_PARAM;
}
if(ACL_SUCCESS!=acldvppSetPicDescWidthStride(picOutputDesc_, hwd->alignWidth))
{
return ERROR_SET_PARAM;
}
if(ACL_SUCCESS!=acldvppSetPicDescHeightStride(picOutputDesc_, hwd->alignHeight))
{
return ERROR_SET_PARAM;
}
return No_Error;
}
三 显示:
void RECV_Video_YUV_Buffer(void *input, uint32_t size, aclrtRunMode mode,void *userData)
{
cv::Mat image=cv::Mat(cv::Size(1920,1080),CV_8UC3);
if(ACL_SUCCESS==aclrtMemcpy(image.data, size, input, size, ACL_MEMCPY_DEVICE_TO_DEVICE))
{
cv::imshow("video",image);
cv::waitKey(1);
}
}
这做法不知道哪里有问题或是否不能这样处理.

谢谢!

我要发帖子