Yuvist 0.9.0 을 공개합니다.


Kivy framework을 사용한 YUV viewer 입니다.

4:0:0, 4:2:0, 4:2:2, 4:4:4 format을 지원하며

fragment shader를 사용하여 YUV to RGB conversion을 하므로 성능이 낮은 CPU에서도 잘 돕니다.




github에서 yuvist-release.zip을 다운받고 bin 디렉토리에서

윈도우이면 yuvist-0.9.0.zip을 맥이면 yuvist-0.9.0.dmg를 푸시면 됩니다.


소스코드는 https://github.com/luuvish/yuvist에 있습니다.

Posted by luuvish
문제의 발단은 이렇습니다.

1) 웹브라우저가 다음과 같이 요청.
GET http://www.any-domain.com/any-route/

2) http://www.any-domain.com/ 웹서버가 자동으로 /any-route/ 뒤에 index.html 을 추가하고 응답.
RES /any-route/index.html

3) 웹브라우저가 index.html 안에 포함된 <script src="scripts/any-script.js"> 를 보고 
any-script.js 요청.
GET http://www.any-domain.com/any-route/scripts/any-script.js

4) http://www.any-domain.com/ 웹서버가 /any-route/scripts/any-script.js 를 응답.
RES /any-route/scripts/any-script.js

5) 웹브라우저가 다음과 같이 요청.
GET http://www.any-domain.com/any-route

6) http://www.any-domain.com/ 웹서버가 자동으로 /any-route 뒤에 /index.html 을 추가하고 응답.
RES /any-route/index.html

7) 웹브라우저가 index.html 안에 포함된 <script src="scripts/
any-script.js"> 를 보고 요청.
GET http://www.any-domain.com/script/
any-script.js

8)
 http://www.any-domain.com/ 웹서버가 /scripts/any-script.js 를 찾을 수 없으므로 404 에러 발생.
RES /scripts/any-script.js - Error 404

즉, 문제는 /any-route 뒤에 / 가 붙지 않았을 때 index.html 은 응답하는데 scripts/any-script.js 는 경로가 /any-route 아래가 아닌 / 로 웹브라우저가 인식하는 것입니다.
생각해 보면 당연한 것일 수도 있는데, 웹브라우저는 any-route 가 실제로 파일인지 directory 인지 알지 못합니다. 설사 알고 요청한 것 일지라도 웹서버의 실제 내용은 아닐 수 있습니다. 그래서 웹브라우저가 /any-route 를 요구했을 때, 웹서버가 index.html 을 보내주어도 웹브라우저는 index.html 이 아니라 /any-route 라는 / 밑의 any-route 라는 파일을 받은 줄 압니다. any-route 의 경로가 / 에 있으므로 script/any-script.js 도 / 에 위치한 줄 알고 웹브라우저는 /script/any-script.js 을 요구하게 됩니다.

이 문제를 해결하는 가장 쉬운 방법은 redirect 로 다시 / 가 뒤에 붙은 url 을 돌려 주는 것입니다.
즉, /any-route 을 요구 받으면 웹서버가 우선 any-route 가 파일인지 디렉토리인지 판단한 후 디텍토리이면 /any-route/ 로 redirect 시키면 됩니다. 그러면 웹브라우저는 /any-route/ 로 다시 요청하면 되죠. 사실, connect.js 의 static middleware 는 기본 설정이 이런 동작을 하도록 되어 있습니다.

var connect = require('connect');
var server = connect.createServer()
  .use(connect.static(__dirname))
  .listen(80, 'www.any-domain.com');

> node server.js

node로 실행하면 server.js 가 실행된 위치에서 ./any-route/index.html 과 ./any-route/scripts/any-script.js 가 잘 읽히는 것을 알 수 있습니다. server.js 가 /any-route 를 요구 받았을 때, connect.static 에서 /any-route/ 로 redirect 시키기 때문에 자연스럽게 위의 문제가 해결됩니다.

그런데!!!

사실 위의 코드는 좀 문제가 있습니다. 불필요하게 외부에 server.js 와 같은 위치의 파일들이 노출되어 버리죠. http://www.any-domain.com/server.js 도 외부에서 볼 수 있습니다. 따라서 다음과 같이 고치는 것이 바람직 합니다.

var connect = require('connect');
var server = connect.createServer()
  .use('/any-route', connect.static(__dirname + '/public'))
  .listen(80, 'www.any-domain.com');

> node server.js

server.js 와 같은 위치에 있는 ./any-route/index.html 과 ./any-route/scripts/any-script.js 는 ./public/index.html 과 ./public/scripts/any-script.js 로 이동시킵니다.
server.use()의 첫번째 파라메터는 요청된 URL의 path 가 일치할 때 두번째 파라메터인 핸들을 수행하도록 합니다. 위와 같이 설정하면 /any-route 로 시작하는 URL의 request는 /any-route 가 제거된 URL이 __dirname + '/public' 에 위치한 파일들과 매치됩니다. 복작하게 router 와 app.get() 으로 패턴매칭하지 않아도 손쉽게 경로를 바꿀 수 있습니다.

