Trouble with openCV getting a stream using a Hikvision camera

I’m using a Hikvision camera with openCV with the purpose of getting a streaming of the camera in a window on my pc. I started using a SDK from HIKVISION (here is the link: https://www.hikvision.com/es/support/download/sdk/device-network-sdk--for-linux-64-bit-/) for getting some examples and start practicing. I used the psdatacall_demo because it was the most similar demo to my objective. This file records a video and saves it in a .dat format.

Below I paste the SDK function where the script saves the buffer in the .dat file. My goal is to change this approach to a real-time display window of the camera video using the OpenCV library.

void PsDataCallBack(LONG lRealHandle, DWORD dwDataType,BYTE *pPacketBuffer,DWORD nPacketSize, void* pUser)
{
	
	if (dwDataType  == NET_DVR_SYSHEAD)
	{	
		g_pFile = fopen("../record/ps.dat", "wb");
		
		if (g_pFile == NULL)
		{
			printf("CreateFileHead fail\n");
			return;
		}

		fwrite(pPacketBuffer, sizeof(unsigned char), nPacketSize, g_pFile);
		printf("write head len=%d\n", nPacketSize);
	}
	else
	{
		if(g_pFile != NULL)
		{
			fwrite(pPacketBuffer, sizeof(unsigned char), nPacketSize, g_pFile);
			printf("write data len=%d\n", nPacketSize);
			//cv::Mat frame = cv::imdecode(cv::Mat(240, 320, CV_8UC1, pPacketBuffer), 1);
			//cv::imshow("Streaming", frame);
		}
	}	

}

I think that this function is the part of the code that should be changed. I have tried to develop this functionality adding the commented lines above, however it gives me this error:

terminate called after throwing an instance of 'cv::Exception'
  what():  OpenCV(4.7.0-dev) /path of the src/loadsave.cpp:800: error: (-215:Assertion failed) buf.checkVector(1, CV_8U) > 0 in function 'imdecode_'

Aborted (core dumped)

Could anyone tell me how can I solve this?

the input to imdecode() is a one dimensional vector, not a 2d image, like:

Mat(1, nPacketSize, CV_8UC1, pPacketBuffer)

I fixed it and then i got the next error:

Error: (-215)size.width>0 && size.height>0 in function imshow

I found that the matrix frame is empty after the imdecode. How can I fix it? I read in some forums that it usually happens because of the video format but I don’t know which format I need and how to change it.

What format is your source stream in? Is it MJPEG or RTSP?

I am pretty sure all hick cameras support RTSP so I would think it would be easier to just open the stream using the RTSP_URL as

VideoCapture cap(RTSP_URL);
Mat frame; cap.read(frame);

Note:

  1. The RTSP_URL url starts rtsp:// see the hickvision docs for info.
  2. Check that you can open the RTSP_URL in VLC media player without filling in the username and password pop up box before attempting to open it with VideoCapture.

That worked to me thank you!!! Here is the code if someone needs it in the future:

#include <stdio.h>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>

int main(){
    cv::VideoCapture cap;
    cap.open("rtsp://<admin>:<password>@<IP>:<RTSP port>/Streaming/channels/101");
    if(!cap.isOpened()){
        printf("Error opening video stream\n");
        return -1;
    }else{
        cv::namedWindow("video", cv::WINDOW_NORMAL);
        while(true){

            cv::Mat frame;
            cap >> frame;

            if(frame.empty()){

                break;

            }else{

                imshow("Video", frame);

                if (cv::waitKey(1)==27){

                    break;

                }
            }
        }
    }
}