ffmpeg는 거의 모든 코덱을 지원한다. 그래서 ffmpeg만 이용하면 별다른 프로그램을 설치하지 않아도 된다.
mp4파일을 한 프레임씩 추출하기위해서 ffmpeg의 dll파일을 이용함. 환경은 python.
python을 접해본지 얼마 되지 않아서 공부하는 셈치고 dll파일의 함수를 실행하는 기능을 이용하기로함.
일단 ffmpeg에서 디코딩하는 예제
를 보고 python으로 옮겨봄.
옮긴것을 바탕으로 작업을 하니 ffmpeg에서 처리된 데이터를 영상처리 라이브러리에 바로 쓸 수 있어서 편리함.
c언어의 함수를 python으로 호출할떄 포인터가 까다로워서 시행착오가 많았음.
c의 구조체를 python으로 바꾸면 이렇다.
//C
struct mystruct {
mydatatype *myvar;
};
#python
class mystruct(Structure):
_fields_=[
('myvar',POINTER(mydatatype))
]
일반적인 python의 클래스를 작성할떄랑은 조금 다르다. ctypes.Structure을 상속받고, _fields_안에 구조체에 있는 변수를 넣어야 한다. 이때 mydatatype를 알 수 없을때나 mydatatype을 찾아보니 엄청나게 양이 많을 때는 2가지 방법이 있다.
첫번째 방법은 POINTER(mydatatype)도 주소를 가리키는 데이터 타입이기 때문에 c_void_p로 고치면됨.
#python
class mystruct(Structure):
_fields_=[
('myvar',c_void_p)
]
두번째 방법은 mydatatype을 선언해 놓기만 하면됨.
#python
class mydatatype(Structure):
pass
class mystruct(Structure):
_fields_=[
('myvar',POINTER(mydatatype))
]
mydatatype이 라이브러리 함수 내부에서만 쓰이는 경우라면 2가지 모두 무난히 돌아간다.
mystruct사용의 차이. 구조체를 선언하고 함수에 구조체에 대한 포인터로 인자를 넘길때
//C
mystruct myvar;
argbypointer(&myvar, NULL);
#python
myvar=mystruct()
argbypointer(byref(myvar), None)
NULL을 넣어야 할때는 None으로 넣으면 됨.
그리고 dll파일이 없다고 나오는 경우나
임의의 폴더에 있는 dll파일을 쓸때는 다음과 같이
#python
os.environ['PATH']+=';'+'C:\\lib'
avcodec=WinDLL('avcodec-58.dll')
os.environ[‘PATH’]에 있는 폴더에서 dll파일을 찾기때문에 해당하는 dll파일이 있는 폴더를 추가해준다.
c의 열거형인 enum은 정수형임. c_int로 처리해도 된다.