Форум программистов, компьютерный форум, киберфорум
C++: OpenCV
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.64/25: Рейтинг темы: голосов - 25, средняя оценка - 4.64
0 / 0 / 0
Регистрация: 26.07.2022
Сообщений: 13
1

ffmpeg работа в несколькими rtsp потоками в одной программе

02.04.2024, 09:25. Показов 4724. Ответов 2

Author24 — интернет-сервис помощи студентам
Добрый день.

Есть простая программа (C++) работы с видео (rtsp поток с нескольких камер).

Я запускаю несколько одинаковых нитей (thread) для работы с разными камерами.
Мьютексами ограничиваю доступ к функциям библиотеки - получения и анализа кадра.

Есть ли возможность внутри библиотеки ffmpeg организовать многопоточную работу с несколькими потоками rtsp видео?

Сбросьте пример пожалуйста (или какие функции посмотреть), направьте в нужную сторону.

Спасибо.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
02.04.2024, 09:25
Ответы с готовыми решениями:

Использование несколькими потоками одной функции
Есть вот такая функция для =которую выполняют рабочие потоки DWORD WINAPI ThreadFunc(void *pV)...

Работа с несколькими потоками
у меня вопрос, к тем кто работает с многопоточными приложениями у меня алгоритм такой: в основном...

Работа с несколькими потоками при обращении к разным textbox
Доброго времени суток, по заданию необходимо чтобы по определенной простой формуле (метод...

Чтение из файла, запись в файл и работа с TList несколькими потоками
Есть задача, основная часть работы которой сводится к алгоритму: 1. Прочитать из текстового...

2
 Аватар для Наталья8
466 / 333 / 64
Регистрация: 09.03.2016
Сообщений: 3,294
13.05.2024, 21:41 2
Я делал такое на opencv. Камеры втыкал в usb.
Материнку поменял и стала работать только одна камера.
Наверное можно таким же образом вставить и ffmpeg.
На ffmpeg я только видеофайлы разбирал.
Нет у меня ни каких камер.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
//   https://web-answers.ru/c/opencv-zapisat-vyvod-veb-kamery-v-fajl-avi.html
#include "stdafx.h"
#include "opencv2/opencv.hpp"
#include <iostream>
            #include <string>
              #include <sstream>
#include <time.h>// Вывод системного времяни на кадр
//------------------
#include <vector>
#include <thread>
//------------------
#include <ctime>// Высокоточный отсчёт времяни
#include <ratio>
#include <chrono>
//------------------
#include <windows.h>
#include <conio.h>
 
#include <mmsystem.h>// Звук PlaySound
#pragma comment(lib, "winmm")// Звук
 
using namespace std;
using namespace cv;
using namespace std::chrono;
 
#define AREA_MIN_SIXE 1800
#define AREA_MAX_SIZE 100000000
//---------------
#define KEYDOWN(vk_code)\
    ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code) \
    ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
 
char put_time[10];// <---- Вывод на экран часов
 
int trashHold(22), trashHold1(22), trashHold2(22);// < ------------ Чувствительность 22
//bool writeDiff = false;//<----------- Не понял зачем
 
