자유롭게 질의 및 응답을 할 수 있는 게시판입니다. 개발자 여러분의 답변이 큰 도움이 됩니다. 
  • 제품설치/등록 오류 문의: 설치/등록 Q&A 이용 (제품 구매 고객 한정)

Delphi FMX 멀티스레드 문제입니다.

2019.08.28 16:05

아크나톤 조회 수:823

본 게시판은 개발자들이 자유롭게 질문과 답변을 공유하는 게시판입니다.
* 따라서 최대한 정중하게 질문을 올려 주세요.
* 질문을 상세히 작성해 주실 수록 좋은 답변이 올라 옵니다.
* 다른 분들도 참고할 수 있도록 결과 댓글 필수(또는 감사 댓글)
(결과 댓글을 달지 않는 경우 다음 질문에 대한 답변이 달리지 않는 불이익이 있을 수 있습니다.)
-----------------------------------------------------------------------------------------------

안녕하세요.

날씨가 많이 시원해졌네요.

 

OpenCV 영상 프로젝트는 여전히 C#과 Delphi 사이에서 고민하고 있는 1인입니다.

C#으로 프로젝트 진행하면서 틈틈히 Delphi에서 핵심적인 부분만 테스트해 보고있는데 멀티스레드에서 막히네요.

 

멀티스레드.png

OpenCV로 영상을 여러개 불러올때 위의 9개 정도 불러올때까진 괜찮습니다.

약, 16개 정도 불러오면 그림에서 빨간색 테두리(시간표시)를 보면 1초단위가 아니라 널뛰기를 합니다.

즉, 화면이 부드럽지 못하고 끊어진다는 뜻이겠죠.

 

시스템 스펙은

CPU : Intel Xwon Silver 4114 2.20 x 2 (총 20코어)

메모리 : 32Gb

GPU : NIVDIA Quadro P620 전용메모리 2Gb x 2

멀티스레드_상태.png

 

작업관리자에서 보면 CPU는 5% 정도로써 놀고있습니다.

메모리, GPU 모두 넉넉한 상태구요.

내부 네트웍은 기가랜입니다.

그런데 자원을 제대로 사용하지 못하는건지 영상이 정상적으로 재생되지 못하고 왜 널뛰기를 하는 것인지 잘 모르겠습니다.

 

주요 코드는 아래와 같습니다.

[스레드 선언]

type

  TCHThread = class(TThread)

  private

    i_TH_Ch : smallint;

    TH_Rect_1, TH_Rect_2, TH_Rect_3, TH_Rect_4 : tcvRect;

    procedure Proc_Disp(i_Ch : smallint);

  protected

    procedure Execute ; override;

  public

    constructor Create(i_Thread_Ch: smallint; Rect_1, Rect_2, Rect_3, Rect_4 : tcvRect);

    destructor Destroy; override;

  end;

 

[스레드생성]

constructor TCHThread.Create(i_Thread_Ch: smallint; Rect_1, Rect_2, Rect_3, Rect_4 : tcvRect);

begin

  inherited Create(True);

  i_TH_Ch := i_Thread_Ch;

  TH_Rect_1 := Rect_1; TH_Rect_2 := Rect_2; TH_Rect_3 := Rect_3; TH_Rect_4 := Rect_4;

{

TThreadPriority WIN32 스레드 우선 순위 상수

tpIdle THREAD_PRIORITY_IDLE -15

tpLowest THREAD_PRIORITY_LOWEST -2

tpLower THREAD_PRIORITY_BELOW_NORMAL -1

tpNomal THREAD_PRIORITY_NOMAL 0

tpHigher THREAD_PRIORITY_ABOVE_NOMAL 1

tpHighest THREAD_PRIORITY_HIGHEST 2

tpTimeCritical THREAD_PRIORITY_TIME_CRITICAL 15

}

  Priority := tpLowest;  // CPU의 스레드 우선순위 정의(현재로썬 뭘 해도 차이없음)

  Self.FreeOnTerminate := False;

  Resume;

end;

 

[스레드실행]

procedure TCHThread.Execute;

var

  i : smallint;

  Src_Img : pIplImage;

  Dest_Img : pIplImage;

  P1_Img, P2_Img, P3_Img, P4_Img : pIplImage;

  // 회전에 필요

  rot_mat: pCvMat;

  scale: double;

  center: TcvPoint2D32f;

begin

  inherited;

  i := i_TH_Ch;

  while Assigned(FormMain.capture[i]) do

    begin

      LockValue.Acquire;

      try

        FormMain.frame[i] := cvQueryFrame(FormMain.capture[i]);

        if Assigned(FormMain.frame[i]) then

          begin

            // 편의상 코드 삭제(영상을 자르고, 회전하고 병합하는 코드)

            try

              TImage(FormMain.FindComponent('Disp'+IntToStr(i))).Bitmap.Canvas.BeginScene;

            finally

              IPLImageToFMXBitmap(Dest_Img, TImage(FormMain.FindComponent('Disp'+IntToStr(i))).Bitmap, False);

              TImage(FormMain.FindComponent('Disp'+IntToStr(i))).Bitmap.Canvas.EndScene;

            end;

            cvReleaseImage(Dest_Img);

            cvReleaseImage(Src_Img);

          end;

      finally

        LockValue.Release;

      end;

    end;

end;

 

 

[스레드 생성하고 실행부분]

procedure TFormMain.Proc_Set_Display(i_Ch, i_Cam_Idx : Integer);

var

  i : Integer;

  s_Url : AnsiString;

