Tạo đường hầm đa phương tiện

Đường hầm đa phương tiện (còn gọi là chế độ đường hầm) cho phép dữ liệu video nén đi qua bộ giải mã video phần cứng trực tiếp đến màn hình mà không cần được xử lý bằng mã ứng dụng hoặc mã khung Android. Mã dành riêng cho thiết bị bên dưới ngăn xếp Android sẽ xác định khung hình video nào cần gửi đến màn hình và thời điểm gửi bằng cách so sánh dấu thời gian trình bày khung hình video với một trong các loại đồng hồ nội bộ sau:

  • Đối với chế độ phát video theo yêu cầu trong Android 5 trở lên, đồng hồ AudioTrack được đồng bộ hoá với dấu thời gian trình bày âm thanh được truyền trong ứng dụng

  • Đối với hoạt động phát lại chương trình phát sóng trực tiếp trên Android 11 trở lên, đồng hồ tham chiếu chương trình (PCR) hoặc đồng hồ thời gian hệ thống (STC) do bộ chỉnh kênh điều khiển

Nền

Chế độ phát video không truyền qua đường hầm trên Android thông báo cho ứng dụng khi một khung hình video nén đã được giải mã. Sau đó, ứng dụng sẽ phát khung hình video đã giải mã lên màn hình để hiển thị vào cùng thời điểm đồng hồ hệ thống với khung hình âm thanh tương ứng, truy xuất các phiên bản AudioTimestamp trước đây để tính toán thời gian chính xác.

Vì chế độ phát video được chuyển hướng bỏ qua mã ứng dụng và giảm số lượng quy trình tác động lên video, nên chế độ này có thể mang lại hiệu suất kết xuất video hiệu quả hơn, tuỳ thuộc vào cách triển khai của OEM. Thư viện này cũng có thể cung cấp nhịp điệu và khả năng đồng bộ hoá video chính xác hơn với đồng hồ đã chọn (PRC, STC hoặc âm thanh) bằng cách tránh các vấn đề về thời gian do độ lệch tiềm ẩn giữa thời gian của các yêu cầu Android để kết xuất video và thời gian của các lệnh vsync phần cứng thực. Tuy nhiên, việc tạo đường hầm cũng có thể làm giảm khả năng hỗ trợ các hiệu ứng GPU, chẳng hạn như làm mờ hoặc các góc bo tròn trong cửa sổ hình trong hình (PiP), vì các vùng đệm bỏ qua ngăn xếp đồ hoạ Android.

Sơ đồ sau đây cho thấy cách tạo đường hầm giúp đơn giản hoá quy trình phát video.

so sánh chế độ truyền thống và chế độ đường hầm

Hình 1. So sánh quy trình phát video không được chuyển hướng và được chuyển hướng.

Dành cho nhà phát triển ứng dụng

Vì hầu hết nhà phát triển ứng dụng đều tích hợp với một thư viện để triển khai tính năng phát, nên trong hầu hết các trường hợp, việc triển khai chỉ yêu cầu định cấu hình lại thư viện đó cho tính năng phát qua đường hầm. Để triển khai trình phát video được chuyển hướng ở cấp thấp, hãy làm theo hướng dẫn sau.

Đối với chế độ phát video theo yêu cầu trong Android 5 trở lên:

  1. Tạo một thực thể SurfaceView.

  2. Tạo một thực thể audioSessionId.

  3. Tạo các thực thể AudioTrackMediaCodec bằng thực thể audioSessionId được tạo ở bước 2.

  4. Xếp hàng dữ liệu âm thanh vào AudioTrack bằng dấu thời gian trình bày cho khung âm thanh đầu tiên trong dữ liệu âm thanh.

Đối với chế độ phát lại chương trình phát sóng trực tiếp trên Android 11 trở lên:

  1. Tạo một thực thể SurfaceView.

  2. Nhận một thực thể avSyncHwId từ Tuner.

  3. Tạo các thực thể AudioTrackMediaCodec bằng thực thể avSyncHwId được tạo ở bước 2.

