2016년 3월 11일 금요일

Gear VR 로 TV 보기 - 5편 (libhdhomerun 을 안드로이드 세상으로~)

 이제 TV 를 full screen 으로 볼 수 있게 되긴 했는데, 아직 hdhomern SDK 와 통합 하지 않았기 때문에 채널을 설정하고 방송을 시작하려면 Ubuntu 나 다른 PC (혹은 라즈베리) 에서 hdhomerun_config 툴로 세팅을 해 줘야 하는 불편함이 남아 있었다.

그렇다면 libhdhomerun 을 android 로 땡겨 와야 한다는 얘긴데... 이걸 어떻게 하지??? 라고 생각하다가 문득 cerbero 가 생각이 났다. 이미 gstreamer 를 포함해서 상당량의 C library 들이 cerbero 를 통해서 android 로 들어왔지 않은가!
그래서 reynaldo 의 6 easy step 에서 대충 흘려 보냈던 cerbero 를 꼼꼼히 뜯어 보기 시작했다.

그런데.. README 파일 말고는 딱히 참고할 site 를 찾을 수가 없다. 어딘가에 공식 홈페이지가 있을 법도 한데 (내 검색 실력이 그렇지 나쁘지는 않은 것 같은데) 안보인다. ㅠㅜ
결국엔 직접 해 보고 이해한 내용을 주관적으로 적을 수 밖에 없다는 결론에 이르렀고 차후에 공식 site 를 찾게 되면 좀 더 보충을 하기로 한다.

그럼 시작,
우선 directory tree 를 살펴 보면 이정도로 이해가 될 것 같다.
.
├── cerbero (python 빌드 스크립트)
├── config (platform 에 따라 설정된 configuration 파일 e.g: android, window, ios, etc)
├── data (platform 별로 사용되는 build tools)
├── packages (패키지 빌드 스크립트)
├── recipes (패키지를 어떻게 요리할지 레시피)
├── test (self 테스트 스크립트)
└── tools (빌드 중 chroot 를 한다가나 할때 필요한 툴들)

여기서 핵심은 recipe 와 package 인데 어떤 library 를 갖고 오고 싶으면 recipe 를 만들고 그 안에 패키지들을 기술하면 빌드가 시작할 때 원격으로 소스를 다운로드 하여 clean room 빌드를 한다. 뭔가 dbuild 같기도 하고 예전 open embedded 같기도 하면서...
여튼 전형적인 clean room 멀티 패키징 빌드 시스템이라고 이해하면 쉽겠다.
느껴지는 차이점은 최종 결과물이 특정 패키징이 아니라 rootstrap 을 archive 한 tar 파일로 나오는 정도?

그 tar 파일을 특정 path 에 풀어 놓으면 ndk-build 할 때 include 하거나 link 할 수 있게 된다.
apk 패키징 할 때 copy 해 와서 사용 되기도 한다. 막상 보니 깔끔하고 쓸만한 것 같다.

그렇다면 새로운 libary 는 어떻게 추가 할까?

1. 빌들 할 platform 에 따라 config 를 선택한다.

 - android 용으로 할거니까 config/cross-android.cbc 를 사용한다.


2. library 의 recipe 를 추가 한다.

 - 처음에는 그냥 manual 하게 기존 recipe 를 복사해서 막무가내로 만들었는데, 알고 보니
  add-recipe 라는 명령어가 있었다. (무식하면 몸이 고생이라는 말이...)

 - 그럼 smart~ 하게 command 로 추가 해 보자
 $ ./cerbero-uninstalled  add-recipe -f -l LGPL-2.1 -c config/cross-android.cbc -o git://anonscm.debian.org/collab-maint/libhdhomerun.git hdhomerun 1.0

 그런데.. 이 커맨드가 만능은 아니고 딱 옵션에 있는 내용만 추가해 주기 때문에 좀 더 보충해  줄 필요가 있다. 내가 추가로 작성한 내용은 아래와 같다.
    commit = 'origin/master'
    files_bins = ['hdhomerun_config']
    files_libs = ['libhdhomerun']
    files_devel = [
            'include/libhdhomerun/hdhomerun_device_selector.h',
            'include/libhdhomerun/hdhomerun_pkt.h',
            'include/libhdhomerun/hdhomerun_control.h',
            'include/libhdhomerun/hdhomerun_device.h',
            'include/libhdhomerun/hdhomerun_os.h',
            'include/libhdhomerun/hdhomerun_channels.h',
            'include/libhdhomerun/hdhomerun_os_windows.h',
            'include/libhdhomerun/hdhomerun_discover.h',
            'include/libhdhomerun/hdhomerun.h',
            'include/libhdhomerun/hdhomerun_channelscan.h',
            'include/libhdhomerun/hdhomerun_video.h',
            'include/libhdhomerun/hdhomerun_os_posix.h',
            'include/libhdhomerun/hdhomerun_types.h',
            'include/libhdhomerun/hdhomerun_sock.h',
            'include/libhdhomerun/hdhomerun_debug.h'
    ]
    def prepare(self):
        self.append_env['CFLAGS'] = " -Wall -O2 -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wpointer-arith "

3. 상세 package 를 기술 한다.

 - recipe 는 말 그대로 어떻게 요리 할지 대략적인 설명이고 좀더 상세하게 기술 하려면 package/hdhomerun.package 파일을 만들어 줘야 한다.

# -*- Mode: Python -*- vi:si:et:sw=4:sts=4:ts=4:syntax=python

class SDKPackage(package.SDKPackage):
    name = "Hdhomerun"
    shortdesc = "Hdhomerun 1.0"
    longdesc = "Hdhomerun 1.0"
    title = "Hdhomerun 1.0"
    url = "http://example.org"
    version = '1.0'
    sdk_version = '1.0'
    codename = 'baseball'
    license = License.LGPL
    uuid = 'b1b4b812-0d09-4a34-8117-8a69b6deecc2'
    vendor = "My Hobby"
    org = "org.example.hdhomerun"
    ignore_package_prefix = True
    packages =[
               # (name, required, selected)
               ('hdhomerun-1.0-core', True, True)
              ]
    install_dir = {
        Platform.LINUX: '/opt/hdhomerun/'}
    root_env_var = 'hdhomerun_1_0_ROOT_%(arch)s'
 위 파일은 간단히 작성한 예제 이기 때문에 기호에 따라 수정해 가면서 사용해야 한다.
 packages 필드를 보면 이해가 되겠지만 hdhomerun.package 는 대표 패키지 파일이고 sub packages 를 기술해서 include 할 수 있다.

 내 경우에는 gstreamer 스타일로 core 패키지 하나를 만들고 이렇게 작성 해 줬다.
# vi:si:et:sw=4:sts=4:ts=4:syntax=python
# -*- Mode: Python -*-

class Package(package.Package):
    name = 'Hdhomerun-1.0-core'
    shortdesc = 'Hdhomerun 1.0 core'
    longdesc = 'Hdhomerun 1.0 core'
    url = "http://example.org"
    version = '1.0'
    codename = 'baseball'
    license = License.LGPL
    vendor = 'Hdhomerun Project'
    org = 'org.example.hdhomerun'
    uuid = '09626750-e8b7-4e40-944d-98b67ed0c6bf'
  다시 한번 말하지만 위 recipe 나 package 파일은 개인적으로 사용하기 위해 모든 문법을 맞추지는 않았기 때문에 배포용이 아니다.

4. 빌드 한다.

 - 여기 까지 했다면 package 명령을 통해서 빌드 할 수 있다.

  $ ./cerbero-uninstalled -c config/cross-android.cbc package hdhomerun

5. JNI 에서 사용한다.

 - 빌드된 library 파일을 특정 경로에 풀어 놓고 환경 변수를 추가 해 준다.

  $ export HDHOMERUN_ROOT_ANDROID=/home/gouache/hobby/hdhomerun

 이제 할 건 다 했다. 사용하고자 하는 Android.mk 파일에 위 환경 변수를 사용해서 추가해 준다.
HDHOMERUN_ROOT        := $(HDHOMERUN_ROOT_ANDROID)
include $(CLEAR_VARS)
LOCAL_MODULE := hdhomerun
LOCAL_SRC_FILES := $(HDHOMERUN_ROOT)/lib/libhdhomerun.so
include $(PREBUILT_SHARED_LIBRARY)
 와우! 이제 libhdhomerun 을 안드로이드에서 사용할 수 있다.

다음에는 libhdhomerun 을 사용해서 HDHomerun 을 control 해 보기로....

댓글 없음: