呑んでる libmythavhogehoge がフルスペックの ffmpeg libavhogehoge であれば見れるはず。ffmpeg の configure オプションは mythtv の configure でも削られていないので地道に –ebable-libfaad とか渡してやるとフルスペックのものが作れるはず。

こんな感じでmythtvの呑んでるソースから libavhogehoge 自体作ってしまうことにしてみたり。

逆に mythtv のソースツリーが libavhogehoge の internal なヘッダ群に依存しまくりなので逆パターン(ffmpeg の libavhogehoge を参照)は面倒くさかったり。

lib(myth)avformat が AAC を捌けるようになったので

2007-11-13 03:03:36.011 \[mov,mp4,m4a,3gp,3g2,mj2 @ 0x2aaaabb91060\]ISO: File Type Major Brand: isom
2007-11-13 03:03:36.019 av\_remove\_stream 0x1
2007-11-13 03:03:36.019 av\_remove\_stream: no change to cur\_st
2007-11-13 03:03:36.019 av\_remove\_stream: removing... s->nb\_streams=1 i=0
2007-11-13 03:03:36.019 av\_remove\_stream: renumbering streams
2007-11-13 03:03:36.064 AFD: Stream #0, has id 0x2 codec id AAC, type Audio, bitrate 0 at 0x0x41b4070
2007-11-13 03:03:36.065 AFD: Looking for decoder for AAC
2007-11-13 03:03:36.065 AFD: Opened codec 0x3db4980, id(AAC) type(Audio)

AACは見つけたらしい。が、id(H264) type(Video)を見つけてくれない。というか、stream自体一つしか認識していないっぽい。

av_remove_stream は

void av\_remove\_stream(AVFormatContext \*s, int id, int remove\_ts) {
int i;
int changes = 0;
for (i=0; inb\_streams; i++) {
if (s->streams\[i\]->id != id)
continue;

idの一致するストリームを消すらしい。呼出元は

AVStream \*av\_add\_stream(AVFormatContext \*s, AVStream \*st, int id)
int i;
  
if (!st)
{
av\_log(s, AV\_LOG\_ERROR, "av\_add\_stream: Error, AVStream is NULL");
return NULL;
}
  
av\_remove\_stream(s, id, 0);
.......
st->id = id;
.......
s->streams\[s->nb\_streams++\] = st;
return st;

ストリームを追加する前処理で既に追加するストリームが存在すれば消してから追加ということっぽい。このとき、引数idがストリームのidに設定される。nb_streamsはコンテクスト内のストリーム数で、この関数によってインクリメントされる。呼出元は av_new_stream 経由で

static int mov\_read\_trak(MOVContext \*c, ByteIOContext \*pb, MOV\_atom\_t atom)
AVStream \*st;
MOVStreamContext \*sc;
st = av\_new\_stream(c->fc, c->fc->nb\_streams);

試したファイルの trak1 に H.264 trak2 に AAC が入ってるはずなのでこの関数は2度呼ばれ、初回呼出時の nb_streams は 0,2回目呼出時の nb_streams は 1のはず。また、av_remove_streamに突入していることより、2回目呼出時までの間に初回呼出で作られた stream の id が 1 に変わってるはず。

static int mov\_read\_tkhd(MOVContext \*c, ByteIOContext \*pb, MOV\_atom\_t atom)
......
st->id = (int)get\_be32(pb); /\* track id (NOT 0 !)\*/
......

tkhd の処理時に 正しい track id を引っ張ってきて書き換えている。コメントどおり、 non zero(というかほぼ1originで連続数なんじゃないか?)なので、trak 2 を追加するときには trak 1が、 trak 4 を追加するときに trak 2 が消え去る運命にあるんじゃなかろうか?

コメント通り正規の trak id は non zero で、かつ st->id が正規のものに書き換えられるとするならば、

static int mov\_read\_trak(MOVContext \*c, ByteIOContext \*pb, MOV\_atom\_t atom)
AVStream \*st;
MOVStreamContext \*sc;
-   st = av\_new\_stream(c->fc, c->fc->nb\_streams);
+   st = av\_new\_stream(c->fc, 0);

テンポラリなidは下手にインクリメントするよりも存在しえない0を指定して置いた方が安全ではなかろうか?

…..

2007-11-13 03:05:40.509 \[mov,mp4,m4a,3gp,3g2,mj2 @ 0x2aaaabb91060\]ISO: File Type Major Brand: isom
2007-11-13 03:05:40.568 AFD: Stream #0, has id 0x1 codec id H264, type Video, bitrate 0 at 0x0x3db4e60
2007-11-13 03:05:40.590 AFD: InitVideoCodec() 0x3db61e0 id(H264) type (Video).
2007-11-13 03:05:40.591 detectInterlace(Detect Scan, Interlaced Scan, 29.97, 480) ->Interlaced Scan
2007-11-13 03:05:40.591 AFD: Using ffmpeg for video decoding
2007-11-13 03:05:40.591 AFD: Looking for decoder for H264
2007-11-13 03:05:40.600 AFD: Opened codec 0x3db61e0, id(H264) type(Video)
2007-11-13 03:05:40.600 AFD: Stream #1, has id 0x2 codec id AAC, type Audio, bitrate 0 at 0x0x3db6600
2007-11-13 03:05:40.600 AFD: Looking for decoder for AAC
2007-11-13 03:05:40.600 AFD: Opened codec 0x3db53a0, id(AAC) type(Audio)

^-^)v