그러나!!!

위의 수정된 코드는 이전의 경로 문제는 깔끔하게 해결했지만 처음에 언급했던 / 의 redirect 문제를 발생시킵니다. connect.static 에서 잘 처리되었던 redirect 이 왜 이 경우에는 동작하지 않는지 당황스럽죠.

문제는 connect.static 은 root 에 대해서는 redirect 를 하지 않기 때문에 발생합니다.
use()의 첫번째 파라메터로 넘겨준 route path 가 매치되면 connect.static 은 그 이후의 URL 경로부터 검색을 시작하는데 URL 경로가 더 이상 없으면 (정확히 /any-route 이면) 자동으로 / 를 URL path 로 지정합니다. 그리고 path 가 / 로 끝나므로 index.html 을 추가하고 index.html 을 응답으로 보내 버립니다.
만약 /any-route/scripts 와 같은 URL 경로가 왔다면, connect.static 은 /scripts 를 URL path 로 인식하고 /scripts 가 디렉토리인 것을 확인 한 후 /scripts/ 로 redirect 했을 것입니다. 오직 route path 가 정확히 일치할 때만 redirect 하지 않습니다.
/ 가 route path 였으면 redirect 를 하지 않아도 별 문제는 없었겠죠. 하지만, 일단 route path 가 / 이외의 path 로 설정되었을 때 index.html 안의 모든 상대 경로는 index.html 의 위치가 아닌 index.html 의 상위 디렉토리로 어긋나 버립니다.

이 모든 것을 무시하고 동작시키는 방법은 있죠.
index.html 안의 <script src="scripts/any-script.js"> 를 <script src="/any-route/scripts/any-script.js"> 처럼 절대 경로로 지정하면 됩니다. 동작은 하긴 하는데, 개발 중에 route path 가 변경되거나 웹서버를 다른 경로에 설치하면 모든 html 의 경로명을 수정해야 합니다. 단순히 노가다를 하는 것이 나쁘다는 것이 아니라 설치와 유지 보수가 어려워지므로 절대로 피해야 할 방법입니다.

connect.static 의 버그이긴 한데 우선 다른 방법으로 수정해 보지요.

var connect = require('connect');
var server = connect.createServer()
  .use(function(req, res, next) {
    if (/^\/any-route$/.test(req.url)) {
      res.statusCode = 301;
      res.setHeader('Location', req.url + '/');
      res.end('Redirecting to ' + req.url + '/');
      return;
    }
    next();
  }) 
  .use('/any-route', connect.static(__dirname + '/public'))
  .listen(80, 'www.any-domain.com');

> node server.js

req.url 을 normalize 하지 않고 단순히 test 하는게 좀 불안하긴 하지만 우선은 동작합니다.
connect.static 이 정식으로 패치되기 전에는 이런식으로 사용해도 무난할 듯 합니다.
 
Posted by luuvish
 AVPlayer와 ffmpeg 모두 열심히 개발하면서 버전이 올라가는 바람에 4월에 올렸던 내용이 어긋나면서 컴파일이 안되고 있었습니다. 주로 arm assembly code 관련된 문제가 많았고, gas-preprocessor.pl 의 매크로 지원 문제라서 받아서 컴파일하는 입장에서는 문제가 생길 때마다 매번 대응하기 곤란했습니다. 매번 git 에 코드가 올라올 때마다 확인할 수도 없는 노릇이어서 이번에는 아예 AVPlayer 소스안에 들어있는 ffmpeg code에 맞추어서 컴파일하도록 했습니다.
 AVPlayer.zip 에 libs/FFmpeg 에 비교적 최근(아마도?) 소스가 들어있으므로 매번 git 에서 clone 할 필요없이 주어진 것으로 컴파일하기로 했습니다. 당장 최신 ffmpeg 의 기능이 필요하지 않다면 상관없을 듯 합니다. 그리고 universal library에 i386의 library는 제외시켰습니다. yasm을 설치하고 이전 스크립트로 컴파일해도 되지만 어차피 AVPlayer에 링크될 때 simulator 용을 만들 수 없으므로 컴파일할 필요는 없습니다. ffmpeg library 자체에 흥미있으신 분들은 이전 글을 참고해서 컴파일해 보시면 될 듯 합니다. 좀 무책임한 선택이지만 매번 버전 차이 때문에 이 글을 업데이트하는 일은 없었으면 하는 바람입니다.


준비물

