スキップしてメイン コンテンツに移動

mythtv Internal player で mp4 (H.264+AAC)が見たい。

呑んでる 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



コメント

このブログの人気の投稿

今日の都電

device-mapper-multipath

Jan 6 00:04:09 ovn2 kernel: [181703.837857] device-mapper: table: 253:0: multipath: error getting device Jan 6 00:04:09 ovn2 kernel: [181703.838212] device-mapper: ioctl: error adding target to table Jan 6 00:04:09 ovn2 multipathd: dm-0: remove map (uevent) Jan 6 00:04:09 ovn2 multipathd: dm-0: remove map (uevent) ぐぬぬ [root@ovn2 multipath]# multipath Jan 06 00:04:16 | ADATA_SX300_2D3920001647: ignoring map [root@ovn2 multipath]# echo "blacklist { > wwid ADATA_SX300_2D3920001647 > }" >> /etc/multipath.conf [root@ovn2 multipath]# service multipathd restart Redirecting to /bin/systemctl restart multipathd.service [root@ovn2 multipath]# multipath [root@ovn2 multipath]# すっきり!