OSS (open sound system) 드라이버 때문에 신입의 한숨이 늘어갑니다..

yakur의 이미지

안녕하세요? 저는 올해 1월에 임베디드 솔루션 회사에 입사했습니다. 원래 VOIP 영상전화기 회사인데...
영업쪽에서 우리 기기에 동영상 재생 가능 여부를 물어와서.. 저에게 포팅을 지시하시더군요..
mplayer 나 vlc 등등으로 해보라 하던데...
우리 기기는 davinci dm6446 입니다. arm코어는 arm926ej-s 지요...
davinci의 DSP 코덱 기능을 쓰는게 아니라 순수 ARM power 로 하라고 하던데.. (DSP코덱은 돈주고 또 사야되니까요)

솔직히 arm 코어에 mplayer 나 vlc 올리는거야... 자료도 많더군요.. 다만 우리 기기만의 문제가 있어 죽겠습니다.

맨처음 mplayer 최신버전을 크로스 컴파일 하려니...하다가 ffmpeg(libavcodec) 컴파일 부분중
플랫폼을 arm 선택하면 arm용 어셈블러 코드를 컴파일 하다가 .eabi attribute 가 인식불가라면서 컴파일 에러...
제가 알기로 현재 우리 TI 다빈치 CDK 에 컴파일러인 arm_v5t_le-gcc 는 eabi 지원이 안되는걸로... 해서 좌절입니다.
그래서 5년전 버전인 mplayer 1.0pre7try2 로 해보니 이건 다행이 ffmpeg 부분(libavcodec)이 어셈블 코드가 없어서 컴파일은 잘됐고
영상도 잘나오는데 다만 -_- 사운드(OSS)에서 딜레이가 생겨서 동시에 비디오도 사운드와 sync 되기 때문에 버버벅 대더군요...
물론 nosound로 하면 비디오는 잘나옵니다. 프레임 정확히...
알고 보니 mplayer 소스에서 oss 제어하는 부분에 ioctl 로 SND_CTL_GETODELAY 라는 넘이 OSS 우리기기 사운드 드라이버에 정의되지 않았더군요.
값을 못얻어 옵니다...
개발자 문서를 더 찾아보니 사운드카드마다 기본적인 딜레이가 3~7초 정도 있어서 그걸 잡아 오는거라더군요.. 실시간 연산해서...
-_-;;
드라이버에 구현이 안되있으니 방법이 없고 막상 구현이 될까 하면서 봤더니 참고할 다른 사운드카드 OSS드라이버 안에 구현된 GETODELAY가 아닌게 아니라
하드웨어 별로 다 코드가 지각각 다르더군요...

GG 치고 vlc 로 해야봐야겠다 생각하고 vlc oss 컨트롤 부분을 보니 다행히 GETODELAY가 없더군요 잘됐다 싶어서 이리저리 에러 뿜는거 잡다가...
거의 컴파일 중반 넘어가서 에러 뿜는걸 찾아보니...

우리 TI davinci CDK 의 컴파일러가 버전이 낮아서 나온 에러더군요...제가 해결할수 있는것도 아니고
회사에서 2천달러 짜리 새 버전의 CDK를 사줄진 모르겠고...(아마 안될듯)
참고로 현재 회사에서 쓰는 버전은 2005년도 버전입니다... -_-;;
게다가 범용 ARM 툴체인을 받아다 새로 컴파일 해서 해보자니...
기존 glibc 나 커널까지 몽땅 재 컴파일 해야되는데 중간에 에러는 ...어떻게 할지
알고보니 컴파일러를 바꾸자면 타겟보드 파일시스템 대부분을 ... 갈아치우게 된다는....생각이 들더군요...

이래저래 방법도 없고...혹시 OSS 드라이버 구현 할줄 아시는 분이 계신다면 팁이라도 주셨으면 좋겠습니다.
아니면... davinci dm6446 에서 동영상 플레이어 포팅 해보신분이라도...

밤새서 해결된다면 밤이라도 새고 싶은데요.. 그런 문제도 아니고 신입한테 빡신걸 준게 아닌가 하네요 ㅠㅠ 에효

tj의 이미지

버퍼 포인터와 현재 재생 중인 시점 차이를 알아야 A-V sync를 할 수 있고, OSS에선 이걸 얻어올 수 있는 방법이 GETODELAY아니면 GETOPTR이구요. 둘 중 하나는 구현하셔야됩니다. 이거 없이는 vlc 할애비도 A-V sync 맞춰서 동영상 재생 못해요. 드라이버 소스만 열심히 쳐다보셔도 어떻게 구현해야할진 대충 아실 수 있을겁니다. 둘 중 하나만 구현돼있으면 나머지 하나는 그냥 계산해서 구현하면 있구요.

yakur의 이미지

제가 능력이 모잘라서인지 밤새 후벼 봤는데-_- 영 감이 안잡히네요...
좀더 힌트를 더 주시면 안될까요?
GETOPTR은 찾았는데 이걸로 GETODELAY를 어떻게 만들지 모르겠군요. ㅡ.,ㅡ
----------------------
이제와 항상 영원히~

이제와 항상 영원히~

feanor의 이미지

맨 처음에 .eabi_attribute에서 컴파일 에러가 났다고 하셨는데, EABI를 쓰지 않는다면 그냥 해당 부분을 삭제하시면 됩니다. (어셈 코드에서 8바이트 스택 alignment를 맞추기 위해 쓰는 것인데 EABI가 아니면 8바이트 스택 alignment를 맞추지 않아도 되므로 무시하면 됩니다.)

yakur의 이미지

그런데.. 제가 OSS가 처음이라 GETOPTR에서 GETODELAY 값 계산하는게 문제네요...
OSS 쪽은 구글신도 별로 답이 많지 않더군요..
실마리는 잡았는데 삽질해야되는데...

혹시 자세한 코드는 무리겠지만 대충 GETOPTR에서 GETODELAY를 계산하는 방법에 대한 개괄적인 내용이라도 알수 있을까요? 관련자료 링크나요...
일단 OSS사이트부터 다시 뒤져보겠습니다만...

오늘 밤새서라도 해놔야겠네요... 도전!

아~ 그리고 답변 감사합니다... ㅎ 정말 감사해요

eabi 답변도 감사합니다.. 이번에 일하면서 eabi 라는걸 첨 알아서 아직 알딸딸하네요 더 파야될듯하네요.
-------------------------------
이제와 항상 영원히~

이제와 항상 영원히~

tj의 이미지

작년에 본거라 이제 기억이 정확하진 않은데요. bitrate과 채널 수를 알면 초당 몇 바이트 먹는지 알 수 있구요, OPTR에서 현재 버퍼에 몇바이트 남아있는 지 알 수 있으니까, 바이트수 * 1000000 / 초당바이트 해서 돌려주면 될거에요 (단위가 usec이었던 거 같은데 하여간 이런 식).

bus710의 이미지

근데 솔직히
영상 전화기까지 제 방에서 소리를 내면 창문 밖으로 던져 버리고 싶어질 겁니다.

영업팀에서야 기능 더 넣으면 잘 팔릴 것 같으니까 넣자는 거겠지만,
집에서 컴퓨터로 음악 듣는 것과 핸드폰 벨소리 울리는 거 외에 다른 소리 나는 뭔가가 있길 바라는 사람이 있나요?

============================================

life is only one time

yakur의 이미지

시키니 하는것일뿐.....흐흑
------------------------
이제와 항상 영원히~

이제와 항상 영원히~

bus710의 이미지

흐흐흑

============================================

life is only one time

yakur의 이미지

Mplayer 에 AV sync 를 위해서 1초에 40번정도 딜레이 값 리턴하는 함수를 돌리는데요(mplayer 내부 함수)
거기서 다음과 같이 세가지 방법으로 구하네요.
1) SNDCTL_DSP_GETODELAY 기본 디폴트 방법
return ((float)[GETODELAY 리턴값])/(float)ao_data.bps;

2) SNDCTL_DSP_GETOSPACE
return ((float)(ao_data.buffersize-[GETOSPACE 리턴값]))/(float)ao_data.bps;

3) return ((float)ao_data.buffersize)/(float)ao_data.bps;
드라이버에 접근안하고 내부값으로만 연산!

요 세가지 방법으로 하게 되어있네요. GETODELAY가 안되서 차선책으로 2번 3번 방법을 써도 딜레이가 생기는건...
혹시나 하는 생각입니다만 이게 보드에서만 딜레이 생깁니다.
일반 PC에서는 세가지중 어떤 방법으로 딜레이값을 구하게 해도 전혀 오디오가 버벅거리지 않고 재생이 잘되거든요.

대략 제가 PRINTF 같은걸로 디버그를 찍어보니 초당 40번 floating 나누기 연산을 하는데요.

혹시 보드에서는 저런 연산이 ARM CPU에 부하를 줘서 3가지중 어떤방법을 취해도 동일하게 딜레이가 나는게 아닐까 가정해봤는데...

의견들이 어떠신지 궁금합니다...

참고로 현재 비디오를 제외하고 mp3 만으로 계속 테스트중입니다. 비디오만 재생할때는 전혀 문제가 없어서요.

------------------------------
이제와 항상 영원히~

이제와 항상 영원히~

tj의 이미지