FFmpeg library만들기
 
  • AVPlayerDist143.zip을 작업할 폴더에 풉니다.
  • __MACOSX 폴더는 지워도 됩니다.
  • https://github.com/yuvi/gas-preprocessor 에서 gas-preprocessor.pl을 가져와 /usr/local/bin으로 복사합니다.
  • AVPlayer 안에 libs 디렉토리로 이동합니다. (cd libs)
  • libs 안에 ffmpeg-armv6, ffmpeg-armv7 디렉토리를 만듭니다. (mkdir ffmpeg-armv6 ffmpeg-armv7)
  • build-armv6 파일을 열어 15번째 줄에서 CONFIGURE_OPTIONS=" ... " 안에 --disable-doc 을 추가합니다.
  • build-armv6 파일의 30번째 줄의 ./configure ... 을 ../FFmpeg/configure ... 으로 수정합니다.
  • build-armv6 파일의 30번째 줄에서 gcc-4.2 와 iPhoneOS4.3.sdk 라고 되어 있는 부분을 자신의 버전과 일치하도록 수정합니다. 어떤 버전인지 자신이 없으면 /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ 과 /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/ 에 실제로 존재하는지 확인하면 됩니다.
  • build-armv7 파일을 열어 build-armv6 에서 수정한 것처럼 고칩니다.
  • FFmpeg 디렉토리에 있는 config.* 파일들을 삭제합니다. (rm -rf FFmpeg/config.*)
    configure를 실행하면 생성되는 파일들인데 이 파일이 FFmpeg에 있으면 ffmpeg-armv6이나 ffmpeg-armv7에서 configure 가 되지 않습니다.
  • 이제 순서대로 build-armv6, build-armv7 스크립트를 실행합니다. (sh build-armv6; sh build-armv7)
    각각의 target에 대해 configure, make를 순서대로 수행하게 됩니다.
    모든 target의 library가 compile되면 ffmpeg-armv6/dist, ffmpeg-armv7/dist 에 include, lib 디렉토리가 만들어지고 해더와 라이브러리가 생성됩니다.
  • combine-libs 파일을 열어서 5번째 줄의 ARCHS="armv6 armv7 i386" 에서 i386 을 지웁니다.
    그리고 8번째 줄의 BUILD_LIBS=" ... " 에서 마지막에 있는 libavcore.a 를 지웁니다.
    28번째 줄과 31번째 줄의 i386 을 armv7 으로 수정합니다.
  • combine-libs를 실행해서 (sh combine-libs) 모든 target의 library를 합칩니다. ffmpeg-uarch에 최종 헤더와 라이브러리가 만들어집니다.

AVPlayer compile하기
  • Xcode로 AVPlayer project를 엽니다.
  • Project Navigator 의 Targets 에서 AVPlayer,AVPlayerHD의 Build Settings을 선택합니다.
  • Search Paths 항목의 Header Search Paths 란의 내용을 수정합니다. ./libs/ffmpeg-uarch/include 으로 수정하고 Recursive를 체크하면 됩니다.
  • Search Paths 항목의 Library Search Paths 란의 내용을 수정합니다. ., ./libs/ffmpeg-uarch/lib 으로 수정하고 Recursive를 체크하지 않아도 됩니다. . 는 libAVPlayerLib.a 을 링크하기 위해 꼭 필요합니다.
  • Project Navigator 의 AVPlayer/libs/FFMPEG 밑의 libavcodec.a, libavcore.a, libavdevice.a, libavfilter.a, libavformat.a, libavutil.a, libswscale.a의 Utilities 창을 열고 경로를 수정합니다. AVPlayer/libs/ffmpeg-uarch/lib 밑에 있는 library를 지정하면 됩니다.
  • 프로젝트의 라이브러리 설정은 모두 수정되었습니다. 이제 build 버튼만 누르면 됩니다. 단, 주의하실 점은 Simulator로는 build가 되지 않습니다. libAVPlayerLib.a에 AVPlayer의 중요한 코드들이 모두 숨어있는데, 이 라이브러리가 i386으로 compile 되어 있지 않습니다. arm용으로만 compile되어 있기 때문에 Device로만 bulid 가능합니다.
Posted by luuvish
AVPlayer를 컴파일하는 방법을 밑에서 포스팅했었습니다. 몇분이 질문을 하셔서 체크도 해볼 겸 다시 컴파일해 보니 왠 걸. 몇 달이나 되었다고 이것 저것 바뀌었더군요. 답변 몇줄 적는 걸로 해결되지 않을 것 같아 다시 정리해 보았습니다. 변경된 부분 위주로 빨간색으로 체크해 두었습니다.


준비물

FFmpeg library만들기
  • AVPlayer-Objects.zip을 작업할 폴더에 풉니다.
  • __MACOSX 폴더는 지우세요.
  • AVPlayer 안에 FFMPEG 디렉토리로 이동합니다.
  • gas-preprocessor.pl을 /usr/local/bin으로 복사합니다.
  • build-armv7으로 armv7용 library만 만드는 것도 가능하지만 combine-libs를 보면 뭔가 이상하죠? 사실 이 스크립드의 원본은 gabriel의 ffmpeg ios compile script입니다. 제대로 armv6, armv7, i386 library를 만들어서 universal library를 만들어 봅시다. (script가 수정되었으니 여기에 첨부된 것을 받으세요)
  • build-ffmpeg-ios4.3.tar.gz


  • 위의 첨부된 파일을 받아 FFMPEG 디렉토리에 풉니다.
  • gabriel의 소스에서 svn의 revision을 고정했고 target 마다 별도의 svn source를 다운하지 않도록 변경되었고 configure의 option이 수정되었습니다. --enable-postproc 이 제거되었고 --enable-gpl 을 off 시켰습니다. gpl option을 켜면 LGPL license가 아닌 GPL license가 됩니다. 모든 소스를 공개해야 되죠. 마찬가지의 이유로 LGPL의 경우 libx264나 libxvid를 사용할 수 없게 됩니다.
  • svn에서 checkout하는 부분은 git으로 clone하도록 수정되었습니다. 더이상 ffmpeg에서 svn로 source를 공유하지 않습니다. 또한 ffmpeg의 configure option이 변경되었기 때문에 --extra-ldflags="-arch arm7" 뒤에 -L/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/usr/lib/system 이 추가되었습니다. 그리고 document 생성에 문제가 있어 --disable-doc 이 추가되었습니다.
  • 바로 build script를 돌리면 지금(2011-04-24)의 ffmpeg은 버그가 있어서 컴파일되지 않습니다.
    Undefined symbols for architecture armv7:
      "memset", referenced from:
          _ff_ac3_bit_alloc_calc_bap_armv6 in libavcodec.a(ac3dsp_armv6.o)
         (maybe you meant:__memset_chk, _memset )
      "ff_vp8_dct_cat_prob", referenced from:
          .Literal_2 in libavcodec.a(vp8_armv6.o)
         (maybe you meant: __ff_vp8_dct_cat_prob)
    ld: symbol(s) not found for architecture armv7
    이런 메시지가 나오면서 link에서 문제가 발생합니다.
    ffmpeg-source/libavcodec/ac3dsp_armv6.S 의 82 line에서
    b memset 을 b X(memset) 으로
    ffmpeg-source/libavcodec/vp8_armv6.S 의 183 line에서
    movrel r4, ff_vp8_dct_cat_prob 를 movrel r4, X(ff_vp8_dct_cat_prob) 로
    수정하셔야 합니다.
  • 이제 순서대로 build-armv6, build-armv7, build-i386 스크립트를 실행합니다. ffmpeg 사이트에서 소스를 checkout해 온 후 configure, make를 순서대로 수행하게 됩니다.
  • 모든 target의 library가 compile되면 ffmpeg-armv6/dist, ffmpeg-armv7/dist, ffmpeg-i386/dist에 include, lib 디렉토리가 만들어지고 해더와 라이브러리가 생성됩니다.
  • combine-libs를 실행해서 모든 target의 library를 합칩니다. ffmpeg-uarch에 최종 헤더와 라이브러리가 만들어집니다. libavcore.a는 더이상 존재하지 않습니다. combine-libs에서도 제거되어야 합니다.

AVPlayer compile하기
  • Xcode로 AVPlayer project를 엽니다.
  • Targets 에서 AVPlayer,AVPlayerHD의 Build Settings을 선택합니다.
  • Search Paths 항목의 Header Search Paths 란의 내용을 수정합니다. $(SRCROOT)/FFMPEG/ffmpeg-uarch/include, $(SRCROOT)/FFMPEG/ffmpeg-armv7/dist/include 이런식으로 수정하고 Recursive를 체크하면 됩니다.
  • Search Paths 항목의 Library Search Paths 란의 내용을 수정합니다. $(SRCROOT)/FFMPEG/ffmpeg-uarch/lib, $(SRCROOT)/FFMPEG/ffmpeg-armv7/dist/lib 식으로 수정하고 Recursive를 체크하면 됩니다.
  • AVPlayer/LIBS/FFMPEG 밑의 libavcodec.a, libavcore.a, libavdevice.a, libavfilter.a, libavformat.a, libavutil.a, libswscale.a의 Utilities 창을 열고 경로를 수정합니다. AVPlayer/FFMPEG/ffmpeg-uarch/lib 밑에 있는 library를 지정하면 됩니다. libavcore.a는 이제 존재하지 않습니다. library에서 제거하세요.
  • 프로젝트의 라이브러리 설정은 모두 수정되었습니다. 이제 build 버튼만 누르면 됩니다. 단, 주의하실 점은 Simulator로는 build가 되지 않습니다. libAVPlayerLib.a에 AVPlayer의 중요한 코드들이 모두 숨어있는데, 이 라이브러리가 i386으로 compile 되어 있지 않습니다. arm용으로만 compile되어 있기 때문에 Device로만 bulid 가능합니다.
Posted by luuvish
근 3월초부터 많은 시간을 Head First 로 시작하는 책들을 읽는데 썼습니다.
별다른 큰 목적이나 계획이 있었던 건 아니고, 웹관련 일을 찔러 보다가 이쪽에 대해 잘 모르는 게 너무 티가 나서 교양(?)을 쌓고자 몇 권 집어 든게 화근이었습니다. 너무 술술 잘 읽히는 거 있죠. (일이 너무 하기 싫어던 게지 --;)

Head First HTML with CSS & XHTML, Head First JavaScript, Head First Ajax, Head First SQL, Head First Design Patterns 까지 읽고 Head First Web Design에서 잠시 열독을 멈춘 상태입니다. 책 한권을 3-4일만에 읽어 버린 꼴이네요. 그림이 좀 많긴 하지만 그렇게 얇은 책도 아닌데... 막상 읽고 나니 좀 얼떨떨 하긴 하네요.


 
Head First 시리즈는 항상 느끼는 거지만 정말 설명하는 법이 탁월합니다. 쉽게 설명하기 위해 내용의 구성과 흐름, 그리고 흥미 유발을 위한 리듬까지 고려되어 있습니다. 조금만 딱딱하거나 어눌한 설명이 나오면 흥미와 집중이 사라지는 저같은 사람에겐 이만한 책이 없습니다. 또한 쉽게 쓰여진 책의 단점인 설명하기 곤란하거나 모순된 상황을 보여주지 않는 (아름다운 모습만 보여주는) 다소 비겁한 태도도 이 책에는 없습니다. 무엇이 문제인지 정확히 설명하는 게 너무 좋습니다. 안방 토크같은 다소 해학적인 논쟁은 상당히 위트있고 세련되어서 전달하고자 하는 문제의 본질과 부각시키고 싶은 차이를 확실히 인식하도록 도와줍니다.

Head First 시리즈가 쉽게 쓰여졌다고는 하지만 확실히 초보자용 책은 아닙니다. 초보자에서 중급자로 넘어가거나 중급자인거 같은데 왠지 기초가 부실한 사람이 읽는 것이 맞을 것 같습니다. 아무것도 모르는 초보자가 읽기엔 내용 중간중간 문맥안에 숨어있는 무시무시한 위트를 정확히 이해 못할 것 같더군요. 그리고 중급자나 고급자 입장에서는 복잡하고 고난이도의 내용이 들어있지 않습니다. Effective C++ 처럼 모든 것을 다 알고 난 후에 그래도 모르는게 있나? 하고 보는 책은 아닙니다. 난이도 상 조금 에메한 위치에 있지만 저처럼 대충 아는데 좀 더 자세한 내용을 빠른 시간에 익히려는 사람에겐 Head First 시리즈를 추천합니다.
Posted by luuvish
한쪽은 Application을 만드는 방식으로 Web Application을 만들려고 합니다.
다른편에서는 Web Application을 만드는 방법을 그대로 사용해서 App을 만들려고 합니다.

결국 지향하는 목표점은 하나입니다.
하나의 개발환경에서 여러 플랫폼을 지원하는 Web/PC/Mobile Application을 만들려는 거죠.

Cappuccino

JavaScript에 Objective-C의 문법을 추가한 Objective-J를 가지고 Cocoa Framework와 유사한 Framework을 지원합니다. 기존의 Mac OSX/iPhone 개발자들이 쉽게 적응할 수 있는게 장점입니다.
280Slides 같은 완성된 결과물을 보면 상당히 매력적입니다.
그러나 아이러니하게도 아직은 iPhone이나 iPad에서 터치가 제대로 동작하지 않아요(?)

Appspresso

HTML & CSS, JavaScript로 만들어진 Web App를 안드로이드/아이폰 App으로 변환해주는 framework입니다.
개발환경은 eclipse의 plugin인 형태로 제공되며 target mobile의 simulator와 연동됩니다.

Titanium

HTML, CSS, JavaScript, Ruby, Rython, PHP를 사용해서 Desktop이나 안드로이드/아이폰 App을 제작할 수 있는 개발 플렛폼을 제공합니다. 대표적인 결과물이 Wonderlist입니다. 프로젝트를 생성하고 컴파일해서 simulator에 돌려볼 수 있는 멋진 환경을 제공합니다만 Appspresso처럼 편집/수정하고 디버깅할 수 있는 eclipse같은 환경은 아직 제공되지 않습니다.(공짜버전이라 그런지도 --;) 다른 환경에 비해 맘에 드는 언어를 선택할 여지가 많다는 게 좋네요.



아직 초기 단계라 어느 것이 더 좋다 어느 것이 대세다라고 말하긴 어렵습니다. 태생적인 한계가 있기 때문에 주류가 될 수 있을 지도 확실하지 않구요. HTML5은 아직 스팩도 확정되지 않았고 Web App과 Desktop App의 분명한 경계가 있기 때문에 위와 같은 시도가 빠르게 정착할 것 같지는 않습니다.
하지만 Web App와 Desktop/Mobile App를 동일한 환경에서 개발하고자 하는 의도와 그 도전은 환영입니다. 사실 Web이나 App이나 하고자 하는 목표는 같은데 여러개의 target을 지원하는데 너무 비용이 드는 것이 현실입니다. 너무 많은 디바이스, 너무 많은 표준, 언어, 시스템, 라이브러리, framework. 결과를 내는데 너무 많은 방법과 도구가 있다는 것이 오히려 혼란스럽고 방해가 되는지도 모릅니다.
Posted by luuvish


XBMC가 AppleTV2와 iPhone/iPad로 porting 되었습니다.

오픈소스 프로젝트이므로 자유롭게 다운받아 Xcode로 컴파일해서 돌려 볼 수 있습니다.
다만 몇가지 제약으로 인해 탈옥된 디바이스에만 올릴 수 있습니다.

탈옥을 했다는 전제하에 아래의 내용을 따라가시면 됩니다.
탈옥한 디바이스에는 AppSync가 설치되어 있어야 합니다.



CodeSign을 속이기 위한 설정

(http://www.alexwhittemore.com/?p=398 참조)
$ cd /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.0.sdk
$ sudo cp SDKSettings.plist SDKSettings.plist.orig
$ sudo vi SDKSettings.plist
<key>CODE_SIGNING_REQUIRED</key> 을 찾아 그 아래줄의
<string>YES</string> 을 <string>NO</string> 로 수정
<key>ENTITLEMENTS_REQUIRED</key> 을 찾아 그 아래줄의
<string>YES</string> 을 <string>NO</string> 로 수정

$ cd /Developer/Platforms/iPhoneOS.platform/
$ sudo cp Info.plist Info.plist.orig
$ sudo vi Info.plist
<key>CODE_SIGN_CONTEXT_CLASS</key> 을 찾아 그 아래줄의
<string>XCiPhoneOSCodeSignContext</string> 을 <string>XCCodeSignContext</string> 로 수정
CODE_SIGN_CONTEXT_CLASS 가 한번 더 나오므로 위와 같이 한번 더 수정

$ cd ~/Desktop
$ vi script

아래의 내용을 카피해서 script file을 만듭니다.
#!/bin/bash
cd /Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Plug-ins/iPhoneOS\ Build\ System\ Support.xcplugin/Contents/MacOS/
dd if=iPhoneOS\ Build\ System\ Support of=working bs=500 count=255
printf "\xc3\x26\x00\x00" >> working
/bin/mv -n iPhoneOS\ Build\ System\ Support iPhoneOS\ Build\ System\ Support.original
/bin/mv working iPhoneOS\ Build\ System\ Support
chmod a+x iPhoneOS\ Build\ System\ Support

$ chmod 777 script
$ ./script

$ mkdir /Developer/iphoneentitlements401
$ cd /Developer/iphoneentitlements401
$ curl -O http://www.alexwhittemore.com/iphone/gen_entitlements.txt
$ mv gen_entitlements.txt gen_entitlements.py
$ chmod 777 gen_entitlements.py



키체인 만들기

$ open /Applications/Utilities/Keychain\ Access.app/

키체인 프로그램이 열리면
Keychain Access (키체인 접근) 메뉴의 Certificate Assistant (인증 지원) 에서
Create a Certificate (인증서 생성) 를 선택

'Name (이름)' : 'iPhone Developer'
'Identity Type (신원 유형)' : 'Self Signed Root (자체 서명 루트)'
'Certificate Type (인증서 유형)' : 'Code Signing (코드 서명)'

위와 같이 iPhone Developer 라는 이름의 코드 서명을 만듭니다.
인증서가 만들어지면 정보입수에서 신뢰를 항상 신뢰로 설정합니다.



XBMC 컴파일하기

XBMC의 iOS branches source를 받아옵니다.
$ git clone https://github.com/xbmc/atv2.git xbmc

일부 툴들이 설치되어 있지 않을 수 있습니다. fink나 port로 설치해야 합니다.
$ sudo fink install autoconf help2man
$ cd xbmc
$ sudo mkdir -p /usr/local/bin
$ sudo cp tools/osx/ios-depends/gas-preprocessor/gas-preprocessor.pl /usr/local/bin/

컴파일을 시작합니다. 상당한 시간이 걸립니다.
$ make -C tools/osx/ios-depends
$ make -C tools/osx/ios-depends/xbmc
$ make xcode_depends

두가지 타겟중 필요한 것을 생성합니다.
$ xcodebuild -project XBMC-IOS.xcodeproj -target XBMC -configuration Release build ONLY_ACTIVE_ARCH=YES ARCHS=armv7 VALID_ARCHS=armv7 IPHONEOS_DEPLOYMENT_TARGET=4.1 SDKROOT=iphoneos4.2
$ xcodebuild -project XBMC-ATV2.xcodeproj -target XBMC -configuration Release build ONLY_ACTIVE_ARCH=YES ARCHS=armv7 VALID_ARCHS=armv7 IPHONEOS_DEPLOYMENT_TARGET=4.1 SDKROOT=iphoneos4.2
Posted by luuvish
TAG ffmpeg, ios, xbmc
VLC는 한번에 제대로 컴파일된 적이 없네요. iOS 버전은 최근에 작업중인지 그나마 덜 고생하고 컴파일 성공했습니다. 프로젝트들이 얽혀있어 분석이 쉽진 않겠네요.

$ tar jxvf VLC-1.1.0-iOS.tar.bz2
$ ln -s VLC-1.1.0-iOS vlc
$ cd vlc/extras/package/ios
  • build_for_iOS.sh 을 열어서 SDK 버전을 수정합니다. 현재 최신버전은 4.2.sdk입니다. IOS_SDK_ROOT="${DEVROOT}/SDKs/iPhone${PLATFORM}3.2.sdk"
  • build_for_iOS.sh 를 실행해서 컴파일해 보면 중간에 에러가 나면서 멈춥니다. patch file의 버전문제인데 ../../contrib/src-arm-apple-darwin10-ios/src/Patches/live-inet_ntop.patch의 161-185 라인을 참고해서 ../../contrib/src-arm-apple-darwin10-ios/src/live/liveMedia/RTSPServer.cpp을 직접 수정하면 됩니다. our_inet_ntoa()의 두번째 인자로 buf를 추가하기만 하면됩니다.
  • 이제 build_for_iOS.sh를 실행해서 컴파일합니다. 완료되면 vlc/install-ios-OS에 해더와 라이브러리가 생성됩니다.
  • MobileVLCKit의 static plugins를 build합니다.
$ cd vlc/projects/macosx/framework
$ xcodebuild -project MobileVLCKit.xcodeproj -target "Aggregate static plugins" -configuration "Release"
  • MobileVLCKit의 MobileVLCKit의 SDK 버전을 최신버전으로 수정하고 build합니다.
$ open MobileVLCKit.xcodeproj
fix Targets/MobileVLCKit - Get Info / Build
Configuration : All Configurations
Architectures / Base SDK : Latest iOS
$ xcodebuild -project MobileVLCKit.xcodeproj -target "MobileVLCKit" -configuration "Release"



MediaLibraryKit compile하기
  • 작업디렉토리(VLC-1.1.0-iOS와 같은 위치)에 MediaLibraryKit 디렉토리를 만들고 압축을 풉니다.
$ mkdir MediaLibraryKit && cd MediaLibraryKit
$ unzip MediaLibraryKit-1.1.0.zip
  • External 디렉토리로 들어가 MobileVLCKit의 링크를 만듭니다.
$ ln -s ../../vlc/projects/macosx/framework/build/Release-iphoneos MobileVLCKit
  • MediaLibraryKit의 SDK 버전을 최신버전으로 수정하고 build합니다.
$ open MobileMediaLibraryKit.xcodeproj
fix Targets/MobileMediaLibraryKit - Get Info / Build
Configuration : All Configurations
Architectures / Base SDK : Latest iOS
$ xcodebuild -project MobileMediaLibraryKit.xcodeproj -configuration "Release"



MobileVLC compile하기
  • 작업디렉토리(VLC-1.1.0-iOS와 같은 위치)에서 MobileVLC의 압축을 풉니다.
$ tar zxvf MobileVLC-1.1.0.tar.gz
$ cd MobileVLC
  • External 밑에 있는 MediaLibraryKit와 MobileVLCKit의 링크가 제대로 되어있는지 확인합니다.
  • MobileVLC의 SDK 버전을 최신버전으로 수정하고 build합니다.
$ open MobileVLC.xcodeproj
fix Targets/MobileVLC - Get Info / Build
Configuration : All Configurations
Architectures / Architectures : Standard (armv6 armv7)
Architectures / Base SDK : Latest iOS
build with Device-Release configurations

Posted by luuvish
TAG ffmpeg, ios, vlc
한국의 맥 사용자에겐 거의 필수 유틸인 Movist를 컴파일해 보았습니다. 코드 업데이트도 안된지 꽤 되었고 그동안 snow leopard에서는 컴파일이 안되는 줄 알았는데 몇번의 시행 착오 끝에 컴파일에 성공했습니다. 컴파일은 되지만 동작이 정말 잘 되는지는 모르겠지만요.




Movist 홈페이지 : http://cocoable.tistory.com/
Movist 구글코드 페이지 : http://code.google.com/p/movist/
Movist 소스 저장소 : http://movist.googlecode.com/svn/trunk

Movist를 compile 하기 위해서는 git와 yasm이 설치되어 있어야 합니다.





FFmpeg library compile하기
    $ svn checkout http://movist.googlecode.com/svn/trunk movist
  • 우선 Movist 소스코드를 가져옵니다.
  • movist/contrib 에 있는 bootstrap 파일을 수정합니다.
    • SDK_TARGET=10.4 를 SDK_TARGET=10.6 으로 수정
      MACOSX_SDK = /Developer/SDKs/MacOSX10.4u.sdk 를 MacOSX10.6.sdk 으로 변경
  • movist/contrib/src 에 있는 build_ffmpeg_mt.sh 파일을 수정합니다.
    • SDK_TARGET=10.4 를 SDK_TARGET=10.6 으로
      MACOSX_SDK = /Developer/SDKs/MacOSX10.4u.sdk 를 MacOSX10.6.sdk 으로
      #git clone git://git.ffmpeg.org/libswscale/ ffmpeg-mt/libswscale 의 주석 #를 제거합니다.
  • movist 디렉토리에서 build_extlib.sh를 실행합니다.
  • patch 파일이 뭔가 문제가 있지만 컴파일은 일단 잘 됩니다.
  • movist/contrib/lib 에 필요한 라이브러리가 생성되었습니다.

Movist compile하기
  • Movist project 을 Xcode로 엽니다.
  • Targets에 있는 Movist의 Info 창을 엽니다.
  • Architectures 항목의 Base SDK 란을 Latest Mac OS X 로 변경합니다.
  • Linking 항목의 Other Linker Flags 의 MacOSX10.4u.sdk를 MacOSX10.6.sdk로 변경합니다.
  • build 해보면 무수한 error message가 나올 겁니다. MMovie_QuickTime.h 의 #import <QTKit/QTKit.h> 가 다른 해더보다 뒤에 올 때 이런 문제가 생깁니다. SDK가 버전업되면서 해더의 dependency에 문제가 생긴 모양입니다. 제일 단순한 해결책은 (정석은 아니지만) Movist.h 파일의 맨 위에 #import <QTKit/QTKit.h> 를 추가하는 것입니다.
  • 이제 문제없이 build 됩니다. ppc일 때 제대로 도는지는 모르겠네요.

Posted by luuvish
요즘 iPhone/iPad 에서 무인코딩으로 동영상을 볼 수 있는 앱으로 잘 나가는 AV Player를 iOS SDK로 compile해 볼 수 있습니다. FFmpeg license 문제로 컴파일할 수 있는 코드가 공개되어 있습니다. 물론 중요한 부분은 library로 묶여있지만 앱의 전체적인 모습과 GUI 구성, FFmpeg library를 어떻게 컴파일해서 합쳤는지 좋은 참고자료가 될 듯 합니다.


준비물

FFmpeg library만들기
  • AVPlayer-XCode.zip을 작업할 폴더에 풉니다.
  • __MACOSX 폴더는 지우세요.
  • AVPlayer 안에 FFMPEG 디렉토리로 이동합니다.
  • gas-preprocessor.pl을 /usr/local/bin으로 복사합니다.
  • build-armv7으로 armv7용 library만 만드는 것도 가능하지만 combine-libs를 보면 뭔가 이상하죠? 사실 이 스크립드의 원본은 gabriel의 ffmpeg ios compile script입니다. 제대로 armv6, armv7, i386 library를 만들어서 universal library를 만들어 봅시다.
  • build-ffmpeg-ios.tar.gz

  • 위의 첨부된 파일을 받아 FFMPEG 디렉토리에 풉니다.
  • gabriel의 소스에서 svn의 revision을 고정했고 target 마다 별도의 svn source를 다운하지 않도록 변경되었고 configure의 option이 수정되었습니다. --enable-postproc 이 제거되었고 --enable-gpl 을 off 시켰습니다. gpl option을 켜면 LGPL license가 아닌 GPL license가 됩니다. 모든 소스를 공개해야 되죠. 마찬가지의 이유로 LGPL의 경우 libx264나 libxvid를 사용할 수 없게 됩니다.
  • 이제 순서대로 build-armv6, build-armv7, build-i386 스크립트를 실행합니다. ffmpeg 사이트에서 소스를 checkout해 온 후 configure, make를 순서대로 수행하게 됩니다.
  • 모든 target의 library가 compile되면 ffmpeg-armv6/dist, ffmpeg-armv7/dist, ffmpeg-i386/dist에 include, lib 디렉토리가 만들어지고 해더와 라이브러리가 생성됩니다.
  • combine-libs를 실행해서 모든 target의 library를 합칩니다. ffmpeg-uarch에 최종 헤더와 라이브러리가 만들어집니다.

AVPlayer compile하기
  • Xcode로 AVPlayer project를 엽니다.
  • Targets 에서 AVPlayer/AVPlayerHD의 Info 창을 엽니다.
  • Search Paths 항목의 Header Search Paths 란의 내용을 수정합니다. $(SRCROOT)/FFMPEG/ffmpeg-uarch/include, $(SRCROOT)/FFMPEG/ffmpeg-armv7/dist/include 이런식으로 수정하고 Recursive를 체크하면 됩니다.
  • Search Paths 항목의 Library Search Paths 란의 내용을 수정합니다. $(SRCROOT)/FFMPEG/ffmpeg-uarch/lib, $(SRCROOT)/FFMPEG/ffmpeg-armv7/dist/lib 식으로 수정하고 Recursive를 체크하면 됩니다.
  • AVPlayer/LIBS/FFMPEG 밑의 libavcodec.a, libavcore.a, libavdevice.a, libavfilter.a, libavformat.a, libavutil.a, libswscale.a의 Info 창을 열고 경로를 수정합니다. AVPlayer/FFMPEG/ffmpeg-uarch/lib 밑에 있는 library를 지정하면 됩니다.
  • 프로젝트의 라이브러리 설정은 모두 수정되었습니다. 이제 build 버튼만 누르면 됩니다. 단, 주의하실 점은 Simulator로는 build가 되지 않습니다. libAVPlayerLib.a에 AVPlayer의 중요한 코드들이 모두 숨어있는데, 이 라이브러리가 i386으로 compile 되어 있지 않습니다. arm용으로만 compile되어 있기 때문에 Device로만 bulid 가능합니다.
Posted by luuvish