Tünel modu olarak da bilinen multimedya tünelleme, sıkıştırılmış video verilerinin uygulama kodu veya Android çerçeve kodu tarafından işlenmeden doğrudan bir donanım video kod çözücüsü aracılığıyla bir ekrana tünellenmesini sağlar. Android yığınının altındaki cihaza özel kod, video çerçevesi sunum zaman damgalarını aşağıdaki dahili saat türlerinden biriyle karşılaştırarak hangi video çerçevelerinin ekrana gönderileceğini ve ne zaman gönderileceğini belirler:
Android 5 veya sonraki sürümlerde isteğe bağlı video oynatma için, uygulama tarafından geçirilen ses sunumu zaman damgalarıyla senkronize edilmiş bir
AudioTracksaatAndroid 11 veya sonraki sürümlerde canlı yayın oynatma için tuner tarafından yönlendirilen bir program referans saati (PCR) veya sistem saati (STC)
Arka plan
Android'de tünel modu dışı video oynatma, sıkıştırılmış bir video karesinin kodu çözüldüğünde uygulamaya bildirim gönderir. Uygulama daha sonra, kod çözme işlemi yapılan video karesini, karşılık gelen ses karesiyle aynı sistem saati zamanında oluşturulmak üzere ekrana gönderir. Doğru zamanlamayı hesaplamak için geçmiş AudioTimestamp örnekleri alınır.
Tünellenmiş video oynatma, uygulama kodunu atlayıp video üzerinde işlem yapan süreçlerin sayısını azalttığı için OEM uygulamasına bağlı olarak daha verimli video oluşturma sağlayabilir. Ayrıca, Android'in video oluşturma isteklerinin zamanlaması ile gerçek donanım dikey senkronizasyonlarının zamanlaması arasındaki olası çarpıklığın neden olduğu zamanlama sorunlarını önleyerek seçilen saatle (ÇHC, STC veya ses) daha doğru video ritmi ve senkronizasyonu sağlayabilir. Ancak, arabellekler Android grafik yığınını atladığından tünel oluşturma, resim içinde resim (PiP) pencerelerinde bulanıklaştırma veya yuvarlak köşeler gibi GPU efektlerinin desteğini de azaltabilir.
Aşağıdaki şemada, tünellemenin video oynatma sürecini nasıl basitleştirdiği gösterilmektedir.

Şekil 1. Tünellenmemiş ve tünellenmiş video oynatma süreçlerinin karşılaştırması.
Uygulama geliştiriciler için
Çoğu uygulama geliştirici, oynatma uygulaması için bir kitaplıkla entegrasyon yaptığından çoğu durumda uygulama için yalnızca bu kitaplığın tünellenmiş oynatma için yeniden yapılandırılması gerekir. Tünellenmiş video oynatıcının düşük düzeyde uygulanması için aşağıdaki talimatları kullanın.
Android 5 veya sonraki sürümlerde isteğe bağlı video oynatma için:
SurfaceViewörneği oluşturun.audioSessionIdörneği oluşturun.2. adımda oluşturulan
audioSessionIdörneğiyleAudioTrackveMediaCodecörneklerini oluşturun.Ses verilerindeki ilk ses karesinin sunu zaman damgasıyla birlikte ses verilerini
AudioTrack'ya sıraya alın.
Android 11 veya sonraki sürümlerde canlı yayın oynatma için:
SurfaceViewörneği oluşturun.TunerkaynağındanavSyncHwIdörneği alın.2. adımda oluşturulan
avSyncHwIdörneğiyleAudioTrackveMediaCodecörnekleri oluşturun.
API çağrısı akışı aşağıdaki kod snippet'lerinde gösterilmektedir:
aab.setContentType(AudioAttributes.CONTENT_TYPE_MOVIE);
// configure for audio clock sync
aab.setFlag(AudioAttributes.FLAG_HW_AV_SYNC);
// or, for tuner clock sync (Android 11 or higher)
new tunerConfig = TunerConfiguration(0, avSyncId);
aab.setTunerConfiguration(tunerConfig);
if (codecName == null) {
return FAILURE;
}
// configure for audio clock sync
mf.setInteger(MediaFormat.KEY_AUDIO_SESSION_ID, audioSessionId);
// or, for tuner clock sync (Android 11 or higher)
mf.setInteger(MediaFormat.KEY_HARDWARE_AV_SYNC_ID, avSyncId);
İsteğe bağlı video oynatmanın davranışı
Tünellenmiş seç-izle video oynatma işlemi AudioTrack
oynatma işlemine örtülü olarak bağlı olduğundan, tünellenmiş video oynatma işlemi ses oynatma işleminin davranışına bağlı olabilir.
Çoğu cihazda, varsayılan olarak ses oynatma başlayana kadar video karesi oluşturulmaz. Ancak uygulama, ses oynatmayı başlatmadan önce bir video karesi oluşturması gerekebilir. Örneğin, arama sırasında kullanıcının mevcut video konumunu göstermek için.
Kuyruğa alınan ilk video karesinin kodu çözülür çözülmez oluşturulması gerektiğini belirtmek için
PARAMETER_KEY_TUNNEL_PEEKparametresini1olarak ayarlayın. Sıkıştırılmış video kareleri kuyrukta yeniden sıralandığında (ör. B kareleri mevcut olduğunda) ilk gösterilen video karesinin her zaman bir I karesi olması gerekir.Sesi çalmaya başlayana kadar sıraya alınan ilk video karesinin oluşturulmasını istemiyorsanız bu parametreyi
0olarak ayarlayın.Bu parametre ayarlanmazsa cihazın davranışını OEM belirler.
AudioTrack'ya ses verileri sağlanmadığında ve arabellekler boş olduğunda (ses yetersizliği) ses saati ilerlemediği için video oynatma, daha fazla ses verisi yazılana kadar durur.Oynatma sırasında, uygulamanın düzeltemediği süreksizlikler ses sunumu zaman damgalarında görünebilir. Bu durumda OEM, mevcut video karesini duraklatarak olumsuz boşlukları, video karelerini bırakarak veya sessiz ses kareleri ekleyerek (OEM uygulamasına bağlı olarak) olumlu boşlukları düzeltir. Eklenen sessiz ses çerçeveleri için
AudioTimestampçerçeve konumu artmaz.
Hassas sarma işlemindeki sıra akışı
Hassas arama, videoda belirli bir noktayı bulmanızı sağlar. Yalnızca en yakın I-frame'e atlayan ve hedef konumdan birkaç saniye sapabilen animasyon karesi aramanın aksine, hassas sarma, videoyu tam olarak istenen zaman damgasında oluşturur. Bu API sırasına uyulması, uygulamanın arka planda önceden oynatma ve zamanlama senkronizasyonunu sorunsuz bir şekilde gerçekleştirmesini sağlar. Bu, oynatma devam ettiğinde hedef karenin anında gösterilmesini sağlar.
Hassas bir arama işlemi gerçekleştirmek için Şekil 2'de gösterilen yürütme sırasını izleyin:
Şekil 2. Hassas sarma için akış sırası
Önemli ayrıntılar:
Paralel yürütme: Tek bir
parkutusundaki adımları aynı anda yürütebilirsiniz. Örneğin,MediaCodecgörüntülü görüşmeleriAudioTrack'dan bağımsızdır.Sıralı bağımlılıklar: İkinci
parkutusuna geçmeden önce ilkparkutusundaki tüm işlemleri çağırın. Uygulama, özellikleAudioTrack.writeve videoMediaCodecarabelleklerininAudioTrack.playçağrılmadan önce sıraya alınmasını sağlamalıdır.
Değişken hızlı oynatmanın sıra akışı
Değişken hızlı oynatma, videoları normal hızdan daha hızlı veya daha yavaş oynatmanıza olanak tanır. Bu özellik, kullanıcıların içerikleri daha hızlı (ör. zaman kazanmak için eğitici dersleri veya podcast'leri 1,5 kat ya da 2 kat hızda oynatma) ya da daha yavaş (ör. atletik oyunları veya eğitici videoları 0,5 kat hızda analiz etme) tüketmesine olanak tanımak için uygulamalar tarafından yaygın olarak kullanılır.
Hızı ayarlamak için Şekil 3'te gösterilen yürütme sırasını izleyin:
Şekil 3. Hızı ayarlamak için adım sırası.
Aşağıdaki davranışlar ve teknik şartlar, Şekil 3'teki sıralı diyagramda yer almaz:
AudioTrack.getTimestamp, orijinal ses girişi frekansına göreframePositiondeğerini döndürür. Örneğin, 44.100 Hz giriş ve 2, 0x oynatma hızıyla 2 saniye oynatıldıktan sonraAudioTrack.getTimestamp, 176.400framePositiondeğerini döndürür.Uygulama
setSpeed(1.5)işlevini çağırır ve bu işlem başarılı olursa, ardından uygulamasetSpeed(30)işlevini çağırır ve bu işlem başarısız olursa oynatma 1, 5 kat hızda kalır.Ses kapatılırsa (
setVolumekullanılarak) video kareleri ses konumuna göre oluşturulduğundan uygulamanın ses arabelleklerini göndermesi gerekir.Hız değiştirildiğinde ses perdesi korunur.
Oynatma hızı, diğer oynatma işlemlerinden etkilenmez.
1. örnek: Oynatma hızı 1,5x ise ve
AudioTrackduraklatılmışsaAudioTrackdevam ettirildikten sonra hız 1,5x olarak kalır.2.örnek: Oynatma hızı 1, 5 kat ise ve kullanıcı farklı bir PTS'ye giderse oynatma hızı 2.Şekil'de gösterildiği gibi 1, 5 kat olarak kalır.
Tüm karelerin, seçilen hızda oluşturulmak üzere zamanında kodunun çözülmesini sağlamak için
KEY_OPERATING_RATEdeğerini video kare hızı ile oynatma hızının çarpımına eşit olacak şekilde ayarlayın.KEY_OPERATING_RATEdeğeri yeterince yüksek ayarlanmamışsa codec, kareleri yeterince hızlı çözemeyebilir ve bu da oynatma sırasında istenmeyen kare düşmelerine neden olabilir.- Örnek: İçeriğin orijinal kare hızı 60 fps ise ve oynatma hızı 2x ise
KEY_OPERATING_RATEdeğerini120olarak ayarlayın.
- Örnek: İçeriğin orijinal kare hızı 60 fps ise ve oynatma hızı 2x ise
Hızı, desteklenen farklı hızlarla tekrar tekrar ayarlamak herhangi bir hataya neden olmamalıdır. Son çağrıdan sonraki oynatma davranışı, hızın yalnızca bir kez ve en son hız ayarına göre ayarlanmasıyla aynı olmalıdır.
Cihaz üreticileri için
Yapılandırma
OEM'ler, tünellenmiş video oynatmayı desteklemek için ayrı bir video kod çözücü oluşturmalıdır.
Bu kod çözücü, media_codecs.xml dosyasında tünellenmiş oynatma özelliğine sahip olduğunu bildirmelidir:
<Feature name="tunneled-playback" required="true"/>
Tünellenmiş bir MediaCodec örneği ses oturumu kimliğiyle yapılandırıldığında AudioFlinger, bu HW_AV_SYNC kimliği için sorgu gönderir:
if (entry.getKey().equals(MediaFormat.KEY_AUDIO_SESSION_ID)) {
int sessionId = 0;
try {
sessionId = (Integer)entry.getValue();
}
catch (Exception e) {
throw new IllegalArgumentException("Wrong Session ID Parameter!");
}
keys[i] = "audio-hw-sync";
values[i] = AudioSystem.getAudioHwSyncForSession(sessionId);
}
Bu sorgu sırasında, AudioFlinger, birincil ses sisteminden HW_AV_SYNC kimliğini alır ve dahili olarak ses oturumu kimliğiyle ilişkilendirir:
audio_hw_device_t *dev = mPrimaryHardwareDev->hwDevice();
char *reply = dev->get_parameters(dev, AUDIO_PARAMETER_HW_AV_SYNC);
AudioParameter param = AudioParameter(String8(reply));
int hwAVSyncId;
param.getInt(String8(AUDIO_PARAMETER_HW_AV_SYNC), hwAVSyncId);
AudioTrack örneği zaten oluşturulmuşsa HW_AV_SYNC kimliği, aynı ses oturumu kimliğine sahip çıkış akışına iletilir. Henüz oluşturulmadıysa HW_AV_SYNC kimliği, AudioTrack oluşturma sırasında çıkış akışına iletilir. Bu işlem, playback
thread tarafından yapılır:
mOutput->stream->common.set_parameters(&mOutput->stream->common, AUDIO_PARAMETER_STREAM_HW_AV_SYNC, hwAVSyncId);
HW_AV_SYNC kimliği, ses çıkışı akışına veya Tuner yapılandırmasına karşılık gelip gelmediğine bakılmaksızın, OEM kodu codec'i ilgili ses çıkışı akışıyla veya tuner akışıyla ilişkilendirebilmesi için OMX ya da Codec2 bileşenine iletilir.
Bileşen yapılandırması sırasında, OMX veya Codec2 bileşeni, codec'i bir Hardware Composer (HWC) katmanıyla ilişkilendirmek için kullanılabilecek bir bant dışı işleyici döndürmelidir. Uygulama bir yüzeyi MediaCodec ile ilişkilendirdiğinde bu yan bant tutma yeri, SurfaceFlinger aracılığıyla HWC'ye aktarılır. Bu tutma yeri, katmanı yan bant katmanı olarak yapılandırır.
err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
if (err != OK) {
ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).", sidebandHandle, err);
return err;
}
HWC, uygun zamanda codec çıkışından yeni görüntü arabellekleri almaktan (ilişkili ses çıkış akışıyla veya tuner programı referans saatiyle senkronize edilmiş), arabellekleri diğer katmanların mevcut içerikleriyle birleştirmekten ve ortaya çıkan görüntüyü göstermekten sorumludur. Bu işlem, normal hazırlık ve ayarlama döngüsünden bağımsız olarak gerçekleşir. Hazırlama ve ayarlama çağrıları yalnızca diğer katmanlar değiştiğinde veya yan bant katmanının özellikleri (ör. konum veya boyut) değiştiğinde gerçekleşir.
OMX
Tünellenmiş bir kod çözücü bileşeni şunları desteklemelidir:
Ses çıkış cihazıyla ilişkili
HW_AV_SYNCkimliğini iletmek içinConfigureVideoTunnelModeParamsyapısını kullananOMX.google.android.index.configureVideoTunnelModeextended parametresini ayarlama.Ses oynatma başlatılıp başlatılmadığına bakılmaksızın, codec'e ilk çözümlenen video karesini oluşturmasını veya oluşturmamasını söyleyen
OMX_IndexConfigAndroidTunnelPeekparametresini yapılandırma.İlk tünellenmiş video karesinin kodu çözüldüğünde ve oluşturulmaya hazır olduğunda
OMX_EventOnFirstTunnelFrameReadyetkinliğini gönderme.
AOSP uygulaması, aşağıdaki kod snippet'inde gösterildiği gibi ACodec içinde OMXNodeInstance üzerinden tünel modunu yapılandırır:
OMX_INDEXTYPE index;
OMX_STRING name = const_cast<OMX_STRING>(
"OMX.google.android.index.configureVideoTunnelMode");
OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
ConfigureVideoTunnelModeParams tunnelParams;
InitOMXParams(&tunnelParams);
tunnelParams.nPortIndex = portIndex;
tunnelParams.bTunneled = tunneled;
tunnelParams.nAudioHwSync = audioHwSync;
err = OMX_SetParameter(mHandle, index, &tunnelParams);
err = OMX_GetParameter(mHandle, index, &tunnelParams);
sidebandHandle = (native_handle_t*)tunnelParams.pSidebandWindow;
Bileşen bu yapılandırmayı destekliyorsa bu codec'e bir bant dışı tutma yeri ayırmalı ve HWC'nin ilişkili codec'i tanımlayabilmesi için pSidebandWindow üyesi aracılığıyla geri geçirmelidir. Bileşen bu yapılandırmayı desteklemiyorsa bTunneled değerini OMX_FALSE olarak ayarlamalıdır.
Codec2
Android 11 veya sonraki sürümlerde Codec2, tünellenmiş oynatmayı destekler. Kod çözücü bileşeni aşağıdakileri desteklemelidir:
Tünel modunu yapılandıran ve ses çıkışı cihazından veya tuner yapılandırmasından alınan
HW_AV_SYNCdeğerlerini iletenC2PortTunneledModeTuningyapılandırılıyor.HWC için bant dışı tutma yerini ayırmak ve almak üzere
C2_PARAMKEY_OUTPUT_TUNNEL_HANDLEsorgulanır.C2_PARAMKEY_TUNNEL_HOLD_RENDER,C2Worköğesine eklendiğinde işleniyor. Bu durumda, codec'e kod çözme ve işin tamamlandığını bildirme talimatı veriliyor ancak 1) codec'e daha sonra oluşturma talimatı verilene veya 2) ses oynatma başlayana kadar çıkış arabelleğini oluşturma talimatı verilmiyor.C2_PARAMKEY_TUNNEL_START_RENDERişleme: Bu, ses oynatma başlamamış olsa bile codec'eC2_PARAMKEY_TUNNEL_HOLD_RENDERile işaretlenen kareyi hemen oluşturma talimatı verir.debug.stagefright.ccodec_delayed_paramsyapılandırılmamış olarak bırakın (önerilir). Yapılandırırsanızfalseolarak ayarlayın.
AOSP uygulaması, aşağıdaki kod snippet'inde gösterildiği gibi C2PortTunnelModeTuning üzerinden CCodec içinde tünel modunu yapılandırır:
if (msg->findInt32("audio-hw-sync", &tunneledPlayback->m.syncId[0])) {
tunneledPlayback->m.syncType =
C2PortTunneledModeTuning::Struct::sync_type_t::AUDIO_HW_SYNC;
} else if (msg->findInt32("hw-av-sync-id", &tunneledPlayback->m.syncId[0])) {
tunneledPlayback->m.syncType =
C2PortTunneledModeTuning::Struct::sync_type_t::HW_AV_SYNC;
} else {
tunneledPlayback->m.syncType =
C2PortTunneledModeTuning::Struct::sync_type_t::REALTIME;
tunneledPlayback->setFlexCount(0);
}
c2_status_t c2err = comp->config({ tunneledPlayback.get() }, C2_MAY_BLOCK,
failures);
std::vector<std::unique_ptr<C2Param>> params;
c2err = comp->query({}, {C2PortTunnelHandleTuning::output::PARAM_TYPE},
C2_DONT_BLOCK, ¶ms);
if (c2err == C2_OK && params.size() == 1u) {
C2PortTunnelHandleTuning::output *videoTunnelSideband =
C2PortTunnelHandleTuning::output::From(params[0].get());
return OK;
}
Bileşen bu yapılandırmayı destekliyorsa bu codec'e bir yan bant tutma yeri ayırmalı ve HWC'nin ilişkili codec'i tanımlayabilmesi için C2PortTunnelHandlingTuning üzerinden geri geçirmelidir.
Ses HAL
İsteğe bağlı video oynatma için Audio HAL, uygulamanın yazdığı her ses verisi bloğunun başında bulunan bir başlıkta büyük endian biçiminde ses verileriyle birlikte ses sunumu zaman damgalarını alır:
struct TunnelModeSyncHeader {
// The 32-bit data to identify the sync header (0x55550002)
int32 syncWord;
// The size of the audio data following the sync header before the next sync
// header might be found.
int32 sizeInBytes;
// The presentation timestamp of the first audio sample following the sync
// header.
int64 presentationTimestamp;
// The number of bytes to skip after the beginning of the sync header to find the
// first audio sample (20 bytes for compressed audio, or larger for PCM, aligned
// to the channel count and sample size).
int32 offset;
}
HWC'nin video karelerini ilgili ses kareleriyle senkronize olarak oluşturması için Audio HAL'nin senkronizasyon başlığını ayrıştırması ve oynatma saatini ses oluşturmayla yeniden senkronize etmek için sunum zaman damgasını kullanması gerekir. Sıkıştırılmış ses oynatılırken yeniden senkronizasyon yapmak için Ses HAL'inin, oynatma süresini belirlemek üzere sıkıştırılmış ses verilerindeki meta verileri ayrıştırması gerekebilir.
Desteği duraklatma
Android 5 veya daha eski sürümlerde duraklatma özelliği desteklenmez. Tünellenmiş oynatmayı yalnızca A/V yetersizliği nedeniyle duraklatabilirsiniz ancak videonun dahili arabelleği büyükse (örneğin, OMX bileşeninde bir saniyelik veri varsa) duraklatma yanıt vermiyormuş gibi görünür.
Android 5.1 veya sonraki sürümlerde AudioFlinger, doğrudan (tünellenmiş) ses çıkışları için duraklatma ve devam ettirme işlemlerini destekler. HAL, duraklatma ve devam ettirme işlemlerini uyguluyorsa duraklatma ve devam ettirme işlemleri HAL'ye iletilir.
Duraklatma, temizleme, devam ettirme çağrı sırası, HAL çağrıları oynatma iş parçacığında (boşaltma ile aynı) yürütülerek uygulanır.
Uygulama önerileri
Ses HAL
Android 11'de A/V senkronizasyonu için PCR veya STC'den alınan donanım senkronizasyonu kimliği kullanılabilir. Bu nedenle, yalnızca video akışı desteklenir.
Android 10 veya önceki sürümlerde, tünellenmiş video oynatmayı destekleyen cihazların audio_policy.conf dosyasında FLAG_HW_AV_SYNC ve AUDIO_OUTPUT_FLAG_DIRECT işaretlerini içeren en az bir ses çıkışı akışı profili olmalıdır. Bu işaretler, sistem saatini ses saatinden ayarlamak için kullanılır.
OMX
Cihaz üreticileri, tünellenmiş video oynatma için ayrı bir OMX bileşenine sahip olmalıdır (üreticiler, güvenli oynatma gibi diğer ses ve video oynatma türleri için ek OMX bileşenlerine sahip olabilir). Tünellenmiş bileşen:
Çıkış bağlantı noktasında 0 arabellek (
nBufferCountMin,nBufferCountActual) belirtin.OMX.google.android.index.prepareForAdaptivePlayback setParameteruzantısını uygulayın.media_codecs.xmldosyasında özelliklerini belirtin ve tünellenmiş oynatma özelliğini beyan edin. Ayrıca, çerçeve boyutu, hizalama veya bit hızıyla ilgili sınırlamalar da açıklanmalıdır. Aşağıda bir örnek gösterilmektedir:<MediaCodec name="OMX.OEM_NAME.VIDEO.DECODER.AVC.tunneled" type="video/avc" > <Feature name="adaptive-playback" /> <Feature name="tunneled-playback" required=”true” /> <Limit name="size" min="32x32" max="3840x2160" /> <Limit name="alignment" value="2x2" /> <Limit name="bitrate" range="1-20000000" /> ... </MediaCodec>
Tünellenmiş ve tünellenmemiş kod çözme işlemlerini desteklemek için aynı OMX bileşeni kullanılıyorsa tünellenmiş oynatma özelliği zorunlu olmamalıdır. Bu durumda, tünellenmiş ve tünellenmemiş kod çözücüler aynı özellik sınırlamalarına sahip olur. Aşağıda bir örnek gösterilmiştir:
<MediaCodec name="OMX._OEM\_NAME_.VIDEO.DECODER.AVC" type="video/avc" >
<Feature name="adaptive-playback" />
<Feature name="tunneled-playback" />
<Limit name="size" min="32x32" max="3840x2160" />
<Limit name="alignment" value="2x2" />
<Limit name="bitrate" range="1-20000000" />
...
</MediaCodec>
Donanım Bestecisi (HWC)
Bir ekranda tünellenmiş katman (HWC_SIDEBAND compositionType içeren bir katman) olduğunda, katmanın sidebandStream değeri OMX video bileşeni tarafından ayrılan bant dışı tutamaktır.
HWC, tünellenmiş OMX bileşeninden gelen kod çözülmüş video karelerini, ilişkili ses parçasıyla (audio-hw-sync kimliğiyle) senkronize eder. Yeni bir video karesi geçerli hale geldiğinde HWC, bu kareyi son hazırlama veya ayarlama çağrısı sırasında alınan tüm katmanların mevcut içerikleriyle birleştirir ve ortaya çıkan görüntüyü gösterir.
Hazırlama veya ayarlama çağrıları yalnızca diğer katmanlar değiştiğinde ya da yan bant katmanının özellikleri (ör. konum veya boyut) değiştiğinde gerçekleşir.
Aşağıdaki şekil, video karelerini (7b) ses (7c) temelinde doğru zamanda görüntülemek için en son kompozisyonla (7a) birleştirmek üzere donanım (veya çekirdek ya da sürücü) senkronizasyon cihazıyla birlikte çalışan HWC'yi gösterir.

Şekil 4. HWC donanım (veya çekirdek ya da sürücü) senkronizasyon aracı.