1 / 1 / 0
Регистрация: 22.04.2016
Сообщений: 40
1

Воспроизведение видео с ip камеры

22.04.2016, 15:21. Показов 54992. Ответов 78
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый день!
Решил написать программку, которая отображала бы в окне поток из сети (по протоколу http или rtsp). Главное, чтобы без задержки!
Имеется обычная китайская ip камера 2mp. Программа Onvif отображает поток с этой камеры по rtsp без задержек. И я хочу также. Как это можно реализовать? И можно там, чтобы сделать цифровой zoom с интерполяцией!?

Неделю перекапывал весь интернет и только закопался:
1 - Поставил плагин VLC в borland, но выдает с секундной задержкой. Вариант отпал(
2 - Попробовал вариант с DirectShow.. значит надо установить фильтр для ip камеры:
- RTSP Client DirectShow Source Filter - не получилось добавить в область GraphEdit (М.б. из-за того что у меня Win7 x64)
- IP Camera [JPEG/MJPEG] DirectShow Filter - виснет GraphEdit при добавлении в область (М.б. из-за того что у меня Win7 x64)
- Onvif Filter (HappyTimeSoft) - Программой не удалось открыть поток с ip камеры(выдает ошибку что устройство не может открыть)
3 - Подумал о варианте использовать GStreamer, но не нашел простяцкого описания о реализации этого метода. (Ну этот вариант на крайняк, т.к. хочу, чтобы моя программа была самостоятельной без каких-либо дополнительных программ)

И по всем этим причинам хочу узнать: Может где-то я что-то не дотянул? Как мне воспроизвести видео с ip камеры без задержки, в среде Borland, например!? И можно чтобы потом добавить цифровой zoom с интерполяцией!?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
22.04.2016, 15:21
Ответы с готовыми решениями:

Запись видео с веб камеры
Новичок в этом деле. Я даже не знаю в какую тему мой вопрос опубликовать. Сейчас набираю теорию...

Захват видео с веб-камеры (C++)
Здравствуйте! Я установил Visual Studio 2015 Community и библиотеку OpenCV 3.1.0 на Windows 10....

DirectShow: захват видео с веб-камеры, воспроизведение
Посоветуйте для начала понятный мануал, что-бы можно было с нуля разобраться (желательно без воды)....

Наложить видео с альфа каналом поверх картинки с камеры, чтобы видео не перекрывало картинку
всем привет! стоит такая задача: есть видео в контейнере .mov, которое содержит альфаканал...

78
0 / 0 / 2
Регистрация: 25.05.2015
Сообщений: 28
29.01.2018, 20:18 61
Author24 — интернет-сервис помощи студентам
Возникла новая проблема...
В самом начале вот этого куска кода выдает исключение "ошибка доступа к памяти"

Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
    x_bgr_frame->data[0] = (uint8_t *)bmp_bits;
    x_bgr_frame->data[0] += x_bgr_frame->linesize[0] * (h - 1);
    x_bgr_frame->linesize[0] = -x_bgr_frame->linesize[0];   
    sws_scale(x_bgr_ctx, frame->data, frame->linesize, 0, codec_ctx->height, x_bgr_frame->data, x_bgr_frame->linesize);
    x_bgr_frame->linesize[0] = -x_bgr_frame->linesize[0];

Задолбал этот UWP !!!
Есть ли другой способ получить буфер с картинкой ???
Спасибо за помощь !!!


Добавлено через 13 минут
fademike
Могу скинуть свой проект под vs 2017.....
Написан на winApi...
Использует класс написаный "vxg" и выложенный в этой теме.
Там все просто...Окно на весь экран..При нажатии ESC выходит меню где по кликам по кнопкам создается мульти окно на 90 камер.
Я его не дописал... Перешел на UWP. Но начало положено и будет легко допилить...прикрутить directX и т.д.
На моем не мощном ноуте при отрисовке видео на 90 окошек не используя графическую карту нагрузка на процессор всего 17%. Правда видео читается с одного файла.... но там в цикле можно вывести из многих файлов....
Как подключить камеру читай в начале этой темы и поймешь...
0
Модератор
3386 / 2158 / 352
Регистрация: 13.01.2012
Сообщений: 8,375
30.01.2018, 07:53 62
tiundv, что-то я вас не пойму - то у вас 90 окон и все работает то все плохо... причину ошибки без контекста понять невозможно - скорее всего bmp_bits содержит либо мусор либо не то что должен либо блок имеет некорректный размер
0
0 / 0 / 2
Регистрация: 25.05.2015
Сообщений: 28
30.01.2018, 21:55 63
"vxg", Рабочий у меня на WinApi а мучаюсь я с UWP c++/cx + directX + xaml...
Самое прикольно что рабочий код из WinApi в UWP не хочет работать...
Спасибо "vxg". Буду искать ошибки.
0
0 / 0 / 0
Регистрация: 23.01.2018
Сообщений: 5
04.10.2018, 12:38 64
vxg, помогите плиз разобраться с Вашим примером. Попытался запустить проект, но не хватает dll файлов.
ffmpeg сейчас видимо более свежий выложен на сайте по ссылке. Не подскажете где взять dll к примеру, или
как прикрутить новую версию ffmpeg. Я чего то не догоняю.
0
Модератор
3386 / 2158 / 352
Регистрация: 13.01.2012
Сообщений: 8,375
05.10.2018, 08:40 65
AntonovAB, вы качали DLL по ссылке? файл help в архиве примера читали?
0
0 / 0 / 0
Регистрация: 23.01.2018
Сообщений: 5
05.10.2018, 09:07 66
vxg, ffmeg скачал по ссылке, но вот help файл прочитать не догадался. Попытался просто запустить экзешник
test_bcb, а он dll кучу хочет. Кажется проясняется чего надо делать. Спасибо за подсказку.
0
Модератор
3386 / 2158 / 352
Регистрация: 13.01.2012
Сообщений: 8,375
05.10.2018, 12:52 67
AntonovAB, он хочет DLL которые качаются с официального сайта - они не включены в проект так как достаточно большие
0
0 / 0 / 0
Регистрация: 23.01.2018
Сообщений: 5
05.10.2018, 18:29 68
vxg, вот тут я и заткнулся. Скачал ffmpeg по ссылке и сунул dll в папку exe примера, но при запуске сообщение что нет dll.
Я просто для начала пытался запустить exe файл. Запрашиваемые dll попытался скачать, но в конечном итоге не нашёл
очередной файл. Где эти dll можно кучкой качнуть? На сайте по ссылке там десяток dll с самой программой ffmpeg.exe,
но нужно ещё похоже, или другой версии. Ладно, завтра попробую сделать компиляцию как в хелпе написано.
0
Модератор
3386 / 2158 / 352
Регистрация: 13.01.2012
Сообщений: 8,375
06.10.2018, 21:01 69
AntonovAB, выложенные здесь примеры используют DLL из ffmpeg-20150421-git-a924b83-win32
1
0 / 0 / 0
Регистрация: 23.01.2018
Сообщений: 5
06.10.2018, 23:39 70
vxg, увы, но сейчас их уже не найти, пытался. Может сбросите?
У меня есть рабочий проект уже давно написанный. Линия цветовой сортировки пластика по цвету. Ранее была
использована юсб вэб камера, но сейчас есть необходимость увеличить расстояние между компом и рабочей зоной
и IP вариант пожалуй единственное решение. Только можно ли передать в TBitmap картинку для анализа? Пока не
знаю, но было бы здорово, чтобы прикрутить старый алгоритм. Вообще это немного не мой профиль и поэтому я
туплю, извиняюсь. В основном с пром контроллерами вожусь, а техническое зрение пока не очень распространено и
не так доступно как хотелось бы. Поэтому для подобных задач приходится использовать комп, а не пром контроллер.
0
0 / 0 / 0
Регистрация: 23.01.2018
Сообщений: 5
10.10.2018, 11:20 71
vxg, запустил наконец пример. Библиотеки взял от libav 11.2. Всё отлично работает, только при закрытии окна
ошибки сыпет. Но это всё мелочи. Спасибо!
0
0 / 0 / 0
Регистрация: 01.09.2020
Сообщений: 5
26.07.2021, 13:01 72
vxg, Спасибо, друг. Ты меня очень выручил своим примером использования ffmpeg в bcb60.
Я уже не знал что делать, чтобы получать RTSP с камер hikvison в своей программе.
А благодаря тебе все получилось.

Добавлено через 4 часа 22 минуты
vxg, Друг, помоги пожалуйста еще раз.
Твоя библиотека прекрасно работает, но если хочу из одной программы две или больше камер, то получаю лишь изображение с той что активировал последней.
0
Модератор
3386 / 2158 / 352
Регистрация: 13.01.2012
Сообщений: 8,375
26.07.2021, 16:19 73
rumvit, я не знаю как именно вы сделали из примера систему которая может много камер, но если она не может наверное она на это не была рассчитана. вообще много камер работают. донор кода для того примера который вы наверное брали за основу работает с множеством камер одновременно, вот тут можно убедиться https://habr.com/ru/post/277955/
Миниатюры
Воспроизведение видео с ip камеры  
0
0 / 0 / 0
Регистрация: 01.09.2020
Сообщений: 5
26.07.2021, 16:31 74
К сожалению работает лишь тот канал, что инициализировался последним.
Такое впечатление, что они используют один ресурс и последний оставляет его за собой.
0
Модератор
3386 / 2158 / 352
Регистрация: 13.01.2012
Сообщений: 8,375
26.07.2021, 20:24 75
rumvit, без кода я не смогу угадать в чем проблема
0
0 / 0 / 0
Регистрация: 01.09.2020
Сообщений: 5
26.07.2021, 22:45 76
У меня потребность в 4 камерах на отдельных дочерних формах
у каждой из них одинаковая реализация.

ufrmCamera_1.h
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
class TfrmCamera_1;
class repaint_thread_t : public TThread
{
public:
    TfrmCamera_1 *form;
 
    repaint_thread_t(bool CreateSuspended, TfrmCamera_1 *form);
 
    void __fastcall repaint(void);
 
    virtual void __fastcall Execute(void);
};
 
class TfrmCamera_1 : public TForm
{
__published:    
 
.....
 
   void __fastcall FormCloseQuery(TObject *Sender, bool &CanClose);
   void __fastcall FormResize(TObject *Sender);
 
private:    // User declarations
public:     // User declarations
   __fastcall TfrmCamera_1(TComponent* Owner);
 
 
.......
 
 
        void __fastcall WMPaint(TWMPaint& Message);
        void __fastcall WMEraseBkgnd(TWMEraseBkgnd& Message);
 
        BEGIN_MESSAGE_MAP
            VCL_MESSAGE_HANDLER(WM_PAINT, TWMPaint, WMPaint)
            VCL_MESSAGE_HANDLER(WM_ERASEBKGND, TWMEraseBkgnd, WMEraseBkgnd)
        END_MESSAGE_MAP(TForm)
 
        HANDLE h_a;
        HANDLE h_b;
 
        int buffer_w, buffer_h;
 
        char *form_bmp_bits;
        HBITMAP form_bmp_h;
 
        TCanvas *mem_c;
 
        repaint_thread_t *repaint_thread;
 
        void create_frame_buffer(void);
        void destroy_frame_buffer(void);
 
        void draw_text(TCanvas *c, int w, int h);
 
};
ufrmCamera_1.cpp

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
167
168
169
170
171
172
class mt_obj
{
public:
    mt_obj(void) {InitializeCriticalSection(&cs);}
    virtual ~mt_obj(void) {DeleteCriticalSection(&cs);}
 
    void lock(void) {EnterCriticalSection(&cs);}
    void unlock(void) {LeaveCriticalSection(&cs);}
 
private:
    CRITICAL_SECTION cs;
 
private:
    mt_obj(const mt_obj &) {}
    const mt_obj &operator =(const mt_obj &) {}
};
 
static mt_obj cs;
 
//---------------------------------------------------------------------------
repaint_thread_t::repaint_thread_t(bool CreateSuspended, TfrmCamera_1 *form): TThread(CreateSuspended), form(form) {}
 
void __fastcall repaint_thread_t::repaint(void)
{
    form->Repaint();
}
 
void __fastcall repaint_thread_t::Execute(void)
{
    while (!Terminated)
    {
        WaitForSingleObject(form->h_a, 250);
        Synchronize(repaint);
        WaitForSingleObject(form->h_b, 250);
    }
}
void cb_fn(void)
{
    cs.lock();
    ffmpeg_test_get_bmp(frmCamera_1->form_bmp_bits, frmCamera_1->buffer_w, frmCamera_1->buffer_h);
    cs.unlock();
 
    ResetEvent(frmCamera_1->h_b);
    SetEvent(frmCamera_1->h_a);
    ResetEvent(frmCamera_1->h_a);
    SetEvent(frmCamera_1->h_b);
}
//---------------------------------------------------------------------------
__fastcall TfrmCamera_1::TfrmCamera_1(TComponent* Owner)
   : TForm(Owner)
{
 
..........
 
    ClientWidth = 400;
    ClientHeight = 300;
 
    h_a = CreateEvent(0, FALSE, FALSE, 0);
    h_b = CreateEvent(0, FALSE, FALSE, 0);
 
    DoubleBuffered = true;
 
    mem_c = new TCanvas;
 
    create_frame_buffer();
 
    repaint_thread = new repaint_thread_t(false, this);
    ffmpeg_test_start("rtsp://admin:Gavrilovo1595159@192.168.0.151/mjpeg/ch1/sub/av_stream", cb_fn);
 
}
 
//---------------------------------------------------------------------------
void __fastcall TfrmCamera_1::FormCloseQuery(TObject *Sender,
      bool &CanClose)
{
    CloseHandle(h_a);
    CloseHandle(h_b);
 
    if(frmMain->ffmpeg_test_stoped ==0)
      ffmpeg_test_stop();
 
    delete repaint_thread;
 
    destroy_frame_buffer();
    frmMain->ffmpeg_test_stoped = 1;
 
}
//---------------------------------------------------------------------------
void __fastcall TfrmCamera_1::FormResize(TObject *Sender)
{
    cs.lock();
    destroy_frame_buffer();
    create_frame_buffer();
    cs.unlock();
}
//---------------------------------------------------------------------------
void __fastcall TfrmCamera_1::WMEraseBkgnd(TWMEraseBkgnd& Message)
{
    Message.Result = 1;
}
//---------------------------------------------------------------------------
 
void __fastcall TfrmCamera_1::WMPaint(TWMPaint& Message)
{
    if (form_bmp_h)
    {
        PAINTSTRUCT ps;
        HDC paint_hdc = BeginPaint(Handle, &ps);
 
        HDC hdc_1 = CreateCompatibleDC(paint_hdc);
        HDC hdc_2 = CreateCompatibleDC(paint_hdc);
        mem_c->Handle = hdc_1;
 
        HBITMAP h_1 = CreateCompatibleBitmap(paint_hdc, buffer_w, buffer_h);
        HBITMAP old_h_1 = (HBITMAP)SelectObject(hdc_1, h_1);
 
        HBITMAP old_h_2 = (HBITMAP)SelectObject(hdc_2, form_bmp_h);
        BitBlt(hdc_1, 0, 0, buffer_w, buffer_h, hdc_2, 0, 0, SRCCOPY);
 
        // ...do something with hdc_1...
       // draw_text(mem_c, buffer_w, buffer_h);
 
        BitBlt(paint_hdc, 0, 0, buffer_w, buffer_h, hdc_1, 0, 0, SRCCOPY);
 
        SelectObject(hdc_1, old_h_1);
        SelectObject(hdc_2, old_h_2);
 
        DeleteObject(h_1);
 
        DeleteDC(hdc_1);
        DeleteDC(hdc_2);
 
        EndPaint(Handle, &ps);
    }
}
//---------------------------------------------------------------------------
void TfrmCamera_1::draw_text(TCanvas *c, int w, int h)
{
    AnsiString s = "...HELLO WORLD...";
 
    c->Brush->Style = bsClear;
    c->Font->Color = clWhite;
    c->Font->Size = 24;
    c->Font->Style = TFontStyles()<< fsBold;
    c->TextOutA(w / 2 - c->TextWidth(s) / 2, h / 2 - c->TextHeight(s) / 2, s);
}
//---------------------------------------------------------------------------
void TfrmCamera_1::destroy_frame_buffer(void)
{
    DeleteObject(form_bmp_h);
}
//---------------------------------------------------------------------------
void TfrmCamera_1::create_frame_buffer(void)
{
    buffer_w = ClientWidth;
    buffer_h = ClientHeight;
 
    BITMAPINFOHEADER form_bmi_hdr;
    form_bmi_hdr.biSize = sizeof(BITMAPINFOHEADER);
    form_bmi_hdr.biWidth = buffer_w;
    form_bmi_hdr.biHeight = buffer_h;
    form_bmi_hdr.biPlanes = 1;
    form_bmi_hdr.biBitCount = 32;
    form_bmi_hdr.biCompression = BI_RGB;
    form_bmi_hdr.biSizeImage = form_bmi_hdr.biWidth * form_bmi_hdr.biHeight * 4;
    form_bmi_hdr.biXPelsPerMeter = 0;
    form_bmi_hdr.biYPelsPerMeter = 0;
    form_bmi_hdr.biClrUsed = 0;
    form_bmi_hdr.biClrImportant = 0;
 
    form_bmp_h = CreateDIBSection(0, (BITMAPINFO *)&form_bmi_hdr, DIB_RGB_COLORS, (void **)&form_bmp_bits, 0, 0);
}

Работает так, что показывает реальное видео лишь последний инициализированный поток.
Остальные стоят как фото.Видимо они замирают когда инициализируется следующий поток.
0
Модератор
3386 / 2158 / 352
Регистрация: 13.01.2012
Сообщений: 8,375
27.07.2021, 11:19 77
rumvit, как выглядит код библиотеки к которому они обращаются?
0
0 / 0 / 0
Регистрация: 01.09.2020
Сообщений: 5
27.07.2021, 13:03 78
Создал два комплекта переменных. Для двух каналов
Получилось так
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
#define EXPORT
#include "ffmpeg_test.h"
 
extern "C" {
#include <libavformat/avformat.h>
#include <libavdevice/avdevice.h>
#include <libswscale/swscale.h>
}
 
#include <stdio.h>
 
static AVFormatContext *format_ctx;
static AVFormatContext *format_ctx2;
 
static int stream;
static int stream2;
 
static AVCodecContext *codec_ctx;
static AVCodecContext *codec_ctx2;
 
static AVFrame *frame;
static AVFrame *frame2;
 
static AVFrame *x_bgr_frame;
static AVFrame *x_bgr_frame2;
 
static SwsContext *x_bgr_ctx;
static SwsContext *x_bgr_ctx2;
 
static HANDLE thread_h;
static HANDLE thread_h2;
static int terminated;
static int terminated2;
 
void (*cb_fn)(void);
void (*cb_fn2)(void);
 
static DWORD WINAPI proc(LPVOID arg)
{
    AVPacket packet;
    AVPacket packet2;    int finished;
 
    while (!terminated)
    {
        if (av_read_frame(format_ctx, &packet) != 0)
        {
            ExitThread(0);
        }
        else if (packet.stream_index == stream)
        {
            if (avcodec_decode_video2(codec_ctx, frame, &finished, &packet) > 0)
            {
                if (finished)
                {
                    cb_fn();
                }
            }
        }
 
        av_free_packet(&packet);
 
    }
 
    ExitThread(0);
}
///////////////////////////////////////////
 
static DWORD WINAPI proc2(LPVOID arg)
{
    AVPacket packet;
    int finished;
    while (!terminated2)
    {
        if (av_read_frame(format_ctx2, &packet) != 0)
        {
            ExitThread(0);
        }
        else if (packet.stream_index == stream2)
        {
            if (avcodec_decode_video2(codec_ctx2, frame2, &finished, &packet) > 0)
            {
                if (finished)
                {
                    cb_fn2();
                }
            }
        }
 
 
 
        av_free_packet(&packet);
 
    
    }
 
    ExitThread(0);
}
/////////////////////////////////////
void DECL_SPEC ffmpeg_test_start(char *src, void (*cb_fn)(void))
{
    ::cb_fn = cb_fn;
 
    av_register_all();
 
    format_ctx = avformat_alloc_context();
    if (!format_ctx)
    {
        return;
    }
 
    AVDictionary *opts = 0;
    av_dict_set(&opts, "rtsp_transport", "tcp", 0);
 
    if (avformat_open_input(&format_ctx, src, 0, &opts) != 0)
    {
        return;
    }
 
    if (avformat_find_stream_info(format_ctx, 0) < 0)
    {
        return;
    }
  
    stream = -1;
    for (int i = 0; i < format_ctx->nb_streams; i++)
        if (format_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
        {
            stream = i;
            break;
        }
    if (stream == -1)
    {
        return;
    }
  
    codec_ctx = format_ctx->streams[stream]->codec;
  
    AVCodec *codec = avcodec_find_decoder(codec_ctx->codec_id);
    if (!codec)
    {
        return;
    }
 
    if (avcodec_open2(codec_ctx, codec, 0) != 0)
    {
        return;
    }
 
    frame = av_frame_alloc();
    if (!frame)
    {
        return;
    }
 
    x_bgr_frame = 0;
 
    terminated = 0;
    DWORD thread_id;
    thread_h = CreateThread
    (
        0,
        0,
        proc,
        0,
        0,
        &thread_id
    );
}
/////////////////////////
void DECL_SPEC ffmpeg_test_start2(char *src, void (*cb_fn2)(void))
{
    ::cb_fn2 = cb_fn2;
 
    av_register_all();
 
    format_ctx2 = avformat_alloc_context();
    if (!format_ctx2)
    {
        return;
    }
 
    AVDictionary *opts = 0;
    av_dict_set(&opts, "rtsp_transport", "tcp", 0);
 
    if (avformat_open_input(&format_ctx2, src, 0, &opts) != 0)
    {
        return;
    }
 
    if (avformat_find_stream_info(format_ctx2, 0) < 0)
    {
        return;
    }
 // 
    stream2 = -1;
    for (int i = 0; i < format_ctx2->nb_streams; i++)
        if (format_ctx2->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
        {
            stream2 = i;
            break;
        }
    if (stream2 == -1)
    {
        return;
    }
  
    codec_ctx2 = format_ctx2->streams[stream2]->codec;
  
    AVCodec *codec = avcodec_find_decoder(codec_ctx2->codec_id);
    if (!codec)
    {
        return;
    }
 
    if (avcodec_open2(codec_ctx2, codec, 0) != 0)
    {
        return;
    }
 
    frame2 = av_frame_alloc();
    if (!frame2)
    {
        return;
    }
 
    x_bgr_frame2 = 0;
 
    terminated2 = 0;
    DWORD thread_id;
    thread_h2 = CreateThread
    (
        0,
        0,
        proc2,
        0,
        0,
        &thread_id
    );
}
 
////////////////////////
 
 
void DECL_SPEC ffmpeg_test_stop(void)
{
    terminated = 1;
 
    WaitForSingleObject(thread_h, INFINITE);
    CloseHandle(thread_h);
 
    sws_freeContext(x_bgr_ctx);
 
    av_free(x_bgr_frame);
    av_free(frame);
  
    avcodec_close(codec_ctx);
  
    avformat_close_input(&format_ctx);
 
    avformat_free_context(format_ctx);
}
///////////////////////////////////
void DECL_SPEC ffmpeg_test_stop2(void)
{
    terminated2 = 1;
 
    WaitForSingleObject(thread_h2, INFINITE);
    CloseHandle(thread_h2);
 
    sws_freeContext(x_bgr_ctx2);
 
    av_free(x_bgr_frame2);
    av_free(frame2);
  
    avcodec_close(codec_ctx2);
  
    avformat_close_input(&format_ctx2);
 
    avformat_free_context(format_ctx2);
}
 
 
///////////////////////////////////
 
 
int DECL_SPEC ffmpeg_test_get_bmp(void *bmp_bits, int w, int h)
{
    if (!x_bgr_frame || x_bgr_frame->width != w || x_bgr_frame->height != h)
    {
        x_bgr_frame = av_frame_alloc();
        if (!x_bgr_frame)
        {
            return 0;
        }
 
        x_bgr_frame->width = w;
        x_bgr_frame->height = h;
 
        if 
        (
            avpicture_fill((AVPicture *)x_bgr_frame, 0, PIX_FMT_RGB32, w, h) < 0
        )
        {
            return 0;
        }
 
        x_bgr_ctx = sws_getContext(codec_ctx->width, codec_ctx->height, codec_ctx->pix_fmt, w, h, PIX_FMT_RGB32, SWS_BICUBIC, 0, 0, 0);
        if (!x_bgr_ctx)
        {
            return 0;
        }
    }
 
    x_bgr_frame->data[0] = (uint8_t *)bmp_bits;
    x_bgr_frame->data[0] += x_bgr_frame->linesize[0] * (h - 1);
    x_bgr_frame->linesize[0] = -x_bgr_frame->linesize[0];   
    sws_scale(x_bgr_ctx, frame->data, frame->linesize, 0, codec_ctx->height, x_bgr_frame->data, x_bgr_frame->linesize);
    x_bgr_frame->linesize[0] = -x_bgr_frame->linesize[0]; 
 
    return 1;
}
/////////////////////////////////////
int DECL_SPEC ffmpeg_test_get_bmp2(void *bmp_bits, int w, int h)
{
    if (!x_bgr_frame2 || x_bgr_frame2->width != w || x_bgr_frame2->height != h)
    {
        x_bgr_frame2 = av_frame_alloc();
        if (!x_bgr_frame2)
        {
            return 0;
        }
 
        x_bgr_frame2->width = w;
        x_bgr_frame2->height = h;
 
        if 
        (
            avpicture_fill((AVPicture *)x_bgr_frame2, 0, PIX_FMT_RGB32, w, h) < 0
        )
        {
            return 0;
        }
 
        x_bgr_ctx2 = sws_getContext(codec_ctx2->width, codec_ctx2->height, codec_ctx2->pix_fmt, w, h, PIX_FMT_RGB32, SWS_BICUBIC, 0, 0, 0);
        if (!x_bgr_ctx2)
        {
            return 0;
        }
    }
 
    x_bgr_frame2->data[0] = (uint8_t *)bmp_bits;
    x_bgr_frame2->data[0] += x_bgr_frame2->linesize[0] * (h - 1);
    x_bgr_frame2->linesize[0] = -x_bgr_frame2->linesize[0];   
    sws_scale(x_bgr_ctx2, frame2->data, frame2->linesize, 0, codec_ctx2->height, x_bgr_frame2->data, x_bgr_frame2->linesize);
    x_bgr_frame2->linesize[0] = -x_bgr_frame2->linesize[0]; 
 
    return 1;
}
 
/////////////////////////////////////
 
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}
Экспортировал
C++
1
2
3
4
5
6
7
8
void DECL_SPEC ffmpeg_test_start(char *src, void (*cb_fn)(void));
void DECL_SPEC ffmpeg_test_stop(void);
void DECL_SPEC ffmpeg_test_start2(char *src, void (*cb_fn2)(void));
void DECL_SPEC ffmpeg_test_stop2(void);
int DECL_SPEC ffmpeg_test_get_bmp(void *bmp_bits, int w, int h); //32 bit
int DECL_SPEC ffmpeg_test_get_bmp2(void *bmp_bits, int w, int h); //32 bit
 
//------------------------------------------------------------------------------
Собрал без проблем.
Иногда работают оба канала
Но чаще оба стоят на месте.

Добавлено через 53 минуты
На самом деле если между созданием форм сделать задержку, то все работает ,заметил.
0
0 / 0 / 0
Регистрация: 01.09.2020
Сообщений: 5
27.07.2021, 21:37 79
vxg, Все склеилось.Работает как и хотелось на 4 RTSP потока.
Больше мне не надо.
Осталось все переделать, чтобы было постройнее и будет все ОК.
Спасибо за пример. Мне очень вошло.
0
27.07.2021, 21:37
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
27.07.2021, 21:37
Помогаю со студенческими работами здесь

Обработка видео с камеры видео наблюдения (для экспертов)
Обработка видео с камеры видео наблюдения (для экспертов) Имеются несколько каналов видео с камер...

дырка для захвата видео с видео камеры
На моем компе стоит Geforce 7600 GS на ней нет порта для видеокамеры как на ноуте:wall: можно ли...

Как сделать так что бы обычное видео из жесткого диска подавалось как видео с вэб-камеры?
кто знает?

Воспроизведение видео
Как в Windows.Forms загрузить видео? Когда я жмякаю на кнопку - &gt; появляется видео и без сигнала...


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

Или воспользуйтесь поиском по форуму:
79
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru