ウィンドウズ用に携帯動画変換君というソフトがある。
このソフトは、携帯電話で再生可能な動画に変換しようという目的で始まり、今ではiPodやPSPに対応していたりする。
実体としては、ffmpeg(改造版)のフロントエンドに便利ツールを組み合わせたものである。
かなりメジャーなソフトであるので、携帯電話で動画を見ている人であればかなりの認知度だろうと思う。
基本的には、変換の本体はffmpegであるので、macでも同等のフロントエンドを開発し、mac用のffmpegを用意すれば使えるようになるのである。
それに注目して作られた携帯動画変換ちゃんなるMacOSX用のソフトがある。
携帯動画変換君の設定がそのまま使えるので、変換君確立された変換方法を引き継ぐことができる。
人のソフトを利用しているともいえなくもないが、macでも同様の処理ができるという画期的ソフトであるのは間違いない。
一番の問題点は、ffmpegの互換性である。
具体的には次となる。
いろいろな方法でやってみた結果、次のようにしてMakeした。
最終的なソース一覧ではこのようになる。ユーザーのホームディレクトリにffmpeg_for_ 3gpというフォルダを作りそこに全てを格納した。

携帯電話変換君はGPL, LGPLライセンスが適応されているプログラムを組み込んで開発されているため、それに対して変更したソースは公開されている。携帯動画変換君 ソースリスト
ダウンロード対象はここで公開されているもののうち、ffmpeg-051130-0.33.tar.gz, xvidcore_patched_diff_011.tar.gz, x264_051028.tar.gzの3つ。
適当な場所に展開する。ホームのディレクトリを推奨。
携帯動画変換ちゃんのHPでも書いてあるが、携帯動画変換君 MacOSXから、mpeg-MobileHackerz-051107-MacOSX-2.zipを検索してみてください。
このバイナリを直接組み込んだりすることはありませんが、コンパイルオプションを調べるのに使います。
mp3のエンコードにlameを使用するので、このソースも取得する。The LAME Project
Get LAME〜Current Versions(SourceForgeのDLへのリンク)〜betaでない最新版を取得(現在は3.97)。
aacのエンコードにfaacを使用するので、このソースも取得する。faadはaacデコーダっぽい。AudioCoding faac
Dwonloads〜betaでない最新版を取得(現在はfaac1.25, faad 2.5)。
DTS関連処理で必要なので、ソースを取得する。libdts
このリンクは安定しないので、自分で探してみて欲しい。http://debian.unnet.nl/のサーバにあると思う。
liba52AC-3の処理で使用される模様。liba52
betaでない最新をDL(現在は0.7.4)
xvidのエンコードに必要。xvid source
Developers welcom (get the latest Xvid source code)〜Developer Downloads〜betaでない最新をDL(現在は1.1.2)
最新のx264では、ビットレートの指定がちゃんとできないため、今回は携帯動画変換君で使用されている古いやつをそのまま使うことにする。
Makeに取りかかる。基本的なMake手順は次のようになる。
ターミナルが起動していないときは、アプリケーション/ユーティリティ/ターミナル.appを起動する。既に起動している場合は、ファイルメニューから新規シェルを選ぶ。
ターミナルのシェルの初期ディレクトリは、ホームディレクトリとなっているので、その下に作ったffmpeg_for_3gpの下の、lame-3.97を指定してやる。
cd ffmpeg_for_3gp/lame-3.97
CPUやコンパイラやライブラリなどにマッチするようにコンフィグレーションする。基本的には自動的にやってくれる。
sh configure checking build system type... i686-apple-darwin8.8.1 checking host system type... i686-apple-darwin8.8.1 〜中略〜 config.status: creating config.h config.status: executing depfiles commands
実行バイナリを生成する。makeと打ってしばらくすると終了する。
エラー(make[2]: Nothing to be done for `all-am'.)っぽいのが出力されているけど、無視。
make make all-recursive Making all in mpglib 〜中略〜 Making all in mac make[2]: Nothing to be done for `all'. make[2]: Nothing to be done for `all-am'.
実行バイナリをインストールする。sudo make installと入力してインストールする。ここでsudoとはsuper userなんとかの略で、アクセス権限をsuper userに昇格させることにより、インストールができるようになる。なお、Password:とパスワード入力を促されるのでそこに管理者パスワードを入力する。(入力した文字は表示されない。)
makeと同様のエラーっぽいのが出力されているけど、無視。
ターミナルを閉じて完了。sudo make install Password: Making install in mpglib 〜中略〜 make[2]: Nothing to be done for `install-exec-am'. make[2]: Nothing to be done for `install-data-am'.
略。
cd ffmpeg_for_3gp/a52dec-0.7.4
sh configure checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... yes 〜中略〜 config.status: creating include/config.h config.status: executing default-1 commands
make Making all in autotools make[1]: Nothing to be done for `all'. 〜中略〜 gcc -g -O3 -fomit-frame-pointer -o compare compare.o -lm make[1]: Nothing to be done for `all-am'.
ターミナルを閉じて完了。sudo make install Password: Making install in autotools 〜中略〜 make[2]: Nothing to be done for `install-exec-am'. make[2]: Nothing to be done for `install-data-am'.
略。
cd ffmpeg_for_3gp/faac
DLしてきた圧縮ファイルを展開すると、多くののファイルが生成されるが、このうち、いくつかに関して改行コードをWIN(CR+LF)からUNIX(LF)に変換する必要がある。どのファイルを変換すればいいかはよく分からないが、そのままで上手くいかないことは分かっている。
MultiTextConverterというソフトを用いて、変換した。環境設定の拡張子の変換対象とするファイルにinを足し、拡張子を持たないファイルを変換するにチェックを入れる。

まあ、面倒なので、変換済のものをアップしておく。
bootstrapというのを実行して、configureを生成する。
sh bootstrap configure.in: installing `./install-sh' configure.in: installing `./mkinstalldirs' configure.in: installing `./missing' common/mp4v2/Makefile.am: installing `./depcomp'
sh configure checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... yes 〜中略〜 config.status: creating config.h config.status: executing depfiles commands
make make all-recursive Making all in include 〜中略〜 creating faac make[2]: Nothing to be done for `all-am'.
ターミナルを閉じて完了。sudo make install Password: Making install in include 〜中略〜 make[2]: Nothing to be done for `install-exec-am'. make[2]: Nothing to be done for `install-data-am'.
略。
cd ffmpeg_for_3gp/faad2
faacと同様に、改行コードを(CR+LF)から(LF)に変換する必要がある。
まだ足りない。下記の2つを適応する必要がある。
http://svn.rpmforge.net/svn/trunk/rpms/faad2/faad2-2.5-buildfix.patch
http://vafer.org/blog/2006/10/
上記の修正を加えたソースをアップしておく。
略。
略。
略。
略。
略。
cd ffmpeg_for_3gp/libdts-0.0.2
略。
略。
略。
略。
略。
cd ffmpeg_for_3gp/x264_051028
pthreadを有効にする。
sh configure --enable-pthread Platform: X86 System: MACOSX avis input: no mp4 output: no pthread: yes vfw: no debug: no visualize: no
アセンブラファイルで問題が出るので、config.makの12行目を次のように修正する。
ただし、config.makはconfigureで生成されるのでconfigure後に行う必要がある。
ASFLAGS=-f macho -DPREFIX
略。
略。
略。
いつもとディレクトリが違うので注意。
cd ffmpeg_for_3gp/xvidcore-1.1.2/build/generic
ファイル名がbootstrap.shなのに注意。
sh bootstrap.sh
MacOSX用にconfig。
sh configure --enable-macosx_module
platform.incはconfigureで生成されるのでconfigure後に行う必要がある。
参考リンク、http://rob.opendot.cl/index.php/useful-stuff/xvid-with-asm-on-os-x/
31行目を次のようにする。
SPECIFIC_CFLAGS=-fPIC -fno-common -no-cpp-precomp -undefined suppressアセンブラファイルで問題が出るので、platform.incの41行目を次のように修正する。
AFLAGS=-I$(<D)/ -f macho -DPREFIXさらに、48行目を次のようにする。
SPECIFIC_LDFLAGS=-r -keep_private_externs -nostdlib && $(CC) $(LDFLAGS) $(PRE_SHARED_LIB) -o libxvidcore.$(SHARED_EXTENSION).$(API_MAJOR) -bundle -flat_namespace -undefined suppress -read_only_relocs suppress
略。
略。
最後に、ffmpegのMakeだ。なかなかやっかいな問題をいくつか解消しなければならない。
略。
cd ffmpeg_for_3gp/ffmpeg_051130
色々オプションをつけてコンフィグレーションする。ただし、shではなく./とする。なぜかshとするとMakefileが消えてしまう。
./configure --enable-mp3lame --enable-faac --enable-faad --enable-amr_nb --enable-amr_wb --disable-ffplay --enable-small --enable-memalign-hack --enable-gpl --enable-xvid --enable-dts --enable-a52 --disable-vhook --enable-pthread --enable-x264
MMXとかの適応のために、色々修正する必要がある。
方針としては、マクロASMALIGNの定義でアドレス配置エラーを修正。
その他、メモリアクセスの仕方をちょっと変更。
config.h line.3 追加。"\"はバックスラッシュです。間違えるとMake通りません。
#define ASMALIGN(ZEROBITS) ".align " #ZEROBITS "\n\t"libavcodec/i386/dsputil_mmx.c line.52 修正
#define JUMPALIGN() __asm __volatile (ASMALIGN(3)::)libavcodec/i386/dsputil_mmx.c line.195 修正
ASMALIGN(4)libavcodec/i386/dsputil_mmx.c line.223 修正
ASMALIGN(4)ibavcodec/i386/dsputil_mmx.c line.366 修正
ASMALIGN(3)ibavcodec/i386/dsputil_mmx.c line.392 修正
ASMALIGN(3)ibavcodec/i386/dsputil_mmx.c line.418 修正
ASMALIGN(3)ibavcodec/i386/dsputil_mmx.c line.1644 修正
"movq _ff_pw_20, %%mm4 \n\t" /* 20 */\ibavcodec/i386/dsputil_mmx.c line.1656 修正
"pmullw _ff_pw_3, %%mm5 \n\t" /* -6x2 + 3x3 */\ibavcodec/i386/dsputil_mmx.c line.1690 修正
"pmullw _ff_pw_3, %%mm6 \n\t" /* 3c - 6b */\ibavcodec/i386/dsputil_mmx.c line.1693 修正
"pmullw _ff_pw_20, %%mm0 \n\t" /* 20a */\ibavcodec/i386/dsputil_mmx.c line.1716 修正
"pmullw _ff_pw_3, %%mm3 \n\t" /* 3c - 6b */\ibavcodec/i386/dsputil_mmx.c line.1719 修正
"pmullw _ff_pw_20, %%mm1 \n\t" /* 20a */\ibavcodec/i386/dsputil_mmx.c line.1742 修正
"pmullw _ff_pw_3, %%mm0 \n\t" /* 3c - 6b */\ibavcodec/i386/dsputil_mmx.c line.1750 修正
"pmullw _ff_pw_20, %%mm6 \n\t" /* 20a */\ibavcodec/i386/dsputil_mmx.c line.1765 修正
"pmullw _ff_pw_20, %%mm3 \n\t" /* 20a */\ibavcodec/i386/dsputil_mmx.c line.1766 修正
"pmullw _ff_pw_3, %%mm4 \n\t" /* 3c - 6b */\ibavcodec/i386/dsputil_mmx.c line.1857 修正
"pmullw _ff_pw_3, %%mm6 \n\t" /* 3c - 6b */\ibavcodec/i386/dsputil_mmx.c line.1860 修正
"pmullw _ff_pw_20, %%mm0 \n\t" /* 20a */\ibavcodec/i386/dsputil_mmx.c line.1878 修正
"pmullw _ff_pw_20, %%mm1 \n\t" /* 20a */\ibavcodec/i386/dsputil_mmx.c line.1879 修正
"pmullw _ff_pw_3, %%mm3 \n\t" /* 3c - 6b */\ibavcodec/i386/dsputil_mmx_avg.h line.757 修正
ASMALIGN(3)ibavcodec/i386/dsputil_mmx_rnd.h line.30-55 修正
ibavcodec/i386/dsputil_mmx_rnd.h line.62-98 修正"lea (%3, %3), %%"REG_a" \n\t" ASMALIGN(3) "1: \n\t" "movq (%1), %%mm0 \n\t" "movq 1(%1), %%mm1 \n\t" "movq (%1, %3), %%mm2 \n\t" "movq 1(%1, %3), %%mm3 \n\t" PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) "movq %%mm4, (%2) \n\t" "movq %%mm5, (%2, %3) \n\t" "add %%"REG_a", %1 \n\t" "add %%"REG_a", %2 \n\t" "movq (%1), %%mm0 \n\t" "movq 1(%1), %%mm1 \n\t" "movq (%1, %3), %%mm2 \n\t" "movq 1(%1, %3), %%mm3 \n\t" PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) "movq %%mm4, (%2) \n\t" "movq %%mm5, (%2, %3) \n\t" "add %%"REG_a", %1 \n\t" "add %%"REG_a", %2 \n\t" "subl $4, %0 \n\t" "jnz 1b \n\t" :"+g"(h), "+S"(pixels), "+D"(block) :"r"((long)line_size) :REG_a, "memory");
ibavcodec/i386/dsputil_mmx_rnd.h line.112-151 修正"testl $1, %0 \n\t" " jz 1f \n\t" "movq (%1), %%mm0 \n\t" "movq (%2), %%mm1 \n\t" "add %4, %1 \n\t" "add $8, %2 \n\t" PAVGB(%%mm0, %%mm1, %%mm4, %%mm6) "movq %%mm4, (%3) \n\t" "add %5, %3 \n\t" "decl %0 \n\t" ASMALIGN(3) "1: \n\t" "movq (%1), %%mm0 \n\t" "movq (%2), %%mm1 \n\t" "add %4, %1 \n\t" "movq (%1), %%mm2 \n\t" "movq 8(%2), %%mm3 \n\t" "add %4, %1 \n\t" PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) "movq %%mm4, (%3) \n\t" "add %5, %3 \n\t" "movq %%mm5, (%3) \n\t" "add %5, %3 \n\t" "movq (%1), %%mm0 \n\t" "movq 16(%2), %%mm1 \n\t" "add %4, %1 \n\t" "movq (%1), %%mm2 \n\t" "movq 24(%2), %%mm3 \n\t" "add %4, %1 \n\t" "add $32, %2 \n\t" PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) "movq %%mm4, (%3) \n\t" "add %5, %3 \n\t" "movq %%mm5, (%3) \n\t" "add %5, %3 \n\t" "subl $4, %0 \n\t" "jnz 1b \n\t"
ibavcodec/i386/dsputil_mmx_rnd.h line.171 修正"lea (%3, %3), %%"REG_a" \n\t" ASMALIGN(3) "1: \n\t" "movq (%1), %%mm0 \n\t" "movq 1(%1), %%mm1 \n\t" "movq (%1, %3), %%mm2 \n\t" "movq 1(%1, %3), %%mm3 \n\t" PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) "movq %%mm4, (%2) \n\t" "movq %%mm5, (%2, %3) \n\t" "movq 8(%1), %%mm0 \n\t" "movq 9(%1), %%mm1 \n\t" "movq 8(%1, %3), %%mm2 \n\t" "movq 9(%1, %3), %%mm3 \n\t" PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) "movq %%mm4, 8(%2) \n\t" "movq %%mm5, 8(%2, %3) \n\t" "add %%"REG_a", %1 \n\t" "add %%"REG_a", %2 \n\t" "movq (%1), %%mm0 \n\t" "movq 1(%1), %%mm1 \n\t" "movq (%1, %3), %%mm2 \n\t" "movq 1(%1, %3), %%mm3 \n\t" PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) "movq %%mm4, (%2) \n\t" "movq %%mm5, (%2, %3) \n\t" "movq 8(%1), %%mm0 \n\t" "movq 9(%1), %%mm1 \n\t" "movq 8(%1, %3), %%mm2 \n\t" "movq 9(%1, %3), %%mm3 \n\t" PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) "movq %%mm4, 8(%2) \n\t" "movq %%mm5, 8(%2, %3) \n\t" "add %%"REG_a", %1 \n\t" "add %%"REG_a", %2 \n\t" "subl $4, %0 \n\t" "jnz 1b \n\t" :"+g"(h), "+S"(pixels), "+D"(block) :"r"((long)line_size) :REG_a, "memory");
ASMALIGN(3)ibavcodec/i386/dsputil_mmx_rnd.h line.209 修正
ASMALIGN(3)ibavcodec/i386/dsputil_mmx_rnd.h line.249 修正
ASMALIGN(3)ibavcodec/i386/dsputil_mmx_rnd.h line.461 修正
ASMALIGN(3)ibavcodec/i386/dsputil_mmx_rnd.h line.512 修正
ASMALIGN(3)ibavcodec/i386/fdct_mmx.c line.354-409 修正
ibavcodec/i386/motion_est_mmx.c line.37 修正#define FDCT_ROW_SSE2_H1(i,t) \ "movq " #i "(%0), %%xmm2 \n\t" \ "movq " #i "+8(%0), %%xmm0 \n\t" \ "movdqa " #t "+32(%1), %%xmm3 \n\t" \ "movdqa " #t "+48(%1), %%xmm7 \n\t" \ "movdqa " #t "(%1), %%xmm4 \n\t" \ "movdqa " #t "+16(%1), %%xmm5 \n\t" #define FDCT_ROW_SSE2_H2(i,t) \ "movq " #i "(%0), %%xmm2 \n\t" \ "movq " #i "+8(%0), %%xmm0 \n\t" \ "movdqa " #t "+32(%1), %%xmm3 \n\t" \ "movdqa " #t "+48(%1), %%xmm7 \n\t" #define FDCT_ROW_SSE2(i) \ "movq %%xmm2, %%xmm1 \n\t" \ "pshuflw $27, %%xmm0, %%xmm0 \n\t" \ "paddsw %%xmm0, %%xmm1 \n\t" \ "psubsw %%xmm0, %%xmm2 \n\t" \ "punpckldq %%xmm2, %%xmm1 \n\t" \ "pshufd $78, %%xmm1, %%xmm2 \n\t" \ "pmaddwd %%xmm2, %%xmm3 \n\t" \ "pmaddwd %%xmm1, %%xmm7 \n\t" \ "pmaddwd %%xmm5, %%xmm2 \n\t" \ "pmaddwd %%xmm4, %%xmm1 \n\t" \ "paddd %%xmm7, %%xmm3 \n\t" \ "paddd %%xmm2, %%xmm1 \n\t" \ "paddd %%xmm6, %%xmm3 \n\t" \ "paddd %%xmm6, %%xmm1 \n\t" \ "psrad %3, %%xmm3 \n\t" \ "psrad %3, %%xmm1 \n\t" \ "packssdw %%xmm3, %%xmm1 \n\t" \ "movdqa %%xmm1, " #i "(%4) \n\t" "movdqa (%2), %%xmm6 \n\t" FDCT_ROW_SSE2_H1(0,0) FDCT_ROW_SSE2(0) FDCT_ROW_SSE2_H2(64,0) FDCT_ROW_SSE2(64) FDCT_ROW_SSE2_H1(16,64) FDCT_ROW_SSE2(16) FDCT_ROW_SSE2_H2(112,64) FDCT_ROW_SSE2(112) FDCT_ROW_SSE2_H1(32,128) FDCT_ROW_SSE2(32) FDCT_ROW_SSE2_H2(96,128) FDCT_ROW_SSE2(96) FDCT_ROW_SSE2_H1(48,192) FDCT_ROW_SSE2(48) FDCT_ROW_SSE2_H2(80,192) FDCT_ROW_SSE2(80) : : "r" (in), "r" (tab_frw_01234567_sse2.tab_frw_01234567_sse2), "r" (fdct_r_row_sse2.fdct_r_row_sse2), "i" (SHIFT_FRW_ROW), "r" (out)
ASMALIGN(4)ibavcodec/i386/motion_est_mmx.c line.73 修正
ASMALIGN(4)ibavcodec/i386/motion_est_mmx.c line.95 修正
ASMALIGN(4)ibavcodec/i386/motion_est_mmx.c line.121 修正
ASMALIGN(4)ibavcodec/i386/motion_est_mmx.c line.122 修正
"movq _bone, %%mm5 \n\t"ibavcodec/i386/motion_est_mmx.c line.158 修正
ASMALIGN(4)ibavcodec/i386/motion_est_mmx.c line.196 修正
ASMALIGN(4)ibavcodec/i386/mpegvideo_mmx.c line.69 修正
ASMALIGN(4)ibavcodec/i386/mpegvideo_mmx.c line.132 修正
ASMALIGN(4)ibavcodec/i386/mpegvideo_mmx.c line.225 修正
ASMALIGN(4)ibavcodec/i386/mpegvideo_mmx.c line.228 修正
ASMALIGN(4)ibavcodec/i386/mpegvideo_mmx.c line.360 修正
ASMALIGN(4)ibavcodec/i386/mpegvideo_mmx.c line.421 修正
ASMALIGN(4)ibavcodec/i386/mpegvideo_mmx.c line.421 修正
ASMALIGN(4)ibavcodec/i386/mpegvideo_mmx_template.c line.102 修正
ASMALIGN(4)ibavcodec/i386/mpegvideo_mmx_template.c line.151 修正
ASMALIGN(4)
以降は、変換君での変更を無効にする。
基本的に、avisythを無効に、タイムスタンプ修正を無効にした。
libavformat/allformat.c line.112
// avs_init(); //libavformat/aviobuf.c line.19 修正
#if 0libavformat/aviobuf.c line.234 修正
#if 1libavformat/aviobuf.c line.254 修正
#if 1libavformat/aviobuf.c line.274 修正
#if 1libavformat/aviobuf.c line.290 修正
#if 1libavformat/aviobuf.c line.311 修正
#if 1libavformat/avisynth.c line.19 追加
#if 0libavformat/avisynth.c line.357 追加
#endiflibavformat/avisythdll.h line.022 追加
#define BYTE unsigned charlibavformat/movenc.h line.1617 修正
mov->time = s->timestamp + 0x7C25B080; // - _timezone; // timestamp is UTC, but most imprementation is LocalTimeffmpeg.c line.4648 修正
// _setmode(_fileno(stdout), _O_BINARY); //
amrwb_floatを最新のものに入れ替える。上書きだとちょっと具合が悪いかもしれない。
make make -C libavcodec all 〜中略〜 cc -Wl,-d,-search_paths_first -g -o output_example output_example.o -L./libavformat -lavformat -L./libavcodec -lavcodec -ldts -lx264 -lz -lmp3lame -lfaad -lfaac -lxvidcore cc '/Users/vict/ffmpeg_for_3gp/ffmpeg_051130'/qt-faststart.c -o qt-faststart make -C doc all make[1]: Nothing to be done for `all'.
sudo make install Password: make -C libavcodec all 〜中略〜 install -d "/usr/local/bin" install -c -s -m 755 ffmpeg "/usr/local/bin"
ffmpeg_051130にffmpegというUNIX実行(Intel)ファイルができているはず。
携帯電話変換ちゃんのHPでもみてください。
また、MPEG Exporter TNGでも使用できるかもしれません。
結果的に、非常に面倒なプロセスを踏まないとffmpegはbuildできないと言うことです。
そんな面倒はいやだという人は、ここから持って行ってください。ffmpeg_for_3gp.zip
OS Xハッキング!
http://htffmpegx.seesaa.net/
How to Use ffmpegXメモ was here
http://journal.mycom.co.jp/column/osx/
The ffmpeg-user Archives
http://lists.mplayerhq.hu/pipermail/ffmpeg-user/
そのほか色々。