/*=======================================
Программа делает столько потоков, обрабатывающих камеры,
сколько USB камер воткнуто в компьютер.
На каждую камеру пишет отдельный файл на диске <D:>
При обнаруженном движении перед камерой.
======================================= */
void myTrackbarCallback(int pos){
    trashHold = pos;//    Только меняет значение переменной порога intruderAlarm
}
void myTrackbarCallback1(int pos){
    trashHold1 = pos;//    Только меняет значение переменной порога intruderAlarm
}
void myTrackbarCallback2(int pos){
    trashHold2 = pos;//    Только меняет значение переменной порога intruderAlarm
}
//=======================================
//=======================================
void fork(VideoCapture cap, int number){
 
    int _frames = 15;
    //-------------------------------------------------------800/600 - 15 frames
 
    std::string str_num(""); std::stringstream ss; ss << number; str_num = "(" + ss.str() + ")";
    
        std::string name_wind = "MyVideo" + str_num;
                                  namedWindow(name_wind, CV_WINDOW_AUTOSIZE); //create a window called "MyVideo"
    double dWidth = cap.get(CV_CAP_PROP_FRAME_WIDTH); //get the width of frames of the video
    double dHeight = cap.get(CV_CAP_PROP_FRAME_HEIGHT); //get the height of frames of the video
 
    cout << "Camera <" << number << "> Frame Size = " << dWidth << "x" << dHeight << endl;
 
    Size frameSize(static_cast<int>(dWidth), static_cast<int>(dHeight));
            //initialize the VideoWriter object
    VideoWriter oVideoWriter("D:\\" + name_wind + ".avi", CV_FOURCC('D', 'I', 'V', 'X'), _frames, frameSize, true);
    //  ----  Вот эта штука пишет в консоль данные видеопотока (который будет писать)
    if (!oVideoWriter.isOpened()) //if not initialize the VideoWriter successfully, exit the program
    {
        cout << "ERROR: Failed to VideoWriter" << endl;
        Sleep(700); return;
    }
 
 
 
 
 
    // **************************************************   
        
if (old.data)// --- Первый проход мимо... в old нет данных
        {
if (trashHold < 14 && number == 0){ cvSetTrackbarPos("Sensit", name_wind.c_str(), 14); trashHold = 14; }// ================== Движок ограничить
if (trashHold1 < 14 && number == 1){ cvSetTrackbarPos("Sensit", name_wind.c_str(), 14); trashHold1 = 14; }// ================== Движок ограничить       
if (trashHold2 < 14 && number == 2){ cvSetTrackbarPos("Sensit", name_wind.c_str(), 14); trashHold2 = 14; }// ================== Движок ограничить
    
    //============================================================== Конец определения движения
            t2 = high_resolution_clock::now();
            time_span = duration_cast<duration<double>>(t2 - t1);// Отрезки точного времени
            seconde = floor(time_span.count());//Счёт секунд записи     
            //-----------------------------
            if (seconde <= 10)
            {
                cv::Mat out_frame = frame.clone();
            // Переменная put_time ОБЬЯВЛЕНА ГЛОБАЛЬНО... Если здесь... то вешало при выходе из потока
                
                putText(out_frame, put_time, Point(30, 54), 2, 1.6// размер в дублях
                    , Scalar(28, 242, 52), 2); // Толщина int  
                oVideoWriter.write(out_frame); //writer the frame into the file 
                if (seconde == 10){
                    putText(out_frame, " PAUSE", Point(30, 158), 2, 2.6// размер в дублях
                        , Scalar(28, 28, 170), 2);
                } // Толщина int   Audio_playing_time -
                imshow(name_wind, out_frame); //show the frame in "MyVideo" window
            }
            waitKey(30);
            if (one){// ----------- Один раз поставить движок, после вывода картинки
                int currentPosition(22), currentPosition1(22), currentPosition2(22);//---------------------(чувств.)
                if (number == 0)cvCreateTrackbar("Sensit", name_wind.c_str(), &currentPosition, 100, myTrackbarCallback);
                if (number == 1)cvCreateTrackbar("Sensit", name_wind.c_str(), &currentPosition1, 100, myTrackbarCallback1);
                if (number == 2)cvCreateTrackbar("Sensit", name_wind.c_str(), &currentPosition2, 100, myTrackbarCallback2);
                            one = false;
                    }
                }// if (old.data)
if (counter % 3 == 0) old = frame.clone();// в old данные    
    if (KEYDOWN(VK_ESCAPE)){
            cvDestroyWindow(name_wind.c_str());
            break;
             }  //<====================================
             }          }
 
 
//=======================================
//=======================================
int main(int argc, char** argv)
{   
    //-------------------------------------------------------
    HANDLE out_handle = GetStdHandle(STD_OUTPUT_HANDLE);
    COORD crd = { 56, 6 }; // <--- Сделаем окошко маленькое
    SMALL_RECT src = { 0, 0, crd.X - 1, crd.Y - 1 };
    SetConsoleWindowInfo(out_handle, true, &src);
    SetConsoleScreenBufferSize(out_handle, crd);
 
    // -------------      Меняем режимы камеры
    CvCapture *capture = cvCreateCameraCapture(0);// Если по дефолту 640/ 480 то 30 фреймов
    cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 800);// Изменение параметров камеры 1280 - 10 frames
    cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 600); // (разрешения)               720
    cvSetCaptureProperty(capture, CV_CAP_PROP_SATURATION, 40);
    //  CV_CAP_PROP_BRIGHTNESS
    //  CV_CAP_PROP_CONTRAST
//      capture = nullptr;//< ----------- Сначала nullptr
//  delete capture;// ------------ Потом delete
    
//========================================= 
    std::vector <std::thread> th_vec;
    int n(0);
    while (true){
    VideoCapture cap(n); // open the video camera no. 0
        if (cap.isOpened())  // if not success, exit program
            th_vec.push_back(std::thread(fork, cap, n));// Передача параметров через запятую, после fork 
        else { cout << "ERROR:  camera <"<< n <<"> not found" << endl; break; }// Если камер нет n останеться нулём
                Sleep(2000); ++n;
             }
    // while (1){ if (KEYDOWN(VK_ESCAPE))break; Sleep(50); }
    for (int i = 0; i < n; ++i){// при выходе из нулевого потока, подвешивает по очереди остальные
        th_vec.at(i).join();
            }
    //if(!th_vec.empty())   th_vec.at(0).join();
        Sleep(500);
    return 0;
}
0
Эксперт функциональных языков программированияЭксперт С++
 Аватар для Royal_X
4323 / 2192 / 966
Регистрация: 01.06.2021
Сообщений: 7,544
23.07.2024, 12:09 3
Цитата Сообщение от Наталья8 Посмотреть сообщение
trashHold
threshold звучит лучше
0
23.07.2024, 12:09
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
23.07.2024, 12:09
Помогаю со студенческими работами здесь

ffmpeg rtsp, снижение нагрузки на ЦПУ
Разрабатываю приложение, которое будет отображать потоки камер видеонаблюдения на ТВ приставке с...

Ffmpeg: потеря пакетов при ретрансляции RTSP
Мне нужно сделать ретрансляцию видео с ip камеры. Решил сделать это на ffmpeg (3.0): ffmpeg -re -i...

ffmpeg получить текущий кадр с ip камеры (rtsp поток)
Добрый день. Столкнулся с несколькими проблемами. Надеюсь на вашу мудрость. Я написал код (С++)...

V4l2 ffmpeg Надо как-то загнать rtsp в виртуальную камеру
Добрый день. Я создал виртуальную камеру в /dev/ sudo modprobe v4l2loopback Появилось,...

Работа с несколькими числами из одной ячейки
Здравствуйте. помогите пожалуйста. есть ячейки в которых несколько чисел например 20 30 50. надо...

Работа с несколькими файлами сразу, лежащими в одной папке
Добрый день. У меня такой вопрос: мне предстоит работать сразу с большим количеством текстовых...

FFmpeg. Переключение между видео потоками
Всем привет. Подскажите пожалуйста, может ли FFmpeg переключатся между видеопотоками в случае,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
Что такое внедрение зависимостей и для чего оно применяется
bytestream 27.01.2025
В современной разработке программного обеспечения одной из ключевых проблем является управление зависимостями между различными компонентами системы. Внедрение зависимостей (Dependency Injection, DI). . .
Как установить cellpadding и cellspacing в CSS
bytestream 27.01.2025
При создании веб-страниц с табличными данными разработчики часто сталкиваются с необходимостью правильного оформления внутренних и внешних отступов в таблицах. В традиционной разметке HTML для этих. . .
Чем отличаются public, protected, package-private и private в Java
bytestream 27.01.2025
В языке программирования Java механизм модификаторов доступа играет ключевую роль в реализации одного из фундаментальных принципов объектно-ориентированного программирования - инкапсуляции. . . .
Зачем нужно explicit в C++. Преобразование типов
bytestream 27.01.2025
В мире программирования на C++ управление преобразованием типов данных играет crucial роль в создании надежного и безопасного кода. Язык C++ предоставляет множество механизмов для контроля над. . .
Как создать удалённую (remote) ветку в Git
bytestream 27.01.2025
Система контроля версий Git стала неотъемлемой частью современной разработки программного обеспечения, предоставляя разработчикам мощные инструменты для управления кодовой базой. Одним из ключевых. . .
Как создать утечку памяти в Java
bytestream 27.01.2025
Утечка памяти в Java представляет собой ситуацию, когда программа неэффективно использует доступную память, удерживая ссылки на объекты, которые больше не нужны для работы приложения. Несмотря на. . .
КуМир: как решать задачи на числа
bytestream 27.01.2025
КуМир (Комплект Учебных МИРов) представляет собой уникальную образовательную среду программирования, разработанную специально для обучения основам алгоритмизации и программирования. Эта система. . .
Исполнитель Черепаха в КуМир: как решать задачи
bytestream 27.01.2025
Исполнитель Черепаха в системе КуМир представляет собой мощный образовательный инструмент, который помогает освоить основы программирования через визуальное представление результатов выполнения. . .
КуМир: как решать задачи на массивы
bytestream 27.01.2025
Массивы представляют собой важнейшую структуру данных в программировании, и система КуМир предоставляет удобные инструменты для работы с ними. В контексте КуМир массив можно представить как. . .
[golang] 26. Remove Duplicates from Sorted Array
alhaos 27.01.2025
Необходимо удалить дубликаты из предоставленного целочисленного отсортированного по взрастанию слайса, нужно изменить значения в слайсе и вернуть количество элементов. / / . . .
КуМир, исполнитель Робот. Решение задач
bytestream 27.01.2025
КуМир (Комплект Учебных МИРов) представляет собой образовательную среду для обучения программированию, которая была создана в Отделении информатики Российской Академии наук. Эта система разработана. . .
Асинхронное программировани­е и async/await в JavaScript
bytestream 27.01.2025
Асинхронное программирование представляет собой фундаментальную концепцию в современной разработке на JavaScript, которая позволяет выполнять длительные операции без блокировки основного потока. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru