Я создал двоичные файлы OpenCV (.dll), используя Cmake и visual studio, которые сгенерировали файл .pdb, который помог мне найти проблему в коде (частично!)
Как происходит этот сбой..
Я использую программное обеспечение, с помощью которого мы можем установить ограничение скорости интернет-загрузки (скорость передачи) для любой конкретной программы.
Теперь, если я подключу IP-камеру к приведенному ниже коду, я заметил, что моему приложению требуется около 100 Кбит/с использования Интернета (скорость передачи) - только тогда я могу без проблем наблюдать за живым потоком. Допустим, я сократил (установил) использование моего приложения в Интернете до 10 Кбит/с [Это причина аварии] в этом случае я должен иметь возможность видеть новый кадр раз в 4+ секунды.
Я получаю ошибку при доступе к доступу, вероятно, потому что (cap>>img;
) cap пытается достичь местоположения в ram и получить кадр, но нет кадра YET, потому что он все еще загружается из-за низкой скорости интернета.
Очевидно, что указатель достигает некоторого местоположения в ram, чтобы захватить фрейм, который еще не присутствует.
Некоторое интересное поведение.,.
Void OpenCamera()
{
VideoCapture cap("http://192.168.1.3:8080/video?x.xmjpeg");
Mat img;
while(true)
{
try
{
if(cap.isOpened()) //also tried grab + retrieve, crashes at grab
cap>>img; //code crashes here
}
catch(...)
{
cout<<"Camera Disconnected"<<endl;
}
}
}
Если я использую весь код в том же классе (внутри одного и того же заголовочного файла), нет никакой проблемы (новый кадр отображается через 4+ секунды без сбоя программы), но если я поместил код в отдельный класс ( другой файл заголовка), затем вызовите функцию для открытия камеры из объекта класса, затем она выйдет из строя , если скорость Интернета сокращена.
странное поведение - если я отлаживаю шаг за шагом, он никогда не сбой!
когда я строю opencv-библиотеку с ffmpeg, я получаю файл .pdb только для opencv (opencv_world310.pdb) - поэтому отладка проблемы с использованием стека вызовов но я не получаю pdb для ffmpeg (потому что Opencv_ffmpeg.dll предварительно скомпилирован, и именно там его сбой)
следовательно, его трудно отлаживать, здание ffmpeg не создает файл pdb, потому что он построен с использованием MSYS
, так что это возможно отлаживать то, что у нас есть?
Я включаю моментальный снимок от отладки визуальной студии, некоторые из переменных, которые помогут понять:
typedef int (*CvGrabFrame_Plugin)( void* capture_handle ); [cap_ffmpeg_api.cpp]
protected: void* ffmpegCapture; [cap_ffmpeg.cpp]
static CvGrabFrame_Plugin icvGrabFrame_FFMPEG_p = 0; [cap_ffmpeg.cpp]
Исключение брошено в 0x0A0AF6F0 (opencv_ffmpeg310.dll) в Sample.exe: 0xC0000005: Место считывания нарушения доступа 0x00000020. Если там есть обработчик для этого исключения, программа может быть безопасно продолжена.
в исходном коде я включил ниже строки и скомпилировал и использовал его в проекте - не работал, снова разбился!
if(ffmpegCapture)
- проверка нулевого указателя
можем ли мы внести некоторые изменения в строку 214 в [cap_ffmpeg.cpp], чтобы избежать сбоя?
другие файлы заголовков - это только одна папка вверх.
Обновление: Я заметил, что программа сразу же срабатывает, когда я ограничиваю скорость интернет-потребления. Я использую С++/Cli (winforms, target dot net Framework = 4.6), у меня есть CameraClass (в отдельном файле заголовка) и основная функция в (отдельный файл заголовка)
Основная функция ниже кода
CameraClass ^CC = gcnew CameraClass();
CC->OpenCamera();
Я не могу создать тип не управляемого объекта в управляемом классе, поэтому я поместил собственные типы (переменные Opencv) в отдельное пространство имен, как показано ниже, чтобы я мог использовать этот класс. возможно, мне нужно использовать внутренние указатели?
#pragma once
#include"opencv2\opencv.hpp"
#include <msclr\marshal_cppstd.h>
namespace SampleApp{
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace System::Threading;
using namespace System::IO;
using namespace std;
namespace
{
cv::VideoCapture cap[5]; //max 5 instance for this class
cv::Mat image[5];
cv::IplImage pic1[5];
cv::IplImage *pic2[5];
}
public ref class CamWindow : public WeifenLuo::WinFormsUI::Docking::DockContent
{
public: CamWindow(void)
{
InitializeComponent();
}
Void OpenCamera()
{
}
.
.
.
.
};
}
Определенное столкновение между обработкой памяти .net и обработкой памяти С++?