begin

  if i_Cam_Idx > 0 then

    begin

           중략

              capture[i_Ch] := cvCreateFileCapture(PAnsiChar(s_Url));

              if Assigned(capture[i_Ch]) then

                begin

                  b_Assign := True;

                  cvSetCaptureProperty(capture[i_Ch], CV_CAP_PROP_FPS, 15.0);

                  cvSetCaptureProperty(capture[i_Ch], CV_CAP_PROP_FOURCC, CV_FOURCC('H','2','6','4'));

                  // ★★★★ 스레드 생성하고 실행(스레드를 배열로 두었습니다) ★★★★★

                  LockValue := TCriticalSection.Create;

                  CH_Thread[i_Ch] := TCHThread.Create(i_Ch, Rect_1[i_Ch], Rect_2[i_Ch], Rect_3[i_Ch], Rect_4[i_Ch]);

                end;

        end;

    end;

end;

 

10개의 영상을 로딩할 경우 CH_Thread[1] ~ CH_Threadp10]으로 10개가 생성되고 서로 다른 영상을 스레드 돌리게됩니다.

 

실제 procedure TCHThread.Execute; 를 보게되면

while Assigned(FormMain.capture[i]) do 문이 있습니다.

영상이 유효하면 계속 영상의 프레임을 받아서 자르고, 회전하여 TImage에 뿌려주라는 것입니다.

스레드 한번 수행하는데 위처럼 해당 스레드가 계속 반복하도록 만든게 문제일까요?

그렇다면 매번 한프레임 한프레임을 스레드 생성하여 영상을 자르고, 회전하여 TImage에 뿌려주라고 하는게 맞는걸까요?

 

시스템 자원이 부족한 문제가 아닌데 이렇게 영상이 뚝뚝 끊어지는 이유를 더더욱 모르겠습니다;;

경험 있으신 분께 도움 요청드립니다.

델파이에서의 멀티스레드 구현 방법도 여러가지인거 같은데 어떻게 구현하는 것이 합리적인지 모르겠습니다;;

 

급해서 관련 문제를 해결하기위해 서핑을 했는데

https://tech.devgear.co.kr/index.php?mid=delphi_news&search_keyword=%EC%8A%A4%EB%A0%88%EB%93%9C&search_target=title_content&document_srl=451442

에서 소개된 AIO - Delphi 용 Coroutine 기반 멀티 스레딩 라이브러리 가 도움이 될까요?

 

번호 제목 글쓴이 날짜 조회 수
공지 [프로그래밍 강의] 2021.6~2021.12 관리자 2015.01.22 15766
공지 유용한 관련 사이트 관리자2 2014.03.20 54580
공지 본 게시판은 개발자 여러분들의 질문과 답변을 공유하는 공간입니다. 관리자 2012.01.10 97985
3179 [해결] D7에서 XE2로 패키지 컨버전시 아이콘 생성되는 문제 [5] file 한림대의료원정보기술센터 2012.07.04 9814
3178 파이어몽키 어플리케이션 폼에 컴포넌트를 올려놓아도 아무것도 안보입니다. file 하두고 2012.07.04 7624
3177 DbExpress에서 BLOB 데이터 저장 및 읽어 오기 [5] secret 마구간 2012.07.05 9
3176 Codegear C++빌더 2007에서 작업할땐 아무 에러 없던것이, XE2 로 빌드하니까 엄청난 에러가 납니다. [1] 초보개발짜 2012.07.06 10216
3175 Translation Manager [3] file 정준 2012.07.12 7863
3174 radphp를 공부해 보려고 하는데요.. [1] 태랑 2012.07.12 7437
3173 델파이 7 사용자입니다. 델파이 XE2에서 더 좋아진 점이 무엇이고, 업그레이드가 꼭 필요한지 알고 싶습니다. [2] file 관리자 2012.07.12 11507
3172 C++빌더 6 사용자입니다. C++빌더 XE2에서 더 좋아진 점이 무엇이고, 업그레이드가 꼭 필요한 이유를 알고 싶습니다 file 관리자 2012.07.12 12086
3171 RAD, 델파이, C++빌더의 에디션별 업그레이드 적용 범위를 알고 싶습니다. 관리자 2012.07.19 7717
3170 iOS 개발 관련 Free Pascal 설치 오류 file 김동환 2012.07.20 9378
3169 델파이에서 Socket ipv6 를 사용 할 수 있는 방법이 있습니까? (Delphi 2007기준) [7] 늦바람 2012.07.20 9317
3168 TImage3D를 마우스로 드레그하여 이동하고 싶은데요. 하두고 2012.07.20 8594
3167 RadPHP 평가판에서 정품으로 바꾸려는데 어떻게 하나요? 관리자 2012.07.20 7053
3166 delphi XE2 Code Editor 한글 깨짐 문제 [2] file 앙구리2 2012.07.22 15826
3165 iOS 개발을 위한 Free Pascal 설치 재 질문 합니다. 김동환 2012.07.24 9238
3164 파이어몽키에서 라인그리기는 어떻게 하나요? [1] Happycube 2012.07.24 8448
3163 Windows7 에서 관리자 권한 토마토 2012.07.25 10704
3162 컴파일관련 에러 질문입니다. [1] dk2 2012.08.02 7791
3161 요즘 델파이에서 코드 품질이나 감사(audit) 할 수 있는 기능이 있나요? 관리자 2012.08.07 7237
3160 델파이 XE 한영전환 문제 확인 해 주세요 [1] memc 2012.08.09 9880