Luồng gọi API được minh hoạ trong các đoạn mã sau:

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);

Hành vi phát video theo yêu cầu

Vì tính năng phát video theo yêu cầu được truyền qua đường hầm có liên kết ngầm với hoạt động phát AudioTrack, nên hành vi phát video được truyền qua đường hầm có thể phụ thuộc vào hành vi phát âm thanh.

  • Theo mặc định, trên hầu hết các thiết bị, khung hình video sẽ không được kết xuất cho đến khi quá trình phát âm thanh bắt đầu. Tuy nhiên, ứng dụng có thể cần kết xuất một khung hình video trước khi bắt đầu phát âm thanh, ví dụ: để cho người dùng thấy vị trí hiện tại của video trong khi tìm kiếm.

    • Để báo hiệu rằng khung hình video đầu tiên trong hàng đợi sẽ được kết xuất ngay khi được giải mã, hãy đặt tham số PARAMETER_KEY_TUNNEL_PEEK thành 1. Khi các khung hình video nén được sắp xếp lại trong hàng đợi (chẳng hạn như khi có khung hình B), điều này có nghĩa là khung hình video đầu tiên được hiển thị phải luôn là khung hình I.

    • Nếu bạn không muốn khung hình video đầu tiên trong hàng đợi được kết xuất cho đến khi quá trình phát âm thanh bắt đầu, hãy đặt tham số này thành 0.

    • Nếu bạn không đặt tham số này, thì OEM sẽ xác định hành vi cho thiết bị.

  • Khi dữ liệu âm thanh không được cung cấp cho AudioTrack và các vùng đệm trống (thiếu dữ liệu âm thanh), quá trình phát video sẽ bị dừng cho đến khi có thêm dữ liệu âm thanh được ghi vì đồng hồ âm thanh không còn hoạt động.

  • Trong quá trình phát, những điểm gián đoạn mà ứng dụng không thể khắc phục có thể xuất hiện trong dấu thời gian trình bày âm thanh. Khi điều này xảy ra, OEM sẽ khắc phục các khoảng trống tiêu cực bằng cách tạm dừng khung hình video hiện tại và khắc phục các khoảng trống tích cực bằng cách loại bỏ khung hình video hoặc chèn khung hình âm thanh im lặng (tuỳ thuộc vào cách triển khai của OEM). Vị trí khung AudioTimestamp không tăng đối với các khung âm thanh im lặng được chèn.

Luồng trình tự của chế độ tua chính xác

Chế độ tua chính xác giúp bạn tìm thấy một vị trí cụ thể trong video. Khác với tính năng tìm kiếm theo khung hình chính (chỉ chuyển đến khung hình I gần nhất và có thể lệch vị trí mục tiêu vài giây), chế độ tua chính xác sẽ kết xuất video tại dấu thời gian được yêu cầu chính xác. Việc tuân thủ trình tự API cụ thể này cho phép ứng dụng thực hiện quá trình tải trước ở chế độ nền và đồng bộ hoá thời gian một cách liền mạch. Điều này đảm bảo khung hình đích hiển thị ngay lập tức khi quá trình phát lại tiếp tục.

Để thực hiện thao tác tìm kiếm chính xác, hãy làm theo thứ tự thực thi minh hoạ trong Hình 2:

luồng tua

Hình 2. Trình tự thao tác để tua chính xác.

Các thông tin chi tiết chính bao gồm:

  • Thực thi song song: Bạn có thể thực thi các bước trong một hộp par duy nhất một cách đồng thời. Ví dụ: cuộc gọi video MediaCodec không phụ thuộc vào AudioTrack.

  • Các phần phụ thuộc tuần tự: Gọi tất cả các thao tác trong hộp par đầu tiên trước khi chuyển sang hộp par thứ hai. Cụ thể, ứng dụng phải đảm bảo rằng AudioTrack.write và các vùng đệm trong MediaCodec video được xếp hàng trước khi gọi AudioTrack.play.

Trình tự phát ở tốc độ có biến đổi

Tính năng phát ở tốc độ thay đổi cho phép bạn phát video ở tốc độ nhanh hơn hoặc chậm hơn tốc độ bình thường. Tính năng này thường được các ứng dụng sử dụng để cho phép người dùng sử dụng nội dung nhanh hơn (chẳng hạn như phát các bài giảng giáo dục hoặc podcast ở tốc độ 1,5x hoặc 2,0x để tiết kiệm thời gian) hoặc chậm hơn (chẳng hạn như phân tích các trận đấu thể thao hoặc video hướng dẫn ở tốc độ 0,5x).

Để đặt tốc độ, hãy làm theo thứ tự thực thi minh hoạ trong Hình 3:

luồng trình tự tốc độ

Hình 3. Trình tự để đặt tốc độ.

Các hành vi và yêu cầu về kỹ thuật sau đây không được ghi lại trong sơ đồ trình tự ở Hình 3:

  • AudioTrack.getTimestamp trả về framePosition dựa trên tần số đầu vào âm thanh ban đầu. Ví dụ: với tốc độ đầu vào 44100 Hz và tốc độ phát 2, 0x, sau khi phát 2 giây, AudioTrack.getTimestamp sẽ trả về framePosition là 176400.

  • Nếu ứng dụng gọi setSpeed(1.5) và thành công, sau đó ứng dụng gọi setSpeed(30) và không thành công, thì tốc độ phát vẫn là 1,5x.

  • Nếu âm thanh bị tắt tiếng (bằng cách dùng setVolume), ứng dụng vẫn phải gửi các vùng đệm âm thanh vì khung hình video được kết xuất dựa trên vị trí âm thanh.

  • Cao độ âm thanh được giữ nguyên khi tốc độ thay đổi.

  • Tốc độ phát không bị ảnh hưởng bởi các thao tác phát khác.

    • Ví dụ 1: Nếu tốc độ phát là 1,5x và AudioTrack đang tạm dừng, thì tốc độ vẫn là 1,5x sau khi tiếp tục AudioTrack.

    • Ví dụ 2: Nếu tốc độ phát là 1,5x và người dùng tìm đến một PTS khác, thì theo Hình 2, tốc độ phát vẫn là 1,5x.

  • Để đảm bảo rằng tất cả khung hình đều được giải mã kịp thời để hiển thị ở tốc độ đã chọn, hãy đặt KEY_OPERATING_RATE sao cho phù hợp với tích của tốc độ khung hình video và tốc độ phát. Nếu KEY_OPERATING_RATE không được đặt đủ cao, thì bộ mã hoá và giải mã có thể không giải mã khung hình đủ nhanh, gây ra hiện tượng giảm khung hình ngoài ý muốn trong quá trình phát.

    • Ví dụ: Nếu tốc độ khung hình gốc của nội dung là 60 khung hình/giây và tốc độ phát là 2x, thì hãy đặt KEY_OPERATING_RATE thành 120.
  • Việc liên tục đặt tốc độ với các tốc độ được hỗ trợ khác nhau sẽ không kích hoạt bất kỳ lỗi nào và hành vi phát sau lệnh gọi cuối cùng sẽ giống như khi tốc độ chỉ được đặt một lần, thành chế độ cài đặt tốc độ gần đây nhất.

Dành cho nhà sản xuất thiết bị

Cấu hình

Các OEM nên tạo một bộ giải mã video riêng để hỗ trợ tính năng phát video qua đường hầm. Bộ giải mã này phải thông báo rằng bộ giải mã có khả năng phát qua đường hầm trong tệp media_codecs.xml:

<Feature name="tunneled-playback" required="true"/>

