Multimedya tünellemesi, sıkıştırılmış video verilerinin bir donanım aracılığıyla tünellenmesine olanak tanır video kod çözücüyü uygulama kodu tarafından işlenmeden veya doğrudan bir ekrana Android çerçeve kodu. Android yığınının altındaki cihaza özel kod Hangi video karelerinin ekrana gönderileceğini ve bunların ne zaman gönderileceğini belirler video karesi sunu zaman damgalarını aşağıdakilerden biriyle karşılaştırarak iç saat türleri:
Android 5 veya sonraki sürümlerde isteğe bağlı video oynatma için
AudioTrack
saat sesli sunu zaman damgalarıyla senkronize edildi geçti uygulama tarafındanAndroid 11 veya sonraki sürümlerde canlı yayın oynatma için program referans saati (PCR) veya sistem saati (STC) kanal tarayıcı
Arka plan
Android'de geleneksel video oynatma için bildirim alır
Sıkıştırılmış bir video karesinin kodu çözüldüğünde uygulama. Ardından, uygulama
sürümler
kodu çözülmüş video karesini, aynı sistem saatinde oluşturulacak şekilde ekrana
konuşma süresini seçerek
geçmiş alma
AudioTimestamps
doğru zamanlamayı hesaplamak için
örneklerden yararlanırız.
Tünelli video oynatma, uygulama kodunu atlayıp işleme koymazsanız, videonun daha etkili bir şekilde oluşturulması için farklılık gösterebilir. Ayrıca daha doğru videolar sunabilir ritmi ve senkronizasyonu ayarlayarak, her zaman Android'in zamanlaması arasında olası bir sapma nedeniyle zamanlama sorunları istekleri ve gerçek donanım vsync'lerinin zamanlamasını kontrol edin. Ancak, tünel kullanımı, trafik izleme gibi GPU efektlerine yönelik desteği de bulanıklaştırma pencere içinde pencere (PiP) pencerelerinde yuvarlatılmış köşeler veya yuvarlatılmış köşeler olduğundan Android grafik grubunu atla.
Aşağıdaki şemada, tünellemenin video oynatma sürecini nasıl basitleştirdiği gösterilmektedir.
Şekil 1. Geleneksel ve tünelli video oynatma süreçlerinin karşılaştırılması
Uygulama geliştiriciler için
Çoğu uygulama geliştirici, oynatmak için bir kitaplıkla entegre olduğundan çoğu durumda, uygulama sürecinin tamamlanması için kitaplığını kullanabilirsiniz. Tünelli videonun alt düzey uygulaması için oynatıcıda kullanmak için aşağıdaki talimatları uygulayı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.audioSessionId
ileAudioTrack
veMediaCodec
örnekleri oluşturun örneği oluşturulur.Ses verilerini
AudioTrack
için sunu zaman damgasıyla ses verilerindeki ilk ses karesi.
Android 11 veya sonraki sürümlerde canlı yayın oynatma için:
SurfaceView
örneği oluşturun.Tuner
sitesinden biravSyncHwId
örneği alın.avSyncHwId
örneğiyleAudioTrack
veMediaCodec
örnekleri oluşturma otomatik olarak oluşturulur.
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 oynatma davranışı
Tünel ile seç-izle video oynatma özelliği AudioTrack
ile dolaylı olarak bağlantılı olduğu için
veya tünelle video oynatmanın davranışı
mevcut.
Çoğu cihazda varsayılan olarak sese kadar video karesi oluşturulmaz oynatma başlar. Ancak, uygulamanın video karesi oluşturmadan önce ses çalmayı başlatma (örneğin, kullanıcıya mevcut videoyu göstermek için) konumunu izleyebilirsiniz.
Sıraya alınan ilk video karesinin en kısa sürede oluşturulması gerektiğini belirtmek için kodu çözülmüşse
PARAMETER_KEY_TUNNEL_PEEK
parametresini1
olarak ayarlayın. Sıkıştırılmış video kareleri sırada yeniden sıralandığında (örneğin, B-kareler varsa, bu, gösterilen ilk video karesinin her zaman I-çerçeve.Sese kadar sıraya alınan ilk video karesinin oluşturulmasını istemiyorsanız oynatma başladığında bu parametreyi
0
olarak ayarlayın.Bu parametre ayarlanmazsa cihazın davranışını OEM belirler.
Ses verileri
AudioTrack
adlı cihaza sağlanmadığında ve arabellekler boş olduğunda (ses az ses), daha fazla ses verisi yazılana kadar video oynatma durur çünkü ses saati artık ileri sürmüyor.Oynatma sırasında, uygulamanın düzeltemeyeceği kesintiler şurada görünebilir: ses sunumu zaman damgalarını kapsıyor. Böyle bir durumda OEM, negatif anahtar kelimeleri düzeltir durmadan oluşan mevcut video karesini ve videonun sonlarına doğru video karesini durdurarak video kareleri ekleme veya sessiz ses kareleri ekleme (OEM'ye bağlı olarak) bakın).
AudioTimestamp
kare konumu sessiz ses kareleri eklendi.
Cihaz üreticileri için
Yapılandırma
OEM'ler, tünelli video oynatmayı desteklemek için ayrı bir video kod çözücü oluşturmalıdır.
Bu kod çözücü,
media_codecs.xml
dosyası:
<Feature name="tunneled-playback" required="true"/>
Tünelli MediaCodec
örneği, ses oturum kimliğiyle yapılandırıldığında
bu HW_AV_SYNC
kimliği için AudioFlinger
sorgusu:
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
, HW_AV_SYNC
kimliğini alır
birincil ses cihazından çıkarır ve bunu dahili olarak sesle ilişkilendirir
oturum kimliği:
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 oluşturulmuşsa HW_AV_SYNC
kimliği
aynı ses oturum kimliğiyle çıkış akışına iletilir. Görmediyse
oluşturulursa HW_AV_SYNC
kimliği, sırasında çıkış akışına iletilir
AudioTrack
oluşturuldu. Bu işlem, oynatma tarafından
ileti dizisi:
mOutput->stream->common.set_parameters(&mOutput->stream->common, AUDIO_PARAMETER_STREAM_HW_AV_SYNC, hwAVSyncId);
HW_AV_SYNC
kimliği (ses çıkış akışına karşılık gelir veya
Tuner
yapılandırması, OMX veya Codec2 bileşenine aktarılır. Böylece,
OEM kodu, codec'i ilgili ses çıkış akışıyla ilişkilendirebilir veya
akarsulara ulaşabilirsiniz.
Bileşen yapılandırması sırasında OMX veya Codec2 bileşeni,
codec'i Donanım Oluşturucu ile ilişkilendirmek için kullanılabilecek yan bant işleyici
(HWC) katmanını kapsayabilir. Uygulama bir yüzeyi MediaCodec
ile ilişkilendirdiğinde, bu yan bant
herkese açık kullanıcı adı, SurfaceFlinger
aracılığıyla HWC'ye geçirilir ve bu işlem
katmanını
yan bant katmanını kullanın.
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, ya da ses çıkışı akışıyla senkronize edilmelidir. tarayıcı programı referans saatine göre, tamponları mevcut ve sonuçta elde edilen resmi görüntüleyebilirsiniz. Bu durum normal hazırlama ve ayarlama döngüsünden bağımsızdır. Görüşmeleri hazırlama ve belirleme yalnızca diğer katmanlar değiştiğinde veya yan bant katmanının özellikleri değiştiğinde ortaya çıkar (konum veya boyut gibi) değişikliğine neden olabilir.
OMX
Tünelli kod çözücü bileşeni aşağıdakileri desteklemelidir:
Genişletilmiş
OMX.google.android.index.configureVideoTunnelMode
ayarlanıyor parametresini içeren birConfigureVideoTunnelModeParams
ses çıkış cihazıyla ilişkilendirilenHW_AV_SYNC
kimliğinde.Şuna bildiren
OMX_IndexConfigAndroidTunnelPeek
parametresini yapılandırmak: ilk kodu çözülmüş video karesini oluşturmaya veya oluşturmamaya başlatılıp başlatılmadığı anlamına gelir.İlk tünel protokolü alındığında
OMX_EventOnFirstTunnelFrameReady
etkinliği gönderiliyor video karesinin kodu çözüldü ve oluşturulmaya hazır.
AOSP uygulaması, tünel modunu
ACodec
-
OMXNodeInstance
aşağıdaki kod snippet'inde gösterildiği gibidir:
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 bir yan bant ayırması gerekir.
bu codec'i işleyebilir ve pSidebandWindow
üyesi üzerinden geri iletebilirsiniz.
için, HWC'nin ilişkili codec'i tanımlayabilmesini sağlar. Bileşen çalışmazsa
bTunneled
, OMX_FALSE
olarak ayarlanmalıdır.
Codec2
Codec2
, Android 11 veya sonraki sürümlerde tünelli oynatmayı destekler. Kod çözücü
bileşeni aşağıdakileri desteklemelidir:
Tünel modunu yapılandıran
C2PortTunneledModeTuning
yapılandırılıyor ve ses çıkış cihazından alınanHW_AV_SYNC
içinde geçer veya kanal ayarlayıcı konfigürasyonunu içerir.C2_PARAMKEY_OUTPUT_TUNNEL_HANDLE
sorgusu sorgulanıyor, HWC için yan bant tutma yeri.Bir
C2Work
öğesine eklendiğindeC2_PARAMKEY_TUNNEL_HOLD_RENDER
işleniyor. codec'e işin tamamlandığına dair kodu çözmesi ve bunu belirtmek için talimat verir, ancak kodu işleme 1) codec'e daha sonra kodu oluşturma talimatı verilir veya 2) ses çalmaya başlar.codec'e şu komutu veren
C2_PARAMKEY_TUNNEL_START_RENDER
işleniyor: işaretli kareyi hemen oluşturur Ses çalma başlamamış olsa bileC2_PARAMKEY_TUNNEL_HOLD_RENDER
.debug.stagefright.ccodec_delayed_params
ürününü yapılandırılmamış olarak bırakın (önerilir). Eğer yapılandırdıysanızfalse
olarak ayarlayın.
AOSP uygulaması, tünel modunu
CCodec
aşağıdaki kod snippet'inde gösterildiği gibi C2PortTunnelModeTuning
aracılığıyla:
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 bir yan bant ayırması gerekir.
bu codec'i işleyip C2PortTunnelHandlingTuning
üzerinden geri aktarın.
için, HWC'nin ilişkili codec'i tanımlayabilmesini sağlar.
Ses HAL'si
Ses HAL, isteğe bağlı video oynatımı için ses sunumunu alır bir başlık içinde büyük-endian biçiminde ses verileriyle satır içi zaman damgaları bulundu uygulamanın yazdığı her ses verisi bloğunun başında:
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 karşılık gelen ses kareleriyle senkronize olarak oluşturması için Ses HAL'nin, senkronizasyon başlığını ayrıştırarak ve sunum zaman damgasını kullanarak oynatma saatini ses oluşturma ile yeniden senkronize eder. Yeniden senkronize etmek için sıkıştırılmış ses çalınıyorsa Ses HAL'nin meta verileri ayrıştırması gerekebilir. sıkıştırılmış ses verilerinin içine girerek oynatma süresini belirleyebilirsiniz.
Desteği duraklat
Android 5 veya önceki sürümlerde duraklatma desteği yoktur. Tünel kullanımını duraklatabilirsiniz yalnızca A/V açıldıktan sonra oynatılabilir, ancak videonun dahili arabelleği büyükse (örneğin, OMX bileşeninde bir saniyelik veri vardır), bu da tepki vermez.
Android 5.1 veya sonraki sürümlerde AudioFlinger
, doğrudan erişim için duraklatma ve devam ettirmeyi destekler
(tünelli) ses çıkışları oluşturun. HAL'de duraklatma ve devam ettirme uyguluyorsa izleme işlemini duraklat
ve öz geçmiş HAL’ye yönlendirilir.
Duraklatma, boşaltma ve devam ettirme çağrısı sırası, HAL çağrıları yürütülerek uygulanır oynatma ileti dizisinde de (boşlukla aynı) yer alır.
Uygulama önerileri
Ses HAL'si
Android 11'de PCR veya STC'deki HW senkronizasyon kimliği, A/V senkronizasyonu için kullanılabilir. yalnızca video akışı desteklenir.
Android 10 veya önceki sürümler için tünelli video oynatmayı destekleyen cihazlarda
FLAG_HW_AV_SYNC
içeren en az bir ses çıkış yayın profili ve
audio_policy.conf
dosyasında AUDIO_OUTPUT_FLAG_DIRECT
işareti mevcut. Bu işaretler
sistem saatini ses saatinden ayarlamak için kullanılır.
OMX
Cihaz üreticileri, tünelli video için ayrı bir OMX bileşenine sahip olmalıdır. (üreticiler, diğer türler için ek OMX bileşenlerine ses ve video oynatma (ör. güvenli oynatma) Tünelli bileşen gereken:
Çıkışında 0 arabellek (
nBufferCountMin
,nBufferCountActual
) belirtin bağlantı noktası.OMX.google.android.index.prepareForAdaptivePlayback setParameter
uzantısını uygulayın.media_codecs.xml
dosyasında özelliklerini belirtin ve tünelle oynatma özelliğini kullanabilirsiniz. Aynı zamanda kareyle ilgili sınırlamaları da net bir şekilde veya bit hızı gibi sorunları çözmek için kullanılabilir. Aşağıda bununla ilgili 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ünelli ve tünelsiz kod çözmeyi desteklemek için aynı OMX bileşeni kullanılıyorsa tünelli oynatma özelliğini gerekli değil olarak bırakır. Hem tünelli hem de Tünelsiz kod çözücüler de aynı kapasite sınırlamalarına sahiptir. Örneğin, aşağıda 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 Oluşturucu (HWC)
üzerinde tünel protokolü (compositionType
HWC_SIDEBAND
içeren katman) olduğunda
katmanın sidebandStream
özelliği,
OMX video bileşeni.
HWC, kodu çözülmüş video karelerini (tünelli OMX bileşeninden)
ilişkilendirilmiş ses parçası (audio-hw-sync
kimliğiyle birlikte). Yeni bir video karesi
güncel hale geldiğinde, HWC bunu tüm katmanların mevcut içeriğiyle birleştirir.
sırasında alınan kararları belirtir ve elde edilen resmi gösterir.
Hazırlama veya ayarlama çağrıları yalnızca diğer katmanlar değiştiğinde veya
özellikleri (konum veya boyut gibi) değişir.
Aşağıdaki şekilde, donanım (veya çekirdek ya da video karelerini (7b) en son besteyle birleştirmek için senkronizasyon aracı (7a) Ses'e göre (7c) doğru zamanda gösterilmesi için.
Şekil 2. HWC donanım (veya çekirdek ya da sürücü) senkronize edici