Чтение потока h264 или h265 с помощью ffmpeg / OpenCV: что быстрее?

#c #opencv #ffmpeg #h.264

#c #opencv #ffmpeg #ч.264

Вопрос:

Я использую OpenCV с поддержкой ffmpeg для чтения потока RTSP, поступающего с IP-камеры, а затем для записи кадров в видео. Проблема в том, что размер кадра составляет 2816×2816 при 20 кадрах в секунду, т.Е. Поступает много данных.

Я заметил, что в потоке была значительная задержка, поэтому я установил размер буфера cv::VideoCapture объекта равным 1, потому что я думал, что кадры могут просто застрять в буфере вместо захвата и обработки. Однако это просто привело к удалению кадров.

Моим следующим шагом было немного поэкспериментировать с размером кадра / fps и кодировкой видео, которое я пишу. Все эти вещи помогли улучшить ситуацию, но в долгосрочной перспективе мне все равно придется использовать размер кадра 2816×2816 и поддерживать до 20 кадров в секунду, поэтому я не могу установить его ниже, к сожалению.

Вот где возникает мой вопрос: учитывая тот факт, что поток камеры будет либо h264, либо h265, какой из них будет считываться cv::VideoCapture объектом быстрее? И как я должен кодировать видео, которое я пишу, чтобы минимизировать время, затрачиваемое на декодирование / кодирование кадров?

Это код, который я использую для справки:

 using namespace cv;
int main(int argc, char** argv)
{
    VideoCapture cap;
    cap.set(CAP_PROP_BUFFERSIZE, 1); // internal buffer will now store only 1 frames

    if (!cap.open("rtsp://admin:admin@1.1.1.1:554/stream")) {
        return -1;
    }
    VideoWriter videoWr;
    Mat frame;
    cap >> frame;
    //int x264 = cv::VideoWriter::fourcc('x', '2', '6', '4'); //I was trying different options
    int x264 = cv::VideoWriter::fourcc('M', 'J', 'P', 'G');
    videoWr = cv::VideoWriter("test_video.avi", 0, 0, 20, frame.size(), true);

    namedWindow("test", WINDOW_NORMAL);
    cv::resizeWindow("test", 1024, 768);
    
    for (;;)
    {
        cap >> frame;
        if (frame.empty()) break; // end of video stream
        
        imshow("test", frame);
        if (waitKey(10) == 27) break; 
        videoWr << frame;
        
    }

    return 0;
}
 

Комментарии:

1. Что-нибудь мешает вам самостоятельно запускать некоторые тесты на вашем собственном оборудовании и программном обеспечении?

2. Если я сталкиваюсь с проблемами с задержкой, я использую cv2.VideoCapture объект с серверной частью gstreamer.

3. @SamVarshavchik Мне ничто не мешает, у меня просто нет большого опыта, когда дело доходит до кодирования / декодирования, поэтому мне было интересно, есть ли какая-то теория, которую я упускаю. Кстати, какой тест вы бы предложили?

4. @mibrahimy Значит, серверная часть gstreamer должна работать быстрее, чем ffmpeg? Я также рассматривал этот вариант ранее, но я не был уверен, будет ли это иметь какое-либо значение.

5. С серверной частью gstreamer задержка должна быть практически нулевой.