2014년 2월 12일 수요일

ffmpeg av_lockmgr_register 사용법

ffmpeg의 thread-safe 하지않은 함수들 - av_register_all, avcodec_open2, avcodec_close
등의 함수들은 보통 호출부에 뮤텍스 락을 걸어주어야 하는데 av_lockmgr_register 함수를
이용하면 이것을 간단하게 해결할 수 있다.

#include <windows.h>
extern "C" {
#include "libavformat/avformat.h"
}

static bool isInit = false;
static HANDLE hMutex = CreateMutex(NULL, FALSE, NULL);

static int lockmgr(void **mtx, enum AVLockOp op)
{
   switch(op) {
      case AV_LOCK_CREATE:
          *mtx = CreateMutex(0, FALSE, 0);
          if(!*mtx)
              return 1;
          return 0;
      case AV_LOCK_OBTAIN:
          return !!WaitForSingleObject(*mtx, INFINITE);
      case AV_LOCK_RELEASE:
          return !!ReleaseMutex(*mtx);
      case AV_LOCK_DESTROY:
          CloseHandle(*mtx);
          return 0;
   }
   return 1;
}

void InitFFmpegLib()
{
WaitForSingleObject(hMutex, INFINITE);

if (!isInit) {
av_register_all();

if (av_lockmgr_register(lockmgr)) {
printf("Could not initialize lock manager!\n");
exit(1);
}
isInit = true;
}

ReleaseMutex(hMutex);
}

프로그램 시작부분에서 InitFFmpegLib() 함수를 호출하면 그 다음부터 thread-unsafe 한
ffmpeg api 함수들은 자동으로 뮤텍스 락을 건다.

댓글 10개:

  1. 한가지 질문이 있어 댓글에 올립니다.
    sw_scale를 이용하여 color convert 및 resize 시간을 계산하기 위해서 우연히 시간을 측정해봤는데. 이상한 결과가 있어서 질문합니다. 1. YUV420P 영상을 디코딩 후 color convert를 하지 않을 때와 YUYV422로 변환할 때는 확실히 속도차이가 납니다. 당연히 color convert를 하지 않을 때가 우세하였습니다. 2. 1080P를 1/2로 리사이즈하고 color convrt 할때 차이는 다소 다릅니다. 당연히 1번과 같이 color convert를 하지 때와 같은 결과가 나와야 하는데..매번 다르게 나오고 있습니다. 혹시나 해서 ffmpeg 자체에서 스레드를 사용하기 때문에 속도 차이가 나는지...아니면 다른 이유인지 잘 모르겠습니다. 답변 부탁드립니다.

    답글삭제
  2. 1080P를 1/2로 리사이즈한다고 했는데 어떻게 했는지 모르지만 거기에 답이 있을거 같습니다. 스케일러는 포멧변환보다 스케일링에 성능을 훨씬 더 많이 사용합니다. 그리고 ffmpeg 쓰레드 사용은 제 경험상 멀티코어 환경하에서는 성능에 별 영향을 안줍니다.

    답글삭제
  3. 답변감사합니다. 혹시 ffmpeg 빌드할때 --enable-win32thred 사용할 때와 사용하지 않을때(--disable-win32thread)는 차이가 많은지요? 제가 봐서는 한채널만 디코딩하면 성능 차이가 날것 같은데 여러채널을 디코딩하면 별 차이가 없어 보입니다. 제 생각이 잘못되었나요^^

    답글삭제
  4. 두 옵션 모두 다 해봤는데 성능차이는 없습니다. cpu사용률 그래프의 위아래 움직임이 서로 다른 경우가 있어서 착각을 하기쉬운데 결론적으로 최종 처리가능한 채널은 항상 동일합니다. 참고로 ffmpeg 빌드는 static library보다 dll 로 사용하는것이 용량도 훨씬 적고 편리합니다.

    답글삭제
  5. 답변감사합니다. sw_scale()함수를 사용하여 리사이즈(1/2) 및 color convert(YUV420->YUV422)와 color convert없이 리사이즈만 하였을 경우 매 프레임에 대한 속도를 출력해 봤습니다. 이론적으로 보면 color convert없이 리사이즈만 하였을 경우 속도가 우위에 있을 것 같은데 500번 프레임부터 속도가 달리나와서 이것을 어떻게 이해를 해야할지 대략 난감합니다. 혹시 제가 잘못 출력했을까요? ㅎㅎㅎ

    답글삭제
  6. 저도 이해가 않가네요.. 리사이징은 프레임 크기가 같을때 매 프레임 동일해야할것 같은데요. 그리고 컬러컨버트는 스케일링과 마찬가지로 어셈블리로 작성되고 cpu의 SIMD 명령으로 처리가 되기때문에 처리속도는 빠릅니다. 실제성능은 스케일링에서 다 먹어요..

    답글삭제
  7. 답변감사합니다. 제가 디버깅모드로 출력하다 보니 속도 차이가 났습니다. 지송...

    답글삭제
  8. 주인장님! 혹시 1080P을 1초에 480프레임을 디코딩할려고 하는데 방법이 있을까요? 너무 난해한 질문을 했나요? ㅎㅎㅎ, ffmeg을 이용하여 1080P를 디코딩하였을 때 평균적으로 0.011~0.012sec 걸리더라구요.

    답글삭제
  9. 제가 테스트한 컴환경은 i5-2400입니다.

    답글삭제
  10. ffmpeg 성능은 테스트 영상 같은걸로 돌려보면 결과를 바로 알 수 있습니다.

    답글삭제