Khi một thực thể MediaCodec được chuyển kênh được định cấu hình bằng mã nhận dạng phiên âm thanh, thực thể đó sẽ truy vấn AudioFlinger cho mã nhận dạng HW_AV_SYNC này:

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);
}

Trong truy vấn này, AudioFlinger sẽ truy xuất mã nhận dạng HW_AV_SYNC từ thiết bị âm thanh chính và liên kết mã nhận dạng này với mã nhận dạng phiên âm thanh theo cách nội bộ:

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);

Nếu một phiên bản AudioTrack đã được tạo, thì mã nhận dạng HW_AV_SYNC sẽ được truyền đến luồng đầu ra có cùng mã phiên âm thanh. Nếu chưa được tạo, thì mã nhận dạng HW_AV_SYNC sẽ được truyền đến luồng đầu ra trong quá trình tạo AudioTrack. Việc này được thực hiện bằng luồng phát:

mOutput->stream->common.set_parameters(&mOutput->stream->common, AUDIO_PARAMETER_STREAM_HW_AV_SYNC, hwAVSyncId);

Mã nhận dạng HW_AV_SYNC, cho dù mã nhận dạng đó tương ứng với luồng đầu ra âm thanh hay cấu hình Tuner, đều được truyền vào thành phần OMX hoặc Codec2 để mã OEM có thể liên kết bộ mã hoá và giải mã với luồng đầu ra âm thanh tương ứng hoặc luồng bộ chỉnh.

Trong quá trình định cấu hình thành phần, thành phần OMX hoặc Codec2 sẽ trả về một tay cầm phụ có thể dùng để liên kết bộ mã hoá và giải mã với một lớp Hardware Composer (HWC). Khi ứng dụng liên kết một bề mặt với MediaCodec, bộ điều khiển phụ này sẽ được truyền xuống HWC thông qua SurfaceFlinger, giúp định cấu hình lớp dưới dạng lớp phụ.

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 chịu trách nhiệm nhận các vùng đệm hình ảnh mới từ đầu ra của bộ mã hoá và giải mã vào thời điểm thích hợp, được đồng bộ hoá với luồng đầu ra âm thanh được liên kết hoặc đồng hồ tham chiếu chương trình của bộ chỉnh, kết hợp các vùng đệm với nội dung hiện tại của các lớp khác và hiển thị hình ảnh kết quả. Điều này xảy ra độc lập với chu kỳ chuẩn bị và thiết lập thông thường. Các lệnh gọi chuẩn bị và đặt chỉ xảy ra khi các lớp khác thay đổi hoặc khi các thuộc tính của lớp phụ (chẳng hạn như vị trí hoặc kích thước) thay đổi.

OMX

Thành phần bộ giải mã được chuyển hướng qua đường hầm phải hỗ trợ những nội dung sau:

  • Đặt tham số mở rộng OMX.google.android.index.configureVideoTunnelMode, sử dụng cấu trúc ConfigureVideoTunnelModeParams để truyền trong mã nhận dạng HW_AV_SYNC được liên kết với thiết bị đầu ra âm thanh.

  • Định cấu hình tham số OMX_IndexConfigAndroidTunnelPeek để cho biết codec có hiển thị hay không hiển thị khung hình video được giải mã đầu tiên, bất kể quá trình phát âm thanh đã bắt đầu hay chưa.

  • Gửi sự kiện OMX_EventOnFirstTunnelFrameReady khi khung hình video được truyền qua đường hầm đầu tiên đã được giải mã và sẵn sàng hiển thị.

Quá trình triển khai AOSP sẽ định cấu hình chế độ đường hầm trong ACodec thông qua OMXNodeInstance như minh hoạ trong đoạn mã sau:

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;

