The Media Kit Table of Contents | The Media Kit Index |
Derived from: none
Declared in: be/media/MediaNode.h
Library: libmedia.so
Allocation: Constructor only
BMediaNodeクラスは、Media Kitに関わる全てのnodeのスーパークラスです。しかしながら、あなたがBMediaNodeから直接派生クラスを作成することは決してありません。その代りに、BMediaNodeから順に派生したシステムインターフェイスクラスの一つから派生させることができます。それら他のクラス (BBufferProducerやBBufferConsumerなど)の使用方法の詳細については、それぞれの文書をご覧下さい。また、新しいnodeをどうやって作成するかという論議については"Creating New Node Classes"の16ページ目を見て下さい。
(複数の継承を使用する際に要求される)仮想継承の動作に癖があるため、あなたはBMediaNodeのコンストラクタをあなたのノードのコンストラクタ中で呼び出さなければならないでしょう。 "About Multiple Virtual Inheritance"の21ページ目をご覧下さい。
|
Media Nodeは、時間に対して高度に敏感な創造物です。その作業を行う上でもっとも微細な遅延が、メディアの再生や録音の品質に激烈な問題を引き起こしうるのです。普段はユーザにとって非常に大きな利益となる仮想記憶は、メディアを処理する作業に対して支障となりえます。時間に対する配慮が不完全な仮想記憶へのヒットは、メディアのパフォーマンスを破壊する原因になりえます。
リアルタイムなメモリ割り当てとロック機能は、仮想記憶システムがnodeのメモリをディスクにキャッシュしてしまうことを防ぐため、nodeをロックダウンする方法を提供します。これはnodeがそれ自身またはそのメモリがスワップファイルから取り出される間停止しなければならないという状態を回避します。
ユーザはどのようなタイプのnodeがロックされたメモリを使用するか、Media performanceアプリケーションを用いて設定することができます。典型的には、nodeはmalloc()及びfree()の代りに、リアルタイムなメモリ割り当てを使用すべきです。rtm_alloc()はB_MEDIA_REALTIME_ALLOCATORフラグがセットされれば自動的にメモリのロックを扱うので、あなたのnodeはそのことについて思い悩む必要はありません。
加えて、もしあなたが書いたnodeのタイプと一致したリアルタイムのフラグがセットされていた場合、あなたのnodeはまた自分のスレッドのスタックをロックダウンするためにmedia_init_realtime_thread()を呼び出します。適切に書かれたnodeは、リアルタイムフラグをチェックせず、常にmedia_init_realtime_thread()を呼び出します。なぜなら、もし対応したフラグがセットされていなければ、この機能はB_MEDIA_REALTIME_DISABLEDを返すからです。あなたは単にエラーを無視し、先へ進むことができます。
For example:
int32 *myThreadData = rtm_alloc(4096); myThread = spawn_thread(myThreadFunction, "Node Thread", B_NORMAL_PRIORITY, &myThreadData); status_t err = media_realtime_init_thread(myThread, 32768, B_MEDIA_REALTIME_VIDEO); if (err != B_OK && err != B_MEDIA_REALTIME_DISABLED) { printf("Can't lock down the thread.n"); } ...
もしadd-onやライブラリからのnodeがリアルタイムパフォーマンスを要求するなら、media_init_realtime_image()関数をメモリ上のイメージをロックダウンするために使用することができます。しかし、そのイメージがmalloc()を使用すると、そのイメージはロックされたメモリを割り当てられないということを銘記して下さい。これは制御不能となります。イメージがそれ自身をロックダウンすることは、さらにパフォーマンスを低下させます。(*)
|
二つのnode間の接続を確立するには、複数の段階を踏みます。nodeは、接続が確立する前に両者のサポートするデータフォーマットについて合意する必要があります。
あなたの書いたnodeがデフォルトの出力として(例えばAudio preferenceアプリケーションを使用して)システムミキサーと接続されることが可能なら、そのnodeは、GetNextInput()関数の自由な入力(free input)が受け入れるフォーマットに関して、できる限り柔軟である必要があります。GetNextInput()からあなたのnodeが返すフォーマットは、交渉プロセスの開始点として使用されるでしょう。より多くのワイルドカードをサポートすれば、その分いいでしょう。
他のnodeと自分のnodeとの間に接続を確立したいアプリケーションは、そのnodeの入力と他方のnodeからの出力のフォーマットを決定し、その後、フォーマットとともにBMediaRoster::Connect()を呼び出します。
もしBMediaRoster::Format()に渡されたフォーマットになんらかのワイルドカードがあれば、media rosterはあなたのnodeの出力に接続されたnodeの中でBBufferProducer::ProposeFormat()を呼び出します。producerは、ワイルドカードをもっとも特殊化されたフォーマットを形成することで特殊化します。それは、残されたどのワイルドカードもproducerにとって互換性を失わずに特化されることが保証されていなければなりません。
結果として得られたフォーマットは、いくつかのワイルドカードを残しています(あるいは、もしproducerが非常に選り好みの激しいものであれば、まったくないかもしれません)。media rosterはその後このフォーマットをあなたのconsumer nodeのBBufferConsumer::AcceptFormat()呼び出しに渡します。この関数は、残されたワイルドカードを特殊化し、このフォーマットを返すために実装されるはずのもので、特殊なフォーマットが記述されます。このフォーマットは接続を確立するために使用されます。
protected:
|
派生したクラスのコンストラクタから呼び出して下さい。
nodeは参照カウント 1 で作成されます。このカウントはAcquire()呼び出しが発行されるたびにインクリメントされ、Release()が呼び出されるたびにデクリメントされます。参照カウントが0になった時、nodeは削除されます。
|
Media serverがそれを使って何をしているかを確実に知っている訳ではない以上、あなたはBMediaNodeを決して削除してはいけません。その代わりに、media serverはnodeの参照カウントを維持し、それが使われなくなった時、自動的に削除します。
|
Acquire()は、nodeの参照カウントをインクリメントした後、nodeへのポインタを返します。
Release()は、その参照カウントをデクリメントし、nodeを開放します。もしカウントがゼロになれば、nodeは削除され、NULLが返されます。そうでなければ、nodeのポインタが返されます。
|
|
nodeによってサポートされたkindのセットに、kindを追加します。これは、システムにそのnodeがサポートするように実装されたnodeのインターフェイスのタイプがなにか知らせます。(BBufferProducerプロトコルをnodeが実装していることを示す)B_BUFFER_PRODUCER及び(音声デジタル化入力機器などの物理入力を実装していることを示す)B_PHYSICAL_INPUTを含めた値を取ることができます。
|
|
この関数は、nodeのインスタンスを作成するBMediaAddOnへのポインタを返すよう実装されます。もしnodeが(add-on中よりむしろ)アプリケーション中で生きていれば、NULLを返します。もしnodeがadd-on中にあれば、outInternalIDはadd-on中のnodeの内部的なIDを内包するように変更されます。
|
nodeは与えられたcookieと時間を記憶するためにAddTimer()関数を実装します。toPerformanceTime時間に到達したとき、nodeは、記録されたtoPerformanceTime値をnotifyPoint引数として渡し、一致したcookieの値とともにTimerExpired()を呼び出します。
AddTimer()は、全く問題なければB_OKを返すよう実装されます。そうでなければ、適切なエラーコードを返します。
|
nodeが要求を監視するnodeのポートのport_idを返します。nodeは有効なKernel Kit portを返すよう実装されなければなりません。
protected:
|
DeleteHook()関数は、BMediaNodeオブジェクトを削除するために呼び出されます。もしnodeが削除される前に追加の動作を必要とするなら、あなたはこの関数を補強することができますが、常に下記の行を含める必要があります :
delete this;
または、関数の継承された原形を通して呼び出します。もしnodeが問題なく削除されたなら、B_OKを返して下さい。そうでなければ、適切なエラーコードを返して下さい。
|
あなたのnodeのアトリビュートをもって(inMaxCount個のアトリビュートを格納する空間を持つ)配列outAttributesを満たすために実装される関数です。
もし問題がなければB_OKを返し、そうでなければ適切なエラーコードを返して下さい。
|
もしあなたのnodeが、それ自身またはそれの派生したインターフェイスが理解できないメッセージを受け取ったなら、この関数に沿ったメッセージを理解し、受け渡して下さい。それはどうにかしてその問題を扱うのに功を奏するでしょう。HandleMessage()関数に受け取られる全ての引数はHandleBadMessage()を通じて直接渡されます。
|
制御ポートから受け取ったメッセージが与えられると、この関数はメッセージを適切なBMediaNodeのフック関数にディスパッチします。もしそのメッセージがフック関数に一致しなければ、B_ERRORが返されます。
あなたがあなた自身の(BBufferConsumer, BBufferProducer等から派生する)media nodeを実装する際は、常にあなたのnodeのHandleMessage()実装を通じてBMediaNode::HandleMessage()を呼び出す必要があります。
例えば、もしあなたのnodeがBBufferProducerとBBufferConsumerの両方から派生しているとすると、あなたはBBufferProducer::HandleMessage()とBBufferConsumer::HandleMessage()を呼び出した後、BMediaNode::HandleMessage()を呼び出すべきです。例えばこんな具合です。
virtual status_t MyBufferProducerConsumer::HandleMessage(int32 message, const void *data, size_t size) { if (code == SOME_THING_I_DO) { DoWhatever(); } else if (BBufferConsumer::HandleMessage(message, data, size) && BBufferProducer::HandleMessage(message, data, size) && BMediaNode::HandleMessage(message, data, size)) { BMediaNode::HandleBadMessage(message, data, size); } }
BMediaNode::HandleBadMessage()は、もしHandleMessage()の実装が一つもそのメッセージを受け入れなかった場合に呼び出されるということに留意して下さい。
0x60000000と0x7FFFFFFFの間のcodeの値はアプリケーションによる利用が可能です。0x60000000未満の値はMedia Kitによる利用のために予約されており、典型的にはあなたのnodeにおける特定の仮想フック関数に対応します。もしあなたがcodeの値を特殊なフックのために知る必要があるという理由を示せるなら、あなたはdevsupport@be.comに電子メールを送り、我々がその情報を共有してもよいとあなたに同意するるかどうかを知ることができます。
|
RETURN CODES
B_OK. そのメッセージはディスパッチされました。
|
メディアサーバーによってnodeに割り当てられたedia_node_idを返します。もしnodeがまだ登録されていなければ結果は0となり、もしnodeの登録を企図している間にエラーが生じたなら結果は負の値になります。
|
nodeに実装されているインターフェイスが何か示すビットマスクを返します。有効なインターフェイスにどんな種類があるかについては181ページの"node_kind"をご覧下さい。
|
nodeの名前を特定する可読性の文字列を返します。このポインタはあなたがnodeをRelease()するまでの間だけ有効であり、その後にはなにもない場所を示すようになります。
protected:
|
BBufferConsumer nodeで使用されることを第一に意図されたこの関数は、新しい change tagの値を作成して返します。
|
アプリケーションがmedia rosterを経由してこのnodeにアクセスする際に使用されるmedia_node構造体を返します。
|
Media Serverは、nodeが登録された後にこのフック関数を呼び出します。
|
stop requestを使用し終わった時(バッファがもはや流れていない時)、この関数を呼び出します。もし誰かがあなたからのstop notificationを待っていれば、それが通達されます。引数 whenPerformanceTimeは、それが扱っているstop命令のperformance timeとなります。
誰かがnode stop messageが通達されるのを待っている… これは、オフライン(レンダリング)モードで動作しているアプリケーションに、nodeが実際に作業を完了した際、知らせます。
もしあなたのnodeがBBufferProducerであれば、下流のconsumerはあなたのnodeが(自動的にであっても)停止したことをBBufferConsumer::ProducerDataStatus(B_PRODUCER_STOPPED)の呼び出しによって知らせます。
|
RETURN CODES
B_OK. No error.
protected:
|
このフック関数は、もしnodeの呼び出しであるBMediaRoster::PrerollNode()をアプリケーションが使用したら、Start()メッセージがあなたのnodeに届く前に呼び出されます。これは、メディアが開始された時に出来るだけ速く反応できるように、nodeにそのメディアへの準備を行う機会を与えます。
protected:
|
whichErrorによって特定されるエラーコードを、このnodeから通知を受け取るものに伝達します(BMediaRoster::StartWatching()及びBMediaRoster::StopWatching()をご覧下さい)。もしinfoがNULLでなければ、それはエラー通知メッセージの規範となるメッセージとして使用されます。
RETURN CODES
B_OK. このエラー報告はエラーなしに送信されました。
protected:
|
この関数は、nodeによって発行された要求が完了したときには必ず呼び出されます。info構造体には要求の結果が記述されています。
info構造体のchange_tagフィールドによって、完了した要求が識別されます。この値は、その要求を開始した関数に渡されるのと同じものです。
もしあなたが幸せなら、B_OKが返され、そうでなければ適切なエラーコードが返されます。
|
protected:
|
RunMode()は、nodeの現在のrun_mode設定を返します。
SetRunMode()フック関数は、nodeのrun modeを変更するよう要求したときに呼び出されます。
182ページの""run_mode"もご覧下さい。
protected:
|
このフック関数は、BMediaRosterの呼び出しによってnodeが指定のmediaTimeをseek(検索)するよう求めた時に呼び出されます。
nodeが検索処理を開始した時間を表すperformanceTimeは、将来実装されます。
|
mediaTimeが0の時は、メディアデータの最初を示します。
|
SetTimeSource()フック関数は、nodeが新しいtime sourceに従属するよう要求された時に呼び出されます。新しい時間軸(time scale)で処理する必要のある修正がなんであれ、そのためにこの関数を追加します。
TimeSource()は、そのnodeが現在従属しているBTimeSourceへのポインタを返します。もしtime sourceが明確に要求されなければ、system time sourceが使用され、それが返されるものとなります。
|
protected:
|
このフック関数は、nodeがBMediaRosterへの要求で開始されるときに呼び出されます。
nodeが動作を開始した時間を示す指定のperformanceTimeは、将来実装されます。
|
protected:
|
このフック関数は、nodeがBMediaRosterへの要求により停止させられる時に呼び出されます。
nodeが停止した時間を示す指定されたperformanceTimeは、将来実装されます。
もしimmediateが真であれば、あなたのnodeはperformanceTimeの値を無視し、同期的に演奏を停止します。Stop()が返ったとき、あなたは下流のconsumerから受け取ったBBufferに書込まないことを約束しており、また再びStart()が呼び出されるまで、更にバッファを送らないことを約束します。
|
nodeは、それが停止した時に持っている全てのバッファを再利用します。
protected:
|
このフック関数は、nodeが従属しているtime sourceが、nodeが見ているperformance timeの進行に突然のジャンプがあって(seek動作経由で)別の所に移されたときに呼び出されます。引数newPerformanceTimeは新しいperformance timeを示します。この変更は、引数atRealTimeによって指定されたreal timeに発生します。
nodeは、深刻などもりや失敗や演奏の加速が生じないように、この変化に対する準備をすることで呼び出しに反応するべきです。適切な手段が、演奏の質に対する影響を最小限にするために講じられるべきです。例えば、音声の一部分がスムーズに繰り返したりスキップされたりできるように、です。
TimeWarp()を実装する時は、BMediaNode::TimeWarp()を他の全てのinheritされたTimeWarp()の形を通して呼び出します。
protected:
|
この関数はwaitUntilで指定されたreal timeか、あるいは制御ポートからメッセージを受け取るまで待ちます。flagsは現在使用されておらず、0でなければなりません。
メッセージを受け取ったら、適切なHandleMessage()呼び出しが行われます。nodeのクラス派生を与えられて:
一旦これが終了すれば、WaitForMessage()が返ります。お分かりのように、これは受け取ったメッセージを処理する作業の大部分を扱うために、あなたの制御ポートから呼び出すことが出来ます。
RETURN CODES
B_OK. 与えられた時間期限の間に発生します。
Declared in: <be/media/MediaNode.h>
Constant | Description |
---|---|
B_NODE_FAILED_START | nodeがStart()要求に失敗。 |
B_NODE_FAILED_STOP | nodeがStop()に失敗。 |
B_NODE_FAILED_SEEK | nodeがSeek()要求に失敗 |
B_NODE_FAILED_SET_RUN_MODE | nodeのrun_modeが設定できなかった。 |
B_NODE_FAILED_TIME_WARP | nodeがtime warp要求を実行できなかった。 |
B_NODE_FAILED_PREROLL | nodeがPreroll()要求に失敗。 |
B_NODE_FAILED_SET_TIME_SOURCE_FO R | nodeのtime sourceが変更できなかった。 |
B_NODE_IN_DISTRESS | nodeが全体的に苦悩している。 |
node_error型は、nodeが、nodeを監視するよう登録されたBMessengerに通知できるエラーを定義しています。
Declared in: <be/media/MediaDefs.h>
Constant | Description |
---|---|
B_BUFFER_PRODUCER | このフレーバーはBBufferProducerを実装しています。 |
B_BUFFER_CONSUMER | このフレーバーはBBufferConsumerを実装しています。 |
B_TIME_SOURCE | このフレーバーはBTimeSourceを実装しています。 |
B_CONTROLLABLE | The flavor implements BControllable. -->このフレーバーはBControllableを実装しています。 |
B_FILE_INTERFACE | このフレーバーはBFileInterfaceを実装しています。 |
B_ENTITY_INTERFACE | このフレーバーはBEntryInterfaceを実装しています(R4では使用不可)。 |
B_PHYSICAL_INPUT | このフレーバーは、(インプットジャックのような)物理的な入力部位を表現します。 |
B_PHYSICAL_OUTPUT | このフレーバーは(ラインアウトのような)物理的な出力部位を表現します。 |
B_SYSTEM_MIXER | このフレーバーはシステムミキサーを表現します。 |
特定のフレーバーにサポートされたnodeの型を定義しています。フレーバーはnodeの一つ以上の型を実装できるため、ビットの論理和を使ってこれらの値を組み合わせることが出来ます。
Declared in: <be/media/MediaNode.h>
run_mode型は、もし演奏速度が要求されている速度から逸脱したら、どうやってnodeがうまく処理するかを示す。
offlineモード(B_OFFLINE)にある場合は、nodeは特定の時間でバッファの処理することを心配する必要はありません。それぞれのバッファのperformance timeはBTimeSourceよりもバッファのタイムスタンプから導かれます。事実、あなたはnodeがofflineモードにある間、nodeの処理スレッドを低い優先度に設定するためset_thread_priority()を呼び出そうと考えるでしょう。これはソフトウェアがディスクにメディアをレンダリングするのに効果的な手法となり、ユーザが背後でレンダリングしている間も作業を続けられるようにします。
recordingモード(B_RECORDING)は、データが物理的な入力装置からサンプリングされている時に使用されます。これらの装置は常にタイムスタンプが過去のバッファを供給します。(バッファはそれがサンプリングされた時刻をスタンプされます。それはもちろん過去で、もしあなたが27世紀の教授からタイムマシーンを盗んだ場合でも、あなたは多分BeOS R127.1を動作させるでしょうし、この本は哀しいほど時代遅れになっているでしょう)
B_RECORDINGモードの使用は、タイムスタンプが過去になるだろう他のnodeに警告するのに有用です。
B_DECREASE_PRECISIONモードでは、nodeは遅延が生じた場合、普通よりも速くメディアデータのバッファを演奏することで追いつくように企図します。音声の場合これはより高いサンプリングレートで再生することを意味します。映像では、フレームレートを一時的に増加させます。
もしnodeがB_INCREASE_LATENCYモードで遅れた場合、nodeは内部的な遅延時間(latency measurement)を増やし、メディアストリーム上のあなたのnodeの上流にあるすべてのnodeのLateNoticeReceived()関数呼び出しを送信します。
あなたのnodeはその後に、バッファが示すperformance timeよりも早くそれぞれのバッファを生成するよう試するため、バッファが目的地に到着するのに、より多くの時間ができます。
このモードは、スループットが大幅に遅れるデータストリームの補正を意図しています。例えば、もしメディアデータがネットワーク越しに流れているなら、バッファ(latency)をさらに追加することでトラフィックの変動に対応することが求められます。
B_DROP_DATAにあるときは、もし遅延が生じれば、nodeは単純にバッファをスキップします。あなたがまだバッファを受け取るなら、正しいperformance timeで可能なかぎり多くのバッファの再生を保持するためにしなければならないことを全て無視すべきであるということに注意して下さい。
The Media Kit Table of Contents | The Media Kit Index |
Copyright © 2000 Be, Inc. All rights reserved..