Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

C++: COM, OLE, ActiveX

Войти
Регистрация
Восстановить пароль
 
 
fademike
1 / 1 / 0
Регистрация: 22.04.2016
Сообщений: 26
#1

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

22.04.2016, 15:21. Просмотров 4200. Ответов 55
Метки нет (Все метки)

Добрый день!
Решил написать программку, которая отображала бы в окне поток из сети (по протоколу 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
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
22.04.2016, 15:21
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Воспроизведение видео с ip камеры (C++ COM):

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

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

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

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

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

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

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
vxg
Модератор
3163 / 1966 / 221
Регистрация: 13.01.2012
Сообщений: 7,528
14.06.2016, 10:49 #16
tiundv, как-то примерно так (обрабатывать изменение размеров окна не стал)
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
#include <windows.h>
 
//---------------------------------------------------------------------------
HWND hWnd;
 
int buffer_w, buffer_h;
 
char *form_bmp_bits;
HBITMAP form_bmp_h;
 
void create_frame_buffer(void);
void destroy_frame_buffer(void);
//---------------------------------------------------------------------------
#include "ffmpeg_test.h"
//---------------------------------------------------------------------------
void cb_fn(void)
{
    ffmpeg_test_get_bmp(form_bmp_bits, buffer_w, buffer_h);
    InvalidateRect(hWnd, NULL, FALSE);    
}
//---------------------------------------------------------------------------
void create_frame_buffer(void)
{
    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);
}
//---------------------------------------------------------------------------
void destroy_frame_buffer(void)
{
    DeleteObject(form_bmp_h);
}
//---------------------------------------------------------------------------
void init(void)
{
    create_frame_buffer();
 
    ffmpeg_test_start("rtsp://127.0.0.1:8554/", cb_fn);
}
//---------------------------------------------------------------------------
void paint(void)
{
    if (form_bmp_h)
    {
        PAINTSTRUCT ps;
        HDC paint_hdc = BeginPaint(hWnd, &ps);
 
        HDC hdc_1 = CreateCompatibleDC(paint_hdc);
        HDC hdc_2 = CreateCompatibleDC(paint_hdc);
 
        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);
 
        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(hWnd, &ps);
    }
}
//---------------------------------------------------------------------------
void uninit(void)
{
    ffmpeg_test_stop();
 
    destroy_frame_buffer();
}
//---------------------------------------------------------------------------
 
LRESULT CALLBACK PictViewWndProc(HWND hWnd, UINT Message, UINT wParam, LONG lParam) {
    switch (Message) {
    case WM_PAINT:
        paint();
        return 0;
    case WM_DESTROY:
        uninit();
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hWnd, Message, wParam, lParam);
}
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow) {
    WNDCLASS WndClass;
    MSG Msg;
    char szClassName[] = "PictView";
 
    WndClass.style = CS_HREDRAW | CS_VREDRAW;
    WndClass.lpfnWndProc = PictViewWndProc;
    WndClass.cbClsExtra = 0;
    WndClass.cbWndExtra = 0;
    WndClass.hInstance = hInstance;
    WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    WndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    WndClass.lpszMenuName = NULL;
    WndClass.lpszClassName = TEXT("PictView");
 
    if (!RegisterClass(&WndClass)) {
        MessageBox(NULL, TEXT("Can't register class"), TEXT("Error"), MB_OK);
        return 0;
    }
 
    hWnd = CreateWindow(TEXT("PictView"), TEXT("Picture View"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
        CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
    if (!hWnd) {
        MessageBox(NULL, TEXT("Can't create window"), TEXT("Error"), MB_OK);
        return 0;
    }
 
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
 
    RECT rect;
    GetWindowRect(hWnd, &rect);
    buffer_w = rect.right - rect.left;
    buffer_h = rect.bottom - rect.top;
 
    init();
    while (GetMessage(&Msg, NULL, 0, 0)) {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;
}
1
tiundv
0 / 0 / 0
Регистрация: 25.05.2015
Сообщений: 22
14.06.2016, 18:08 #17
vxg - Большое спасибо вам. Завтра на работе проверю как камеру цепляет.

Добавлено через 9 минут
vxg и еще вопрос если можно.... зачем в функциях указывать второй void - (void init(void)). Осмысленного ответа для новичка не нашел.
0
fademike
1 / 1 / 0
Регистрация: 22.04.2016
Сообщений: 26
15.06.2016, 12:45  [ТС] #18
Цитата Сообщение от tiundv Посмотреть сообщение
зачем в функциях указывать второй void - (void init(void)).
Второй void- это параметр, который принимает функция "init" (в данном случае ничего).
если не void, то например как то так:
C
1
2
3
4
5
void init(char * str)
{
    create_frame_buffer();
    ffmpeg_test_start(str, cb_fn);
}
а вызов: init("rtsp://127.0.0.1:8554/");
1
vxg
Модератор
3163 / 1966 / 221
Регистрация: 13.01.2012
Сообщений: 7,528
15.06.2016, 14:09 #19
fademike, имелось ввиду следующее: обязательно ли указывать ключевое слово void что бы компилятор понял что функция не имеет параметров или можно оставить пустые скобки
tiundv, как то так
В языке C для задания прототипа функции, не имеющей параметров, вместо списка параметров используется ключевое слово void. В языке C++ пустой список параметров в прототипе функция означает, что функция на имеет параметров. Слово void в этом случае необязательно.
с первым void который указывает на тип возвращаемого значения такой фокус лучше не делать
В версии C89, если тип данных возвращаемый функцией, явно не задан, то подразумевается тип int. В языке C++ и версии C99, тип int по умолчанию, не поддерживается, хотя в большинстве компиляторов C++ такое предположение остаётся в силе.
1
tiundv
0 / 0 / 0
Регистрация: 25.05.2015
Сообщений: 22
16.06.2016, 18:50 #20
Спасибо ребята за обьяснение. Если можно то помогите еще.... Пытался вывести видео с камеры в дочернее окно... куча ошибок...Помогите пожалуйста. И вторая просьба...- Не могли бы вы обьяснить что за метод "static DWORD WINAPI proc(LPVOID arg)" что он делает ? И обязательно ли использовать "DECL_SPEC" ? Ниже мой код вывода дочерних окон и ошибки при запуске....
ffmpeg_test.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
#pragma once
 
//------------------------------------------------------------------------------
//ffmpeg_test 1.0
//------------------------------------------------------------------------------
#ifndef ffmpeg_test_h
#define ffmpeg_test_h
//------------------------------------------------------------------------------
#include <windows.h>
#include <windowsx.h>
#include <fstream>
#include <string>
#include<iostream>
#include <conio.h>
#include <stdio.h>
#include <vector>
using namespace std;
//------------------------------------------------------------------------------
#ifdef EXPORT
#define DECL_SPEC __declspec(dllexport) __stdcall
#else
#define DECL_SPEC __declspec(dllimport) __stdcall
#endif
 
#ifdef __cplusplus
extern "C" {
#endif
    //------------------------------------------------------------------------------
    void DECL_SPEC ffmpeg_test_start(char *src, void(*cb_fn)(void));
    void DECL_SPEC ffmpeg_test_stop(void);
    int DECL_SPEC ffmpeg_test_get_bmp(void *bmp_bits, int w, int h); //32 bit
                                                                     //------------------------------------------------------------------------------
#ifdef __cplusplus
} //extern "C"
#endif
 
#undef EXPORT
  //------------------------------------------------------------------------------
#endif //ffmpeg_test_h
#define ID_FIRSTCHILD   100
#define ID_SECONDCHILD  101
#define ID_THIRDCHILD   102
BOOL CALLBACK EnumChildProc(HWND hwndChild, LPARAM lParam);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK ChildProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK PictViewWndProc(HWND, UINT, UINT, LONG);
void init(void);
void paint(void);
void uninit(void);

main.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
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
#include "ffmpeg_test.h"
 
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
HWND hWnd;
 
int buffer_w, buffer_h;
 
char *form_bmp_bits;
HBITMAP form_bmp_h;
 
void create_frame_buffer(void);
void destroy_frame_buffer(void);
//char readFile(char *fName, int arg);
//char readFile2(char *fName, int arg);
//wstring s2ws(const string& str);
 
HINSTANCE hinst;
//---------------------------------------------------------------------------
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    HWND hwnd;
    MSG msg;
    WNDCLASS w;
    hinst = hInstance;
    memset(&w, 0, sizeof(WNDCLASS));
    w.style = CS_HREDRAW | CS_VREDRAW;
    w.lpfnWndProc = PictViewWndProc;
    w.hInstance = hInstance;
    w.hbrBackground = GetStockBrush(WHITE_BRUSH);
    w.lpszClassName = TEXT("C Windows");
    w.hCursor = LoadCursor(NULL, IDC_ARROW);
    RegisterClass(&w);
    hwnd = CreateWindow(TEXT("C Windows"), TEXT("C Windows"), WS_OVERLAPPEDWINDOW,
        10, 10, 600, 480, NULL, NULL, hInstance, NULL);
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
//---------------------------------------------------------------------------
LRESULT CALLBACK PictViewWndProc(HWND hwnd, UINT Message, WPARAM wparam, LPARAM lparam)
{
    RECT rcClient;
    int i;
    switch (Message)
    {
    case WM_CREATE: // создание основного окна
        for (int i = 0; i < 3; i++) // Создание трех  дочерних окна
        {
            WNDCLASS w;
            memset(&w, 0, sizeof(WNDCLASS));
            w.lpfnWndProc = ChildProc;
            w.hInstance = hinst;
            w.hbrBackground = GetStockBrush(WHITE_BRUSH);
            w.lpszClassName = TEXT("ChildWClass");
            w.hCursor = LoadCursor(NULL, IDC_CROSS);
            RegisterClass(&w);
            HWND child;
            child = CreateWindowEx(0, TEXT("ChildWClass"), (LPCTSTR)NULL,
                WS_CHILD | WS_BORDER | WS_VISIBLE, i * 50, i * 50,
                50, 50, hwnd, (HMENU)(int)(ID_FIRSTCHILD + i), hinst, NULL);
            ShowWindow(child, SW_NORMAL);
            UpdateWindow(child);
            RECT rect;
            GetWindowRect(hWnd, &rect);
            buffer_w = rect.right - rect.left;
            buffer_h = rect.bottom - rect.top;
 
            init();
        }
        return 0;
    case WM_SIZE:   // изменение размеров основного окна
                    // Получает габариты рабочей области главного окна и перечисляет дочерние окна.
                    // Передает габариты в дочерние окна в ходе перечисления.
        GetClientRect(hwnd, &rcClient);
        EnumChildWindows(hwnd, EnumChildProc, (LPARAM)&rcClient);
        return 0;
    }
    if (Message == WM_DESTROY)
    {
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, Message, wparam, lparam);
}
//---------------------------------------------------------------------------
LRESULT CALLBACK ChildProc(HWND hwnd, UINT Message, WPARAM wparam, LPARAM lparam)
{
    switch (Message) {
    case WM_PAINT:
        paint();
        return 0;
    case WM_DESTROY:
        uninit();
        PostQuitMessage(0);
        return 0;
    }
    /*if (Message == WM_DESTROY)
    {
        return 0;
    }*/
    return DefWindowProc(hwnd, Message, wparam, lparam);
}
//---------------------------------------------------------------------------
BOOL CALLBACK EnumChildProc(HWND hwndChild, LPARAM lParam)
{
    LPRECT rcParent;
    int i, idChild;
    // Восстановление идентификатора дочернего окна.
    // Использовать его для установки дочернего окна.
    idChild = GetWindowLong(hwndChild, GWL_ID);
    if (idChild == ID_FIRSTCHILD)
        i = 0;
    else if (idChild == ID_SECONDCHILD)
        i = 1;
    else
        i = 2;
    // Размер и позиция дочернего окна.
    rcParent = (LPRECT)lParam;
    MoveWindow(hwndChild, (rcParent->right / 3) * i, 0, rcParent->right / 3, rcParent->bottom, TRUE);
    // Удостоверитесь, что дочернее окно видимо
    ShowWindow(hwndChild, SW_SHOW);
    return TRUE;
}
//---------------------------------------------------------------------------
void cb_fn(void)
{
    ffmpeg_test_get_bmp(form_bmp_bits, buffer_w, buffer_h);
    InvalidateRect(hWnd, NULL, FALSE);
}
//---------------------------------------------------------------------------
void create_frame_buffer(void)
{
    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);
}
//---------------------------------------------------------------------------
void destroy_frame_buffer(void)
{
    DeleteObject(form_bmp_h);
}
//---------------------------------------------------------------------------
void init(void)
{
    create_frame_buffer();
    ffmpeg_test_start("rtsp://admin:admin@192.168.1.108:554/cam/realmonitor?channel=1&subtype=0", cb_fn);
}
//---------------------------------------------------------------------------
void paint(void)
{
    if (form_bmp_h)
    {
        PAINTSTRUCT ps;
        HDC paint_hdc = BeginPaint(hWnd, &ps);
 
        HDC hdc_1 = CreateCompatibleDC(paint_hdc);
        HDC hdc_2 = CreateCompatibleDC(paint_hdc);
 
        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);
 
        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(hWnd, &ps);
    }
}
//---------------------------------------------------------------------------
void uninit(void)
{
    ffmpeg_test_stop();
 
    destroy_frame_buffer();
}

При сборке выдает предупреждения:
Кликните здесь для просмотра всего текста
CSS
1
2
3
4
1>     Создается библиотека D:\_PROJECTS\VSProjects\Win32Project2\Debug\Win32Project2.lib и объект D:\_PROJECTS\VSProjects\Win32Project2\Debug\Win32Project2.exp
1>main.obj : warning LNK4217: локально определенный символ _ffmpeg_test_start@8 импортирован в функцию "void __cdecl init(void)" (?init@@YAXXZ)
1>main.obj : warning LNK4217: локально определенный символ _ffmpeg_test_stop@0 импортирован в функцию "void __cdecl uninit(void)" (?uninit@@YAXXZ)
1>main.obj : warning LNK4217: локально определенный символ _ffmpeg_test_get_bmp@12 импортирован в функцию "void __cdecl cb_fn(void)" (?cb_fn@@YAXXZ)

При отладке без подключенной камеры ошибок нет но процесс попадает сразу в фоновые. При подключеной камере ошибки такие:
Кликните здесь для просмотра всего текста
CSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
>   Win32Project2.exe!ffmpeg_test_get_bmp(void * bmp_bits, int w, int h)Строка 129  C++
        bmp_bits    0x00000000  void *
+       codec_ctx   0x038d08e0 {av_class=avcodec-57.dll!0x10b834e0 {class_name=0x10b834c0 "AVCodecContext" item_name=avcodec-57.dll!0x0fcafae0 ...} ...}    AVCodecContext *
        codec_ctx->height   720 int
0x05068220 {data=0x05068220 {0x0683d040 "lnqrrruxwwuttrsrtpptuzxyzzxxy{{yx{xsstqollnnmmkkkhghidfhc^^]\\^[YWSTSQNLMNNMKKLNPRUW[[VUVRPOONKLKJMGKLGHJJJKLLLNPQRTWTTVTTWVWWWWXXXYY[\\VXXYYYZ[\\]^^^[[^_^_^]_a^aaabba_ddefffffffhifeighfefghiijjjjjjkklmm..., ...} ...}
>   Win32Project2.exe!cb_fn()Строка 137 C++
        buffer_h    0   int
        buffer_w    0   int
+       form_bmp_bits   0x00000000 <NULL>   char *
>   Win32Project2.exe!proc(void * arg)Строка 43 C++
+       &finished   0x0673f7f0 {1}  int *
+       &packet 0x0673f7fc {buf=0x04251fc0 {buffer=0x0348dde0 {...} data=0x052281a0 "" size=49127 } pts=18000 dts=18000 ...}    AVPacket *
+       codec_ctx   0x038d08e0 {av_class=avcodec-57.dll!0x10b834e0 {class_name=0x10b834c0 "AVCodecContext" item_name=avcodec-57.dll!0x0fcafae0 ...} ...}    AVCodecContext *
        finished    1   int
+       frame   0x05068220 {data=0x05068220 {0x0683d040 "lnqrrruxwwuttrsrtpptuzxyzzxxy{{yx{xsstqollnnmmkkkhghidfhc^^]\\^[YWSTSQNLMNNMKKLNPRUW[[VUVRPOONKLKJMGKLGHJJJKLLLNPQRTWTTVTTWVWWWWXXXYY[\\VXXYYYZ[\\]^^^[[^_^_^]_a^aaabba_ddefffffffhifeighfefghiijjjjjjkklmm..., ...} ...}  AVFrame *

При остановке отладки уведомляет так:
Кликните здесь для просмотра всего текста
CSS
1
Вызвано исключение по адресу 0x00AD665A (swscale-4.dll) в Win32Project2.exe: 0xC0000005: нарушение прав доступа при чтении по адресу 0x00000038.

Это малая часть ошибок...
Прошу вас помочь !!!
За ранее СПАСИБО !!!

Добавлено через 16 минут
Попробовал одно дочерное окно вывести и при отладке выскакивает окно где написано:
Кликните здесь для просмотра всего текста
Вызвано исключение по адресу 0x0FEF665A (swscale-4.dll) в Win32Project2.exe: 0xC0000005: нарушение прав доступа при чтении по адресу 0x00000038.

Если для этого исключения имеется обработчик, выполнение программы может быть продолжено безопасно.
0
vxg
Модератор
3163 / 1966 / 221
Регистрация: 13.01.2012
Сообщений: 7,528
16.06.2016, 19:28 #21
tiundv
1 OMG
2 вы запихали приложение в код который раньше был DLL - в этом случае вам не нужны DECL_SPEC, но где же в этом случае сами функции то и весь их обвес, что то их не видно... наверное остались где-то в другом модуле
3 HOLLY SHIT
4 у вас в заголовочном файле строчки после #endif //ffmpeg_test_h - это нехорошо
5 где же присваивается значение hWnd? нигде не видно... в то же время GetWindowRect и paint спокойно в него тычут...
1
tiundv
0 / 0 / 0
Регистрация: 25.05.2015
Сообщений: 22
18.06.2016, 22:04 #22
vxg - Спасибо за помощь. Все работает. Теперь пытаюсь вывести видео в несколько дочерних окошек. Пока не получается. Понимаю почему но пока решение не нашел. Пытаюсь создать отдельный класс с методами и переменными чтоб для каждого дочернего окошка работал свой экземпляр класса с переменными. Но не знаю правильно ли это будет в плане оптимизации и быстродействия. Я просто запутался немного. Допустим переменные (HWND hWnd; int buffer_w, buffer_h; char *form_bmp_bits; HBITMAP form_bmp_h как я понимаю должны для каждого окошка и потока камеры быть отдельно. Но они глобальные и изменение влияют на все выводы дочерних окон. Я пытаюсь засунуть все эти переменные и методы их использующие в один класс и для каждого созданного дочернего окна буду создавать новый этот класс и передавать в него нужные параметры и вызывать функции. Но столкнулся с тем что не могу запихнуть все нужные методы в класс. Например метод (static DWORD WINAPI proc) вообще не получается засунуть в класс.
Может я не в ту сторону смотрю и не так понимаю? Прошу разьяснить что я не так делаю или не так понимаю
Заранее БОЛЬШОЕ СПАСИБО !!!
0
vxg
Модератор
3163 / 1966 / 221
Регистрация: 13.01.2012
Сообщений: 7,528
18.06.2016, 22:26 #23
tiundv, все отлично засовывается в один класс - в проекте откуда это взято оно так и есть - я сделал все глобальным для упрощения примера и что бы жизнь мёдом не казалась) процедура потока не нуждается в размножении - просто создавая для каждой камеры свой поток передавайте ему в качестве параметра указатель на тот самый класс и процедура будет работать на его данных
1
tiundv
0 / 0 / 0
Регистрация: 25.05.2015
Сообщений: 22
18.06.2016, 23:22 #24
Спасибо за помощь vxg. Буду копать в этом направлении.

Добавлено через 13 минут
vxg : Еще вопрос - при внедрении метода (static DWORD WINAPI proc(LPVOID arg)) в класс "InitCam" типа так static DWORD WINAPI InitCam:roc(LPVOID arg) ругается на static что типа здесь нельзя указывать тип хранения а если убрать static то при компиляции выдвет ошибку :
Кликните здесь для просмотра всего текста
нестатическая ссылка не член должна указываться относительно заданного объекта Win32Project2


Добавлено через 3 минуты
какой то смайлик сам появляется вместо буквы "p" в proc. правка не помогает. что за прикол не знаю
0
vxg
Модератор
3163 / 1966 / 221
Регистрация: 13.01.2012
Сообщений: 7,528
19.06.2016, 00:38 #25
tiundv, не делайте эту функцию внутри класса она должна быть сама по себе - посмотрите статью на хабре на которую я давал ссылку
1
tiundv
0 / 0 / 0
Регистрация: 25.05.2015
Сообщений: 22
19.06.2016, 04:35 #26
vxg - Я тогда вообще не понимаю какие методы и переменные нужно поместить в класс. Они все ссылаются друг на друга. Пример по вашей ссылке смотрел...там мне вообще не понятно что и где находится...буду изучать и пробовать..терпение и труд все перетрут...спасибо вам за все
0
vxg
Модератор
3163 / 1966 / 221
Регистрация: 13.01.2012
Сообщений: 7,528
19.06.2016, 07:55 #27
tiundv, у страха глаза велики) чуть позже скину как можно это завернуть в класс
1
tiundv
0 / 0 / 0
Регистрация: 25.05.2015
Сообщений: 22
19.06.2016, 11:13 #28
vxg - Буду признателен

Добавлено через 43 секунды
С праздником вас всех !!!
0
vxg
Модератор
3163 / 1966 / 221
Регистрация: 13.01.2012
Сообщений: 7,528
19.06.2016, 15:12 #29
tiundv, к примеру так
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
#include <windows.h>
//---------------------------------------------------------------------------
extern "C" {
#include <libavformat/avformat.h>
#include <libavdevice/avdevice.h>
#include <libswscale/swscale.h>
}
 
#include <stdio.h>
 
class ipc_t
{
public:
    AVFormatContext *format_ctx;
 
    int stream;
 
    AVCodecContext *codec_ctx;
 
    AVFrame *frame;
 
    AVFrame *x_bgr_frame;
 
    SwsContext *x_bgr_ctx;
 
    HANDLE thread_h;
    int terminated;
 
    DWORD proc(void);
 
    void ffmpeg_test_start(char *src);
    void ffmpeg_test_stop(void);
    int ffmpeg_test_get_bmp(void *bmp_bits, int w, int h);
 
 
/********************/
 
 
    HWND hWnd;
     
    int buffer_w, buffer_h;
     
    char *form_bmp_bits;
    HBITMAP form_bmp_h;
     
    void cb(void);
    void create_frame_buffer(void);
    void destroy_frame_buffer(void);
    void init(void);
    void paint(void);
    void uninit(void);
};
 
static DWORD WINAPI global_proc(LPVOID arg)
{
    ipc_t *ipc= (ipc_t *)arg;
    return ipc->proc();
}
 
DWORD ipc_t::proc(void)
{
    AVPacket packet;
    int finished;
    while (!terminated)
    {
        if (av_read_frame(format_ctx, &packet) != 0)
        {
            return 0;
        }
        else if (packet.stream_index == stream)
        {
            if (avcodec_decode_video2(codec_ctx, frame, &finished, &packet) > 0)
            {
                if (finished)
                {
                    cb();
                }
            }
        }
        av_free_packet(&packet);
    }
 
    return 0;
}
 
void ipc_t::ffmpeg_test_start(char *src)
{
    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,
        global_proc,
        this,
        0,
        &thread_id
    );
}
 
void ipc_t::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);
}
 
int ipc_t::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)
    {
        sws_freeContext(x_bgr_ctx);
        av_free(x_bgr_frame);
 
        x_bgr_frame = 0;
        x_bgr_ctx = 0;
 
        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;
}
//---------------------------------------------------------------------------
void ipc_t::cb(void)
{
    ffmpeg_test_get_bmp(form_bmp_bits, buffer_w, buffer_h);
    InvalidateRect(hWnd, NULL, FALSE);    
}
//---------------------------------------------------------------------------
void ipc_t::create_frame_buffer(void)
{
    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);
}
//---------------------------------------------------------------------------
void ipc_t::destroy_frame_buffer(void)
{
    DeleteObject(form_bmp_h);
}
//---------------------------------------------------------------------------
void ipc_t::init(void)
{
    create_frame_buffer();
 
    ffmpeg_test_start("rtsp://127.0.0.1:8554/");
}
//---------------------------------------------------------------------------
void ipc_t::paint(void)
{
    if (form_bmp_h)
    {
        PAINTSTRUCT ps;
        HDC paint_hdc = BeginPaint(hWnd, &ps);
 
        HDC hdc_1 = CreateCompatibleDC(paint_hdc);
        HDC hdc_2 = CreateCompatibleDC(paint_hdc);
 
        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);
 
        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(hWnd, &ps);
    }
}
//---------------------------------------------------------------------------
void ipc_t::uninit(void)
{
    ffmpeg_test_stop();
 
    destroy_frame_buffer();
}
//---------------------------------------------------------------------------
ipc_t ipc;
 
LRESULT CALLBACK PictViewWndProc(HWND hWnd, UINT Message, UINT wParam, LONG lParam) {
    switch (Message) {
    case WM_PAINT:
        ipc.paint();
        return 0;
    case WM_DESTROY:
        ipc.uninit();
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hWnd, Message, wParam, lParam);
}
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow) {
    WNDCLASS WndClass;
    MSG Msg;
    char szClassName[] = "PictView";
 
    WndClass.style = CS_HREDRAW | CS_VREDRAW;
    WndClass.lpfnWndProc = PictViewWndProc;
    WndClass.cbClsExtra = 0;
    WndClass.cbWndExtra = 0;
    WndClass.hInstance = hInstance;
    WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    WndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    WndClass.lpszMenuName = NULL;
    WndClass.lpszClassName = TEXT("PictView");
 
    if (!RegisterClass(&WndClass)) {
        MessageBox(NULL, TEXT("Can't register class"), TEXT("Error"), MB_OK);
        return 0;
    }
 
    ipc.hWnd = CreateWindow(TEXT("PictView"), TEXT("Picture View"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
        CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
    if (!ipc.hWnd) {
        MessageBox(NULL, TEXT("Can't create window"), TEXT("Error"), MB_OK);
        return 0;
    }
 
    ShowWindow(ipc.hWnd, nCmdShow);
    UpdateWindow(ipc.hWnd);
 
    RECT rect;
    GetWindowRect(ipc.hWnd, &rect);
    ipc.buffer_w = rect.right - rect.left;
    ipc.buffer_h = rect.bottom - rect.top;
 
    ipc.init();
    while (GetMessage(&Msg, NULL, 0, 0)) {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;
}
1
tiundv
0 / 0 / 0
Регистрация: 25.05.2015
Сообщений: 22
19.06.2016, 16:22 #30
vxg - Спасибо большое. вы очень мне помогли.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.06.2016, 16:22
Привет! Вот еще темы с ответами:

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

Воспроизведение видео - C++ WinAPI
Суть вот в чем: после совершения некого действия на консоли, нужно запустить окно, в котором будет проигрываться видео, и, желательно,...

Воспроизведение видео - C#
Подскажите что не так, ошибка когда нажимаю на PictureBox. using System; using System.Collections.Generic; using...

Воспроизведение видео - Lazarus
У меня windows 7 64 разрядная, установлен 64-х разрядный лазарус. В программе требуется воспроизвести несколько видео-фрагментов. Для этой...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
19.06.2016, 16:22
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru