반응형

얼마전 HEIF 변환 프로그램인 iTrans HEIF를 3.03으로 업데이트 하면서 GPAC를 다운그레이드 했었다.

 

 

정확한 원인을 찾지는 못했지만, 뭔가 변환 중에 문제가 발생하는 건 확실했기 때문이었다.

 

현상을 제대로 파악하기 위해, 시간을 들여서 mp4box를 버전별로 테스트를 해보기로 했다.

 

오류 현상 식별

 

테스트 조건과 목표는 다음과 같이 구성했다.

 

1. 아이폰으로 촬영한 HEIF 파일들을 변환하면서 문제 추적
2. 공식 사이트에서 다운받은 버전과 직접 컴파일한 버전을 모두 테스트
3. 목표는 깃헙에 공개된 릴리즈 번호를 기준으로 문제가 발생한 첫 릴리즈를 찾는 것

 

일단, 모든 mp4box가 사진들의 정보를 이상 없이 읽어냈다.

문제가 발생하는 HEIF에서도 아래와 같이 정보를 제대로 읽는다.

 

mp4box.exe -info problem1.heic
Root Meta type: "pict" - 52 resource item(s)
Primary Item - ID 49
Item #1 - ID 1 - type hvc1  - Name:
Item #2 - ID 2 - type hvc1  - Name:
Item #3 - ID 3 - type hvc1  - Name:
Item #4 - ID 4 - type hvc1  - Name:
Item #5 - ID 5 - type hvc1  - Name:
(...)
Item #47 - ID 47 - type hvc1  - Name:
Item #48 - ID 48 - type hvc1  - Name:
Item #49 - ID 49 - type grid  - Name:
Item #50 - ID 50 - type hvc1  - Name:
Item #51 - ID 51 - type Exif  - Name:
File has no movie (moov) - static data container

 

그런데, 실제로 저 파일에서 각 조각(Item)을 읽어내는 건 얘기가 다르다.

우선, 각 조각들을 읽어내는 배치 파일은 대략 아래와 같다.

 

mp4box.exe -dump-item 1:path=01.hevc problem1.heic
mp4box.exe -dump-item 2:path=02.hevc problem1.heic
mp4box.exe -dump-item 3:path=03.hevc problem1.heic
mp4box.exe -dump-item 4:path=04.hevc problem1.heic
mp4box.exe -dump-item 5:path=05.hevc problem1.heic
(...)
mp4box.exe -dump-item 44:path=44.hevc problem1.heic
mp4box.exe -dump-item 45:path=45.hevc problem1.heic
mp4box.exe -dump-item 46:path=46.hevc problem1.heic
mp4box.exe -dump-item 47:path=47.hevc problem1.heic
mp4box.exe -dump-item 48:path=48.hevc problem1.heic

 

이 배치 파일을 mp4box 버전마다 돌려서 문제가 발생하는 버전을 찾으면 되는 것이다.

문제를 일으킬 때는 대략 아래와 같은 화면을 볼 수 있다.

 

mp4box.exe -dump-item 1:path=01.hevc problem1.heic
mp4box.exe -dump-item 2:path=02.hevc problem1.heic
mp4box.exe -dump-item 3:path=03.hevc problem1.heic
mp4box.exe -dump-item 4:path=04.hevc problem1.heic
mp4box.exe -dump-item 5:path=05.hevc problem1.heic
Error writing data (Bad file descriptor): 238 blocks to write but 0 blocks written

mp4box.exe -dump-item 6:path=06.hevc problem1.heic
mp4box.exe -dump-item 7:path=07.hevc problem1.heic
mp4box.exe -dump-item 8:path=08.hevc problem1.heic
mp4box.exe -dump-item 9:path=09.hevc problem1.heic
mp4box.exe -dump-item 10:path=10.hevc problem1.heic
mp4box.exe -dump-item 11:path=11.hevc problem1.heic
Error writing data (Bad file descriptor): 235 blocks to write but 0 blocks written

mp4box.exe -dump-item 12:path=12.hevc problem1.heic
mp4box.exe -dump-item 13:path=13.hevc problem1.heic
mp4box.exe -dump-item 14:path=14.hevc problem1.heic
mp4box.exe -dump-item 15:path=15.hevc problem1.heic
Error writing data (Bad file descriptor): 260 blocks to write but 0 blocks written

(...)

 

버전별로 따라가면서 테스트해본 결과 아래와 같은 결론을 낼 수 있었다.

 

1. 3efc028(Commits on Jun 12, 2020) 및 그 이후의 버전에서 모두 동일한 문제가 발생함
2. 그 직전의 버전인 e90526f(Commits on Jun 12, 2020)과 그 이전에는 전혀 문제 없음
3. 공식 사이트에서 받은 버전과 직접 컴파일한 버전 모두 동일하게 동작함

 

원인 추적

 

문제가 발생하는 부분의 코드를 디버거로 추적해보니 의외로 오류의 1차적 원인은 쉽게 식별되었다.

meta.c 파일에서 캐쉬된 내용을 다 정리하기 전에 파일 포인터를 닫아버린 것이다.

 

if (resource) {
	gf_fclose(resource);
}
gf_bs_del(item_bs);

 

위에서 보이는 gf_bs_del()은 마지막에 쓰기 캐쉬를 정리한다.

그런데, gf_bs_del()을 수행하기 전에 gf_close(resource)에서 파일포인터를 닫은 것이다.

 

이 둘의 순서를 바꾸는 것만으로 위에서 언급한 문제는 해결이 가능한 것 같다.

 

하지만, 이게 근본적인 해결책인지도 알 수 없고, 이로 인한 부작용이 어떻게 발생할 지도 알 수 없다.

 

GitHub에 이슈 제기

 

여기까지 추적한 뒤, 내가 할만한 작업은 다 한 것으로 판단하고, GitHub에 정식으로 이슈를 제기했다.

 

부디 이 문제가 빨리 해결되기를.

 


 

문제 해결

 

이슈를 제기한지 하루만에 문제가 수정되었다. 내가 생각한 수정안은 일단 맞았던 것 같고, 한 군데 더 수정되었다.

 

 

반응형

공유하기

facebook twitter kakaoTalk kakaostory naver band