Nếu thành phần hỗ trợ cấu hình này, thì thành phần đó sẽ phân bổ một giá trị nhận dạng phụ cho codec này và truyền giá trị nhận dạng đó trở lại thông qua thành phần pSidebandWindow để HWC có thể xác định codec được liên kết. Nếu thành phần không hỗ trợ cấu hình này, thì thành phần đó sẽ đặt bTunneled thành OMX_FALSE.

Codec2

Trong Android 11 trở lên, Codec2 hỗ trợ chế độ phát qua đường hầm. Thành phần bộ giải mã phải hỗ trợ những nội dung sau:

  • Định cấu hình C2PortTunneledModeTuning, định cấu hình chế độ đường hầm và truyền trong HW_AV_SYNC được truy xuất từ thiết bị đầu ra âm thanh hoặc cấu hình bộ chỉnh.

  • Truy vấn C2_PARAMKEY_OUTPUT_TUNNEL_HANDLE để phân bổ và truy xuất ô điều khiển phụ cho HWC.

  • Xử lý C2_PARAMKEY_TUNNEL_HOLD_RENDER khi được đính kèm vào C2Work, hướng dẫn bộ mã hoá và giải mã giải mã và báo hiệu hoàn tất công việc, nhưng không hiển thị vùng đệm đầu ra cho đến khi 1) bộ mã hoá và giải mã được hướng dẫn hiển thị vùng đệm đó sau hoặc 2) quá trình phát âm thanh bắt đầu.

  • Xử lý C2_PARAMKEY_TUNNEL_START_RENDER, hướng dẫn bộ mã hoá và giải mã kết xuất ngay khung hình được đánh dấu bằng C2_PARAMKEY_TUNNEL_HOLD_RENDER, ngay cả khi quá trình phát âm thanh chưa bắt đầu.

  • Để debug.stagefright.ccodec_delayed_params ở trạng thái chưa định cấu hình (nên dùng). Nếu bạn định cấu hình, hãy đặt thành false.

Quá trình triển khai AOSP định cấu hình chế độ đường hầm trong CCodec thông qua C2PortTunnelModeTuning, như minh hoạ trong đoạn mã sau:

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, &params);
if (c2err == C2_OK && params.size() == 1u) {
    C2PortTunnelHandleTuning::output *videoTunnelSideband =
            C2PortTunnelHandleTuning::output::From(params[0].get());
    return OK;
}

Nếu thành phần hỗ trợ cấu hình này, thì thành phần đó sẽ phân bổ một tay cầm phụ cho codec này và truyền lại thông qua C2PortTunnelHandlingTuning để HWC có thể xác định codec được liên kết.

HAL âm thanh

Đối với chế độ phát video theo yêu cầu, Audio HAL nhận các dấu thời gian trình chiếu âm thanh cùng với dữ liệu âm thanh ở định dạng big-endian bên trong một tiêu đề nằm ở đầu mỗi khối dữ liệu âm thanh mà ứng dụng ghi:

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 kết xuất các khung hình video đồng bộ với các khung hình âm thanh tương ứng, Audio HAL phải phân tích cú pháp tiêu đề đồng bộ hoá và sử dụng dấu thời gian trình bày để đồng bộ hoá lại đồng hồ phát với quá trình kết xuất âm thanh. Để đồng bộ hoá lại khi âm thanh nén đang phát, Audio HAL có thể cần phân tích cú pháp siêu dữ liệu bên trong dữ liệu âm thanh nén để xác định thời lượng phát.

Tạm dừng hỗ trợ

Android 5 trở xuống không hỗ trợ tính năng tạm dừng. Bạn chỉ có thể tạm dừng quá trình phát qua đường hầm bằng cách thiếu A/V, nhưng nếu bộ đệm trong cho video có kích thước lớn (ví dụ: có 1 giây dữ liệu trong thành phần OMX), thì thao tác tạm dừng sẽ có vẻ không phản hồi.

Trong Android 5.1 trở lên, AudioFlinger hỗ trợ tạm dừng và tiếp tục cho đầu ra âm thanh trực tiếp (được truyền qua đường hầm). Nếu HAL triển khai tính năng tạm dừng và tiếp tục, thì lệnh tạm dừng và tiếp tục theo dõi sẽ được chuyển tiếp đến HAL.

Trình tự gọi tạm dừng, xoá, tiếp tục được tuân thủ bằng cách thực thi các lệnh gọi HAL trong luồng phát (tương tự như giảm tải).

Đề xuất triển khai

HAL âm thanh

Đối với Android 11, bạn có thể sử dụng mã nhận dạng đồng bộ hoá phần cứng từ PCR hoặc STC để đồng bộ hoá âm thanh/hình ảnh, vì vậy, hệ thống có hỗ trợ luồng chỉ có video.

Đối với Android 10 trở xuống, các thiết bị hỗ trợ chế độ phát video qua đường hầm phải có ít nhất một hồ sơ luồng đầu ra âm thanh có cờ FLAG_HW_AV_SYNCAUDIO_OUTPUT_FLAG_DIRECT trong tệp audio_policy.conf. Các cờ này được dùng để đặt đồng hồ hệ thống từ đồng hồ âm thanh.

OMX

Nhà sản xuất thiết bị nên có một thành phần OMX riêng để phát video qua đường hầm (nhà sản xuất có thể có các thành phần OMX bổ sung cho các loại phát âm thanh và video khác, chẳng hạn như phát an toàn). Thành phần được chuyển hầm phải:

  • Chỉ định 0 vùng đệm (nBufferCountMin, nBufferCountActual) trên cổng đầu ra của vùng đệm.

  • Triển khai tiện ích OMX.google.android.index.prepareForAdaptivePlayback setParameter.

  • Chỉ định các chức năng của tính năng này trong tệp media_codecs.xml và khai báo tính năng phát qua đường hầm. Bạn cũng nên nêu rõ mọi hạn chế về kích thước khung hình, độ căn chỉnh hoặc tốc độ bit. Sau đây là ví dụ minh hoạ:

    <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>
    

Nếu cùng một thành phần OMX được dùng để hỗ trợ việc giải mã có đường hầm và không có đường hầm, thì thành phần đó sẽ để tính năng phát có đường hầm ở trạng thái không bắt buộc. Cả bộ giải mã được chuyển hướng và không được chuyển hướng đều có cùng các hạn chế về khả năng. Sau đây là ví dụ minh hoạ:

<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>

Hardware Composer (HWC)

Khi có một lớp được chuyển hướng (lớp có HWC_SIDEBAND compositionType) trên màn hình, sidebandStream của lớp đó là tay cầm phụ được thành phần video OMX phân bổ.

HWC đồng bộ hoá các khung hình video đã giải mã (từ thành phần OMX được truyền qua đường hầm) với bản âm thanh được liên kết (có mã nhận dạng audio-hw-sync). Khi một khung hình video mới trở thành khung hình hiện tại, HWC sẽ kết hợp khung hình đó với nội dung hiện tại của tất cả các lớp nhận được trong lệnh gọi chuẩn bị hoặc đặt gần đây nhất và hiển thị hình ảnh kết quả. Các lệnh gọi chuẩn bị hoặc đặt chỉ xảy ra khi các lớp khác thay đổi hoặc khi các thuộc tính của lớp phụ (chẳng hạn như vị trí hoặc kích thước) thay đổi.

Hình sau đây minh hoạ HWC hoạt động với bộ đồng bộ hoá phần cứng (hoặc nhân hoặc trình điều khiển), để kết hợp các khung hình video (7b) với thành phần mới nhất (7a) để hiển thị vào đúng thời điểm, dựa trên âm thanh (7c).

HWC kết hợp các khung hình video dựa trên âm thanh

Hình 4. Trình đồng bộ hoá phần cứng (hoặc nhân hoặc trình điều khiển) HWC.