사운드 플레이할 때 사운드 칩이 보는 하드웨어/드라이버 버퍼가 있고, 응용프로그램에서 디코딩해서 두는 버퍼가 있구요. 1)의 ODELAY/OPTR은 드라이버에 "내가 지금 write를 하면 얼마나 있다가 소리가 나오는거야?"라고 물어보는 거고, 2)의 OSPACE는 하드웨어/드라이버 버퍼에 쓸 공간이 얼마나 남았는지, 3)은 응용프로그램 버퍼의 딜레이만 계산하는건데, 3)은 하드웨어 버퍼의 딜레이는 무시하는 거고, 2)는 드라이버와 하드웨어의 구현에 따라 거의 맞을 수도 있지만 더 늦거나 덩어리로 업데이트되도 상관없는 거라서, 제대로 하려면 OPTR/ODELAY로 해야해요.

madman93의 이미지

좀 힘든일을 하시는 군요!!
mplayer ao (audio output) 이 oss만 있는건 아닌데..
oss만 하시는 이유는 oss만 지원가능해서 입니까?
oss가 무난하긴 하지만요

AV sync를 맞출려고 버벅 거리는 건가요?

그러면 AV를 따로 싱크를 안 맞추고 돌리면 버벅 거리지는 않는다는거죠?

---------------------------------------------
git init
git add .
git commit -am "project init"
---------------------------------------------

---------------------------------------------
git init
git add .
git commit -am "project init"
---------------------------------------------

yakur의 이미지

현재 우리 보드에서 OSS 드라이버로만 사운드 드라이버가 되어있구요.
alsa는 드라이버가 없습니다.

싱크문제는요 비디오 없이 mp3만 재생해도 기본적으로 사운드카드 드라이버에 DELAY를 물어보기 때문에 생기구요...
그리고 싱크는 기본적으로 맞추게 되어있더라고요... Mplayer 소스를 수정하면 모르겠지만...
근데 결국 싱크가 맞아야 정상이니... 어쩔수가 없지요.

---------------------
이제와 항상 영원히~

이제와 항상 영원히~

bushi의 이미지

arm926ej-s 만 활용하실거면 codesourcery.com 에서 lite 버전 다운받아 사용하시면 컴파일러 걱정은 잠시 잊으셔도 되고요.

OPTR 이건 ODELAY 이건... 드라이버내에 잡아놓은 버퍼 중에 현재 사용중인 버퍼, 다시말해 전송대기 중인 버퍼를 알아내면 됩니다.
OPTR 은 위치를, ODELAY 는 크기를 돌려주죠.
나머진 어플리케이션 쪽에서 sampling rate, bits per sample, channels 를 바탕으로 스스로 계산(해야)합니다.
OTPR 은 mmap() 을 사용해서 연주하는 놈들, 주로 오디오 서버처럼 여러 음원을 믹싱해야 하는 놈들이나 게임 처럼 비디오에 오디오를 싱크시켜야하는 놈들이 사용하고,
ODELAY 는 write() 를 사용해서 연주하는 놈들이 사용하기에 부족함이 없습니다.

ALSA 가 대인배 기질이 있어 여러모로 편한데, mixer, 그러니까 코덱 칩 내부의 power(path) 제어부분을 만들어주기가 좀 어지럽죠.
그래도... OSS 드라이버가 있다면 ALSA 로 바꾸기가 그리 힘들진 않은데요.
애초에 바닥부터 작성할 때도 OSS 보단 ALSA 가 쉽고요. 대인배 대인배...

voip 영상전화기에 사용할 목적의 솔루션이 아니라 부가기능의 일부로 사용할 미디어플레이어 등을 염두에 둔 선행개발인가요 ?

OTL

yakur의 이미지

테스트 목적이에요... 동영상 원활히 재생가능한가? 어떤 코덱이 적절한가? 우리기기에 맞는 인코딩 스펙은 어떤가?
뭐 이런거...

-------------------
이제와 항상 영원히~

이제와 항상 영원히~

김정균의 이미지

흠.. mplayer가 GPL이고, oss도 gpl일것 같은데, 수정 사항에 대한 공개를 염두에 두시고 작업을 하셔야 할 듯 싶습니다만.. 도움이 안되고 골치거리만 드려서 죄송합니다. :-)

yakur의 이미지

우선 지금까지 답해주신 분들께 정말 감사드립니다. 아직 확실하게 수정은 못하고 있지만 어느정도 감은 잡힌거 같네요. ㅎ

그리고 정균님이 언급하신 GPL 문제는 뭐 OSS 사운드 드라이버는 상업용이라 GPL 아니구요. OSS가 아니라 해당 하드웨어 드라이버만 작업하려는거구요.
mplayer 는 그냥 우리 기기에 대한 동영상 재생 가능 여부를 알아보기 위해 올린거라서요.

상업용 판매하고는 거의 무관할듯합니다. 외부 의뢰가 영업쪽으로 들어와서 우리 조건상 가능한지 판단하려고 한거기 때문에...
----------------------
이제와 항상 영원히~

이제와 항상 영원히~