昨日(2017年11月8日の日記参照)の続きです。
本来見たかった道をざっくりまとめておくと、
これが 2017年11月6日の日記の前半で分かった部分。
これが 2017年11月6日の日記の後半で分かった部分。
これが 2017年11月7日の日記で分かった部分。
これが 2017年11月8日の日記で分かった部分です。そのあとはlooperとは何ぞや?という点を追いかけていましたが、まだわからない状態です。
肝心のACodec::BaseState::mCodecに何が入っているのか?についてはUninitializedStateを手掛かりに見ていきます。
//android/frameworks/av/media/libstagefright/ACodec.cpp
struct ACodec::BaseState : public AState {
BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
...
ACodec *mCodec; //★★これが知りたい★★
//★★UninitializedStateを手掛かりに見てみる★★
struct ACodec::UninitializedState : public ACodec::BaseState {
...
ACodec::UninitializedState::UninitializedState(ACodec *codec)
: BaseState(codec) { //★★BaseStateに丸投げ★★
}
//★★BaseStateを見てみる★★
struct ACodec::BaseState : public AState {
BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
...
ACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
: AState(parentState),
mCodec(codec) { //★★引数をそのまま設定しているだけ★★
}
//★★UninitializedStateの生成個所を探す★★
ACodec::ACodec()
: mQuirks(0),
...
mDescribeHDRStaticInfoIndex((OMX_INDEXTYPE)0) {
mUninitializedState = new UninitializedState(this); //★★thisが指すものはACodec★★
mLoadedState = new LoadedState(this);
つまりACodec::BaseState::mCodecは、UninitializeStateを生成したACodecです。もう一つの謎getLooper() が何を返すのか?も見てみます。
//android/frameworks/av/include/media/stagefright/foundation/AHandler.h
struct AHandler : public RefBase {
...
wp<ALooper> getLooper() const {
return mLooper; //★★mLooperを返すだけ★★
}
...
inline void setID(ALooper::handler_id id, wp<ALooper> looper) {
mID = id;
mLooper = looper; //★★mLooperはsetIDの引数そのまま★★
}
//android/frameworks/av/include/media/libstagefright/foundation/ALooperRoster.cpp
ALooper::handler_id ALooperRoster::registerHandler(
const sp<ALooper> looper, const sp<AHandler> &handler) {
Mutex::Autolock autoLock(mLock);
if (handler->id() != 0) {
CHECK(!"A handler must only be registered once.");
return INVALID_OPERATION;
}
HandlerInfo info;
info.mLooper = looper;
info.mHandler = handler;
ALooper::handler_id handlerID = mNextHandlerID++;
mHandlers.add(handlerID, info);
handler->setID(handlerID, looper); //★★setIDを呼んでいる個所はここだけ★★
return handlerID;
}
//media/libstagefright/foundation/ALooper.cpp
ALooperRoster gLooperRoster;
...
ALooper::handler_id ALooper::registerHandler(const sp<AHandler> &handler) {
return gLooperRoster.registerHandler(this, handler);
}
ALooper::registerHandlerはALooperをAHandlerに登録する仕組み、AHandler::getLooper() はAHandlerに登録されたALooperを返す仕組みのようです。取得 / 設定が一致しないのでややこしいです。設計を失敗したのかなあ?
例えばAHandler *hogeとALooper *fugaがあってfuga->registerHandler(hoge) としたならば、hoge->getLooper() は先ほど登録したfugaを返します。
ちなみにACodecはAHandlerを継承しているのでgetLooper() 関数を持っています。
ここまで分かればALooper::registerHandler() を呼んでいる個所を見て、引数がACodecオブジェクトであろう場所を見つければ、looperが指しているのが、どのALooperなのか?がやっと判明します。
しかしregisterHandler() の呼び出し箇所は非常に多くて、追いきれません。うーん、別のアプローチが必要でしょうか……?
< | 2017 | > | ||||
<< | < | 11 | > | >> | ||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
- | - | - | 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | - | - |
合計:
本日:
管理者: Katsuhiro Suzuki(katsuhiro( a t )katsuster.net)
This is Simple Diary 1.0
Copyright(C) Katsuhiro Suzuki 2006-2023.
Powered by PHP 8.2.15.
using GD bundled (2.1.0 compatible)(png support.)